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

block.rs 11KB

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