A Rust library for reading the OpenStreetMap PBF file format (*.osm.pbf).

elements.rs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. //! Nodes, ways and relations
  2. use errors::*;
  3. use block::str_from_stringtable;
  4. use proto::osmformat::PrimitiveBlock;
  5. use proto::osmformat;
  6. use std;
  7. /// An OpenStreetMap node element (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Node)).
  8. pub struct Node<'a> {
  9. block: &'a PrimitiveBlock,
  10. osmnode: &'a osmformat::Node,
  11. }
  12. impl<'a> Node<'a> {
  13. pub(crate) fn new(block: &'a PrimitiveBlock, osmnode: &'a osmformat::Node) -> Node<'a> {
  14. Node {
  15. block: block,
  16. osmnode: osmnode,
  17. }
  18. }
  19. /// Returns the node id. It should be unique between nodes and might be negative to indicate
  20. /// that the element has not yet been uploaded to a server.
  21. pub fn id(&self) -> i64 {
  22. self.osmnode.get_id()
  23. }
  24. /// Returns an iterator over the tags of this node (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Tags)).
  25. pub fn tags(&self) -> TagIter<'a> {
  26. TagIter {
  27. block: self.block,
  28. key_indices: self.osmnode.get_keys().iter(),
  29. val_indices: self.osmnode.get_vals().iter(),
  30. }
  31. }
  32. /// Returns additional metadata for this element.
  33. pub fn info(&self) -> Info<'a> {
  34. Info::new(self.block, self.osmnode.get_info())
  35. }
  36. /// Returns the latitude coordinate in degrees.
  37. pub fn lat(&self) -> f64 {
  38. 0.000_000_001_f64 * (self.block.get_lat_offset() +
  39. (i64::from(self.block.get_granularity()) *
  40. self.osmnode.get_lat())) as f64
  41. }
  42. /// Returns the longitude coordinate in degrees.
  43. pub fn lon(&self) -> f64 {
  44. 0.000_000_001_f64 * (self.block.get_lon_offset() +
  45. (i64::from(self.block.get_granularity()) *
  46. self.osmnode.get_lon())) as f64
  47. }
  48. }
  49. /// An OpenStreetMap way element (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Way)).
  50. ///
  51. /// A way contains an ordered list of node references that can be accessed with the `refs` or the
  52. /// `refs_slice` method.
  53. pub struct Way<'a> {
  54. block: &'a PrimitiveBlock,
  55. osmway: &'a osmformat::Way,
  56. }
  57. impl<'a> Way<'a> {
  58. pub(crate) fn new(block: &'a PrimitiveBlock, osmway: &'a osmformat::Way) -> Way<'a> {
  59. Way {
  60. block: block,
  61. osmway: osmway,
  62. }
  63. }
  64. /// Returns the way id.
  65. pub fn id(&self) -> i64 {
  66. self.osmway.get_id()
  67. }
  68. /// Returns an iterator over the tags of this way (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Tags)).
  69. pub fn tags(&self) -> TagIter<'a> {
  70. TagIter {
  71. block: self.block,
  72. key_indices: self.osmway.get_keys().iter(),
  73. val_indices: self.osmway.get_vals().iter(),
  74. }
  75. }
  76. /// Returns additional metadata for this element.
  77. pub fn info(&self) -> Info<'a> {
  78. Info::new(self.block, self.osmway.get_info())
  79. }
  80. /// Returns an iterator over the references of this way. Each reference should correspond to a
  81. /// node id.
  82. pub fn refs(&self) -> WayRefIter<'a> {
  83. WayRefIter {
  84. deltas: self.osmway.get_refs().iter(),
  85. current: 0,
  86. }
  87. }
  88. /// Returns a slice of references. Each reference should correspond to a node id.
  89. pub fn refs_slice(&self) -> &[i64] {
  90. self.osmway.get_refs()
  91. }
  92. }
  93. /// An OpenStreetMap relation element (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Relation)).
  94. ///
  95. /// A relation contains an ordered list of members that can be of any element type.
  96. pub struct Relation<'a> {
  97. block: &'a PrimitiveBlock,
  98. osmrel: &'a osmformat::Relation,
  99. }
  100. impl<'a> Relation<'a> {
  101. pub(crate) fn new(block: &'a PrimitiveBlock, osmrel: &'a osmformat::Relation) -> Relation<'a> {
  102. Relation {
  103. block: block,
  104. osmrel: osmrel,
  105. }
  106. }
  107. /// Returns the relation id.
  108. pub fn id(&self) -> i64 {
  109. self.osmrel.get_id()
  110. }
  111. /// Returns an iterator over the tags of this relation (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Tags)).
  112. pub fn tags(&self) -> TagIter<'a> {
  113. TagIter {
  114. block: self.block,
  115. key_indices: self.osmrel.get_keys().iter(),
  116. val_indices: self.osmrel.get_vals().iter(),
  117. }
  118. }
  119. /// Returns additional metadata for this element.
  120. pub fn info(&self) -> Info<'a> {
  121. Info::new(self.block, self.osmrel.get_info())
  122. }
  123. /// Returns an iterator over the members of this relation.
  124. pub fn members(&self) -> RelMemberIter<'a> {
  125. RelMemberIter::new(self.block, self.osmrel)
  126. }
  127. }
  128. /// An iterator over the references of a way.
  129. ///
  130. /// Each reference corresponds to a node id.
  131. pub struct WayRefIter<'a> {
  132. deltas: std::slice::Iter<'a, i64>,
  133. current: i64,
  134. }
  135. impl<'a> Iterator for WayRefIter<'a> {
  136. type Item = i64;
  137. fn next(&mut self) -> Option<Self::Item> {
  138. match self.deltas.next() {
  139. Some(&d) => {
  140. self.current += d;
  141. Some(self.current)
  142. },
  143. None => None,
  144. }
  145. }
  146. fn size_hint(&self) -> (usize, Option<usize>) {
  147. self.deltas.size_hint()
  148. }
  149. }
  150. impl<'a> ExactSizeIterator for WayRefIter<'a> {}
  151. /// The element type of a relation member.
  152. pub enum RelMemberType {
  153. Node,
  154. Way,
  155. Relation
  156. }
  157. impl From<osmformat::Relation_MemberType> for RelMemberType {
  158. fn from(rmt: osmformat::Relation_MemberType) -> RelMemberType {
  159. match rmt {
  160. osmformat::Relation_MemberType::NODE => RelMemberType::Node,
  161. osmformat::Relation_MemberType::WAY => RelMemberType::Way,
  162. osmformat::Relation_MemberType::RELATION => RelMemberType::Relation,
  163. }
  164. }
  165. }
  166. //TODO encapsulate member_id based on member_type (NodeId, WayId, RelationId)
  167. /// A member of a relation.
  168. ///
  169. /// Each member has a member type and a member id that references an element of that type.
  170. pub struct RelMember<'a> {
  171. block: &'a PrimitiveBlock,
  172. pub role_sid: i32,
  173. pub member_id: i64,
  174. pub member_type: RelMemberType,
  175. }
  176. impl<'a> RelMember<'a> {
  177. /// Returns the role of a relation member.
  178. pub fn role(&self) -> Result<&'a str> {
  179. str_from_stringtable(self.block, self.role_sid as usize)
  180. }
  181. }
  182. /// An iterator over the members of a relation.
  183. pub struct RelMemberIter<'a> {
  184. block: &'a PrimitiveBlock,
  185. role_sids: std::slice::Iter<'a, i32>,
  186. member_id_deltas: std::slice::Iter<'a, i64>,
  187. member_types: std::slice::Iter<'a, osmformat::Relation_MemberType>,
  188. current_member_id: i64,
  189. }
  190. impl<'a> RelMemberIter<'a> {
  191. fn new(block: &'a PrimitiveBlock, osmrel: &'a osmformat::Relation) -> RelMemberIter<'a> {
  192. RelMemberIter {
  193. block: block,
  194. role_sids: osmrel.get_roles_sid().iter(),
  195. member_id_deltas: osmrel.get_memids().iter(),
  196. member_types: osmrel.get_types().iter(),
  197. current_member_id: 0,
  198. }
  199. }
  200. }
  201. impl<'a> Iterator for RelMemberIter<'a> {
  202. type Item = RelMember<'a>;
  203. fn next(&mut self) -> Option<Self::Item> {
  204. match (self.role_sids.next(),
  205. self.member_id_deltas.next(),
  206. self.member_types.next()) {
  207. (Some(role_sid), Some(mem_id_delta), Some(member_type)) => {
  208. self.current_member_id += *mem_id_delta;
  209. Some(RelMember {
  210. block: self.block,
  211. role_sid: *role_sid,
  212. member_id: self.current_member_id,
  213. member_type: RelMemberType::from(*member_type),
  214. })
  215. },
  216. _ => None,
  217. }
  218. }
  219. fn size_hint(&self) -> (usize, Option<usize>) {
  220. self.role_sids.size_hint()
  221. }
  222. }
  223. impl<'a> ExactSizeIterator for RelMemberIter<'a> {}
  224. /// An iterator over the tags of an element.
  225. pub struct TagIter<'a> {
  226. block: &'a PrimitiveBlock,
  227. key_indices: std::slice::Iter<'a, u32>,
  228. val_indices: std::slice::Iter<'a, u32>,
  229. }
  230. //TODO return Result?
  231. impl<'a> Iterator for TagIter<'a> {
  232. type Item = (&'a str, &'a str);
  233. fn next(&mut self) -> Option<Self::Item> {
  234. match (self.key_indices.next(), self.val_indices.next()) {
  235. (Some(&key_index), Some(&val_index)) => {
  236. let k_res = str_from_stringtable(self.block, key_index as usize);
  237. let v_res = str_from_stringtable(self.block, val_index as usize);
  238. if let (Ok(k), Ok(v)) = (k_res, v_res) {
  239. Some((k, v))
  240. } else {
  241. None
  242. }
  243. },
  244. _ => None,
  245. }
  246. }
  247. fn size_hint(&self) -> (usize, Option<usize>) {
  248. self.key_indices.size_hint()
  249. }
  250. }
  251. impl<'a> ExactSizeIterator for TagIter<'a> {}
  252. /// Additional metadata that might be included in each element.
  253. pub struct Info<'a> {
  254. block: &'a PrimitiveBlock,
  255. info: &'a osmformat::Info,
  256. }
  257. impl<'a> Info<'a> {
  258. fn new(block: &'a PrimitiveBlock, info: &'a osmformat::Info) -> Info<'a> {
  259. Info {
  260. block: block,
  261. info: info,
  262. }
  263. }
  264. /// Returns the version of this element.
  265. pub fn version(&self) -> Option<i32> {
  266. if self.info.has_version() {
  267. Some(self.info.get_version())
  268. } else {
  269. None
  270. }
  271. }
  272. /// Returns the time stamp in milliseconds since the epoch.
  273. pub fn milli_timestamp(&self) -> Option<i64> {
  274. if self.info.has_timestamp() {
  275. Some(self.info.get_timestamp() * i64::from(self.block.get_date_granularity()))
  276. } else {
  277. None
  278. }
  279. }
  280. /// Returns the changeset id.
  281. pub fn changeset(&self) -> Option<i64> {
  282. if self.info.has_changeset() {
  283. Some(self.info.get_changeset())
  284. } else {
  285. None
  286. }
  287. }
  288. /// Returns the user id.
  289. pub fn uid(&self) -> Option<i32> {
  290. if self.info.has_uid() {
  291. Some(self.info.get_uid())
  292. } else {
  293. None
  294. }
  295. }
  296. /// Returns the user name.
  297. pub fn user(&self) -> Option<Result<&'a str>> {
  298. if self.info.has_user_sid() {
  299. Some(str_from_stringtable(self.block, self.info.get_user_sid() as usize))
  300. } else {
  301. None
  302. }
  303. }
  304. /// Returns the visibility status of an element. This is only relevant if the PBF file contains
  305. /// historical information.
  306. pub fn visible(&self) -> bool {
  307. if self.info.has_visible() {
  308. self.info.get_visible()
  309. } else {
  310. // If the visible flag is not present it must be assumed to be true.
  311. true
  312. }
  313. }
  314. }