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
//! Coordinate reference system identification (the `coordRefSys` member).

use serde::{Deserialize, Serialize};

/// The OGC URI for WGS 84 longitude/latitude (2D), the JSON-FG default CRS.
pub const CRS84: &str = "http://www.opengis.net/def/crs/OGC/0/CRS84";
/// The OGC URI for WGS 84 longitude/latitude/height (3D).
pub const CRS84H: &str = "http://www.opengis.net/def/crs/OGC/0/CRS84h";

/// The value of a `coordRefSys` member: a single reference, or (for a compound CRS) an
/// array of at least two references.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CoordRefSys {
    /// A single coordinate reference system.
    Single(RefSys),
    /// A compound CRS, e.g. a horizontal CRS combined with a vertical one.
    Compound(Vec<RefSys>),
}

/// A single coordinate reference system: either a plain URI, or a by-reference object
/// that may pin a dynamic CRS to an `epoch`.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum RefSys {
    /// A CRS identified by URI, e.g. `http://www.opengis.net/def/crs/EPSG/0/3857`.
    Uri(String),
    /// A CRS identified by reference, optionally with a coordinate epoch.
    Reference(Reference),
}

/// A `{"type": "Reference", "href": …, "epoch": …}` coordinate reference system object.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Reference {
    #[serde(rename = "type")]
    pub kind: ReferenceKind,
    pub href: String,
    /// The coordinate epoch for a dynamic CRS, e.g. `2017.23`.
    #[serde(skip_serializing_if = "Option::is_none", default)]
    pub epoch: Option<f64>,
}

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

impl CoordRefSys {
    /// A CRS identified by the given URI.
    pub fn uri(uri: impl Into<String>) -> Self {
        CoordRefSys::Single(RefSys::Uri(uri.into()))
    }

    /// A CRS built from an EPSG code, e.g. `3857` →
    /// `http://www.opengis.net/def/crs/EPSG/0/3857`.
    pub fn from_epsg(code: u32) -> Self {
        CoordRefSys::uri(format!("http://www.opengis.net/def/crs/EPSG/0/{code}"))
    }

    /// WGS 84 longitude/latitude (`CRS84`), the JSON-FG default 2D CRS.
    pub fn crs84() -> Self {
        CoordRefSys::uri(CRS84)
    }

    /// `true` if this is WGS 84 longitude/latitude (`CRS84`) or lon/lat/height
    /// (`CRS84h`) — the coordinate reference systems allowed in a feature's GeoJSON
    /// `geometry` member. Producers use this to decide between `geometry` and `place`.
    pub fn is_wgs84(&self) -> bool {
        matches!(
            self,
            CoordRefSys::Single(RefSys::Uri(uri)) if uri == CRS84 || uri == CRS84H
        )
    }
}