-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprojection.rs
106 lines (96 loc) · 3.59 KB
/
projection.rs
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
95
96
97
98
99
100
101
102
103
104
105
106
use std::sync::Arc;
use pcd_core::pointcloud::point::{Point, PointCloud};
use projection_transform::{crs::*, jprect::JPRZone, vshift::Jgd2011ToWgs84};
use super::Transform;
pub struct ProjectionTransform {
jgd2wgs: Arc<Jgd2011ToWgs84>,
output_epsg: EpsgCode,
}
impl Transform for ProjectionTransform {
fn transform(&self, point_cloud: PointCloud) -> PointCloud {
let input_epsg = point_cloud.metadata.epsg;
match input_epsg {
EPSG_JGD2011_JPRECT_I
| EPSG_JGD2011_JPRECT_II
| EPSG_JGD2011_JPRECT_III
| EPSG_JGD2011_JPRECT_IV
| EPSG_JGD2011_JPRECT_V
| EPSG_JGD2011_JPRECT_VI
| EPSG_JGD2011_JPRECT_VII
| EPSG_JGD2011_JPRECT_VIII
| EPSG_JGD2011_JPRECT_IX
| EPSG_JGD2011_JPRECT_X
| EPSG_JGD2011_JPRECT_XI
| EPSG_JGD2011_JPRECT_XII
| EPSG_JGD2011_JPRECT_XIII
| EPSG_JGD2011_JPRECT_XIV
| EPSG_JGD2011_JPRECT_XV
| EPSG_JGD2011_JPRECT_XVI
| EPSG_JGD2011_JPRECT_XVII
| EPSG_JGD2011_JPRECT_XVIII
| EPSG_JGD2011_JPRECT_XIX
| EPSG_JGD2011_JPRECT_I_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_II_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_III_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_IV_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_V_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_VI_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_VII_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_VIII_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_IX_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_X_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_XI_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_XII_JGD2011_HEIGHT
| EPSG_JGD2011_JPRECT_XIII_JGD2011_HEIGHT => {
self.transform_from_jgd2011(point_cloud, Some(input_epsg))
}
_ => {
panic!("Unsupported input CRS: {}", input_epsg);
}
}
}
}
impl ProjectionTransform {
pub fn new(jgd2wgs: Arc<Jgd2011ToWgs84>, output_epsg: EpsgCode) -> Self {
Self {
jgd2wgs,
output_epsg,
}
}
fn rectangular_to_lnglat(x: f64, y: f64, height: f64, input_epsg: EpsgCode) -> (f64, f64, f64) {
let zone = JPRZone::from_epsg(input_epsg).unwrap();
let proj = zone.projection();
let (lng, lat, height) = proj.project_inverse(x, y, height).unwrap();
(lng, lat, height)
}
fn transform_from_jgd2011(
&self,
point_cloud: PointCloud,
rectangular: Option<EpsgCode>,
) -> PointCloud {
let mut points = vec![];
match self.output_epsg {
EPSG_WGS84_GEOGRAPHIC_3D => {
for (x, y, z, point) in point_cloud.iter() {
let (lng, lat, height) = if let Some(input_epsg) = rectangular {
Self::rectangular_to_lnglat(x, y, z, input_epsg)
} else {
(x, y, z)
};
let (lng, lat, height) = self.jgd2wgs.convert(lng, lat, height);
points.push(Point {
x: lng,
y: lat,
z: height,
color: point.color.clone(),
attributes: point.attributes.clone(),
});
}
}
_ => {
panic!("Unsupported output CRS: {}", self.output_epsg);
}
};
PointCloud::new(points, self.output_epsg)
}
}