1use serde::{Deserialize, Serialize};
2
3use crate::cartesian::NewCartesianPoint2d;
4use crate::geo::datum::Datum;
5use crate::geo::impls::projection::{GeodesyProjection, WebMercator};
6use crate::geo::traits::point::NewGeoPoint;
7use crate::geo::traits::projection::Projection;
8
9#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
11pub struct Crs {
12 datum: Datum,
13 projection_type: ProjectionType,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
18#[non_exhaustive]
19pub enum ProjectionType {
20 Unknown,
22 None,
24 WebMercator,
26 Other(String),
28}
29
30impl Crs {
31 pub const EPSG3857: Crs = Crs {
33 datum: Datum::WGS84,
34 projection_type: ProjectionType::WebMercator,
35 };
36
37 pub const WGS84: Crs = Crs {
39 datum: Datum::WGS84,
40 projection_type: ProjectionType::None,
41 };
42
43 pub fn new(datum: Datum, projection_type: ProjectionType) -> Self {
45 Self {
46 datum,
47 projection_type,
48 }
49 }
50
51 pub fn get_projection<In, Out>(
55 &self,
56 ) -> Option<Box<dyn Projection<InPoint = In, OutPoint = Out>>>
57 where
58 In: NewGeoPoint + 'static,
59 Out: NewCartesianPoint2d + 'static,
60 {
61 match &self.projection_type {
62 ProjectionType::WebMercator => Some(Box::new(WebMercator::new(self.datum))),
63 ProjectionType::Other(definition) => {
64 Some(Box::new(GeodesyProjection::new(definition)?))
65 }
66 _ => None,
67 }
68 }
69}