1use super::{DatumParams, DatumType, ParameterValue};
2use crate::proj::{
3 AZIMUTH_PROJECTION_CENTRE, FALSE_EASTING, FALSE_NORTHING, LATITUDE_OF_FALSE_ORIGIN,
4 LATITUDE_OF_NATURAL_ORIGIN, LATITUDE_OF_PROJECTION_CENTRE, LONGITUDE_OF_FALSE_ORIGIN,
5 LONGITUDE_OF_NATURAL_ORIGIN, LONGITUDE_OF_PROJECTION_CENTRE, ProjValue,
6 SCALE_FACTOR_AT_NATURAL_ORIGIN, name_to_param_id,
7};
8use alloc::{collections::BTreeMap, string::String};
9use s2json::{GetXY, GetZ, NewXY, NewXYZ, SetXY, SetZ};
10
11#[repr(C)]
13#[derive(Debug, Default, Copy, Clone, PartialEq)]
14pub struct Coords(pub f64, pub f64, pub f64, pub f64);
15impl Coords {
16 pub fn new(x: f64, y: f64, z: f64, t: f64) -> Coords {
18 Coords(x, y, z, t)
19 }
20 pub fn new_xy(x: f64, y: f64) -> Coords {
22 Coords(x, y, 0.0, 0.0)
23 }
24}
25impl GetXY for Coords {
26 fn x(&self) -> f64 {
27 self.0
28 }
29 fn y(&self) -> f64 {
30 self.1
31 }
32}
33impl GetZ for Coords {
34 fn z(&self) -> Option<f64> {
35 Some(self.2)
36 }
37}
38impl NewXY for Coords {
39 fn new_xy(x: f64, y: f64) -> Self {
40 Coords(x, y, 0.0, 0.0)
41 }
42}
43impl NewXYZ for Coords {
44 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
45 Coords(x, y, z, 0.0)
46 }
47}
48impl SetXY for Coords {
49 fn set_x(&mut self, x: f64) {
50 self.0 = x;
51 }
52 fn set_y(&mut self, y: f64) {
53 self.1 = y;
54 }
55}
56impl SetZ for Coords {
57 fn set_z(&mut self, z: f64) {
58 self.2 = z;
59 }
60}
61
62#[repr(C)]
64#[derive(Debug, Default, Copy, Clone, PartialEq)]
65pub struct Complex {
66 pub r: f64,
68 pub i: f64,
70}
71
72#[derive(Debug, Default, Clone, Copy, PartialEq)]
74pub enum ProjMethod {
75 #[default]
77 Ellipsoidal = 0,
78 Spheroidal = 1,
80}
81
82#[derive(Debug, Default, Clone, Copy, PartialEq)]
84pub enum ProjMode {
85 #[default]
87 NPole = 0,
88 SPole = 1,
90 Equit = 2,
92 Obliq = 3,
94}
95
96#[derive(Debug, Clone, PartialEq)]
98#[allow(non_snake_case)]
99pub struct Proj {
100 pub name: String,
103 pub params: BTreeMap<i64, ProjValue>,
105
106 pub ellps: String,
111 pub a: f64,
113 pub b: f64,
115 pub ra: f64,
117 pub rb: f64,
119 pub sphere: bool,
121 pub alpha: f64,
124 pub e: f64,
126 pub es: f64,
128 pub e2: f64,
130 pub e2s: f64,
132 pub e3: f64,
134 pub e3s: f64,
136 pub one_es: f64,
138 pub rone_es: f64,
140 pub f: f64,
143 pub f2: f64,
145 pub n: f64,
147 pub rf: f64,
149 pub rf2: f64,
151 pub rn: f64,
153 pub J: f64,
155
156 pub es_orig: f64,
158 pub a_orig: f64,
160
161 pub over: bool,
164 pub geoc: bool,
166 pub is_ll: bool,
168 pub is_geocent: bool,
170 pub left: IoUnits,
172 pub right: IoUnits,
174
175 pub lam0: f64,
178 pub phi0: f64,
180 pub x0: f64,
182 pub y0: f64,
184 pub z0: f64,
186 pub t0: f64,
188
189 pub k0: f64,
192 pub to_meter: f64,
194 pub fr_meter: f64,
196 pub vto_meter: f64,
198 pub vfr_meter: f64,
200
201 pub datum_type: DatumType,
204 pub datum_params: DatumParams,
206
207 pub from_greenwich: f64,
209}
210impl Default for Proj {
211 fn default() -> Self {
212 Self {
213 name: "".into(),
214 params: BTreeMap::new(),
215 ellps: "".into(),
216 a: 0.,
217 b: 0.,
218 ra: 0.,
219 rb: 0.,
220 sphere: false,
221 alpha: 0.,
222 e: 0.,
223 es: 0.,
224 e2: 0.,
225 e2s: 0.,
226 e3: 0.,
227 e3s: 0.,
228 one_es: 0.,
229 rone_es: 0.,
230 f: 0.,
231 f2: 0.,
232 n: 0.,
233 rf: 0.,
234 rf2: 0.,
235 rn: 0.,
236 J: 0.,
237 es_orig: 0.,
238 a_orig: 0.,
239 over: false,
240 geoc: false,
241 is_ll: false,
242 is_geocent: false,
243 left: IoUnits::RADIANS,
244 right: IoUnits::CLASSIC,
245 lam0: 0.,
246 phi0: 0.,
247 x0: 0.,
248 y0: 0.,
249 z0: 0.,
250 t0: 0.,
251 k0: 1.,
252 to_meter: 1.,
253 fr_meter: 1.,
254 vto_meter: 1.,
255 vfr_meter: 1.,
256 datum_type: DatumType::NoDatum,
257 datum_params: DatumParams::default(),
258 from_greenwich: 0.,
259 }
260 }
261}
262impl Proj {
263 pub fn add_param(&mut self, param: &ParameterValue) {
265 if let Some(id) = ¶m.id {
267 self.insert_param(id.code.i64(), param.into());
268 } else if !param.ids.is_empty() {
269 for id in ¶m.ids {
270 self.insert_param(id.code.i64(), param.into());
271 }
272 } else {
273 self.insert_param(name_to_param_id(¶m.name), param.into());
275 }
276 }
277 pub fn set_f64(&mut self, id: i64, value: f64) {
279 self.insert_param(id, value.into());
280 }
281 fn insert_param(&mut self, id: i64, value: ProjValue) {
288 self.add_to_params(id, &value);
289 self.params.insert(id, value);
290 }
291 fn add_to_params(&mut self, id: i64, value: &ProjValue) {
293 match id {
294 LONGITUDE_OF_FALSE_ORIGIN
295 | LONGITUDE_OF_NATURAL_ORIGIN
296 | LONGITUDE_OF_PROJECTION_CENTRE => self.lam0 = value.f64(),
297 LATITUDE_OF_FALSE_ORIGIN
298 | LATITUDE_OF_NATURAL_ORIGIN
299 | LATITUDE_OF_PROJECTION_CENTRE => self.phi0 = value.f64(),
300 SCALE_FACTOR_AT_NATURAL_ORIGIN => self.k0 = value.f64(),
301 AZIMUTH_PROJECTION_CENTRE => self.alpha = value.f64(),
302 FALSE_EASTING => self.x0 = value.f64(),
303 FALSE_NORTHING => self.y0 = value.f64(),
304 _ => {}
305 }
306 }
307}
308
309#[derive(Debug, Default, Copy, Clone, PartialEq)]
311pub enum Direction {
312 FWD = 1,
314 #[default]
316 IDENT = 0,
317 INV = -1,
319}
320
321#[derive(Debug, Default, Clone, PartialEq)]
323pub enum IoUnits {
324 #[default]
326 WHATEVER = 0,
327 CLASSIC = 1,
329 PROJECTED = 2,
331 CARTESIAN = 3,
333 RADIANS = 4,
335 DEGREES = 5,
337}