use wbprojection::{
EpsgIdentifyPolicy,
epsg_from_srs_reference as wb_epsg_from_srs_reference,
identify_epsg_from_wkt_with_policy as wb_identify_epsg_from_wkt_with_policy,
to_ogc_wkt,
};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Crs {
pub epsg: Option<u32>,
pub wkt: Option<String>,
}
impl Crs {
pub fn new() -> Self {
Self::default()
}
pub fn from_epsg(epsg: u32) -> Self {
Self { epsg: Some(epsg), wkt: ogc_wkt_from_epsg(epsg) }
}
pub fn with_epsg(mut self, epsg: u32) -> Self {
self.epsg = Some(epsg);
self
}
pub fn with_wkt(mut self, wkt: impl Into<String>) -> Self {
self.wkt = Some(wkt.into());
self
}
}
pub fn ogc_wkt_from_epsg(epsg: u32) -> Option<String> {
to_ogc_wkt(epsg).ok()
}
pub fn epsg_from_srs_reference(s: &str) -> Option<u32> {
wb_epsg_from_srs_reference(s)
}
pub fn epsg_from_wkt(wkt: &str) -> Option<u32> {
epsg_from_wkt_lenient(wkt)
}
pub fn epsg_from_wkt_lenient(wkt: &str) -> Option<u32> {
wb_identify_epsg_from_wkt_with_policy(wkt, EpsgIdentifyPolicy::Lenient)
}
pub fn epsg_from_wkt_strict(wkt: &str) -> Option<u32> {
wb_identify_epsg_from_wkt_with_policy(wkt, EpsgIdentifyPolicy::Strict)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_epsg_srs_forms() {
assert_eq!(epsg_from_srs_reference("EPSG:3857"), Some(3857));
assert_eq!(
epsg_from_srs_reference("urn:ogc:def:crs:EPSG::32633"),
Some(32633)
);
}
#[test]
fn parses_epsg_from_wkt_authority() {
let wkt = "GEOGCS[\"WGS 84\",AUTHORITY[\"EPSG\",\"4326\"]]";
assert_eq!(epsg_from_wkt(wkt), Some(4326));
}
#[test]
fn parses_epsg_from_legacy_wkt_without_authority_lenient() {
let wkt = "PROJCS[\"NAD83_CSRS_UTM_zone_17N\",GEOGCS[\"GCS_NAD83(CSRS)\",DATUM[\"D_North_American_1983_CSRS\",SPHEROID[\"GRS_1980\",6378137,298.257222101]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",-81],PARAMETER[\"scale_factor\",0.9996],PARAMETER[\"false_easting\",500000],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]";
assert_eq!(epsg_from_wkt_lenient(wkt), Some(2958));
}
#[test]
fn strict_mode_rejects_ambiguous_legacy_wkt() {
let wkt = "PROJCS[\"NAD83_CSRS_UTM_zone_17N\",GEOGCS[\"GCS_NAD83(CSRS)\",DATUM[\"D_North_American_1983_CSRS\",SPHEROID[\"GRS_1980\",6378137,298.257222101]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",-81],PARAMETER[\"scale_factor\",0.9996],PARAMETER[\"false_easting\",500000],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]";
assert_eq!(epsg_from_wkt_strict(wkt), None);
}
#[test]
fn does_not_extract_epsg_from_arbitrary_wkt_text() {
let wkt = "PROJCS[\"Custom (EPSG:2056)\",GEOGCS[\"WGS 84\"]]";
assert_eq!(epsg_from_wkt(wkt), None);
}
}