#file-offset #osm-pbf #scan #records #protobuf #explicit #parser

osmpbf-parser

解析 osm protobuf 文件并扫描具有显式文件偏移量的记录

5 个稳定版本

1.3.1 2021 年 8 月 30 日
1.2.0 2021 年 8 月 28 日
1.1.0 2021 年 8 月 28 日
1.0.0 2021 年 8 月 28 日

#272 in 地理空间


用于 peermaps-ingest

BSD-3-Clause

57KB
1.5K SLoC

osmpbf-parser

解析开放街图 protobuf 文件并扫描具有显式文件偏移量的记录

此软件包与 osmpbf 的主要区别在于,您可以获得显式的 u64 文件偏移量,用于跳转和扫描,并且可以通过为同一文件创建多个文件句柄和解析器实例来并行操作,从而实现自己的并发策略。

此示例遍历 osmpbf 文件中的所有 blob,并打印诊断信息,例如元素类型(节点、道路或关系)、每个 blob 的文件偏移量和字节长度、项目数量以及 ID 范围。

use std::fs::File;
use osmpbf_parser::{Parser,Element};

type Error = Box<dyn std::error::Error+Send+Sync+'static>;

fn main() -> Result<(),Error> {
  let args = std::env::args().collect::<Vec<String>>();
  let h = File::open(&args[1])?;
  let file_len = h.metadata()?.len();
  let mut opd = Parser::new(Box::new(h));
  let mut offset = 0;
  while offset < file_len {
    let (byte_len,items) = opd.read(offset)?;
    let mut etype = "";
    let mut min_id = i64::MAX;
    let mut max_id = i64::MIN;
    for item in items.iter() {
      match item {
        Element::Node(node) => {
          etype = "node";
          min_id = node.id.min(min_id);
          max_id = node.id.max(max_id);
        },
        Element::Way(way) => {
          etype = "way";
          min_id = way.id.min(min_id);
          max_id = way.id.max(max_id);
        },
        Element::Relation(relation) => {
          etype = "relation";
          min_id = relation.id.min(min_id);
          max_id = relation.id.max(max_id);
        },
      }
    }
    if !items.is_empty() {
      println!["{}: offset={} byte_len={} items.len()={} id range {}..{}",
        etype, offset, byte_len, items.len(), min_id, max_id];
    }
    offset += byte_len;
  }
  Ok(())
}

还有更多显式的读取文件块、blob 标头和未解码 blob 的例程。

依赖项

~2MB
~33K SLoC