2 个稳定版本
1.2.0 | 2023年6月9日 |
---|---|
1.1.0 | 2023年5月28日 |
1.0.0 |
|
#77 在 国际化(i18n)
815 每月下载次数
用于 osm-lump-ways
765KB
1K SLoC
country-boundaries
是一个快速离线反向地理编码器:找到地理位置所在的区域。
它是同名 Java 库的移植,具有几乎相同的 API,并使用相同的文件格式。
版权和许可证
© 2023 Tobias Zwick。此库根据 Apache License 2.0 条款发布。
示例中使用的默认数据来源于 OpenStreetMap,因此根据 开放数据数据库许可证(ODbL)授权,© OpenStreetMap 贡献者。如果使用它,则需要署名。
示例用法
use std::collections::HashSet;
use country_boundaries::{BoundingBox, CountryBoundaries, LatLon, BOUNDARIES_ODBL_360X180};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create an instance from ODbL licensed data, (c) OpenStreetMap contributors. Treat the value as a singleton.
let boundaries = CountryBoundaries::from_reader(BOUNDARIES_ODBL_360X180)?;
// You can read other/own boundaries data with custom raster sizes from other sources also from file.
// See section "Data" below.
// get country id(s) for Dallas¹
assert_eq!(
vec!["US-TX", "US"],
boundaries.ids(LatLon::new(33.0, -97.0)?)
);
// check that German exclave in Switzerland² is in Germany
assert!(
boundaries.is_in(LatLon::new(47.6973, 8.6910)?, "DE")
);
// check if position is in any country where the first day of the workweek is Saturday. It is
// more efficient than calling `is_in` for every id in a row.
assert!(
!boundaries.is_in_any(
LatLon::new(21.0, 96.0)?,
&HashSet::from(["BD", "DJ", "IR", "PS"])
)
);
// get which country ids can be found within the cell(s) that contain a bounding box around the Vaalserberg³
assert_eq!(
HashSet::from(["NL", "LU", "DE", "BE", "BE-VLG", "BE-WAL"]),
boundaries.intersecting_ids(BoundingBox::new(50.6, 5.9, 50.8, 6.1)?)
);
// get which country ids completely cover a bounding box around the Vaalserberg³
assert_eq!(
HashSet::new(),
boundaries.containing_ids(BoundingBox::new(50.6, 5.9, 50.8, 6.1)?)
);
Ok(())
}
ids 的命名方式和可用区域取决于使用的数据。示例中使用的数据是默认数据(见下文)。
数据
默认数据是从 JOSM 项目中的此文件生成的,它根据 开放数据数据库许可证(ODbL)授权,© OpenStreetMap 贡献者。如果使用它,则需要署名。
您也可以从 GeoJson 或 OSM XML 生成自己的(国家)边界文件,使用 Java 项目 中 /generator/
文件夹中的 Java 命令行应用程序,然后使用该文件。例如,Natural Earth 数据是公共领域。
默认数据
为了您的方便,默认数据以字节形式包含在发行版中,您可以通过以下常量访问它们:BOUNDARIES_ODBL_360X180
、BOUNDARIES_ODBL_180X60
或BOUNDARIES_ODBL_60X30
。(链接器确保仅包含您使用的常量)。这些都是相同的数据,只是不同的栅格大小:栅格越大,文件大小越大,但查询速度也越快,有关速度的详细信息请参阅下一节。精度是相同的。
默认数据集之所以这么小,是因为实际的国家和州界已经从它们的实际边界简化了一些。通常,它是为了满足OpenStreetMap编辑的要求而制作的。
-
在精度方面,它努力确保每个定居点和主要道路都在正确的边界一侧,在人口密集地区精度可能更高。然而,它对海洋边界一无所知,只能返回陆地上的正确结果。
-
当有可用时,它使用ISO 3166-1 alpha-2国家代码作为ID,否则使用ISO 3166-2作为子区域代码。
-
它包括🇺🇸美国、🇨🇦加拿大、🇦🇺澳大利亚、🇨🇳中国、🇮🇳印度、🇪🇸西班牙、🇬🇧英国、🇧🇪比利时、🇧🇦波斯尼亚和黑塞哥维那、🇮🇩印度尼西亚、🇫🇲密克罗尼西亚、🇰🇲科摩罗以及大多数其他国家的ISO 3166-2代码的自治子区域,例如🇷🇺俄罗斯境内的共和国、🇮🇹意大利等地的自治地区。
有关详细信息,请参阅源文件(您可以在JOSM中打开它)。
速度
在单线程上查询100万个随机位置大约需要0.1秒,使用Ryzen 5700X CPU。
对于上述测量,我使用了一个360x180的栅格(=一个单元是经度1°,纬度1°)。您可以选择更小的栅格以获得更小的文件,或者选择更大的栅格以获得更快的查询。根据我的测试,一个60x30(=一个单元是经纬度6°)的文件大约小4倍,但查询速度慢4倍。
默认提供60x30、180x90和360x180栅格的文件(请参阅上面的章节),但您也可以创建具有自定义栅格大小的文件。
之所以这么快,是因为源数据的边界被分割成栅格,所以,点在多边形内检查(如果有),只需要对位于点所在的单元中的小几何体进行。
库为什么不直接消耗GeoJSON或类似的文件,而是只消耗从它生成的文件,是因为源几何体的切片不需要在每次文件加载时都进行,而只需在将当前版本的边界放入发行版之前进行一次。