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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. extern crate osmpbf;
  2. use osmpbf::*;
  3. static TEST_FILE_PATHS: [&str; 3] = [
  4. "tests/test.osm.pbf",
  5. "tests/test_nozlib.osm.pbf",
  6. "tests/test_nozlib_nodense.osm.pbf",
  7. ];
  8. fn approx_eq(a: f64, b: f64) -> bool {
  9. (a - b).abs() < 1.0e-6
  10. }
  11. // Compare the content of a HeaderBlock with known values from the test file.
  12. fn check_header_block_content(block: &HeaderBlock) {
  13. for feature in block.required_features() {
  14. if feature != "OsmSchema-V0.6" && feature != "DenseNodes" {
  15. panic!("unknown required feature: {}", feature);
  16. }
  17. }
  18. assert_eq!(block.optional_features().len(), 0);
  19. }
  20. // Compare the content of a PrimitiveBlock with known values from the test file.
  21. fn check_primitive_block_content(block: &PrimitiveBlock) {
  22. let nodes: Vec<_> = block.groups().flat_map(|g| g.nodes()).collect();
  23. if !nodes.is_empty() {
  24. assert_eq!(nodes.len(), 3);
  25. // node 1 lat
  26. assert!(approx_eq(nodes[1].lat(), 52.11992359584));
  27. assert_eq!(nodes[1].nano_lat(), 52119923500);
  28. assert_eq!(nodes[1].decimicro_lat(), 521199235);
  29. // node 1 lon
  30. assert!(approx_eq(nodes[1].lon(), 11.62564468943));
  31. assert_eq!(nodes[1].nano_lon(), 11625644600);
  32. assert_eq!(nodes[1].decimicro_lon(), 116256446);
  33. // node 2 lat
  34. assert!(approx_eq(nodes[2].lat(), 52.11989910567));
  35. assert_eq!(nodes[2].nano_lat(), 52119899100);
  36. assert_eq!(nodes[2].decimicro_lat(), 521198991);
  37. //node 2 lon
  38. assert!(approx_eq(nodes[2].lon(), 11.63101926915));
  39. assert_eq!(nodes[2].nano_lon(), 11631019200);
  40. assert_eq!(nodes[2].decimicro_lon(), 116310192);
  41. assert_eq!(nodes[0].id(), 105);
  42. assert_eq!(nodes[1].id(), 106);
  43. assert_eq!(nodes[2].id(), 108);
  44. assert_eq!(nodes[0].info().uid(), Some(17));
  45. assert_eq!(nodes[1].info().uid(), Some(17));
  46. assert_eq!(nodes[2].info().uid(), Some(17));
  47. }
  48. let dense_nodes: Vec<_> = block.groups().flat_map(|g| g.dense_nodes()).collect();
  49. if !dense_nodes.is_empty() {
  50. assert_eq!(dense_nodes.len(), 3);
  51. // node 1 lat
  52. assert!(approx_eq(dense_nodes[1].lat(), 52.11992359584));
  53. assert_eq!(dense_nodes[1].nano_lat(), 52119923500);
  54. assert_eq!(dense_nodes[1].decimicro_lat(), 521199235);
  55. //node 1 lon
  56. assert!(approx_eq(dense_nodes[1].lon(), 11.62564468943));
  57. assert_eq!(dense_nodes[1].nano_lon(), 11625644600);
  58. assert_eq!(dense_nodes[1].decimicro_lon(), 116256446);
  59. //node 2 lat
  60. assert!(approx_eq(dense_nodes[2].lat(), 52.11989910567));
  61. assert_eq!(dense_nodes[2].nano_lat(), 52119899100);
  62. assert_eq!(dense_nodes[2].decimicro_lat(), 521198991);
  63. // node 2 lon
  64. assert!(approx_eq(dense_nodes[2].lon(), 11.63101926915));
  65. assert_eq!(dense_nodes[2].nano_lon(), 11631019200);
  66. assert_eq!(dense_nodes[2].decimicro_lon(), 116310192);
  67. assert_eq!(dense_nodes[0].id, 105);
  68. assert_eq!(dense_nodes[1].id, 106);
  69. assert_eq!(dense_nodes[2].id, 108);
  70. assert_eq!(dense_nodes[0].uid, 17);
  71. assert_eq!(dense_nodes[1].uid, 17);
  72. assert_eq!(dense_nodes[2].uid, 17);
  73. }
  74. {
  75. let ways: Vec<_> = block.groups().flat_map(|g| g.ways()).collect();
  76. assert_eq!(ways.len(), 1);
  77. let way_tags = ways[0].tags().collect::<Vec<_>>();
  78. assert_eq!(way_tags.len(), 2);
  79. assert!(way_tags.contains(&("building", "yes")));
  80. assert!(way_tags.contains(&("name", "triangle")));
  81. }
  82. {
  83. let relations: Vec<_> = block.groups().flat_map(|g| g.relations()).collect();
  84. assert_eq!(relations.len(), 1);
  85. let tags = relations[0].tags().collect::<Vec<_>>();
  86. assert_eq!(tags.len(), 1);
  87. assert!(tags.contains(&("rel_key", "rel_value")));
  88. let members = relations[0].members().collect::<Vec<_>>();
  89. assert_eq!(members.len(), 1);
  90. assert_eq!(members[0].role().unwrap(), "test_role");
  91. }
  92. }
  93. #[test]
  94. fn read_blobs() {
  95. for path in &TEST_FILE_PATHS {
  96. let reader = BlobReader::from_path(path).unwrap();
  97. let blobs = reader.collect::<Result<Vec<_>>>().unwrap();
  98. assert_eq!(blobs.len(), 2);
  99. assert_eq!(blobs[0].get_type(), BlobType::OsmHeader);
  100. assert_eq!(blobs[1].get_type(), BlobType::OsmData);
  101. let header = blobs[0].to_headerblock().unwrap();
  102. check_header_block_content(&header);
  103. let primitive_block = blobs[1].to_primitiveblock().unwrap();
  104. check_primitive_block_content(&primitive_block);
  105. }
  106. }
  107. #[test]
  108. fn read_mmap_blobs() {
  109. for path in &TEST_FILE_PATHS {
  110. let mmap = unsafe { Mmap::from_path(path).unwrap() };
  111. let reader = MmapBlobReader::new(&mmap);
  112. let blobs = reader.collect::<Result<Vec<_>>>().unwrap();
  113. assert_eq!(blobs.len(), 2);
  114. assert_eq!(blobs[0].get_type(), BlobType::OsmHeader);
  115. assert_eq!(blobs[1].get_type(), BlobType::OsmData);
  116. if let BlobDecode::OsmHeader(header) = blobs[0].decode().unwrap() {
  117. check_header_block_content(&header);
  118. } else {
  119. panic!("Unexpected blob type");
  120. }
  121. if let BlobDecode::OsmData(primitive_block) = blobs[1].decode().unwrap() {
  122. check_primitive_block_content(&primitive_block);
  123. } else {
  124. panic!("Unexpected blob type");
  125. }
  126. }
  127. }
  128. #[test]
  129. fn decode_blob() {
  130. for path in &TEST_FILE_PATHS {
  131. let reader = BlobReader::from_path(path).unwrap();
  132. let blobs = reader.collect::<Result<Vec<_>>>().unwrap();
  133. assert_eq!(blobs.len(), 2);
  134. assert_eq!(blobs[0].get_type(), BlobType::OsmHeader);
  135. assert_eq!(blobs[1].get_type(), BlobType::OsmData);
  136. // Decoding to the wrong blob type should not panic but produce an Err.
  137. assert!(blobs[0].to_primitiveblock().is_err());
  138. assert!(blobs[1].to_headerblock().is_err());
  139. assert!(blobs[0].to_headerblock().is_ok());
  140. assert!(blobs[1].to_primitiveblock().is_ok());
  141. }
  142. }
  143. #[test]
  144. fn read_elements() {
  145. for path in &TEST_FILE_PATHS {
  146. let reader = ElementReader::from_path(path).unwrap();
  147. let mut elements = 0_usize;
  148. reader.for_each(|_element| elements += 1).unwrap();
  149. assert_eq!(elements, 5);
  150. }
  151. }
  152. #[test]
  153. fn par_read_elements() {
  154. for path in &TEST_FILE_PATHS {
  155. let reader = ElementReader::from_path(path).unwrap();
  156. let elements = reader
  157. .par_map_reduce(|_element| 1, || 0_usize, |a, b| a + b)
  158. .unwrap();
  159. assert_eq!(elements, 5);
  160. }
  161. }