2 个稳定版本

1.2.0 2023年6月9日
1.1.0 2023年5月28日
1.0.0 2023年5月6日

#77国际化(i18n)

Download history 325/week @ 2024-03-16 249/week @ 2024-03-23 277/week @ 2024-03-30 209/week @ 2024-04-06 166/week @ 2024-04-13 188/week @ 2024-04-20 118/week @ 2024-04-27 243/week @ 2024-05-04 310/week @ 2024-05-11 141/week @ 2024-05-18 85/week @ 2024-05-25 157/week @ 2024-06-01 180/week @ 2024-06-08 192/week @ 2024-06-15 347/week @ 2024-06-22 86/week @ 2024-06-29

815 每月下载次数
用于 osm-lump-ways

Apache-2.0

765KB
1K SLoC

crates.io version docs.rs docs

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_360X180BOUNDARIES_ODBL_180X60BOUNDARIES_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或类似的文件,而是只消耗从它生成的文件,是因为源几何体的切片不需要在每次文件加载时都进行,而只需在将当前版本的边界放入发行版之前进行一次。

无运行时依赖