jsonfg 0.1.0

Types for OGC Features and Geometries JSON (JSON-FG), a GeoJSON superset with support for arbitrary coordinate reference systems, solids, and curved geometries.
Documentation
//! The JSON-FG `FeatureCollection` object.

use serde::{Deserialize, Serialize};

use crate::JsonObject;
use crate::crs::CoordRefSys;
use crate::feature::{Feature, FeatureType};
use crate::measures::Measures;

/// A JSON-FG feature collection.
///
/// Collection-level members such as [`coord_ref_sys`](FeatureCollection::coord_ref_sys)
/// and [`feature_type`](FeatureCollection::feature_type) provide the default for the
/// contained features, which then omit those members. As with [`Feature`], set
/// [`conforms_to`](FeatureCollection::conforms_to) only on this top-level object.
///
/// OGC API members that are not part of core JSON-FG — `links`, `timeStamp`,
/// `numberMatched`, `numberReturned` — are preserved through
/// [`foreign_members`](FeatureCollection::foreign_members).
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct FeatureCollection {
    #[serde(rename = "type", default)]
    pub kind: FeatureCollectionKind,

    /// Declared conformance classes. Set only on the top-level object of a document.
    #[serde(
        rename = "conformsTo",
        skip_serializing_if = "Option::is_none",
        default
    )]
    pub conforms_to: Option<Vec<String>>,

    #[serde(
        rename = "featureType",
        skip_serializing_if = "Option::is_none",
        default
    )]
    pub feature_type: Option<FeatureType>,

    /// The dimension (0–3) of the geometries in this collection, if uniform.
    #[serde(
        rename = "geometryDimension",
        skip_serializing_if = "Option::is_none",
        default
    )]
    pub geometry_dimension: Option<u8>,

    #[serde(
        rename = "featureSchema",
        skip_serializing_if = "Option::is_none",
        default
    )]
    pub feature_schema: Option<crate::feature::FeatureSchema>,

    /// The default coordinate reference system for the features' `place` geometries.
    #[serde(
        rename = "coordRefSys",
        skip_serializing_if = "Option::is_none",
        default
    )]
    pub coord_ref_sys: Option<CoordRefSys>,

    #[serde(skip_serializing_if = "Option::is_none", default)]
    pub measures: Option<Measures>,

    /// The features. Always serialized (as `[]` when empty).
    pub features: Vec<Feature>,

    /// Any additional members (`links`, `timeStamp`, `numberMatched`, `numberReturned`,
    /// …), preserved verbatim.
    #[serde(flatten)]
    pub foreign_members: JsonObject,
}

impl Default for FeatureCollection {
    fn default() -> Self {
        FeatureCollection {
            kind: FeatureCollectionKind::FeatureCollection,
            conforms_to: None,
            feature_type: None,
            geometry_dimension: None,
            feature_schema: None,
            coord_ref_sys: None,
            measures: None,
            features: Vec::new(),
            foreign_members: JsonObject::new(),
        }
    }
}

impl FeatureCollection {
    /// A new, empty feature collection.
    pub fn new() -> Self {
        FeatureCollection::default()
    }
}

impl FromIterator<Feature> for FeatureCollection {
    fn from_iter<I: IntoIterator<Item = Feature>>(iter: I) -> Self {
        FeatureCollection {
            features: iter.into_iter().collect(),
            ..Default::default()
        }
    }
}

/// Marker for the `type` member of a [`FeatureCollection`]; always serializes as
/// `"FeatureCollection"`.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum FeatureCollectionKind {
    #[default]
    FeatureCollection,
}