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 在 地理空间
53 每月下载量
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 --address "vancouver canada"
库
请参阅 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_address
或OSMGeoMapper::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) -> i32
和osm_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