1#[derive(Clone)]
5pub struct Projection
6{
7 projection_utm: proj4rs::proj::Proj,
8 projection_wgs84: proj4rs::proj::Proj,
9 offset_x: f64,
10 offset_y: f64,
11}
12
13fn utm_zone(lon: f64, lat: f64) -> i32
14{
15 if (56.0..64.0).contains(&lat) && (3.0..12.0).contains(&lon)
16 {
17 return 32;
18 }
19 else if (72.0..84.0).contains(&lat)
21 {
22 if (0.0..9.0).contains(&lon)
23 {
24 return 31;
25 }
26 else if (9.0..21.0).contains(&lon)
27 {
28 return 33;
29 }
30 else if (21.0..33.0).contains(&lon)
31 {
32 return 35;
33 }
34 else if (33.0..42.0).contains(&lon)
35 {
36 return 37;
37 }
38 }
39 ((lon + 180.0) / 6.0) as i32 + 1
40}
41
42impl Projection
43{
44 pub fn new(lon: f64, lat: f64) -> Projection
46 {
47 let utm_z: i32 = utm_zone(lon, lat);
48 let proj_str = format!(
49 "+proj=utm +zone={} +datum=WGS84 +units=m +no_defs +type=crs",
50 utm_z
51 );
52 let proj_from = proj4rs::proj::Proj::from_proj_string(&proj_str[..]).unwrap();
53 let proj_to = proj4rs::proj::Proj::from_proj_string(concat!(
54 "+proj=longlat +ellps=WGS84",
55 " +datum=WGS84 +no_defs"
56 ))
57 .unwrap();
58
59 let mut point_3d = (lon.to_radians(), lat.to_radians(), 0.0);
60 proj4rs::transform::transform(&proj_to, &proj_from, &mut point_3d).unwrap();
61
62 Projection {
63 projection_utm: proj_from,
64 projection_wgs84: proj_to,
65 offset_x: point_3d.0,
66 offset_y: point_3d.1,
67 }
68 }
69 pub fn from_wgs84(&self, lon: f64, lat: f64) -> (f64, f64)
71 {
72 let mut point_3d = (lon.to_radians(), lat.to_radians(), 0.0);
73 proj4rs::transform::transform(&self.projection_wgs84, &self.projection_utm, &mut point_3d)
74 .unwrap();
75 (point_3d.0 - self.offset_x, point_3d.1 - self.offset_y)
76 }
77 pub fn to_wgs84(&self, x: f64, y: f64) -> (f64, f64)
79 {
80 let mut point_3d = (x + self.offset_x, y + self.offset_y, 0.0);
81 proj4rs::transform::transform(&self.projection_utm, &self.projection_wgs84, &mut point_3d)
82 .unwrap();
83 (point_3d.0.to_degrees(), point_3d.1.to_degrees())
84 }
85}