#openstreetmap #osm #tui #geojson #command-line-interface

bin+lib osm-geo-mapper

在终端中导航 OpenStreetMap 数据

27 个版本

0.8.0 2021 年 12 月 17 日
0.7.0 2021 年 6 月 15 日
0.6.2 2021 年 3 月 15 日
0.5.1 2020 年 12 月 1 日
0.5.0 2020 年 11 月 30 日

#90地理空间

Download history 13/week @ 2024-02-21 38/week @ 2024-02-28 83/week @ 2024-03-27 113/week @ 2024-04-03

53 每月下载量

MIT 许可证

195KB
3.5K SLoC

OSM Geo Mapper

用于通过坐标查询 OpenStreetMap 数据的 Rust 库和用于在终端中浏览 OpenStreetMap 数据的终端应用程序。可以解析 OSM/PBF/GeoJSON 文件或使用地址或经纬度获取 OSM 数据,并在终端中显示结果线/点/多边形。

允许在地图上移动

  • 使用箭头键进行方向移动(也支持 vi 键 h,j,k,l)
  • 按 'z' 缩放/缩小
  • 按住 'Shift' 可以快速移动 10 倍
  • 按 'Enter' 在当前位置加载更多数据(使用之前选择的半径)
  • 按 'q' 或 Esc 退出

但是为什么

我有一个基于终端的僵尸生存游戏的想法,玩家可以选择地球上任何地方。

结果证明,仅仅解析和列出所有类型的 OpenStreetMap 数据就是一项巨大的工作,并且值得拥有自己的库。

此库公开了一个线程安全的数据结构,用于通过二维坐标查询 OSM 数据,大致模拟纬度和经度度数。

用法

命令行界面

./osm-geo-mapper --help

osm-geo-mapper 0.8.0

Will display OpenStreeMap data (PBF/OSM/GeoJSON) lines/points/polygons in the terminal.

USAGE:
    osm-geo-mapper [OPTIONS]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
-a, --address <address>              The address that will be used when fetching OpenStreetMap data (ignored if OSM/PBF/GeoJSON file is provided)
-g, --geojson-file <geojson-file>    Optionally provide a GeoJSON file directly to be parsed and displayed in the terminal
--latitude <latitude>            The latitude that will be used when fetching OpenStreetMap data (ignored if address or OSM/PBF/GeoJSON file is provided)
--longitude <longitude>          The longitude that will be used when fetching OpenStreetMap data (ignored if address or OSM/PBF/GeoJSON file is provided)
-o, --osm-file <osm-file>            Optionally provide a OSM file directly to be parsed and displayed in the terminal
-p, --pbf-file <pbf-file>            Optionally provide a PBF file directly to be parsed and displayed in the terminal
-r, --radius <radius>                The radius of the area of land to retrieve in 100,000th of a lat/lon degree (roughly a meter at the equator) - defaults to 200 (0.002 degrees or ~200m). Significantly impacts loading times. Ignored if PBF/GeoJSON file is provided

./osm-geo-mapper --address "ottawa canada"

OSM Geo Mapper

./osm-geo-mapper --address "vancouver canada"

OSM Geo Mapper

请参阅 tests/ 文件夹中的示例用法,但主要涉及以下 OSMGeoMapper 方法

use osm_geo_mapper::interface::{ OSMGeoMapper, Location };

OSMGeoMapper::from_address(address: String, radius: Option<u32>) -> Result<OSMGeoMapper, Box<dyn std::error::Error>>

OSMGeoMapper::from_address 接受一个地址字符串和可选的半径(以 100,000 分之一的度为单位,或大致赤道上的米),并返回一个 OSMGeoMapper 对象。

OSMGeoMapper::from_lat_lon(latitude: f64, longitude: f64, radius: Option<u32>) -> Result<OSMGeoMapper, Box<dyn std::error::Error>>

OSMGeoMapper::from_lat_lon 与上面的方法类似,但接受纬度和经度而不是地址。

OSMGeoMapper::from_geojson_file(geojson_file: String, location: Option<Location>) -> Result<OSMGeoMapper, Box<dyn std::error::Error>>

OSMGeoMapper::from_geojson_file 直接接受 geojson 文件路径,并返回一个 OSMGeoMapper 对象。 location 可选参数目前没有用处。

OSMGeoMapper 类型定义如下

pub struct OSMGeoMapper {
    pub data_structure: Arc<RwLock<HashMap<geo_types::Coordinate<i32>, Vec<Arc<GeoTile>>>>>,
    pub coordinates: geo_types::Coordinate<i32>,
    pub radius: u32
}

data_structure通过坐标访问各种GeoTiles。由于使用了Arc<RwLock<>>包装器,这个数据结构是线程安全的。当将其发送到另一个线程时,直接使用OSMGeoMapper::atomic_clone(&self)OSMGeoMapper.data_structure.clone()。使用OSMGeoMapper::get/get_real()data_structure.read()/try_read()data_structure.write()/try_write()来锁定资源进行读写操作。

coordinates存储地址的x/y坐标(如果使用了OSMGeoMapper::from_address),或最初提供的经纬度。它们不再以原始的经纬度格式存在,而是在数据结构的坐标系中(每一步是1/100,000度,或在大约赤道上一米左右)。

radius是选择的数据原始获取半径(如果使用了OSMGeoMapper::from_addressOSMGeoMapper::from_lat_lon)。

如果您想获取位于实际经纬度-75.6903082/45.4211063的GeoTile,您将使用以下方法调用OSMGeoMapper::get_real(45.4211063, -75.6903082)。请注意,精度只到小数点后6位。上述方法调用等同于OSMGeoMapper::get(45421106, -75690308)

您还可以直接从(一旦读取锁定)OSMGeoMapper.data_structure字段获取GeoTile(例如):data_structure.get(geo_types::Coordinate { x: -7569031, y: 4542111 })

您可以使用以下辅助函数在真实坐标和OSMGeoMapper坐标之间进行转换:osm_geo_mapper::operations::to_tile_scale(f64) -> i32osm_geo_mapper::operations::from_tile_scale(i32) -> f64

GeoTile可以代表许多事物——请参阅features.rs

您还可以使用以下三种辅助方法之一将更多数据加载到您的OSMGeoMapper.data_structure中:

OSMGeoMapper::load_more_from_lat_lon(&mut self, latitude: f64, longitude: f64, radius: Option<u32>) -> Result<(), Box<dyn std::error::Error>>

OSMGeoMapper::load_more_from_address(&mut self, address: String, radius: Option<u32>) -> Result<(), Box<dyn std::error::Error>>

OSMGeoMapper::load_more_from_geojson_file(&mut self, geojson_file: String) -> Result<(), Box<dyn std::error::Error>>

请参阅test_multiple_threads()测试函数,位于tests/lib_tests.rs,以查看同时加载数据的示例。

待办事项

  • 实现逻辑,在未通过命令行提供的情况下,在geojson文件中间选择经纬度
  • 实现(二进制?)序列化要加载/缓存的地图数据
  • 继续调整主题
  • 需要处理速率限制的Overpass API调用(需要解析XML响应)的逻辑

问题

在某些终端模拟器中(在urxvt中已确认),Shift + 移动不起作用。

依赖项

~27MB
~394K SLoC