oxigdal_services/ogc_features/
crs.rs1use super::error::FeaturesError;
4
5pub const CRS84_URI: &str = "http://www.opengis.net/def/crs/OGC/1.3/CRS84";
7pub const EPSG4326_URI: &str = "http://www.opengis.net/def/crs/EPSG/0/4326";
9pub const EPSG3857_URI: &str = "http://www.opengis.net/def/crs/EPSG/0/3857";
11pub const EPSG4258_URI: &str = "http://www.opengis.net/def/crs/EPSG/0/4258";
13pub const EPSG25832_URI: &str = "http://www.opengis.net/def/crs/EPSG/0/25832";
15pub const EPSG25833_URI: &str = "http://www.opengis.net/def/crs/EPSG/0/25833";
17
18const EARTH_RADIUS_M: f64 = 6_378_137.0;
20const PI: f64 = std::f64::consts::PI;
22
23pub struct CrsTransform;
25
26impl CrsTransform {
27 pub fn supported_crs_uris() -> Vec<String> {
29 vec![
30 CRS84_URI.to_string(),
31 EPSG4326_URI.to_string(),
32 EPSG3857_URI.to_string(),
33 EPSG4258_URI.to_string(),
34 EPSG25832_URI.to_string(),
35 EPSG25833_URI.to_string(),
36 ]
37 }
38
39 pub fn bbox_to_wgs84(bbox: [f64; 4], source_crs: &str) -> Result<[f64; 4], FeaturesError> {
45 match source_crs {
46 CRS84_URI | EPSG4326_URI | EPSG4258_URI => Ok(bbox),
48
49 EPSG3857_URI => {
51 let lon_min = bbox[0] / EARTH_RADIUS_M * (180.0 / PI);
52 let lat_min =
53 (2.0 * (bbox[1] / EARTH_RADIUS_M).exp().atan() - PI / 2.0) * (180.0 / PI);
54 let lon_max = bbox[2] / EARTH_RADIUS_M * (180.0 / PI);
55 let lat_max =
56 (2.0 * (bbox[3] / EARTH_RADIUS_M).exp().atan() - PI / 2.0) * (180.0 / PI);
57 Ok([lon_min, lat_min, lon_max, lat_max])
58 }
59
60 other => Err(FeaturesError::InvalidCrs(format!(
61 "CRS not supported for bbox transformation: {other}"
62 ))),
63 }
64 }
65
66 pub fn is_supported(uri: &str) -> bool {
68 matches!(
69 uri,
70 CRS84_URI | EPSG4326_URI | EPSG3857_URI | EPSG4258_URI | EPSG25832_URI | EPSG25833_URI
71 )
72 }
73}