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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. //! `HeaderBlock`, `PrimitiveBlock` and `PrimitiveGroup`s
  2. use dense::DenseNodeIter;
  3. use elements::{Element, Node, Relation, Way};
  4. use error::{new_error, ErrorKind, Result};
  5. use proto::osmformat;
  6. use std;
  7. /// A `HeaderBlock`. It contains metadata about following `PrimitiveBlock`s.
  8. #[derive(Clone, Debug)]
  9. pub struct HeaderBlock {
  10. header: osmformat::HeaderBlock,
  11. }
  12. impl HeaderBlock {
  13. pub(crate) fn new(header: osmformat::HeaderBlock) -> HeaderBlock {
  14. HeaderBlock { header }
  15. }
  16. /// Returns a list of required features that a parser needs to implement to parse the following
  17. /// `PrimitiveBlock`s.
  18. pub fn required_features(&self) -> &[String] {
  19. self.header.get_required_features()
  20. }
  21. /// Returns a list of optional features that a parser can choose to ignore.
  22. pub fn optional_features(&self) -> &[String] {
  23. self.header.get_optional_features()
  24. }
  25. }
  26. /// A `PrimitiveBlock`. It contains a sequence of groups.
  27. #[derive(Clone, Debug)]
  28. pub struct PrimitiveBlock {
  29. block: osmformat::PrimitiveBlock,
  30. }
  31. impl PrimitiveBlock {
  32. pub(crate) fn new(block: osmformat::PrimitiveBlock) -> PrimitiveBlock {
  33. PrimitiveBlock { block }
  34. }
  35. /// Returns an iterator over the elements in this `PrimitiveBlock`.
  36. pub fn elements(&self) -> BlockElementsIter {
  37. BlockElementsIter::new(&self.block)
  38. }
  39. /// Returns an iterator over the groups in this `PrimitiveBlock`.
  40. pub fn groups(&self) -> GroupIter {
  41. GroupIter::new(&self.block)
  42. }
  43. /// Calls the given closure on each element.
  44. pub fn for_each_element<F>(&self, mut f: F)
  45. where
  46. F: for<'a> FnMut(Element<'a>),
  47. {
  48. for group in self.groups() {
  49. for node in group.nodes() {
  50. f(Element::Node(node))
  51. }
  52. for dnode in group.dense_nodes() {
  53. f(Element::DenseNode(dnode))
  54. }
  55. for way in group.ways() {
  56. f(Element::Way(way));
  57. }
  58. for relation in group.relations() {
  59. f(Element::Relation(relation));
  60. }
  61. }
  62. }
  63. /// Returns the raw stringtable. Elements in a `PrimitiveBlock` do not store strings
  64. /// themselves; instead, they just store indices to the stringtable. By convention, the
  65. /// contained strings are UTF-8 encoded but it is not safe to assume that (use
  66. /// `std::str::from_utf8`).
  67. pub fn raw_stringtable(&self) -> &[Vec<u8>] {
  68. self.block.get_stringtable().get_s()
  69. }
  70. }
  71. /// A `PrimitiveGroup` contains a sequence of elements of one type.
  72. #[derive(Clone, Debug)]
  73. pub struct PrimitiveGroup<'a> {
  74. block: &'a osmformat::PrimitiveBlock,
  75. group: &'a osmformat::PrimitiveGroup,
  76. }
  77. impl<'a> PrimitiveGroup<'a> {
  78. fn new(
  79. block: &'a osmformat::PrimitiveBlock,
  80. group: &'a osmformat::PrimitiveGroup,
  81. ) -> PrimitiveGroup<'a> {
  82. PrimitiveGroup { block, group }
  83. }
  84. /// Returns an iterator over the nodes in this group.
  85. pub fn nodes(&self) -> GroupNodeIter<'a> {
  86. GroupNodeIter::new(self.block, self.group)
  87. }
  88. /// Returns an iterator over the dense nodes in this group.
  89. pub fn dense_nodes(&self) -> DenseNodeIter<'a> {
  90. DenseNodeIter::new(self.block, self.group.get_dense())
  91. }
  92. /// Returns an iterator over the ways in this group.
  93. pub fn ways(&self) -> GroupWayIter<'a> {
  94. GroupWayIter::new(self.block, self.group)
  95. }
  96. /// Returns an iterator over the relations in this group.
  97. pub fn relations(&self) -> GroupRelationIter<'a> {
  98. GroupRelationIter::new(self.block, self.group)
  99. }
  100. }
  101. /// An iterator over the elements in a `PrimitiveGroup`.
  102. #[derive(Clone, Debug)]
  103. pub struct BlockElementsIter<'a> {
  104. block: &'a osmformat::PrimitiveBlock,
  105. state: ElementsIterState,
  106. groups: std::slice::Iter<'a, osmformat::PrimitiveGroup>,
  107. dense_nodes: DenseNodeIter<'a>,
  108. nodes: std::slice::Iter<'a, osmformat::Node>,
  109. ways: std::slice::Iter<'a, osmformat::Way>,
  110. relations: std::slice::Iter<'a, osmformat::Relation>,
  111. }
  112. #[derive(Copy, Clone, Debug)]
  113. enum ElementsIterState {
  114. Group,
  115. DenseNode,
  116. Node,
  117. Way,
  118. Relation,
  119. }
  120. impl<'a> BlockElementsIter<'a> {
  121. fn new(block: &'a osmformat::PrimitiveBlock) -> BlockElementsIter<'a> {
  122. BlockElementsIter {
  123. block,
  124. state: ElementsIterState::Group,
  125. groups: block.get_primitivegroup().iter(),
  126. dense_nodes: DenseNodeIter::empty(block),
  127. nodes: [].iter(),
  128. ways: [].iter(),
  129. relations: [].iter(),
  130. }
  131. }
  132. /// Performs an internal iteration step. Returns `None` until there is a value for the iterator to
  133. /// return. Returns `Some(None)` to end the iteration.
  134. #[inline]
  135. #[allow(clippy::option_option)]
  136. fn step(&mut self) -> Option<Option<Element<'a>>> {
  137. match self.state {
  138. ElementsIterState::Group => match self.groups.next() {
  139. Some(group) => {
  140. self.state = ElementsIterState::DenseNode;
  141. self.dense_nodes = DenseNodeIter::new(self.block, group.get_dense());
  142. self.nodes = group.get_nodes().iter();
  143. self.ways = group.get_ways().iter();
  144. self.relations = group.get_relations().iter();
  145. None
  146. }
  147. None => Some(None),
  148. },
  149. ElementsIterState::DenseNode => match self.dense_nodes.next() {
  150. Some(dense_node) => Some(Some(Element::DenseNode(dense_node))),
  151. None => {
  152. self.state = ElementsIterState::Node;
  153. None
  154. }
  155. },
  156. ElementsIterState::Node => match self.nodes.next() {
  157. Some(node) => Some(Some(Element::Node(Node::new(self.block, node)))),
  158. None => {
  159. self.state = ElementsIterState::Way;
  160. None
  161. }
  162. },
  163. ElementsIterState::Way => match self.ways.next() {
  164. Some(way) => Some(Some(Element::Way(Way::new(self.block, way)))),
  165. None => {
  166. self.state = ElementsIterState::Relation;
  167. None
  168. }
  169. },
  170. ElementsIterState::Relation => match self.relations.next() {
  171. Some(rel) => Some(Some(Element::Relation(Relation::new(self.block, rel)))),
  172. None => {
  173. self.state = ElementsIterState::Group;
  174. None
  175. }
  176. },
  177. }
  178. }
  179. }
  180. impl<'a> Iterator for BlockElementsIter<'a> {
  181. type Item = Element<'a>;
  182. #[inline]
  183. fn next(&mut self) -> Option<Self::Item> {
  184. loop {
  185. if let Some(element) = self.step() {
  186. return element;
  187. }
  188. }
  189. }
  190. }
  191. /// An iterator over the groups in a `PrimitiveBlock`.
  192. #[derive(Clone, Debug)]
  193. pub struct GroupIter<'a> {
  194. block: &'a osmformat::PrimitiveBlock,
  195. groups: std::slice::Iter<'a, osmformat::PrimitiveGroup>,
  196. }
  197. impl<'a> GroupIter<'a> {
  198. fn new(block: &'a osmformat::PrimitiveBlock) -> GroupIter<'a> {
  199. GroupIter {
  200. block,
  201. groups: block.get_primitivegroup().iter(),
  202. }
  203. }
  204. }
  205. impl<'a> Iterator for GroupIter<'a> {
  206. type Item = PrimitiveGroup<'a>;
  207. fn next(&mut self) -> Option<Self::Item> {
  208. match self.groups.next() {
  209. Some(g) => Some(PrimitiveGroup::new(self.block, g)),
  210. None => None,
  211. }
  212. }
  213. fn size_hint(&self) -> (usize, Option<usize>) {
  214. self.groups.size_hint()
  215. }
  216. }
  217. impl<'a> ExactSizeIterator for GroupIter<'a> {}
  218. /// An iterator over the nodes in a `PrimitiveGroup`.
  219. #[derive(Clone, Debug)]
  220. pub struct GroupNodeIter<'a> {
  221. block: &'a osmformat::PrimitiveBlock,
  222. nodes: std::slice::Iter<'a, osmformat::Node>,
  223. }
  224. impl<'a> GroupNodeIter<'a> {
  225. fn new(
  226. block: &'a osmformat::PrimitiveBlock,
  227. group: &'a osmformat::PrimitiveGroup,
  228. ) -> GroupNodeIter<'a> {
  229. GroupNodeIter {
  230. block,
  231. nodes: group.get_nodes().iter(),
  232. }
  233. }
  234. }
  235. impl<'a> Iterator for GroupNodeIter<'a> {
  236. type Item = Node<'a>;
  237. fn next(&mut self) -> Option<Self::Item> {
  238. match self.nodes.next() {
  239. Some(n) => Some(Node::new(self.block, n)),
  240. None => None,
  241. }
  242. }
  243. fn size_hint(&self) -> (usize, Option<usize>) {
  244. self.nodes.size_hint()
  245. }
  246. }
  247. impl<'a> ExactSizeIterator for GroupNodeIter<'a> {}
  248. /// An iterator over the ways in a `PrimitiveGroup`.
  249. #[derive(Clone, Debug)]
  250. pub struct GroupWayIter<'a> {
  251. block: &'a osmformat::PrimitiveBlock,
  252. ways: std::slice::Iter<'a, osmformat::Way>,
  253. }
  254. impl<'a> GroupWayIter<'a> {
  255. fn new(
  256. block: &'a osmformat::PrimitiveBlock,
  257. group: &'a osmformat::PrimitiveGroup,
  258. ) -> GroupWayIter<'a> {
  259. GroupWayIter {
  260. block,
  261. ways: group.get_ways().iter(),
  262. }
  263. }
  264. }
  265. impl<'a> Iterator for GroupWayIter<'a> {
  266. type Item = Way<'a>;
  267. fn next(&mut self) -> Option<Self::Item> {
  268. match self.ways.next() {
  269. Some(way) => Some(Way::new(self.block, way)),
  270. None => None,
  271. }
  272. }
  273. fn size_hint(&self) -> (usize, Option<usize>) {
  274. self.ways.size_hint()
  275. }
  276. }
  277. impl<'a> ExactSizeIterator for GroupWayIter<'a> {}
  278. /// An iterator over the relations in a `PrimitiveGroup`.
  279. #[derive(Clone, Debug)]
  280. pub struct GroupRelationIter<'a> {
  281. block: &'a osmformat::PrimitiveBlock,
  282. rels: std::slice::Iter<'a, osmformat::Relation>,
  283. }
  284. impl<'a> GroupRelationIter<'a> {
  285. fn new(
  286. block: &'a osmformat::PrimitiveBlock,
  287. group: &'a osmformat::PrimitiveGroup,
  288. ) -> GroupRelationIter<'a> {
  289. GroupRelationIter {
  290. block,
  291. rels: group.get_relations().iter(),
  292. }
  293. }
  294. }
  295. impl<'a> Iterator for GroupRelationIter<'a> {
  296. type Item = Relation<'a>;
  297. fn next(&mut self) -> Option<Self::Item> {
  298. match self.rels.next() {
  299. Some(rel) => Some(Relation::new(self.block, rel)),
  300. None => None,
  301. }
  302. }
  303. fn size_hint(&self) -> (usize, Option<usize>) {
  304. self.rels.size_hint()
  305. }
  306. }
  307. impl<'a> ExactSizeIterator for GroupRelationIter<'a> {}
  308. pub(crate) fn str_from_stringtable(
  309. block: &osmformat::PrimitiveBlock,
  310. index: usize,
  311. ) -> Result<&str> {
  312. if let Some(vec) = block.get_stringtable().get_s().get(index) {
  313. std::str::from_utf8(vec)
  314. .map_err(|e| new_error(ErrorKind::StringtableUtf8 { err: e, index }))
  315. } else {
  316. Err(new_error(ErrorKind::StringtableIndexOutOfBounds { index }))
  317. }
  318. }