use serde::{Deserialize, Serialize};
pub trait ProjectedPoint: Sized {
const WKID: u32;
const NAME: &'static str;
fn x(&self) -> f64;
fn y(&self) -> f64;
fn to_location_json(&self) -> String {
format!(
r#"{{"x":{},"y":{},"spatialReference":{{"wkid":{}}}}}"#,
self.x(),
self.y(),
Self::WKID
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Wgs84Point {
#[serde(rename = "x")]
lon: f64,
#[serde(rename = "y")]
lat: f64,
}
impl Wgs84Point {
pub fn new(lon: f64, lat: f64) -> Self {
Self { lon, lat }
}
pub fn lon(&self) -> f64 {
self.lon
}
pub fn lat(&self) -> f64 {
self.lat
}
}
impl ProjectedPoint for Wgs84Point {
const WKID: u32 = 4326;
const NAME: &'static str = "WGS84";
fn x(&self) -> f64 {
self.lon
}
fn y(&self) -> f64 {
self.lat
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct WebMercatorPoint {
x: f64,
y: f64,
}
impl WebMercatorPoint {
pub fn new(x: f64, y: f64) -> Self {
Self { x, y }
}
pub fn x(&self) -> f64 {
self.x
}
pub fn y(&self) -> f64 {
self.y
}
}
impl ProjectedPoint for WebMercatorPoint {
const WKID: u32 = 3857;
const NAME: &'static str = "Web Mercator";
fn x(&self) -> f64 {
self.x
}
fn y(&self) -> f64 {
self.y
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct StatePlanePoint<const ZONE: u32> {
x: f64,
y: f64,
}
impl<const ZONE: u32> StatePlanePoint<ZONE> {
pub fn new(x: f64, y: f64) -> Self {
Self { x, y }
}
pub fn x(&self) -> f64 {
self.x
}
pub fn y(&self) -> f64 {
self.y
}
}
impl<const ZONE: u32> ProjectedPoint for StatePlanePoint<ZONE> {
const WKID: u32 = ZONE;
const NAME: &'static str = "State Plane";
fn x(&self) -> f64 {
self.x
}
fn y(&self) -> f64 {
self.y
}
}
pub type CaliforniaZone5 = StatePlanePoint<2229>;
pub type CaliforniaZone5Meters = StatePlanePoint<2771>;
pub type OregonNorth = StatePlanePoint<2269>;
pub type OregonNorthMeters = StatePlanePoint<2913>;
pub type WashingtonNorth = StatePlanePoint<2285>;
pub type WashingtonNorthMeters = StatePlanePoint<2926>;