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

dense.rs 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //! Iterate over the dense nodes in a `PrimitiveGroup`
  2. use errors::*;
  3. use proto::osmformat;
  4. use block::str_from_stringtable;
  5. use std;
  6. //TODO Add getter functions for id, version, uid, ...
  7. /// An OpenStreetMap node element from a compressed array of DenseNodes (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Node)).
  8. pub struct DenseNode<'a> {
  9. block: &'a osmformat::PrimitiveBlock,
  10. /// The node id. It should be unique between nodes and might be negative to indicate
  11. /// that the element has not yet been uploaded to a server.
  12. pub id: i64,
  13. /// The version of this element.
  14. pub version: i32,
  15. timestamp: i64,
  16. /// The changeset id.
  17. pub changeset: i64,
  18. /// The user id.
  19. pub uid: i32,
  20. user_sid: i32,
  21. lat: i64,
  22. lon: i64,
  23. keys_vals_indices: &'a [i32],
  24. }
  25. impl<'a> DenseNode<'a> {
  26. /// Returns the user name.
  27. pub fn user(&self) -> Result<&'a str> {
  28. str_from_stringtable(self.block, self.user_sid as usize)
  29. }
  30. /// Returns the latitude coordinate in degrees.
  31. pub fn lat(&self) -> f64 {
  32. 0.000_000_001_f64 * (self.block.get_lat_offset() +
  33. (i64::from(self.block.get_granularity()) *
  34. self.lat)) as f64
  35. }
  36. /// Returns the longitude coordinate in degrees.
  37. pub fn lon(&self) -> f64 {
  38. 0.000_000_001_f64 * (self.block.get_lon_offset() +
  39. (i64::from(self.block.get_granularity()) *
  40. self.lon)) as f64
  41. }
  42. /// Returns the time stamp in milliseconds since the epoch.
  43. pub fn milli_timestamp(&self) -> i64 {
  44. self.timestamp * i64::from(self.block.get_date_granularity())
  45. }
  46. /// Returns an iterator over the tags of this way (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Tags)).
  47. pub fn tags(&self) -> DenseTagIter<'a> {
  48. DenseTagIter {
  49. block: self.block,
  50. keys_vals_indices: self.keys_vals_indices.iter(),
  51. }
  52. }
  53. }
  54. /// An iterator over dense nodes. It decodes the delta encoded values.
  55. pub struct DenseNodeIter<'a> {
  56. block: &'a osmformat::PrimitiveBlock,
  57. dids: std::slice::Iter<'a, i64>, // deltas
  58. cid: i64, // current id
  59. versions: std::slice::Iter<'a, i32>,
  60. dtimestamps: std::slice::Iter<'a, i64>, // deltas
  61. ctimestamp: i64,
  62. dchangesets: std::slice::Iter<'a, i64>, // deltas
  63. cchangeset: i64,
  64. duids: std::slice::Iter<'a, i32>, // deltas
  65. cuid: i32,
  66. duser_sids: std::slice::Iter<'a, i32>, // deltas
  67. cuser_sid: i32,
  68. dlats: std::slice::Iter<'a, i64>, // deltas
  69. clat: i64,
  70. dlons: std::slice::Iter<'a, i64>, // deltas
  71. clon: i64,
  72. keys_vals_slice: &'a [i32],
  73. keys_vals_index: usize,
  74. }
  75. impl<'a> DenseNodeIter<'a> {
  76. pub(crate) fn new(block: &'a osmformat::PrimitiveBlock,
  77. osmdense: &'a osmformat::DenseNodes) -> DenseNodeIter<'a> {
  78. let info = osmdense.get_denseinfo();
  79. DenseNodeIter {
  80. block: block,
  81. dids: osmdense.get_id().iter(),
  82. cid: 0,
  83. versions: info.get_version().iter(),
  84. dtimestamps: info.get_timestamp().iter(),
  85. ctimestamp: 0,
  86. dchangesets: info.get_changeset().iter(),
  87. cchangeset: 0,
  88. duids: info.get_uid().iter(),
  89. cuid: 0,
  90. duser_sids: info.get_user_sid().iter(),
  91. cuser_sid: 0,
  92. dlats: osmdense.get_lat().iter(),
  93. clat: 0,
  94. dlons: osmdense.get_lon().iter(),
  95. clon: 0,
  96. keys_vals_slice: osmdense.get_keys_vals(),
  97. keys_vals_index: 0,
  98. }
  99. }
  100. }
  101. impl<'a> Iterator for DenseNodeIter<'a> {
  102. type Item = DenseNode<'a>;
  103. fn next(&mut self) -> Option<Self::Item> {
  104. match (self.dids.next(),
  105. self.versions.next(),
  106. self.dtimestamps.next(),
  107. self.dchangesets.next(),
  108. self.duids.next(),
  109. self.duser_sids.next(),
  110. self.dlats.next(),
  111. self.dlons.next()) {
  112. (Some(did),
  113. Some(version),
  114. Some(dtimestamp),
  115. Some(dchangeset),
  116. Some(duid),
  117. Some(duser_sid),
  118. Some(dlat),
  119. Some(dlon)) => {
  120. self.cid += *did;
  121. self.ctimestamp += *dtimestamp;
  122. self.cchangeset += *dchangeset;
  123. self.cuid += *duid;
  124. self.cuser_sid += *duser_sid;
  125. self.clat += *dlat;
  126. self.clon += *dlon;
  127. let start_index = self.keys_vals_index;
  128. let mut end_index = start_index;
  129. for chunk in self.keys_vals_slice[self.keys_vals_index..].chunks(2) {
  130. if chunk[0] != 0 && chunk.len() == 2 {
  131. end_index += 2;
  132. self.keys_vals_index += 2;
  133. } else {
  134. self.keys_vals_index += 1;
  135. break;
  136. }
  137. }
  138. Some(DenseNode {
  139. block: self.block,
  140. id: self.cid,
  141. version: *version,
  142. timestamp: self.ctimestamp,
  143. changeset: self.cchangeset,
  144. uid: self.cuid,
  145. user_sid: self.cuser_sid,
  146. lat: self.clat,
  147. lon: self.clon,
  148. keys_vals_indices: &self.keys_vals_slice[start_index..end_index],
  149. })
  150. },
  151. _ => None,
  152. }
  153. }
  154. fn size_hint(&self) -> (usize, Option<usize>) {
  155. self.dids.size_hint()
  156. }
  157. }
  158. impl<'a> ExactSizeIterator for DenseNodeIter<'a> {}
  159. /// An iterator over the tags in a dense node.
  160. pub struct DenseTagIter<'a> {
  161. block: &'a osmformat::PrimitiveBlock,
  162. keys_vals_indices: std::slice::Iter<'a, i32>,
  163. }
  164. //TODO return Result
  165. impl<'a> Iterator for DenseTagIter<'a> {
  166. type Item = (&'a str, &'a str);
  167. fn next(&mut self) -> Option<Self::Item> {
  168. match (self.keys_vals_indices.next(), self.keys_vals_indices.next()) {
  169. (Some(&key_index), Some(&val_index)) => {
  170. let k_res = str_from_stringtable(self.block, key_index as usize);
  171. let v_res = str_from_stringtable(self.block, val_index as usize);
  172. if let (Ok(k), Ok(v)) = (k_res, v_res) {
  173. Some((k, v))
  174. } else {
  175. None
  176. }
  177. },
  178. _ => None,
  179. }
  180. }
  181. fn size_hint(&self) -> (usize, Option<usize>) {
  182. self.keys_vals_indices.size_hint()
  183. }
  184. }
  185. impl<'a> ExactSizeIterator for DenseTagIter<'a> {}