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

read.rs 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. extern crate osmpbf;
  2. use osmpbf::*;
  3. static TEST_FILE_PATH: &str = "tests/test.osm.pbf";
  4. fn approx_eq(a: f64, b: f64) -> bool {
  5. (a - b).abs() < 1.0e-6
  6. }
  7. // Compare the content of a HeaderBlock with known values from the test file.
  8. fn check_header_block_content(block: &HeaderBlock) {
  9. assert!(block.required_features().contains(&String::from("OsmSchema-V0.6")));
  10. assert!(block.required_features().contains(&String::from("DenseNodes")));
  11. assert_eq!(block.optional_features().len(), 0);
  12. }
  13. // Compare the content of a PrimitiveBlock with known values from the test file.
  14. fn check_primitive_block_content(block: &PrimitiveBlock) {
  15. let nodes = block.groups().flat_map(|g| g.nodes()).count();
  16. assert_eq!(nodes, 0);
  17. {
  18. let dense_nodes: Vec<_> = block.groups().flat_map(|g| g.dense_nodes()).collect();
  19. assert_eq!(dense_nodes.len(), 3);
  20. assert!(approx_eq(dense_nodes[1].lat(), 52.11992359584));
  21. assert!(approx_eq(dense_nodes[1].lon(), 11.62564468943));
  22. assert!(approx_eq(dense_nodes[2].lat(), 52.11989910567));
  23. assert!(approx_eq(dense_nodes[2].lon(), 11.63101926915));
  24. assert_eq!(dense_nodes[0].id, 105);
  25. assert_eq!(dense_nodes[1].id, 106);
  26. assert_eq!(dense_nodes[2].id, 108);
  27. assert_eq!(dense_nodes[0].uid, 17);
  28. assert_eq!(dense_nodes[1].uid, 17);
  29. assert_eq!(dense_nodes[2].uid, 17);
  30. }
  31. {
  32. let ways: Vec<_> = block.groups().flat_map(|g| g.ways()).collect();
  33. assert_eq!(ways.len(), 1);
  34. let way_tags = ways[0].tags().collect::<Vec<_>>();
  35. assert_eq!(way_tags.len(), 2);
  36. assert!(way_tags.contains(&("building", "yes")));
  37. assert!(way_tags.contains(&("name", "triangle")));
  38. }
  39. }
  40. #[test]
  41. fn read() {
  42. let reader = BlobReader::from_path(TEST_FILE_PATH).unwrap();
  43. let blobs = reader.collect::<Result<Vec<_>>>().unwrap();
  44. assert_eq!(blobs.len(), 2);
  45. assert_eq!(blobs[0].get_type(), BlobType::OsmHeader);
  46. assert_eq!(blobs[1].get_type(), BlobType::OsmData);
  47. let header = blobs[0].to_headerblock().unwrap();
  48. check_header_block_content(&header);
  49. let primitive_block = blobs[1].to_primitiveblock().unwrap();
  50. check_primitive_block_content(&primitive_block);
  51. }
  52. #[test]
  53. fn mmap_read() {
  54. let mmap = unsafe { Mmap::from_path(TEST_FILE_PATH).unwrap() };
  55. let reader = MmapBlobReader::new(&mmap);
  56. let blobs = reader.collect::<Result<Vec<_>>>().unwrap();
  57. assert_eq!(blobs.len(), 2);
  58. assert_eq!(blobs[0].get_type(), BlobType::OsmHeader);
  59. assert_eq!(blobs[1].get_type(), BlobType::OsmData);
  60. if let BlobDecode::OsmHeader(header) = blobs[0].decode().unwrap() {
  61. check_header_block_content(&header);
  62. } else {
  63. panic!("Unexpected blob type");
  64. }
  65. if let BlobDecode::OsmData(primitive_block) = blobs[1].decode().unwrap() {
  66. check_primitive_block_content(&primitive_block);
  67. } else {
  68. panic!("Unexpected blob type");
  69. }
  70. }
  71. #[test]
  72. fn decode_blob() {
  73. let reader = BlobReader::from_path(TEST_FILE_PATH).unwrap();
  74. let blobs = reader.collect::<Result<Vec<_>>>().unwrap();
  75. assert_eq!(blobs.len(), 2);
  76. assert_eq!(blobs[0].get_type(), BlobType::OsmHeader);
  77. assert_eq!(blobs[1].get_type(), BlobType::OsmData);
  78. // Decoding to the wrong blob type should not panic but produce an Err.
  79. assert!(blobs[0].to_primitiveblock().is_err());
  80. assert!(blobs[1].to_headerblock().is_err());
  81. assert!(blobs[0].to_headerblock().is_ok());
  82. assert!(blobs[1].to_primitiveblock().is_ok());
  83. }