1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use crate::{
error::{InvalidGeometry, InvalidLatLng},
geom::ToCells,
CellIndex, LatLng, Resolution,
};
use std::boxed::Box;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Point(geo::Point<f64>);
impl Point {
pub fn from_radians(
point: geo::Point<f64>,
) -> Result<Self, InvalidGeometry> {
Self::check_coords(&point).map(|_| Self(point))
}
pub fn from_degrees(
mut point: geo::Point<f64>,
) -> Result<Self, InvalidGeometry> {
point.set_x(point.x().to_radians());
point.set_y(point.y().to_radians());
Self::from_radians(point)
}
fn check_coords(point: &geo::Point<f64>) -> Result<(), InvalidGeometry> {
if !super::coord_is_valid(point.0) {
return Err(InvalidGeometry::new("x and y must be valid"));
}
Ok(())
}
}
impl From<Point> for geo::Point<f64> {
fn from(value: Point) -> Self {
value.0
}
}
impl TryFrom<Point> for LatLng {
type Error = InvalidLatLng;
fn try_from(value: Point) -> Result<Self, Self::Error> {
Self::new(value.0.y(), value.0.x())
}
}
impl ToCells for Point {
fn max_cells_count(&self, _resolution: Resolution) -> usize {
1
}
fn to_cells(
&self,
resolution: Resolution,
) -> Box<dyn Iterator<Item = CellIndex> + '_> {
let ll = LatLng::try_from(*self).expect("valid coordinate");
Box::new(std::iter::once(ll.to_cell(resolution)))
}
}