1#![deny(missing_copy_implementations, trivial_numeric_casts, trivial_casts, unused_extern_crates,
2 unused_import_braces, unused_qualifications)]
3
4extern crate fnv;
5extern crate xml;
6
7use std::io::prelude::*;
8use std::str::FromStr;
9
10use xml::reader::{EventReader, XmlEvent};
11use xml::attribute::OwnedAttribute;
12
13pub mod error;
14use error::{Error, ErrorReason};
15use fnv::FnvHashMap;
16
17mod elements;
18pub use elements::{Bounds, Coordinate, Id, Member, Node, Reference, Relation, Role, Tag,
19 UnresolvedReference, Way};
20mod polygon;
21
22#[derive(Debug)]
23pub struct OSM {
24 pub bounds: Option<Bounds>,
25 pub nodes: FnvHashMap<Id, Node>,
26 pub ways: FnvHashMap<Id, Way>,
27 pub relations: FnvHashMap<Id, Relation>,
28}
29
30impl OSM {
31 fn empty() -> OSM {
32 OSM {
33 bounds: None,
34 nodes: FnvHashMap::default(),
35 ways: FnvHashMap::default(),
36 relations: FnvHashMap::default(),
37 }
38 }
39
40 pub fn parse<R: Read>(source: R) -> Result<OSM, Error> {
41 let mut osm = OSM::empty();
42
43 let mut parser = EventReader::new(source);
44
45 loop {
46 match parse_element_data(&mut parser) {
47 Err(Error::XmlParseError(err)) => return Err(Error::XmlParseError(err)),
48 Err(Error::BoundsMissing(_)) => osm.bounds = None,
49 Err(Error::MalformedTag(_)) |
50 Err(Error::MalformedNode(_)) |
51 Err(Error::MalformedWay(_)) |
52 Err(Error::MalformedRelation(_)) |
53 Err(Error::UnknownElement) => continue,
54 Ok(data) => match data {
55 ElementData::EndOfDocument => return Ok(osm),
56 ElementData::Ignored => continue,
57 ElementData::Bounds(minlat, minlon, maxlat, maxlon) => {
58 osm.bounds = Some(Bounds {
59 minlat: minlat,
60 minlon: minlon,
61 maxlat: maxlat,
62 maxlon: maxlon,
63 });
64 }
65 ElementData::Node(id, lat, lon, tags) => {
66 osm.nodes.insert(
67 id,
68 Node {
69 id: id,
70 lat: lat,
71 lon: lon,
72 tags: tags,
73 },
74 );
75 }
76 ElementData::Way(id, node_refs, tags) => {
77 osm.ways.insert(
78 id,
79 Way {
80 id: id,
81 nodes: node_refs,
82 tags: tags,
83 },
84 );
85 }
86 ElementData::Relation(relation) => {
87 osm.relations.insert(relation.id, relation);
88 }
89 },
90 }
91 }
92 }
93
94 pub fn resolve_reference<'a>(&self, reference: &UnresolvedReference) -> Reference {
95 match *reference {
96 UnresolvedReference::Node(id) => self.nodes
97 .get(&id)
98 .map(Reference::Node)
99 .unwrap_or(Reference::Unresolved),
100 UnresolvedReference::Way(id) => self.ways
101 .get(&id)
102 .map(Reference::Way)
103 .unwrap_or(Reference::Unresolved),
104 UnresolvedReference::Relation(id) => self.relations
105 .get(&id)
106 .map(Reference::Relation)
107 .unwrap_or(Reference::Unresolved),
108 }
109 }
110}
111
112enum ElementType {
113 Bounds,
114 Node,
115 Way,
116 Relation,
117 Tag,
118 NodeRef,
119 Member,
120}
121
122enum ElementData {
123 Bounds(Coordinate, Coordinate, Coordinate, Coordinate),
124 Node(Id, Coordinate, Coordinate, Vec<Tag>),
125 Way(Id, Vec<UnresolvedReference>, Vec<Tag>),
126 Relation(Relation),
127 EndOfDocument,
130 Ignored,
131}
132
133
134impl FromStr for ElementType {
135 type Err = Error;
136
137 fn from_str(s: &str) -> Result<ElementType, Error> {
138 match s.to_lowercase().as_ref() {
139 "bounds" => Ok(ElementType::Bounds),
140 "node" => Ok(ElementType::Node),
141 "way" => Ok(ElementType::Way),
142 "relation" => Ok(ElementType::Relation),
143 "tag" => Ok(ElementType::Tag),
144 "nd" => Ok(ElementType::NodeRef),
145 "member" => Ok(ElementType::Member),
146 _ => Err(Error::UnknownElement),
147 }
148 }
149}
150
151fn parse_element_data<R: Read>(parser: &mut EventReader<R>) -> Result<ElementData, Error> {
152 let element = try!(parser.next());
153 match element {
154 XmlEvent::EndDocument => Ok(ElementData::EndOfDocument),
155 XmlEvent::StartElement {
156 name, attributes, ..
157 } => {
158 let element_type = try!(ElementType::from_str(&name.local_name));
159
160 match element_type {
161 ElementType::Bounds => parse_bounds(&attributes),
162 ElementType::Node => parse_node(parser, &attributes),
163 ElementType::Way => parse_way(parser, &attributes),
164 ElementType::Relation => parse_relation(parser, &attributes),
165 _ => Err(Error::UnknownElement),
166 }
167 }
168 _ => Ok(ElementData::Ignored),
169 }
170}
171
172fn parse_relation<R: Read>(
173 parser: &mut EventReader<R>,
174 attrs: &Vec<OwnedAttribute>,
175) -> Result<ElementData, Error> {
176 let id = try!(find_attribute("id", attrs).map_err(Error::MalformedRelation));
177
178 let mut members = Vec::new();
179 let mut tags = Vec::new();
180
181 loop {
182 match try!(parser.next()) {
183 XmlEvent::EndElement { name } => {
184 let element_type = try!(ElementType::from_str(&name.local_name));
185
186 match element_type {
187 ElementType::Relation => {
188 return Ok(ElementData::Relation(Relation {
189 id: id,
190 members: members,
191 tags: tags,
192 }))
193 }
194 _ => continue,
195 }
196 }
197 XmlEvent::StartElement {
198 name, attributes, ..
199 } => {
200 let element_type = try!(ElementType::from_str(&name.local_name));
201
202 match element_type {
203 ElementType::Tag => if let Ok(tag) = parse_tag(&attributes) {
204 tags.push(tag);
205 },
206 ElementType::Member => {
207 let el_type = try!(
208 find_attribute_uncasted("type", &attributes)
209 .map_err(Error::MalformedRelation)
210 );
211 let el_ref = try!(
212 find_attribute("ref", &attributes).map_err(Error::MalformedRelation)
213 );
214 let el_role = try!(
215 find_attribute_uncasted("role", &attributes)
216 .map_err(Error::MalformedRelation)
217 );
218
219 let el = match el_type.to_lowercase().as_ref() {
220 "node" => Member::Node(UnresolvedReference::Node(el_ref), el_role),
221 "way" => Member::Way(UnresolvedReference::Way(el_ref), el_role),
222 "relation" => {
223 Member::Relation(UnresolvedReference::Relation(el_ref), el_role)
224 }
225 _ => return Err(Error::MalformedRelation(ErrorReason::Missing)),
226 };
227
228 members.push(el);
229 }
230 ElementType::Bounds |
231 ElementType::Node |
232 ElementType::Relation |
233 ElementType::Way |
234 ElementType::NodeRef => {
235 return Err(Error::MalformedRelation(ErrorReason::IllegalNesting))
236 }
237 }
238 }
239 _ => continue,
240 }
241 }
242}
243
244fn parse_way<R: Read>(
245 parser: &mut EventReader<R>,
246 attrs: &Vec<OwnedAttribute>,
247) -> Result<ElementData, Error> {
248 let id = try!(find_attribute("id", attrs).map_err(Error::MalformedWay));
249
250 let mut node_refs = Vec::new();
251 let mut tags = Vec::new();
252
253 loop {
254 match try!(parser.next()) {
255 XmlEvent::EndElement { name } => {
256 let element_type = try!(ElementType::from_str(&name.local_name));
257
258 match element_type {
259 ElementType::Way => return Ok(ElementData::Way(id, node_refs, tags)),
260 _ => continue,
261 }
262 }
263 XmlEvent::StartElement {
264 name, attributes, ..
265 } => {
266 let element_type = try!(ElementType::from_str(&name.local_name));
267
268 match element_type {
269 ElementType::Tag => if let Ok(tag) = parse_tag(&attributes) {
270 tags.push(tag);
271 },
272 ElementType::NodeRef => {
273 let node_ref =
274 try!(find_attribute("ref", &attributes).map_err(Error::MalformedWay));
275 node_refs.push(UnresolvedReference::Node(node_ref));
276 }
277 ElementType::Bounds |
278 ElementType::Node |
279 ElementType::Relation |
280 ElementType::Way |
281 ElementType::Member => {
282 return Err(Error::MalformedWay(ErrorReason::IllegalNesting))
283 }
284 }
285 }
286 _ => continue,
287 }
288 }
289}
290
291fn parse_node<R: Read>(
292 parser: &mut EventReader<R>,
293 attrs: &Vec<OwnedAttribute>,
294) -> Result<ElementData, Error> {
295 let id = try!(find_attribute("id", attrs).map_err(Error::MalformedNode));
296 let lat = try!(find_attribute("lat", attrs).map_err(Error::MalformedNode));
297 let lon = try!(find_attribute("lon", attrs).map_err(Error::MalformedNode));
298
299 let mut tags = Vec::new();
300
301 loop {
302 match try!(parser.next()) {
303 XmlEvent::EndElement { name } => {
304 let element_type = try!(ElementType::from_str(&name.local_name));
305
306 match element_type {
307 ElementType::Node => return Ok(ElementData::Node(id, lat, lon, tags)),
308 _ => continue,
309 }
310 }
311 XmlEvent::StartElement {
312 name, attributes, ..
313 } => {
314 let element_type = try!(ElementType::from_str(&name.local_name));
315
316 match element_type {
317 ElementType::Tag => if let Ok(tag) = parse_tag(&attributes) {
318 tags.push(tag);
319 },
320 ElementType::Bounds |
321 ElementType::Node |
322 ElementType::Relation |
323 ElementType::Way |
324 ElementType::NodeRef |
325 ElementType::Member => {
326 return Err(Error::MalformedNode(ErrorReason::IllegalNesting))
327 }
328 }
329 }
330 _ => continue,
331 }
332 }
333}
334
335fn parse_tag(attributes: &Vec<OwnedAttribute>) -> Result<Tag, Error> {
336 let key = try!(find_attribute_uncasted("k", attributes).map_err(Error::MalformedTag));
337 let val = try!(find_attribute_uncasted("v", attributes).map_err(Error::MalformedTag));
338 Ok(Tag { key: key, val: val })
339}
340
341fn parse_bounds(attrs: &Vec<OwnedAttribute>) -> Result<ElementData, Error> {
342 let minlat = try!(find_attribute("minlat", attrs).map_err(Error::BoundsMissing));
343 let minlon = try!(find_attribute("minlon", attrs).map_err(Error::BoundsMissing));
344 let maxlat = try!(find_attribute("maxlat", attrs).map_err(Error::BoundsMissing));
345 let maxlon = try!(find_attribute("maxlon", attrs).map_err(Error::BoundsMissing));
346
347 Ok(ElementData::Bounds(minlat, minlon, maxlat, maxlon))
348}
349
350fn find_attribute<T>(name: &str, attrs: &Vec<OwnedAttribute>) -> Result<T, ErrorReason>
351where
352 ErrorReason: From<<T as std::str::FromStr>::Err>,
353 T: FromStr,
354{
355 let val_raw = try!(find_attribute_uncasted(name, attrs));
356 let val = try!(val_raw.parse::<T>());
357 Ok(val)
358}
359
360fn find_attribute_uncasted(name: &str, attrs: &Vec<OwnedAttribute>) -> Result<String, ErrorReason> {
361 let attr = attrs.iter().find(|attr| attr.name.local_name == name);
362 match attr {
363 Some(a) => Ok(a.value.clone()),
364 None => Err(ErrorReason::Missing),
365 }
366}