kasane_logic/geometry/point/coordinate/
impls.rs1use crate::{
2 Coordinate, Ecef, MAX_ZOOM_LEVEL, Point, SpatialIdError, WGS84_A, WGS84_E2,
3 geometry::traits::CoverSingleIds,
4};
5use std::fmt;
6
7impl fmt::Debug for Coordinate {
8 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9 f.debug_struct("Coordinate")
10 .field("latitude", &self.latitude)
11 .field("longitude", &self.longitude)
12 .field("altitude", &self.altitude)
13 .finish()
14 }
15}
16
17impl From<Coordinate> for Ecef {
18 fn from(value: Coordinate) -> Self {
30 let lat = value.latitude.to_radians();
31 let lon = value.longitude.to_radians();
32 let h = value.altitude;
33
34 let sin_lat = lat.sin();
35 let cos_lat = lat.cos();
36 let sin_lon = lon.sin();
37 let cos_lon = lon.cos();
38
39 let n = WGS84_A / (1.0 - WGS84_E2 * sin_lat * sin_lat).sqrt();
40
41 let x = (n + h) * cos_lat * cos_lon;
42 let y = (n + h) * cos_lat * sin_lon;
43 let z = (n * (1.0 - WGS84_E2) + h) * sin_lat;
44
45 Ecef::new(x, y, z)
46 }
47}
48
49impl Default for Coordinate {
51 fn default() -> Self {
52 Self {
53 latitude: 0.0,
54 longitude: 0.0,
55 altitude: 0.0,
56 }
57 }
58}
59
60impl Point for Coordinate {}
61
62impl CoverSingleIds for Coordinate {
63 fn cover_single_ids(
64 &self,
65 z: u8,
66 ) -> Result<impl Iterator<Item = crate::SingleId>, crate::Error> {
67 if z > MAX_ZOOM_LEVEL as u8 {
68 return Err(SpatialIdError::ZOutOfRange { z }.into());
69 }
70 Ok(std::iter::once(self.single_id(z)?))
71 }
72}