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

block.rs 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //! `HeaderBlock`, `PrimitiveBlock` and `PrimitiveGroup`s
  2. use dense::DenseNodeIter;
  3. use elements::{Node, Way, Relation};
  4. use errors::*;
  5. use proto::osmformat;
  6. use std;
  7. /// A `HeaderBlock`. It contains metadata about following `PrimitiveBlock`s.
  8. pub struct HeaderBlock {
  9. header: osmformat::HeaderBlock,
  10. }
  11. impl HeaderBlock {
  12. pub(crate) fn new(header: osmformat::HeaderBlock) -> HeaderBlock {
  13. HeaderBlock { header: header }
  14. }
  15. /// Returns a list of required features that a parser needs to implement to parse the following
  16. /// `PrimitiveBlock`s.
  17. pub fn required_features(&self) -> &[String] {
  18. self.header.get_required_features()
  19. }
  20. /// Returns a list of optional features that a parser can choose to ignore.
  21. pub fn optional_features(&self) -> &[String] {
  22. self.header.get_optional_features()
  23. }
  24. }
  25. /// A `PrimitiveBlock`. It contains a sequence of groups.
  26. pub struct PrimitiveBlock {
  27. block: osmformat::PrimitiveBlock,
  28. }
  29. impl PrimitiveBlock {
  30. pub(crate) fn new(block: osmformat::PrimitiveBlock) -> PrimitiveBlock {
  31. PrimitiveBlock { block: block }
  32. }
  33. /// Returns an iterator over the groups in this `PrimitiveBlock`.
  34. pub fn groups(&self) -> GroupIter {
  35. GroupIter::new(&self.block)
  36. }
  37. }
  38. /// A `PrimitiveGroup` contains a sequence of elements of one type.
  39. pub struct PrimitiveGroup<'a> {
  40. block: &'a osmformat::PrimitiveBlock,
  41. group: &'a osmformat::PrimitiveGroup,
  42. }
  43. impl<'a> PrimitiveGroup<'a> {
  44. fn new(block: &'a osmformat::PrimitiveBlock,
  45. group: &'a osmformat::PrimitiveGroup)
  46. -> PrimitiveGroup<'a> {
  47. PrimitiveGroup {
  48. block: block,
  49. group: group,
  50. }
  51. }
  52. /// Returns an iterator over the nodes in this group.
  53. pub fn nodes(&self) -> GroupNodeIter<'a> {
  54. GroupNodeIter::new(self.block, self.group)
  55. }
  56. /// Returns an iterator over the dense nodes in this group.
  57. pub fn dense_nodes(&self) -> DenseNodeIter<'a> {
  58. DenseNodeIter::new(self.block, self.group.get_dense())
  59. }
  60. /// Returns an iterator over the ways in this group.
  61. pub fn ways(&self) -> GroupWayIter<'a> {
  62. GroupWayIter::new(self.block, self.group)
  63. }
  64. /// Returns an iterator over the relations in this group.
  65. pub fn relations(&self) -> GroupRelationIter<'a> {
  66. GroupRelationIter::new(self.block, self.group)
  67. }
  68. }
  69. /// An iterator over the groups in a `PrimitiveBlock`.
  70. pub struct GroupIter<'a> {
  71. block: &'a osmformat::PrimitiveBlock,
  72. groups: std::slice::Iter<'a, osmformat::PrimitiveGroup>,
  73. }
  74. impl<'a> GroupIter<'a> {
  75. fn new(block: &'a osmformat::PrimitiveBlock) -> GroupIter<'a> {
  76. GroupIter {
  77. block: block,
  78. groups: block.get_primitivegroup().iter(),
  79. }
  80. }
  81. }
  82. impl<'a> Iterator for GroupIter<'a> {
  83. type Item = PrimitiveGroup<'a>;
  84. fn next(&mut self) -> Option<Self::Item> {
  85. match self.groups.next() {
  86. Some(g) => Some(PrimitiveGroup::new(self.block, g)),
  87. None => None,
  88. }
  89. }
  90. fn size_hint(&self) -> (usize, Option<usize>) {
  91. self.groups.size_hint()
  92. }
  93. }
  94. impl<'a> ExactSizeIterator for GroupIter<'a> {}
  95. /// An iterator over the nodes in a `Group`.
  96. pub struct GroupNodeIter<'a> {
  97. block: &'a osmformat::PrimitiveBlock,
  98. nodes: std::slice::Iter<'a, osmformat::Node>,
  99. }
  100. impl<'a> GroupNodeIter<'a> {
  101. fn new(block: &'a osmformat::PrimitiveBlock,
  102. group: &'a osmformat::PrimitiveGroup)
  103. -> GroupNodeIter<'a> {
  104. GroupNodeIter {
  105. block: block,
  106. nodes: group.get_nodes().iter(),
  107. }
  108. }
  109. }
  110. impl<'a> Iterator for GroupNodeIter<'a> {
  111. type Item = Node<'a>;
  112. fn next(&mut self) -> Option<Self::Item> {
  113. match self.nodes.next() {
  114. Some(n) => Some(Node::new(self.block, n)),
  115. None => None,
  116. }
  117. }
  118. fn size_hint(&self) -> (usize, Option<usize>) {
  119. self.nodes.size_hint()
  120. }
  121. }
  122. impl<'a> ExactSizeIterator for GroupNodeIter<'a> {}
  123. /// An iterator over the ways in a `Group`.
  124. pub struct GroupWayIter<'a> {
  125. block: &'a osmformat::PrimitiveBlock,
  126. ways: std::slice::Iter<'a, osmformat::Way>,
  127. }
  128. impl<'a> GroupWayIter<'a> {
  129. fn new(block: &'a osmformat::PrimitiveBlock,
  130. group: &'a osmformat::PrimitiveGroup)
  131. -> GroupWayIter<'a> {
  132. GroupWayIter {
  133. block: block,
  134. ways: group.get_ways().iter(),
  135. }
  136. }
  137. }
  138. impl<'a> Iterator for GroupWayIter<'a> {
  139. type Item = Way<'a>;
  140. fn next(&mut self) -> Option<Self::Item> {
  141. match self.ways.next() {
  142. Some(way) => Some(Way::new(self.block, way)),
  143. None => None,
  144. }
  145. }
  146. fn size_hint(&self) -> (usize, Option<usize>) {
  147. self.ways.size_hint()
  148. }
  149. }
  150. impl<'a> ExactSizeIterator for GroupWayIter<'a> {}
  151. /// An iterator over the relations in a `Group`.
  152. pub struct GroupRelationIter<'a> {
  153. block: &'a osmformat::PrimitiveBlock,
  154. rels: std::slice::Iter<'a, osmformat::Relation>,
  155. }
  156. impl<'a> GroupRelationIter<'a> {
  157. fn new(block: &'a osmformat::PrimitiveBlock,
  158. group: &'a osmformat::PrimitiveGroup)
  159. -> GroupRelationIter<'a> {
  160. GroupRelationIter {
  161. block: block,
  162. rels: group.get_relations().iter(),
  163. }
  164. }
  165. }
  166. impl<'a> Iterator for GroupRelationIter<'a> {
  167. type Item = Relation<'a>;
  168. fn next(&mut self) -> Option<Self::Item> {
  169. match self.rels.next() {
  170. Some(rel) => Some(Relation::new(self.block, rel)),
  171. None => None,
  172. }
  173. }
  174. fn size_hint(&self) -> (usize, Option<usize>) {
  175. self.rels.size_hint()
  176. }
  177. }
  178. impl<'a> ExactSizeIterator for GroupRelationIter<'a> {}
  179. pub(crate) fn str_from_stringtable(block: &osmformat::PrimitiveBlock, index: usize) -> Result<&str> {
  180. if let Some(vec) = block.get_stringtable().get_s().get(index) {
  181. std::str::from_utf8(vec)
  182. .chain_err(|| "failed to decode string from string table")
  183. } else {
  184. Err(ErrorKind::StringtableIndexOutOfBounds(index).into())
  185. }
  186. }