#esri #spatial #gis #arc-gis #json-object

serde_esri

用于序列化和反序列化来自 Esri 位置服务的 JSON 的库

3 个不稳定版本

0.3.1 2024 年 4 月 17 日
0.3.0 2024 年 4 月 16 日
0.2.0 2024 年 4 月 11 日

#55 in 地理空间

MIT/Apache

93KB
1.5K SLoC

serde_esri

Esri JSON 解析库。

此 crate 提供了具有 serde::Deserializeserde::Serialize trait 实现的 Esri JSON 对象表示。

serde_esri 具有其他功能

  • geo 为 Esri JSON 对象实现了 From
  • geoarrow 通过实现 geoarrow 几何特性和提供工具函数 featureset_to_geoarrow(),该函数将 FeatureSet 转换为 arrow GeoTable,与 arrow 和 geoarrow 兼容。
  • places-client 为 Places 服务 REST API 提供了 API 客户端。

示例用法

此示例从特征服务中读取一些特征并返回一个 FeatureSet 结构体。它说明了 geo 和 geoarrow 功能的使用。

[dependencies]
geo = "0.28.0"
geoarrow = "0.2.0"
reqwest = { version = "0.12.3", features = ["blocking"] }
serde_esri = { version = "0.2.0", features = ["geo", "geoarrow"] }
serde_json = "1.0.115"
use geo::{GeodesicArea, Polygon};
use serde_esri::arrow_compat::featureset_to_geoarrow;
use serde_esri::features::FeatureSet;
use std::io::Read;

fn main() {
    let flayer_url = "https://services.arcgis.com/P3ePLMYs2RVChkJx/ArcGIS/rest/services/USA_Counties_Generalized_Boundaries/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&resultRecordCount=5&f=json";
    let mut res = reqwest::blocking::get(flayer_url).unwrap();
    let mut body = String::new();

    // Read the request into a String
    res.read_to_string(&mut body).unwrap();

    // Parse into a 2D FeatureSet
    let fset: FeatureSet<2> = serde_json::from_str(&body).unwrap();

    // Utilize the `geo` feature by converting to Polygon
    // and calculate geodesic area
    // iterate through the features
    let area = fset
        .features
        .clone()
        .into_iter()
        .map(|feat| {
            // convert to a geo_types::Polygon
            let poly = Polygon::from(feat.geometry.unwrap().as_polygon().unwrap());
            // calculate geodesic area
            poly.geodesic_area_unsigned()
        })
        .collect::<Vec<_>>();

    // print areas
    println!("{:?}", area);

    // convert to a geoarrow GeoTable
    println!("{:?}", featureset_to_geoarrow(fset).unwrap());
}

支持的 Esri JSON 对象

几何形状

Esri 几何对象由以下结构体编码

  • EsriPoint
  • EsriMultiPoint<N>
  • EsriPolyline<N>
  • EsriPolygon<N>
  • EsriEnvelope

它们被封装在 EsriGeometry 枚举中

enum EsriGeometry<const N: usize> {
    Point(EsriPoint),
    MultiPoint(EsriMultiPoint<N>),
    Polygon(EsriPolygon<N>),
    Polyline(EsriPolyline<N>),
    Envelope(EsriEnvelope),
}

参数 N 用于指定几何形状的维度。使用 <2> 表示二维数据,<3> 表示 Z 值,当 MZ 都存在时使用 <4>

特征集

Esri JSON FeatureSet 是从 特征服务 最常返回的内容。它包含多个可选字段,最重要的是,一个 Feature 向量。

特征是一个具有 geometryattributes 字段的 struct。几何形状必须是可能的几何形状之一,属性可以是键值对。

struct Feature<const N: usize> {
    geometry: Option<EsriGeometry<N>>,
    attributes: Option<Map<String, Value>>,
}

特征集的定义为

pub struct FeatureSet<const N: usize> {
    // ... other optional fields 
    features: Vec<Feature<N>>,
    geometryType: Option<String>,
    spatialReference: SpatialReference,
}

空间参考

Esri 空间参考对象SpatialReference struct 表示。请注意,尽管所有字段都是可选的,但应始终提供其中一个。

struct SpatialReference {
    wkid: Option<u32>,
    latest_wkid: Option<u32>,
    vcs_wkid: Option<u32>,
    latest_vcs_wkid: Option<u32>,
    wkt: Option<String>,
}

地点服务 API 客户端

在您的 Cargo.toml 中激活 PlaceAPI 客户端

[dependencies]
serde_esri = { version = "0.3.0", features = ["places-client"] }
fn main() {

    let client = PlacesClient::new(
        PLACES_API_URL,
        "your-developer-credential",
    );

    // Use the query within extent query builder to create query parameters
    let params = WithinExtentQueryParamsBuilder::default()
        .xmin(139.74)
        .ymin(35.65)
        .xmax(139.75)
        .ymax(35.66)
        .build()
        .unwrap();

    // Call the within_extent method with the query parameters
    let res = client.within_extent(params).unwrap();

    // use the automatic pagination for the iterator method
    res.into_iter()
        .for_each(|r| println!("{:?}", r.unwrap().name));
}

依赖关系

~2–18MB
~223K SLoC