1use crate::{First, Fourth, GridCell, Second, Third};
2
3#[derive(Clone, Copy)]
4pub struct Coordinate {
5 pub longitude: f64,
6 pub latitude: f64,
7}
8
9impl Coordinate {
10 pub fn first_cell(&self) -> GridCell<First> {
11 let degree_y = 40.0 / 60.0;
13 let y = (self.latitude / degree_y).floor();
14
15 let east = self.longitude.floor();
17 let x = east - 100.0;
18 GridCell {
19 code: (x + 100.0 * y) as u64,
20 west_longitude: east,
21 south_latitude: y * degree_y,
22 phantom: Default::default(),
23 }
24 }
25
26 pub fn second_cell(&self, first: &GridCell<First>) -> GridCell<Second> {
27 let degree_y = 5.0 / 60.0;
29 let y = ((self.latitude - first.south_latitude) / degree_y).floor();
30
31 let degree_x = 7.5 / 60.0;
33 let x = ((self.longitude - first.west_longitude) / degree_x).floor();
34
35 GridCell {
36 code: first.code * 100 + (y * 10.0 + x) as u64,
37 west_longitude: first.west_longitude + x * degree_x,
38 south_latitude: first.south_latitude + y * degree_y,
39 phantom: Default::default(),
40 }
41 }
42
43 pub fn third_cell(&self, second: &GridCell<Second>) -> GridCell<Third> {
44 let degree_y = 30.0 / 60.0 / 60.0;
46 let y = ((self.latitude - second.south_latitude) / degree_y).floor();
47
48 let degree_x = 45.0 / 60.0 / 60.0;
50 let x = ((self.longitude - second.west_longitude) / degree_x).floor();
51
52 GridCell {
53 code: second.code * 100 + (y * 10.0 + x) as u64,
54 west_longitude: second.west_longitude + x * degree_x,
55 south_latitude: second.south_latitude + y * degree_y,
56 phantom: Default::default(),
57 }
58 }
59
60 pub fn fourth_cell(&self, third: &GridCell<Third>) -> GridCell<Fourth> {
61 let degree_y = 15.0 / 60.0 / 60.0;
63 let y = ((self.latitude - third.south_latitude) / degree_y).floor();
64
65 let degree_x = 22.5 / 60.0 / 60.0;
67 let x = ((self.longitude - third.west_longitude) / degree_x).floor();
68
69 let code = (x + 1.0) + y * 2.0;
71 GridCell {
72 code: third.code * 10 + (code as u64),
73 west_longitude: third.west_longitude + x * degree_x,
74 south_latitude: third.south_latitude + y * degree_y,
75 phantom: Default::default(),
76 }
77 }
78}