1use crate::proj::{
3 AxisSwapConverter, CoordinateStep, Proj, ProjectionTransform, Step, derive_sphere,
4 name_to_unit, to_camel_case,
5};
6use alloc::{
7 boxed::Box,
8 format,
9 rc::Rc,
10 string::{String, ToString},
11 vec,
12 vec::Vec,
13};
14use core::cell::RefCell;
15use libm::fabs;
16use serde::{Deserialize, Serialize};
17
18pub trait ToProjJSON {
22 fn set_usage(&mut self, _usage: ObjectUsage) {}
24 fn set_anchor(&mut self, _anchor: String) {}
26 fn set_unit(&mut self, _unit: Unit) {}
28 fn set_id(&mut self, _id: Id) {}
30 fn set_axis(&mut self, _axis: Axis) {}
32 fn set_coordinate_system(&mut self, _cs: CoordinateSystem) {}
34 fn set_temporal_extent(&mut self, _extent: TemporalExtent) {}
36 fn set_vertical_extent(&mut self, _extent: VerticalExtent) {}
38 fn set_bbox(&mut self, _bbox: ProjBBox) {}
40 fn set_area(&mut self, _area: Option<String>) {}
42 fn set_method(&mut self, _method: Method) {}
44 fn set_ensemble(&mut self, _ensemble: DatumEnsemble) {}
46 fn set_member(&mut self, _member: DatumEnsembleMember) {}
48 fn set_ellipsoid(&mut self, _ellipsoid: Ellipsoid) {}
50 fn set_accuracy(&mut self, _accuracy: String) {}
52 fn set_epoch(&mut self, _epoch: f64) {}
54 fn set_frame_epoch(&mut self, _epoch: f64) {}
56 fn set_datum(&mut self, _datum: Datum) {}
58 fn set_parameter(&mut self, _parameter: ParameterValue) {}
60 fn set_meridian(&mut self, _meridian: Meridian) {}
62 fn set_prime_meridian(&mut self, _prime_meridian: PrimeMeridian) {}
64 fn set_conversion(&mut self, _conversion: Conversion) {}
66 fn set_geodetic_crs(&mut self, _geodetic_crs: GeodeticCRS) {}
68 fn set_projected_crs(&mut self, _projected_crs: ProjectedCRS) {}
70 fn set_projection(&mut self, _name: String) {}
72 fn set_order(&mut self, _order: usize) {}
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
82#[serde(untagged)]
83pub enum ProjJSON {
84 CRS(Box<CRS>),
86 Datum(Box<Datum>),
88 DatumEnsemble(Box<DatumEnsemble>),
90 Ellipsoid(Box<Ellipsoid>),
92 PrimeMeridian(Box<PrimeMeridian>),
94 SingleOperation(Box<SingleOperation>),
96 ConcatenatedOperation(Box<ConcatenatedOperation>),
98 CoordinateMetadata(Box<CoordinateMetadata>),
100}
101impl Default for ProjJSON {
102 fn default() -> Self {
103 ProjJSON::CRS(Box::default())
104 }
105}
106impl ToProjJSON for ProjJSON {
107 fn set_id(&mut self, id: Id) {
108 match self {
109 ProjJSON::CRS(crs) => crs.set_id(id),
110 ProjJSON::Datum(datum) => datum.set_id(id),
111 ProjJSON::DatumEnsemble(ensemble) => ensemble.set_id(id),
112 ProjJSON::PrimeMeridian(prime_meridian) => prime_meridian.set_id(id),
113 ProjJSON::Ellipsoid(ellipsoid) => ellipsoid.set_id(id),
114 ProjJSON::SingleOperation(operation) => operation.set_id(id),
115 ProjJSON::ConcatenatedOperation(operation) => operation.set_id(id),
116 ProjJSON::CoordinateMetadata(metadata) => metadata.set_id(id),
117 }
118 }
119 fn set_datum(&mut self, datum: Datum) {
120 *self = ProjJSON::Datum(Box::new(datum));
121 }
122 fn set_ensemble(&mut self, ensemble: DatumEnsemble) {
123 *self = ProjJSON::DatumEnsemble(Box::new(ensemble));
124 }
125 fn set_prime_meridian(&mut self, prime_meridian: PrimeMeridian) {
126 *self = ProjJSON::PrimeMeridian(Box::new(prime_meridian));
127 }
128 fn set_geodetic_crs(&mut self, geodetic_crs: GeodeticCRS) {
129 *self = ProjJSON::CRS(Box::new(CRS::GeodeticCRS(Box::new(geodetic_crs))));
130 }
131 fn set_projected_crs(&mut self, projected_crs: ProjectedCRS) {
132 *self = ProjJSON::CRS(Box::new(CRS::ProjectedCRS(Box::new(projected_crs))));
133 }
134}
135impl ProjJSON {
136 pub fn to_projection_transform(&self) -> ProjectionTransform {
138 let mut proj_transform = ProjectionTransform::default();
139 match self {
140 ProjJSON::CRS(crs) => crs.to_projection_transform(&mut proj_transform),
141 _ => panic!("Unsupported operation"),
142 }
143
144 proj_transform
145 }
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
150#[serde(untagged)]
151pub enum CRS {
152 BoundCRS(Box<BoundCRS>),
154 CompoundCRS(Box<CompoundCRS>),
156 DerivedEngineeringCRS(Box<DerivedEngineeringCRS>),
158 DerivedGeodeticCRS(Box<DerivedGeodeticCRS>),
160 DerivedParametricCRS(Box<DerivedParametricCRS>),
162 DerivedProjectedCRS(Box<DerivedProjectedCRS>),
164 DerivedTemporalCRS(Box<DerivedTemporalCRS>),
166 DerivedVerticalCRS(Box<DerivedVerticalCRS>),
168 EngineeringCRS(Box<EngineeringCRS>),
170 GeodeticCRS(Box<GeodeticCRS>),
172 ParametricCRS(Box<ParametricCRS>),
174 ProjectedCRS(Box<ProjectedCRS>),
177 TemporalCRS(Box<TemporalCRS>),
179 VerticalCRS(Box<VerticalCRS>),
181}
182impl Default for CRS {
183 fn default() -> Self {
184 CRS::GeodeticCRS(Box::default())
185 }
186}
187impl ToProjJSON for CRS {
188 fn set_id(&mut self, id: Id) {
189 match self {
190 CRS::BoundCRS(crs) => crs.set_id(id),
191 CRS::CompoundCRS(crs) => crs.set_id(id),
192 CRS::DerivedEngineeringCRS(crs) => crs.set_id(id),
193 CRS::DerivedGeodeticCRS(crs) => crs.set_id(id),
194 CRS::DerivedParametricCRS(crs) => crs.set_id(id),
195 CRS::DerivedProjectedCRS(crs) => crs.set_id(id),
196 CRS::DerivedTemporalCRS(crs) => crs.set_id(id),
197 CRS::DerivedVerticalCRS(crs) => crs.set_id(id),
198 CRS::EngineeringCRS(crs) => crs.set_id(id),
199 CRS::GeodeticCRS(crs) => crs.set_id(id),
200 CRS::ParametricCRS(crs) => crs.set_id(id),
201 CRS::ProjectedCRS(crs) => crs.set_id(id),
202 CRS::TemporalCRS(crs) => crs.set_id(id),
203 CRS::VerticalCRS(crs) => crs.set_id(id),
204 }
205 }
206 fn set_geodetic_crs(&mut self, geodetic_crs: GeodeticCRS) {
207 *self = CRS::GeodeticCRS(geodetic_crs.into());
208 }
209 fn set_projected_crs(&mut self, projected_crs: ProjectedCRS) {
210 *self = CRS::ProjectedCRS(projected_crs.into());
211 }
212}
213impl CRS {
214 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
216 match self {
217 CRS::GeodeticCRS(crs) => crs.to_projection_transform(proj_transform),
218 CRS::ProjectedCRS(crs) => crs.to_projection_transform(proj_transform),
219 _ => panic!("Unsupported operation"),
220 };
221 }
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
228#[serde(untagged)]
229pub enum Datum {
230 GeodeticReferenceFrame(GeodeticReferenceFrame),
232 VerticalReferenceFrame(VerticalReferenceFrame),
234 DynamicGeodeticReferenceFrame(DynamicGeodeticReferenceFrame),
236 DynamicVerticalReferenceFrame(DynamicVerticalReferenceFrame),
238 TemporalDatum(TemporalDatum),
240 ParametricDatum(ParametricDatum),
242 EngineeringDatum(EngineeringDatum),
244}
245impl Datum {
246 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
248 match self {
250 Datum::GeodeticReferenceFrame(d) => d.to_projection_transform(proj_transform),
251 _ => todo!(),
252 };
259 }
260}
261impl Default for Datum {
262 fn default() -> Self {
263 Datum::GeodeticReferenceFrame(GeodeticReferenceFrame::default())
264 }
265}
266impl ToProjJSON for Datum {
267 fn set_id(&mut self, id: Id) {
268 match self {
269 Datum::GeodeticReferenceFrame(d) => d.set_id(id),
270 Datum::VerticalReferenceFrame(d) => d.set_id(id),
271 Datum::DynamicGeodeticReferenceFrame(d) => d.set_id(id),
272 Datum::DynamicVerticalReferenceFrame(d) => d.set_id(id),
273 Datum::TemporalDatum(d) => d.set_id(id),
274 Datum::ParametricDatum(d) => d.set_id(id),
275 Datum::EngineeringDatum(d) => d.set_id(id),
276 }
277 }
278 fn set_prime_meridian(&mut self, pm: PrimeMeridian) {
279 match self {
280 Datum::GeodeticReferenceFrame(d) => {
281 d.set_prime_meridian(pm);
282 }
283 Datum::DynamicGeodeticReferenceFrame(d) => {
284 d.set_prime_meridian(pm);
285 }
286 _ => {}
287 }
288 }
289}
290
291#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
314#[serde(default)]
315pub struct ProjBBox {
316 pub south_latitude: f64,
318 pub west_longitude: f64,
320 pub north_latitude: f64,
322 pub east_longitude: f64,
324}
325
326#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
340#[serde(default)]
341pub struct VerticalExtent {
342 pub minimum: f64,
344 pub maximum: f64,
346 pub unit: Unit,
348}
349
350#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
365#[serde(default)]
366pub struct TemporalExtent {
367 pub start: String,
369 pub end: String,
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize)]
375#[serde(untagged)]
376pub enum ProjValue {
377 Bool(bool),
379 F64(f64),
381 I64(i64),
383 String(String),
385}
386impl Default for ProjValue {
387 fn default() -> Self {
388 ProjValue::String("".into())
389 }
390}
391impl PartialEq for ProjValue {
392 fn eq(&self, other: &Self) -> bool {
393 match (self, other) {
394 (ProjValue::Bool(a), ProjValue::Bool(b)) => a == b,
395 (ProjValue::F64(a), ProjValue::F64(b)) => fabs(*a - *b) < f64::EPSILON,
396 (ProjValue::I64(a), ProjValue::I64(b)) => a == b,
397 (ProjValue::String(a), ProjValue::String(b)) => a == b,
398 _ => false,
399 }
400 }
401}
402impl ProjValue {
403 pub fn bool(&self) -> bool {
405 match self {
406 ProjValue::Bool(b) => *b,
407 ProjValue::F64(f) => *f != 0.0,
408 ProjValue::I64(i) => *i != 0,
409 ProjValue::String(s) => s.to_lowercase() == "true" || self.i64() != 0,
410 }
411 }
412 pub fn f64(&self) -> f64 {
414 match self {
415 ProjValue::Bool(b) => {
416 if *b {
417 1.0
418 } else {
419 0.0
420 }
421 }
422 ProjValue::F64(f) => *f,
423 ProjValue::I64(i) => *i as f64,
424 ProjValue::String(s) => s.parse().unwrap_or(0.0),
425 }
426 }
427 pub fn i64(&self) -> i64 {
429 match self {
430 ProjValue::Bool(b) => {
431 if *b {
432 1
433 } else {
434 0
435 }
436 }
437 ProjValue::F64(f) => *f as i64,
438 ProjValue::I64(i) => *i,
439 ProjValue::String(s) => s.parse().unwrap_or(0),
440 }
441 }
442 pub fn string(&self) -> String {
444 match self {
445 ProjValue::Bool(b) => b.to_string(),
446 ProjValue::F64(f) => f.to_string(),
447 ProjValue::I64(i) => i.to_string(),
448 ProjValue::String(s) => s.clone(),
449 }
450 }
451}
452impl From<&str> for ProjValue {
453 fn from(v: &str) -> ProjValue {
454 ProjValue::String(v.into())
455 }
456}
457impl From<String> for ProjValue {
458 fn from(v: String) -> ProjValue {
459 ProjValue::String(v)
460 }
461}
462impl From<ProjValue> for String {
463 fn from(v: ProjValue) -> String {
464 match v {
465 ProjValue::String(s) => s,
466 _ => "".into(),
467 }
468 }
469}
470impl From<f64> for ProjValue {
471 fn from(v: f64) -> ProjValue {
472 ProjValue::F64(v)
473 }
474}
475
476#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
489#[serde(default)]
490pub struct Id {
491 pub authority: String,
493 pub code: ProjValue,
495 pub version: Option<ProjValue>,
498 #[serde(skip_serializing_if = "Option::is_none")]
500 pub authority_citation: Option<String>,
501 #[serde(skip_serializing_if = "Option::is_none")]
503 pub uri: Option<String>,
504}
505
506pub type Ids = Vec<Id>;
508
509#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
532#[serde(default)]
533pub struct ParameterValue {
534 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
536 pub schema: Option<String>,
537 #[serde(rename = "type")]
539 pub r#type: Option<String>, pub name: String,
542 pub value: ProjValue,
544 #[serde(skip_serializing_if = "Option::is_none")]
546 pub unit: Option<Unit>,
547 #[serde(skip_serializing_if = "Option::is_none")]
549 pub id: Option<Id>,
550 #[serde(skip_serializing_if = "Vec::is_empty")]
552 pub ids: Ids,
553 pub is_file: bool,
555}
556impl ParameterValue {
557 pub fn rad(&self) -> f64 {
559 let unit = self.unit.clone().unwrap_or_else(|| name_to_unit(&self.name));
561 self.value.f64() * unit.rad()
562 }
563}
564impl From<&ParameterValue> for ProjValue {
565 fn from(p_value: &ParameterValue) -> Self {
566 ProjValue::F64(p_value.rad())
567 }
568}
569impl ToProjJSON for ParameterValue {
570 fn set_id(&mut self, id: Id) {
571 if !self.ids.is_empty() {
573 self.ids.push(id);
574 } else if let Some(i) = self.id.clone() {
575 self.ids.extend(vec![i, id]);
576 self.id = None;
577 } else {
578 self.id = Some(id);
579 }
580 }
581 fn set_unit(&mut self, unit: Unit) {
582 self.unit = Some(unit);
583 }
584}
585
586#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
590#[serde(default)]
591pub struct ParametricCRS {
592 #[serde(rename = "type")]
594 pub r#type: Option<String>, pub name: String,
597 pub datum: ParametricDatum,
599 pub coordinate_system: Option<CoordinateSystem>,
601 #[serde(flatten, skip_serializing_if = "Option::is_none")]
603 pub usage: Option<ObjectUsage>,
604 #[serde(skip_serializing_if = "Vec::is_empty")]
606 pub usages: Vec<ObjectUsage>,
607}
608impl ToProjJSON for ParametricCRS {
609 fn set_id(&mut self, id: Id) {
610 if self.usage.is_none() && self.usages.is_empty() {
611 self.usage = Some(ObjectUsage::default());
612 }
613 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
614 u.set_id(id);
615 }
616 }
617 fn set_usage(&mut self, usage: ObjectUsage) {
618 if self.usages.is_empty() {
620 if let Some(u) = self.usage.clone() {
621 self.usages.extend(vec![u, usage]);
622 self.usage = None;
623 } else {
624 self.usage = Some(usage);
625 }
626 } else {
627 self.usages.push(usage);
628 }
629 }
630 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
631 self.coordinate_system = Some(cs);
632 }
633 fn set_axis(&mut self, axis: Axis) {
635 if let Some(ref mut cs) = self.coordinate_system {
636 cs.axis.push(axis);
637 }
638 }
639 fn set_unit(&mut self, unit: Unit) {
640 if let Some(ref mut cs) = self.coordinate_system {
641 for axis in cs.axis.iter_mut() {
642 axis.unit = Some(unit.clone());
643 }
644 }
645 }
646}
647
648#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
652#[serde(default)]
653pub struct ParametricDatum {
654 #[serde(rename = "type")]
656 pub r#type: Option<String>, pub name: String,
659 pub anchor: String,
661 #[serde(flatten, skip_serializing_if = "Option::is_none")]
663 pub usage: Option<ObjectUsage>,
664 #[serde(skip_serializing_if = "Vec::is_empty")]
666 pub usages: Vec<ObjectUsage>,
667}
668impl ToProjJSON for ParametricDatum {
669 fn set_id(&mut self, id: Id) {
670 if self.usage.is_none() && self.usages.is_empty() {
671 self.usage = Some(ObjectUsage::default());
672 }
673 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
674 u.set_id(id);
675 }
676 }
677 fn set_usage(&mut self, usage: ObjectUsage) {
678 if self.usages.is_empty() {
680 if let Some(u) = self.usage.clone() {
681 self.usages.extend(vec![u, usage]);
682 self.usage = None;
683 } else {
684 self.usage = Some(usage);
685 }
686 } else {
687 self.usages.push(usage);
688 }
689 }
690 fn set_anchor(&mut self, anchor: String) {
691 self.anchor = anchor;
692 }
693}
694
695#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
699#[serde(default)]
700pub struct PointMotionOperation {
701 #[serde(rename = "type")]
703 pub r#type: Option<String>, pub name: String,
706 pub source_crs: CRS,
708 pub method: Method,
710 #[serde(skip_serializing_if = "Vec::is_empty")]
712 pub parameters: Vec<ParameterValue>,
713 #[serde(skip_serializing_if = "Option::is_none")]
715 pub accuracy: Option<String>,
716 #[serde(flatten, skip_serializing_if = "Option::is_none")]
718 pub usage: Option<ObjectUsage>,
719 #[serde(skip_serializing_if = "Vec::is_empty")]
721 pub usages: Vec<ObjectUsage>,
722}
723impl ToProjJSON for PointMotionOperation {
724 fn set_id(&mut self, id: Id) {
725 if self.usage.is_none() && self.usages.is_empty() {
726 self.usage = Some(ObjectUsage::default());
727 }
728 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
729 u.set_id(id);
730 }
731 }
732 fn set_usage(&mut self, usage: ObjectUsage) {
733 if self.usages.is_empty() {
735 if let Some(u) = self.usage.clone() {
736 self.usages.extend(vec![u, usage]);
737 self.usage = None;
738 } else {
739 self.usage = Some(usage);
740 }
741 } else {
742 self.usages.push(usage);
743 }
744 }
745 fn set_accuracy(&mut self, accuracy: String) {
746 self.accuracy = Some(accuracy);
747 }
748 fn set_projection(&mut self, name: String) {
749 self.method = Method { name, ..Default::default() };
750 }
751 fn set_method(&mut self, method: Method) {
752 self.method = method;
753 }
754 fn set_parameter(&mut self, parameter: ParameterValue) {
755 self.parameters.push(parameter);
756 }
757}
758
759#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
763#[serde(default)]
764pub struct Method {
765 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
767 pub schema: Option<String>,
768 #[serde(rename = "type")]
770 pub r#type: Option<String>, pub name: String,
773 #[serde(skip_serializing_if = "Option::is_none")]
775 pub id: Option<Id>,
776 #[serde(skip_serializing_if = "Vec::is_empty")]
778 pub ids: Ids,
779}
780impl Method {
781 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
783 proj_transform.method = Step::from_method(self, proj_transform.proj.clone()).unwrap();
785 }
786}
787impl ToProjJSON for Method {
788 fn set_id(&mut self, id: Id) {
789 if !self.ids.is_empty() {
791 self.ids.push(id);
792 } else if let Some(i) = self.id.clone() {
793 self.ids.extend(vec![i, id]);
794 self.id = None;
795 } else {
796 self.id = Some(id);
797 }
798 }
799}
800
801#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
803pub enum BaseUnit {
804 #[serde(rename = "metre")]
806 #[default]
807 Metre,
808 #[serde(rename = "degree")]
810 Degree,
811 #[serde(rename = "unity")]
813 Unity,
814}
815
816#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
818#[serde(rename_all = "PascalCase")]
819pub enum UnitType {
820 LinearUnit,
822 AngularUnit,
824 ScaleUnit,
826 TimeUnit,
828 ParametricUnit,
830 #[default]
832 Unit,
833}
834impl From<&str> for UnitType {
835 fn from(s: &str) -> Self {
836 match s {
837 "LENGTHUNIT" => UnitType::LinearUnit,
838 "ANGLEUNIT" => UnitType::AngularUnit,
839 "SCALEUNIT" => UnitType::ScaleUnit,
840 "TIMEUNIT" => UnitType::TimeUnit,
841 "PARAMETRICUNIT" => UnitType::ParametricUnit,
842 _ => UnitType::Unit, }
844 }
845}
846
847#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
849#[serde(default)]
850pub struct UnitObject {
851 #[serde(rename = "type")]
853 pub r#type: UnitType,
854 pub name: String,
856 #[serde(skip_serializing_if = "Option::is_none")]
858 pub conversion_factor: Option<f64>,
859 #[serde(skip_serializing_if = "Option::is_none")]
861 pub id: Option<Id>,
862 #[serde(skip_serializing_if = "Vec::is_empty")]
864 pub ids: Ids,
865}
866impl UnitObject {
867 pub fn set_unit_type(&mut self, unit_type: UnitType) {
869 self.r#type = unit_type;
870 }
871 pub fn rad(&self) -> f64 {
873 match self.r#type {
874 UnitType::AngularUnit => self.conversion_factor.unwrap_or(1.0),
875 _ => 1.0,
876 }
877 }
878 pub fn meters(&self) -> f64 {
880 match self.r#type {
881 UnitType::LinearUnit => self.conversion_factor.unwrap_or(1.0),
882 _ => 1.0,
883 }
884 }
885}
886impl ToProjJSON for UnitObject {
887 fn set_id(&mut self, id: Id) {
888 if !self.ids.is_empty() {
890 self.ids.push(id);
891 } else if let Some(i) = self.id.clone() {
892 self.ids.extend(vec![i, id]);
893 self.id = None;
894 } else {
895 self.id = Some(id);
896 }
897 }
898}
899
900#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
927#[serde(untagged)]
928pub enum Unit {
929 BaseUnit(BaseUnit),
931 UnitObject(UnitObject),
933}
934impl Default for Unit {
935 fn default() -> Self {
936 Unit::BaseUnit(BaseUnit::default())
937 }
938}
939impl Unit {
940 pub fn new_deg() -> Self {
942 Unit::BaseUnit(BaseUnit::Degree)
943 }
944 pub fn set_unit_type(&mut self, unit_type: UnitType) {
946 match self {
947 Unit::BaseUnit(_) => {}
948 Unit::UnitObject(unit) => unit.set_unit_type(unit_type),
949 };
950 }
951 pub fn rad(&self) -> f64 {
953 match self {
954 Unit::BaseUnit(unit) => match unit {
955 BaseUnit::Metre => 1.0,
956 BaseUnit::Degree => core::f64::consts::PI / 180.0,
957 BaseUnit::Unity => 1.0,
958 },
959 Unit::UnitObject(unit) => unit.rad(),
960 }
961 }
962 pub fn meters(&self) -> f64 {
964 match self {
965 Unit::BaseUnit(unit) => match unit {
966 BaseUnit::Metre => 1.0,
967 BaseUnit::Degree => core::f64::consts::PI / 180.0,
968 BaseUnit::Unity => 1.0,
969 },
970 Unit::UnitObject(unit) => unit.meters(),
971 }
972 }
973}
974impl ToProjJSON for Unit {
975 fn set_unit(&mut self, unit: Unit) {
976 *self = unit
977 }
978}
979
980#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
984#[serde(default)]
985pub struct BoundCRS {
986 #[serde(rename = "type")]
988 pub r#type: Option<String>,
989 pub name: Option<String>,
991 pub source_crs: Box<CRS>,
993 pub target_crs: Box<CRS>,
995 pub transformation: AbridgedTransformation,
997 #[serde(flatten, skip_serializing_if = "Option::is_none")]
999 pub usage: Option<ObjectUsage>,
1000 #[serde(skip_serializing_if = "Vec::is_empty")]
1002 pub usages: Vec<ObjectUsage>,
1003}
1004impl ToProjJSON for BoundCRS {
1005 fn set_id(&mut self, id: Id) {
1006 if self.usage.is_none() && self.usages.is_empty() {
1007 self.usage = Some(ObjectUsage::default());
1008 }
1009 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1010 u.set_id(id);
1011 }
1012 }
1013 fn set_usage(&mut self, usage: ObjectUsage) {
1014 if self.usages.is_empty() {
1016 if let Some(u) = self.usage.clone() {
1017 self.usages.extend(vec![u, usage]);
1018 self.usage = None;
1019 } else {
1020 self.usage = Some(usage);
1021 }
1022 } else {
1023 self.usages.push(usage);
1024 }
1025 }
1026}
1027
1028#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1032#[serde(default)]
1033pub struct ConcatenatedOperation {
1034 #[serde(rename = "type")]
1036 pub r#type: Option<String>, pub name: String,
1039 pub source_crs: CRS,
1041 pub target_crs: CRS,
1043 #[serde(skip_serializing_if = "Vec::is_empty")]
1045 pub steps: Vec<SingleOperation>,
1046 #[serde(skip_serializing_if = "Option::is_none")]
1048 pub accuracy: Option<String>,
1049 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1051 pub usage: Option<ObjectUsage>,
1052 #[serde(skip_serializing_if = "Vec::is_empty")]
1054 pub usages: Vec<ObjectUsage>,
1055}
1056impl ToProjJSON for ConcatenatedOperation {
1057 fn set_id(&mut self, id: Id) {
1058 if self.usage.is_none() && self.usages.is_empty() {
1059 self.usage = Some(ObjectUsage::default());
1060 }
1061 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1062 u.set_id(id);
1063 }
1064 }
1065 fn set_usage(&mut self, usage: ObjectUsage) {
1066 if self.usages.is_empty() {
1068 if let Some(u) = self.usage.clone() {
1069 self.usages.extend(vec![u, usage]);
1070 self.usage = None;
1071 } else {
1072 self.usage = Some(usage);
1073 }
1074 } else {
1075 self.usages.push(usage);
1076 }
1077 }
1078 fn set_accuracy(&mut self, accuracy: String) {
1079 self.accuracy = Some(accuracy);
1080 }
1081}
1082
1083#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1087#[serde(default)]
1088pub struct AbridgedTransformation {
1089 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
1091 pub schema: Option<String>,
1092 #[serde(rename = "type")]
1094 pub r#type: Option<String>, pub name: String,
1097 #[serde(skip_serializing_if = "Option::is_none")]
1099 pub source_crs: Option<Box<CRS>>,
1100 pub method: Method,
1102 #[serde(skip_serializing_if = "Vec::is_empty")]
1104 pub parameters: Vec<ParameterValue>,
1105 #[serde(skip_serializing_if = "Option::is_none")]
1107 pub id: Option<Id>,
1108 #[serde(skip_serializing_if = "Vec::is_empty")]
1110 pub ids: Ids,
1111}
1112impl ToProjJSON for AbridgedTransformation {
1113 fn set_projection(&mut self, name: String) {
1114 self.method = Method { name, ..Default::default() };
1115 }
1116 fn set_method(&mut self, method: Method) {
1117 self.method = method;
1118 }
1119 fn set_parameter(&mut self, parameter: ParameterValue) {
1120 self.parameters.push(parameter);
1121 }
1122 fn set_id(&mut self, id: Id) {
1123 if !self.ids.is_empty() {
1125 self.ids.push(id);
1126 } else if let Some(i) = self.id.clone() {
1127 self.ids.extend(vec![i, id]);
1128 self.id = None;
1129 } else {
1130 self.id = Some(id);
1131 }
1132 }
1133}
1134
1135#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1139#[serde(default)]
1140pub struct CompoundCRS {
1141 #[serde(rename = "type")]
1143 pub r#type: Option<String>, pub name: String,
1146 #[serde(skip_serializing_if = "Vec::is_empty")]
1148 pub components: Vec<CRS>,
1149 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1151 pub usage: Option<ObjectUsage>,
1152 #[serde(skip_serializing_if = "Vec::is_empty")]
1154 pub usages: Vec<ObjectUsage>,
1155}
1156impl ToProjJSON for CompoundCRS {
1157 fn set_id(&mut self, id: Id) {
1158 if self.usage.is_none() && self.usages.is_empty() {
1159 self.usage = Some(ObjectUsage::default());
1160 }
1161 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1162 u.set_id(id);
1163 }
1164 }
1165 fn set_usage(&mut self, usage: ObjectUsage) {
1166 if self.usages.is_empty() {
1168 if let Some(u) = self.usage.clone() {
1169 self.usages.extend(vec![u, usage]);
1170 self.usage = None;
1171 } else {
1172 self.usage = Some(usage);
1173 }
1174 } else {
1175 self.usages.push(usage);
1176 }
1177 }
1178}
1179
1180#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1184#[serde(default)]
1185pub struct EngineeringCRS {
1186 #[serde(rename = "type")]
1188 pub r#type: Option<String>, pub name: String,
1191 pub datum: EngineeringDatum,
1193 pub coordinate_system: Option<CoordinateSystem>,
1195 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1197 pub usage: Option<ObjectUsage>,
1198 #[serde(skip_serializing_if = "Vec::is_empty")]
1200 pub usages: Vec<ObjectUsage>,
1201}
1202impl ToProjJSON for EngineeringCRS {
1203 fn set_id(&mut self, id: Id) {
1204 if self.usage.is_none() && self.usages.is_empty() {
1205 self.usage = Some(ObjectUsage::default());
1206 }
1207 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1208 u.set_id(id);
1209 }
1210 }
1211 fn set_usage(&mut self, usage: ObjectUsage) {
1212 if self.usages.is_empty() {
1214 if let Some(u) = self.usage.clone() {
1215 self.usages.extend(vec![u, usage]);
1216 self.usage = None;
1217 } else {
1218 self.usage = Some(usage);
1219 }
1220 } else {
1221 self.usages.push(usage);
1222 }
1223 }
1224 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
1225 self.coordinate_system = Some(cs);
1226 }
1227 fn set_axis(&mut self, axis: Axis) {
1229 if let Some(ref mut cs) = self.coordinate_system {
1230 cs.axis.push(axis);
1231 }
1232 }
1233 fn set_unit(&mut self, unit: Unit) {
1234 if let Some(ref mut cs) = self.coordinate_system {
1235 for axis in cs.axis.iter_mut() {
1236 axis.unit = Some(unit.clone());
1237 }
1238 }
1239 }
1240}
1241
1242#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1246#[serde(default)]
1247pub struct EngineeringDatum {
1248 #[serde(rename = "type")]
1250 pub r#type: Option<String>, pub name: String,
1253 #[serde(skip_serializing_if = "Option::is_none")]
1255 pub anchor: Option<String>,
1256 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1258 pub usage: Option<ObjectUsage>,
1259 #[serde(skip_serializing_if = "Vec::is_empty")]
1261 pub usages: Vec<ObjectUsage>,
1262}
1263impl ToProjJSON for EngineeringDatum {
1264 fn set_id(&mut self, id: Id) {
1265 if self.usage.is_none() && self.usages.is_empty() {
1266 self.usage = Some(ObjectUsage::default());
1267 }
1268 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1269 u.set_id(id);
1270 }
1271 }
1272 fn set_usage(&mut self, usage: ObjectUsage) {
1273 if self.usages.is_empty() {
1275 if let Some(u) = self.usage.clone() {
1276 self.usages.extend(vec![u, usage]);
1277 self.usage = None;
1278 } else {
1279 self.usage = Some(usage);
1280 }
1281 } else {
1282 self.usages.push(usage);
1283 }
1284 }
1285 fn set_anchor(&mut self, anchor: String) {
1286 self.anchor = Some(anchor);
1287 }
1288}
1289
1290#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq)]
1292#[serde(rename_all = "camelCase")]
1293pub enum AxisDirection {
1294 North,
1296 NorthNorthEast,
1298 NorthEast,
1300 EastNorthEast,
1302 East,
1304 EastSouthEast,
1306 SouthEast,
1308 SouthSouthEast,
1310 South,
1312 SouthSouthWest,
1314 SouthWest,
1316 WestSouthWest,
1318 West,
1320 WestNorthWest,
1322 NorthWest,
1324 NorthNorthWest,
1326 Up,
1328 Down,
1330 GeocentricX,
1332 GeocentricY,
1334 GeocentricZ,
1336 ColumnPositive,
1338 ColumnNegative,
1340 RowPositive,
1342 RowNegative,
1344 DisplayRight,
1346 DisplayLeft,
1348 DisplayUp,
1350 DisplayDown,
1352 Forward,
1354 Aft,
1356 Port,
1358 Starboard,
1360 Clockwise,
1362 CounterClockwise,
1364 Towards,
1366 AwayFrom,
1368 Future,
1370 Past,
1372 #[default]
1374 Unspecified,
1375}
1376impl From<String> for AxisDirection {
1377 fn from(s: String) -> Self {
1378 serde_json::from_str(&format!("\"{}\"", &s))
1379 .or_else(|_| serde_json::from_str(&format!("\"{}\"", to_camel_case(&s))))
1380 .unwrap_or_else(|_| {
1381 match s.to_lowercase().as_str() {
1383 "n" => AxisDirection::North,
1384 "ne" | "northeast" => AxisDirection::NorthEast,
1385 "e" => AxisDirection::East,
1386 "se" | "southeast" => AxisDirection::SouthEast,
1387 "s" => AxisDirection::South,
1388 "sw" | "southwest" => AxisDirection::SouthWest,
1389 "w" => AxisDirection::West,
1390 "nw" | "northwest" => AxisDirection::NorthWest,
1391 _ => AxisDirection::Unspecified,
1392 }
1393 })
1394 }
1395}
1396
1397#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1399#[serde(rename_all = "lowercase")]
1400pub enum AxisRangeMeaning {
1401 #[default]
1403 Exact,
1404 Wraparound,
1406}
1407
1408#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1412#[serde(default)]
1413pub struct Axis {
1414 #[serde(rename = "type")]
1416 pub r#type: Option<String>, pub name: String,
1419 pub abbreviation: String,
1421 pub direction: AxisDirection,
1424 pub order: usize,
1427 #[serde(skip_serializing_if = "Option::is_none")]
1429 pub meridian: Option<Meridian>,
1430 #[serde(skip_serializing_if = "Option::is_none")]
1432 pub unit: Option<Unit>,
1433 #[serde(skip_serializing_if = "Option::is_none")]
1435 pub minimum_value: Option<f64>,
1436 #[serde(skip_serializing_if = "Option::is_none")]
1438 pub maximum_value: Option<f64>,
1439 #[serde(skip_serializing_if = "Option::is_none")]
1442 pub range_meaning: Option<AxisRangeMeaning>,
1443 #[serde(skip_serializing_if = "Option::is_none")]
1445 pub id: Option<Id>,
1446 #[serde(skip_serializing_if = "Vec::is_empty")]
1448 pub ids: Ids,
1449}
1450impl Axis {
1451 pub fn adjust_if_needed(&mut self) {
1453 if self.order != 0 {
1454 return;
1455 }
1456 let name = self.name.to_lowercase();
1457 self.order = if name.contains("longitude")
1458 || name.contains("northing")
1459 || name.contains("(lon)")
1460 || name.contains("(Y)")
1461 || name.contains("(N)")
1462 {
1463 2
1464 } else if name.contains("z") {
1465 3
1466 } else {
1467 0
1468 };
1469 }
1470}
1471impl ToProjJSON for Axis {
1472 fn set_id(&mut self, id: Id) {
1473 if !self.ids.is_empty() {
1475 self.ids.push(id);
1476 } else if let Some(i) = self.id.clone() {
1477 self.ids.extend(vec![i, id]);
1478 self.id = None;
1479 } else {
1480 self.id = Some(id);
1481 }
1482 }
1483 fn set_unit(&mut self, unit: Unit) {
1484 self.unit = Some(unit);
1485 }
1486 fn set_meridian(&mut self, meridian: Meridian) {
1487 self.meridian = Some(meridian);
1488 }
1489 fn set_order(&mut self, order: usize) {
1490 self.order = order;
1491 }
1492}
1493
1494#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1498#[serde(default)]
1499pub struct Meridian {
1500 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
1502 pub schema: Option<String>,
1503 #[serde(rename = "type")]
1505 pub r#type: Option<String>, pub longitude: ValueInDegreeOrValueAndUnit,
1508 #[serde(skip_serializing_if = "Option::is_none")]
1510 pub id: Option<Id>,
1511 #[serde(skip_serializing_if = "Vec::is_empty")]
1513 pub ids: Ids,
1514}
1515impl ToProjJSON for Meridian {
1516 fn set_id(&mut self, id: Id) {
1517 if !self.ids.is_empty() {
1519 self.ids.push(id);
1520 } else if let Some(i) = self.id.clone() {
1521 self.ids.extend(vec![i, id]);
1522 self.id = None;
1523 } else {
1524 self.id = Some(id);
1525 }
1526 }
1527}
1528
1529#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1533#[serde(default)]
1534pub struct ValueAndUnit {
1535 pub value: f64,
1537 pub unit: Unit,
1539}
1540impl ValueAndUnit {
1541 pub fn rad(&self) -> f64 {
1543 self.value * self.unit.rad()
1544 }
1545}
1546
1547#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1549#[serde(untagged)]
1550pub enum ValueInDegreeOrValueAndUnit {
1551 F64(f64),
1553 ValueAndUnit(ValueAndUnit),
1555}
1556impl ValueInDegreeOrValueAndUnit {
1557 pub fn from_unit(unit: Unit, value: f64) -> Self {
1559 ValueInDegreeOrValueAndUnit::ValueAndUnit(ValueAndUnit { value, unit })
1560 }
1561 pub fn rad(&self) -> f64 {
1563 match self {
1564 ValueInDegreeOrValueAndUnit::F64(value) => (*value).to_radians(),
1565 ValueInDegreeOrValueAndUnit::ValueAndUnit(value) => value.rad(),
1566 }
1567 }
1568}
1569impl Default for ValueInDegreeOrValueAndUnit {
1570 fn default() -> Self {
1571 ValueInDegreeOrValueAndUnit::F64(0.0)
1572 }
1573}
1574impl ToProjJSON for ValueInDegreeOrValueAndUnit {
1575 fn set_unit(&mut self, unit: Unit) {
1576 match self {
1577 ValueInDegreeOrValueAndUnit::F64(val) => {
1578 *self =
1579 ValueInDegreeOrValueAndUnit::ValueAndUnit(ValueAndUnit { value: *val, unit });
1580 }
1581 ValueInDegreeOrValueAndUnit::ValueAndUnit(value) => value.unit = unit,
1582 }
1583 }
1584}
1585
1586#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1588#[serde(untagged)]
1589pub enum ValueInMetreOrValueAndUnit {
1590 F64(f64),
1592 ValueAndUnit(ValueAndUnit),
1594}
1595impl ValueInMetreOrValueAndUnit {
1596 pub fn from_unit(unit: Unit, value: f64) -> Self {
1598 ValueInMetreOrValueAndUnit::ValueAndUnit(ValueAndUnit { value, unit })
1599 }
1600 pub fn meters(&self) -> f64 {
1602 match self {
1603 ValueInMetreOrValueAndUnit::F64(value) => *value,
1604 ValueInMetreOrValueAndUnit::ValueAndUnit(value) => value.unit.meters() * value.value,
1605 }
1606 }
1607}
1608impl Default for ValueInMetreOrValueAndUnit {
1609 fn default() -> Self {
1610 ValueInMetreOrValueAndUnit::F64(0.0)
1611 }
1612}
1613impl From<f64> for ValueInMetreOrValueAndUnit {
1614 fn from(value: f64) -> Self {
1615 ValueInMetreOrValueAndUnit::F64(value)
1616 }
1617}
1618
1619#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1623#[serde(untagged)]
1624pub enum SingleOperation {
1625 Conversion(Box<Conversion>),
1627 Transformation(Box<Transformation>),
1629 PointMotionOperation(Box<PointMotionOperation>),
1631}
1632impl ToProjJSON for SingleOperation {
1633 fn set_id(&mut self, id: Id) {
1634 match self {
1635 SingleOperation::Conversion(c) => c.set_id(id),
1636 SingleOperation::Transformation(t) => t.set_id(id),
1637 SingleOperation::PointMotionOperation(p) => p.set_id(id),
1638 }
1639 }
1640 fn set_conversion(&mut self, conversion: Conversion) {
1641 *self = SingleOperation::Conversion(Box::new(conversion));
1642 }
1643}
1644
1645#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1649#[serde(default)]
1650pub struct DeformationModel {
1651 pub name: String,
1653 #[serde(skip_serializing_if = "Option::is_none")]
1655 pub id: Option<Id>,
1656}
1657
1658#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1662#[serde(default)]
1663pub struct DerivedEngineeringCRS {
1664 #[serde(rename = "type")]
1666 pub r#type: Option<String>, pub name: String,
1669 pub base_crs: EngineeringCRS,
1671 pub conversion: Conversion,
1673 pub coordinate_system: CoordinateSystem,
1675 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1677 pub usage: Option<ObjectUsage>,
1678 #[serde(skip_serializing_if = "Vec::is_empty")]
1680 pub usages: Vec<ObjectUsage>,
1681}
1682impl ToProjJSON for DerivedEngineeringCRS {
1683 fn set_id(&mut self, id: Id) {
1684 if self.usage.is_none() && self.usages.is_empty() {
1685 self.usage = Some(ObjectUsage::default());
1686 }
1687 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1688 u.set_id(id);
1689 }
1690 }
1691 fn set_usage(&mut self, usage: ObjectUsage) {
1692 if self.usages.is_empty() {
1694 if let Some(u) = self.usage.clone() {
1695 self.usages.extend(vec![u, usage]);
1696 self.usage = None;
1697 } else {
1698 self.usage = Some(usage);
1699 }
1700 } else {
1701 self.usages.push(usage);
1702 }
1703 }
1704 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
1705 self.coordinate_system = cs;
1706 }
1707 fn set_conversion(&mut self, conversion: Conversion) {
1708 self.conversion = conversion;
1709 }
1710 fn set_axis(&mut self, axis: Axis) {
1712 self.coordinate_system.axis.push(axis);
1713 }
1714 fn set_unit(&mut self, unit: Unit) {
1715 for axis in self.coordinate_system.axis.iter_mut() {
1716 axis.unit = Some(unit.clone());
1717 }
1718 }
1719}
1720
1721#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1725#[serde(default)]
1726pub struct DerivedGeodeticCRS {
1727 #[serde(rename = "type")]
1729 pub r#type: Option<String>, pub name: String,
1732 pub base_crs: GeodeticCRS,
1734 pub conversion: Conversion,
1736 pub coordinate_system: CoordinateSystem,
1738 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1740 pub usage: Option<ObjectUsage>,
1741 #[serde(skip_serializing_if = "Vec::is_empty")]
1743 pub usages: Vec<ObjectUsage>,
1744}
1745impl ToProjJSON for DerivedGeodeticCRS {
1746 fn set_id(&mut self, id: Id) {
1747 if self.usage.is_none() && self.usages.is_empty() {
1748 self.usage = Some(ObjectUsage::default());
1749 }
1750 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1751 u.set_id(id);
1752 }
1753 }
1754 fn set_usage(&mut self, usage: ObjectUsage) {
1755 if self.usages.is_empty() {
1757 if let Some(u) = self.usage.clone() {
1758 self.usages.extend(vec![u, usage]);
1759 self.usage = None;
1760 } else {
1761 self.usage = Some(usage);
1762 }
1763 } else {
1764 self.usages.push(usage);
1765 }
1766 }
1767 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
1768 self.coordinate_system = cs;
1769 }
1770 fn set_conversion(&mut self, conversion: Conversion) {
1771 self.conversion = conversion;
1772 }
1773 fn set_geodetic_crs(&mut self, geodetic_crs: GeodeticCRS) {
1774 self.base_crs = geodetic_crs;
1775 }
1776 fn set_axis(&mut self, axis: Axis) {
1778 self.coordinate_system.axis.push(axis);
1779 }
1780 fn set_unit(&mut self, unit: Unit) {
1781 for axis in self.coordinate_system.axis.iter_mut() {
1782 axis.unit = Some(unit.clone());
1783 }
1784 }
1785}
1786
1787#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1791#[serde(default)]
1792pub struct GeodeticCRS {
1793 #[serde(rename = "type")]
1795 pub r#type: Option<String>, pub name: String,
1798 #[serde(skip_serializing_if = "Option::is_none")]
1802 pub datum: Option<Datum>,
1803 #[serde(skip_serializing_if = "Option::is_none")]
1805 pub datum_ensemble: Option<DatumEnsemble>,
1806 #[serde(skip_serializing_if = "Option::is_none")]
1808 pub coordinate_system: Option<CoordinateSystem>,
1809 #[serde(skip_serializing_if = "Option::is_none")]
1812 pub deformation_models: Option<Vec<DeformationModel>>,
1813 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1815 pub usage: Option<ObjectUsage>,
1816 #[serde(skip_serializing_if = "Vec::is_empty")]
1818 pub usages: Vec<ObjectUsage>,
1819}
1820impl ToProjJSON for GeodeticCRS {
1821 fn set_id(&mut self, id: Id) {
1822 if self.usage.is_none() && self.usages.is_empty() {
1823 self.usage = Some(ObjectUsage::default());
1824 }
1825 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1826 u.set_id(id);
1827 }
1828 }
1829 fn set_usage(&mut self, usage: ObjectUsage) {
1830 if self.usages.is_empty() {
1832 if let Some(u) = self.usage.clone() {
1833 self.usages.extend(vec![u, usage]);
1834 self.usage = None;
1835 } else {
1836 self.usage = Some(usage);
1837 }
1838 } else {
1839 self.usages.push(usage);
1840 }
1841 }
1842 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
1843 self.coordinate_system = Some(cs);
1844 }
1845 fn set_datum(&mut self, datum: Datum) {
1846 self.datum = Some(datum);
1847 }
1848 fn set_ensemble(&mut self, ensemble: DatumEnsemble) {
1849 self.datum_ensemble = Some(ensemble);
1850 }
1851 fn set_prime_meridian(&mut self, prime_meridian: PrimeMeridian) {
1853 if let Some(ref mut datum) = self.datum {
1854 datum.set_prime_meridian(prime_meridian);
1855 }
1856 }
1857 fn set_axis(&mut self, axis: Axis) {
1859 if let Some(ref mut cs) = self.coordinate_system {
1860 cs.axis.push(axis);
1861 }
1862 }
1863 fn set_unit(&mut self, unit: Unit) {
1864 if let Some(ref mut cs) = self.coordinate_system {
1865 for axis in cs.axis.iter_mut() {
1866 axis.unit = Some(unit.clone());
1867 }
1868 }
1869 }
1870}
1871impl GeodeticCRS {
1872 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
1874 proj_transform.proj.borrow_mut().name = self.name.clone();
1875 if let Some(datum_ensemble) = &self.datum_ensemble {
1878 datum_ensemble.to_projection_transform(proj_transform);
1879 }
1880 if let Some(datum) = &self.datum {
1881 datum.to_projection_transform(proj_transform);
1882 }
1883 if let Some(coordinate_system) = &self.coordinate_system {
1884 coordinate_system.to_projection_transform(proj_transform);
1885 }
1886 }
1887}
1888
1889#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1893#[serde(default)]
1894pub struct GeodeticReferenceFrame {
1895 #[serde(rename = "type")]
1897 pub r#type: Option<String>, pub name: String,
1900 pub ellipsoid: Ellipsoid,
1902 #[serde(skip_serializing_if = "Option::is_none")]
1904 pub anchor: Option<String>,
1905 #[serde(skip_serializing_if = "Option::is_none")]
1907 pub anchor_epoch: Option<f64>,
1908 #[serde(skip_serializing_if = "Option::is_none")]
1910 pub prime_meridian: Option<PrimeMeridian>,
1911 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1913 pub usage: Option<ObjectUsage>,
1914 #[serde(skip_serializing_if = "Vec::is_empty")]
1916 pub usages: Vec<ObjectUsage>,
1917}
1918impl GeodeticReferenceFrame {
1919 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
1921 self.ellipsoid.to_projection_transform(proj_transform);
1922 if let Some(pm) = &self.prime_meridian {
1923 pm.to_projection_transform(proj_transform);
1924 }
1925 }
1926}
1927impl ToProjJSON for GeodeticReferenceFrame {
1928 fn set_id(&mut self, id: Id) {
1929 if self.usage.is_none() && self.usages.is_empty() {
1930 self.usage = Some(ObjectUsage::default());
1931 }
1932 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1933 u.set_id(id);
1934 }
1935 }
1936 fn set_usage(&mut self, usage: ObjectUsage) {
1937 if self.usages.is_empty() {
1939 if let Some(u) = self.usage.clone() {
1940 self.usages.extend(vec![u, usage]);
1941 self.usage = None;
1942 } else {
1943 self.usage = Some(usage);
1944 }
1945 } else {
1946 self.usages.push(usage);
1947 }
1948 }
1949 fn set_anchor(&mut self, anchor: String) {
1950 self.anchor = Some(anchor);
1951 }
1952 fn set_ellipsoid(&mut self, ellipsoid: Ellipsoid) {
1953 self.ellipsoid = ellipsoid;
1954 }
1955 fn set_epoch(&mut self, epoch: f64) {
1956 self.anchor_epoch = Some(epoch);
1957 }
1958 fn set_prime_meridian(&mut self, prime_meridian: PrimeMeridian) {
1959 self.prime_meridian = Some(prime_meridian);
1960 }
1961}
1962
1963#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
1967#[serde(default)]
1968pub struct DerivedParametricCRS {
1969 #[serde(rename = "type")]
1971 pub r#type: Option<String>, pub name: String,
1974 pub base_crs: ParametricCRS,
1976 pub conversion: Conversion,
1978 pub coordinate_system: CoordinateSystem,
1980 #[serde(flatten, skip_serializing_if = "Option::is_none")]
1982 pub usage: Option<ObjectUsage>,
1983 #[serde(skip_serializing_if = "Vec::is_empty")]
1985 pub usages: Vec<ObjectUsage>,
1986}
1987impl ToProjJSON for DerivedParametricCRS {
1988 fn set_id(&mut self, id: Id) {
1989 if self.usage.is_none() && self.usages.is_empty() {
1990 self.usage = Some(ObjectUsage::default());
1991 }
1992 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
1993 u.set_id(id);
1994 }
1995 }
1996 fn set_usage(&mut self, usage: ObjectUsage) {
1997 if self.usages.is_empty() {
1999 if let Some(u) = self.usage.clone() {
2000 self.usages.extend(vec![u, usage]);
2001 self.usage = None;
2002 } else {
2003 self.usage = Some(usage);
2004 }
2005 } else {
2006 self.usages.push(usage);
2007 }
2008 }
2009 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
2010 self.coordinate_system = cs;
2011 }
2012 fn set_conversion(&mut self, conversion: Conversion) {
2013 self.conversion = conversion;
2014 }
2015 fn set_axis(&mut self, axis: Axis) {
2017 self.coordinate_system.axis.push(axis);
2018 }
2019 fn set_unit(&mut self, unit: Unit) {
2020 for axis in self.coordinate_system.axis.iter_mut() {
2021 axis.unit = Some(unit.clone());
2022 }
2023 }
2024}
2025
2026#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2030#[serde(default)]
2031pub struct DerivedProjectedCRS {
2032 #[serde(rename = "type")]
2034 pub r#type: Option<String>, pub name: String,
2037 pub base_crs: ProjectedCRS,
2039 pub conversion: Conversion,
2041 pub coordinate_system: CoordinateSystem,
2043 #[serde(flatten, skip_serializing_if = "Option::is_none")]
2045 pub usage: Option<ObjectUsage>,
2046 #[serde(skip_serializing_if = "Vec::is_empty")]
2048 pub usages: Vec<ObjectUsage>,
2049}
2050impl ToProjJSON for DerivedProjectedCRS {
2051 fn set_id(&mut self, id: Id) {
2052 if self.usage.is_none() && self.usages.is_empty() {
2053 self.usage = Some(ObjectUsage::default());
2054 }
2055 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
2056 u.set_id(id);
2057 }
2058 }
2059 fn set_usage(&mut self, usage: ObjectUsage) {
2060 if self.usages.is_empty() {
2062 if let Some(u) = self.usage.clone() {
2063 self.usages.extend(vec![u, usage]);
2064 self.usage = None;
2065 } else {
2066 self.usage = Some(usage);
2067 }
2068 } else {
2069 self.usages.push(usage);
2070 }
2071 }
2072 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
2073 self.coordinate_system = cs;
2074 }
2075 fn set_conversion(&mut self, conversion: Conversion) {
2076 self.conversion = conversion;
2077 }
2078 fn set_projected_crs(&mut self, projected_crs: ProjectedCRS) {
2079 self.base_crs = projected_crs;
2080 }
2081 fn set_axis(&mut self, axis: Axis) {
2083 self.coordinate_system.axis.push(axis);
2084 }
2085 fn set_unit(&mut self, unit: Unit) {
2086 for axis in self.coordinate_system.axis.iter_mut() {
2087 axis.unit = Some(unit.clone());
2088 }
2089 }
2090}
2091
2092#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2096#[serde(default)]
2097pub struct DerivedTemporalCRS {
2098 #[serde(rename = "type")]
2100 pub r#type: Option<String>, pub name: String,
2103 pub base_crs: TemporalCRS,
2105 pub conversion: Conversion,
2107 pub coordinate_system: CoordinateSystem,
2109 #[serde(flatten, skip_serializing_if = "Option::is_none")]
2111 pub usage: Option<ObjectUsage>,
2112 #[serde(skip_serializing_if = "Vec::is_empty")]
2114 pub usages: Vec<ObjectUsage>,
2115}
2116impl ToProjJSON for DerivedTemporalCRS {
2117 fn set_id(&mut self, id: Id) {
2118 if self.usage.is_none() && self.usages.is_empty() {
2119 self.usage = Some(ObjectUsage::default());
2120 }
2121 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
2122 u.set_id(id);
2123 }
2124 }
2125 fn set_usage(&mut self, usage: ObjectUsage) {
2126 if self.usages.is_empty() {
2128 if let Some(u) = self.usage.clone() {
2129 self.usages.extend(vec![u, usage]);
2130 self.usage = None;
2131 } else {
2132 self.usage = Some(usage);
2133 }
2134 } else {
2135 self.usages.push(usage);
2136 }
2137 }
2138 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
2139 self.coordinate_system = cs;
2140 }
2141 fn set_conversion(&mut self, conversion: Conversion) {
2142 self.conversion = conversion;
2143 }
2144 fn set_axis(&mut self, axis: Axis) {
2146 self.coordinate_system.axis.push(axis);
2147 }
2148 fn set_unit(&mut self, unit: Unit) {
2149 for axis in self.coordinate_system.axis.iter_mut() {
2150 axis.unit = Some(unit.clone());
2151 }
2152 }
2153}
2154
2155#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2159#[serde(default)]
2160pub struct DerivedVerticalCRS {
2161 #[serde(rename = "type")]
2163 pub r#type: Option<String>, pub name: String,
2166 pub base_crs: VerticalCRS,
2168 pub conversion: Conversion,
2170 pub coordinate_system: CoordinateSystem,
2172 #[serde(flatten, skip_serializing_if = "Option::is_none")]
2174 pub usage: Option<ObjectUsage>,
2175 #[serde(skip_serializing_if = "Vec::is_empty")]
2177 pub usages: Vec<ObjectUsage>,
2178}
2179impl ToProjJSON for DerivedVerticalCRS {
2180 fn set_id(&mut self, id: Id) {
2181 if self.usage.is_none() && self.usages.is_empty() {
2182 self.usage = Some(ObjectUsage::default());
2183 }
2184 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
2185 u.set_id(id);
2186 }
2187 }
2188 fn set_usage(&mut self, usage: ObjectUsage) {
2189 if self.usages.is_empty() {
2191 if let Some(u) = self.usage.clone() {
2192 self.usages.extend(vec![u, usage]);
2193 self.usage = None;
2194 } else {
2195 self.usage = Some(usage);
2196 }
2197 } else {
2198 self.usages.push(usage);
2199 }
2200 }
2201 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
2202 self.coordinate_system = cs;
2203 }
2204 fn set_conversion(&mut self, conversion: Conversion) {
2205 self.conversion = conversion;
2206 }
2207 fn set_axis(&mut self, axis: Axis) {
2209 self.coordinate_system.axis.push(axis);
2210 }
2211 fn set_unit(&mut self, unit: Unit) {
2212 for axis in self.coordinate_system.axis.iter_mut() {
2213 axis.unit = Some(unit.clone());
2214 }
2215 }
2216}
2217
2218#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2222#[serde(default)]
2223pub struct DynamicGeodeticReferenceFrame {
2224 #[serde(rename = "type")]
2226 pub r#type: Option<String>, pub name: String,
2229 pub ellipsoid: Ellipsoid,
2231 pub frame_reference_epoch: f64,
2233 #[serde(skip_serializing_if = "Option::is_none")]
2235 pub anchor: Option<String>,
2236 pub anchor_epoch: Option<f64>,
2238 #[serde(skip_serializing_if = "Option::is_none")]
2240 pub prime_meridian: Option<PrimeMeridian>,
2241 #[serde(flatten, skip_serializing_if = "Option::is_none")]
2243 pub usage: Option<ObjectUsage>,
2244 #[serde(skip_serializing_if = "Vec::is_empty")]
2246 pub usages: Vec<ObjectUsage>,
2247}
2248impl ToProjJSON for DynamicGeodeticReferenceFrame {
2249 fn set_id(&mut self, id: Id) {
2250 if self.usage.is_none() && self.usages.is_empty() {
2251 self.usage = Some(ObjectUsage::default());
2252 }
2253 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
2254 u.set_id(id);
2255 }
2256 }
2257 fn set_usage(&mut self, usage: ObjectUsage) {
2258 if self.usages.is_empty() {
2260 if let Some(u) = self.usage.clone() {
2261 self.usages.extend(vec![u, usage]);
2262 self.usage = None;
2263 } else {
2264 self.usage = Some(usage);
2265 }
2266 } else {
2267 self.usages.push(usage);
2268 }
2269 }
2270 fn set_anchor(&mut self, anchor: String) {
2271 self.anchor = Some(anchor);
2272 }
2273 fn set_epoch(&mut self, epoch: f64) {
2274 self.anchor_epoch = Some(epoch);
2275 }
2276 fn set_frame_epoch(&mut self, epoch: f64) {
2277 self.frame_reference_epoch = epoch;
2278 }
2279 fn set_ellipsoid(&mut self, ellipsoid: Ellipsoid) {
2280 self.ellipsoid = ellipsoid;
2281 }
2282 fn set_prime_meridian(&mut self, prime_meridian: PrimeMeridian) {
2283 self.prime_meridian = Some(prime_meridian);
2284 }
2285}
2286
2287#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2289#[serde(default)]
2290pub struct DatumEnsembleMember {
2291 pub name: String,
2293 #[serde(skip_serializing_if = "Option::is_none")]
2295 pub id: Option<Id>,
2296 #[serde(skip_serializing_if = "Vec::is_empty")]
2298 pub ids: Ids,
2299}
2300impl ToProjJSON for DatumEnsembleMember {
2301 fn set_id(&mut self, id: Id) {
2302 if !self.ids.is_empty() {
2304 self.ids.push(id);
2305 } else if let Some(i) = self.id.clone() {
2306 self.ids.extend(vec![i, id]);
2307 self.id = None;
2308 } else {
2309 self.id = Some(id);
2310 }
2311 }
2312}
2313
2314#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2326#[serde(default)]
2327pub struct DatumEnsemble {
2328 #[serde(rename = "type")]
2330 pub r#type: Option<String>, pub name: String,
2333 #[serde(skip_serializing_if = "Vec::is_empty")]
2335 pub members: Vec<DatumEnsembleMember>,
2336 pub accuracy: String,
2338 #[serde(skip_serializing_if = "Option::is_none")]
2340 pub ellipsoid: Option<Ellipsoid>,
2341 #[serde(skip_serializing_if = "Option::is_none")]
2343 pub id: Option<Id>,
2344 #[serde(skip_serializing_if = "Vec::is_empty")]
2346 pub ids: Ids,
2347}
2348impl ToProjJSON for DatumEnsemble {
2349 fn set_accuracy(&mut self, accuracy: String) {
2350 self.accuracy = accuracy;
2351 }
2352 fn set_ellipsoid(&mut self, ellipsoid: Ellipsoid) {
2353 self.ellipsoid = Some(ellipsoid);
2354 }
2355 fn set_member(&mut self, member: DatumEnsembleMember) {
2356 self.members.push(member);
2357 }
2358 fn set_id(&mut self, id: Id) {
2359 if !self.ids.is_empty() {
2361 self.ids.push(id);
2362 } else if let Some(i) = self.id.clone() {
2363 self.ids.extend(vec![i, id]);
2364 self.id = None;
2365 } else {
2366 self.id = Some(id);
2367 }
2368 }
2369}
2370impl DatumEnsemble {
2371 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
2373 if let Some(ellipsoid) = &self.ellipsoid {
2374 ellipsoid.to_projection_transform(proj_transform);
2375 }
2376 }
2377}
2378
2379#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2417#[serde(default)]
2418pub struct Ellipsoid {
2419 #[serde(rename = "type")]
2421 pub r#type: Option<String>, pub name: String,
2424 pub semi_major_axis: Option<ValueInMetreOrValueAndUnit>,
2427 pub semi_minor_axis: Option<ValueInMetreOrValueAndUnit>,
2431 pub inverse_flattening: Option<ValueInMetreOrValueAndUnit>,
2434 pub radius: Option<ValueInMetreOrValueAndUnit>,
2437 #[serde(skip_serializing_if = "Option::is_none")]
2439 pub id: Option<Id>,
2440 #[serde(skip_serializing_if = "Vec::is_empty")]
2442 pub ids: Ids,
2443}
2444impl ToProjJSON for Ellipsoid {
2445 fn set_id(&mut self, id: Id) {
2446 if !self.ids.is_empty() {
2448 self.ids.push(id);
2449 } else if let Some(i) = self.id.clone() {
2450 self.ids.extend(vec![i, id]);
2451 self.id = None;
2452 } else {
2453 self.id = Some(id);
2454 }
2455 }
2456}
2457impl Ellipsoid {
2458 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
2460 let proj = &mut proj_transform.proj.borrow_mut();
2461 proj.ellps = self.name.clone();
2462 if let Some(semi_major_axis) = &self.semi_major_axis {
2463 proj.a = semi_major_axis.meters();
2464 }
2465 if let Some(semi_minor_axis) = &self.semi_minor_axis {
2466 proj.b = semi_minor_axis.meters();
2467 }
2468 if let Some(inverse_flattening) = &self.inverse_flattening {
2469 proj.rf = inverse_flattening.meters();
2470 }
2471 if let Some(radius) = &self.radius {
2472 proj.a = radius.meters();
2473 proj.b = radius.meters();
2474 proj.rf = 0.0;
2475 }
2476 derive_sphere(proj);
2477 }
2478}
2479
2480#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2490#[serde(default)]
2491pub struct PrimeMeridian {
2492 #[serde(rename = "type")]
2494 pub r#type: Option<String>, pub name: String,
2497 pub longitude: ValueInDegreeOrValueAndUnit,
2500 #[serde(skip_serializing_if = "Option::is_none")]
2502 pub id: Option<Id>,
2503 #[serde(skip_serializing_if = "Vec::is_empty")]
2505 pub ids: Ids,
2506}
2507impl PrimeMeridian {
2508 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
2510 proj_transform.proj.borrow_mut().from_greenwich = self.longitude.rad();
2511 }
2512}
2513impl ToProjJSON for PrimeMeridian {
2514 fn set_id(&mut self, id: Id) {
2515 if !self.ids.is_empty() {
2517 self.ids.push(id);
2518 } else if let Some(i) = self.id.clone() {
2519 self.ids.extend(vec![i, id]);
2520 self.id = None;
2521 } else {
2522 self.id = Some(id);
2523 }
2524 }
2525 fn set_unit(&mut self, unit: Unit) {
2526 self.longitude.set_unit(unit);
2527 }
2528}
2529
2530#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2535#[serde(default)]
2536pub struct ProjectedCRS {
2537 #[serde(rename = "type")]
2539 pub r#type: Option<String>, pub name: String,
2542 pub base_crs: GeodeticCRS,
2545 pub conversion: Conversion,
2547 pub coordinate_system: CoordinateSystem,
2549 #[serde(flatten, skip_serializing_if = "Option::is_none")]
2551 pub usage: Option<ObjectUsage>,
2552 #[serde(skip_serializing_if = "Vec::is_empty")]
2554 pub usages: Vec<ObjectUsage>,
2555}
2556impl ToProjJSON for ProjectedCRS {
2557 fn set_id(&mut self, id: Id) {
2558 if self.usage.is_none() && self.usages.is_empty() {
2559 self.usage = Some(ObjectUsage::default());
2560 }
2561 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
2562 u.set_id(id);
2563 }
2564 }
2565 fn set_usage(&mut self, usage: ObjectUsage) {
2566 if self.usages.is_empty() {
2568 if let Some(u) = self.usage.clone() {
2569 self.usages.extend(vec![u, usage]);
2570 self.usage = None;
2571 } else {
2572 self.usage = Some(usage);
2573 }
2574 } else {
2575 self.usages.push(usage);
2576 }
2577 }
2578 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
2579 self.coordinate_system = cs;
2580 }
2581 fn set_conversion(&mut self, conversion: Conversion) {
2582 self.conversion = conversion;
2583 }
2584 fn set_geodetic_crs(&mut self, geodetic_crs: GeodeticCRS) {
2585 self.base_crs = geodetic_crs;
2586 }
2587 fn set_axis(&mut self, axis: Axis) {
2589 self.coordinate_system.set_axis(axis);
2590 }
2591 fn set_unit(&mut self, unit: Unit) {
2592 self.coordinate_system.set_unit(unit);
2593 }
2594 fn set_projection(&mut self, name: String) {
2596 self.conversion.set_projection(name);
2597 }
2598 fn set_method(&mut self, method: Method) {
2599 self.conversion.set_method(method);
2600 }
2601 fn set_parameter(&mut self, parameter: ParameterValue) {
2602 self.conversion.set_parameter(parameter);
2603 }
2604}
2605impl ProjectedCRS {
2606 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
2608 self.coordinate_system.to_projection_transform(proj_transform);
2610 self.base_crs.to_projection_transform(proj_transform);
2612 self.conversion.to_projection_transform(proj_transform);
2614 }
2615}
2616
2617#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2621#[serde(default)]
2622pub struct Conversion {
2623 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
2625 pub schema: Option<String>,
2626 #[serde(rename = "type")]
2628 pub r#type: Option<String>, pub name: String,
2631 pub method: Method,
2633 #[serde(skip_serializing_if = "Vec::is_empty")]
2635 pub parameters: Vec<ParameterValue>,
2636 #[serde(skip_serializing_if = "Option::is_none")]
2638 pub id: Option<Id>,
2639 #[serde(skip_serializing_if = "Vec::is_empty")]
2641 pub ids: Ids,
2642}
2643impl ToProjJSON for Conversion {
2644 fn set_id(&mut self, id: Id) {
2645 if !self.ids.is_empty() {
2647 self.ids.push(id);
2648 } else if let Some(i) = self.id.clone() {
2649 self.ids.extend(vec![i, id]);
2650 self.id = None;
2651 } else {
2652 self.id = Some(id);
2653 }
2654 }
2655 fn set_projection(&mut self, name: String) {
2656 self.method = Method { name, ..Default::default() };
2657 }
2658 fn set_method(&mut self, method: Method) {
2659 self.method = method;
2660 }
2661 fn set_parameter(&mut self, parameter: ParameterValue) {
2662 self.parameters.push(parameter);
2663 }
2664}
2665impl Conversion {
2666 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
2668 for param in self.parameters.iter() {
2670 proj_transform.proj.borrow_mut().add_param(param);
2671 }
2672 self.method.to_projection_transform(proj_transform);
2673 }
2674}
2675
2676#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2680#[serde(default)]
2681pub struct CoordinateMetadata {
2682 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
2684 pub schema: Option<String>,
2685 #[serde(rename = "type")]
2687 pub r#type: Option<String>, pub crs: CRS,
2690 #[serde(rename = "coordinateEpoch", skip_serializing_if = "Option::is_none")]
2692 pub coordinate_epoch: Option<f64>,
2693}
2694impl ToProjJSON for CoordinateMetadata {
2695 fn set_epoch(&mut self, epoch: f64) {
2696 self.coordinate_epoch = Some(epoch);
2697 }
2698}
2699
2700#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2710pub enum CoordinateSystemSubtype {
2711 #[serde(rename = "Cartesian")]
2713 #[default]
2714 Cartesian,
2715 #[serde(rename = "spherical")]
2717 Spherical,
2718 #[serde(rename = "ellipsoidal")]
2720 Ellipsoidal,
2721 #[serde(rename = "vertical")]
2723 Vertical,
2724 #[serde(rename = "ordinal")]
2726 Ordinal,
2727 #[serde(rename = "parametric")]
2729 Parametric,
2730 #[serde(rename = "affine")]
2732 Affine,
2733 #[serde(rename = "TemporalDateTime")]
2735 TemporalDateTime,
2736 #[serde(rename = "TemporalCount")]
2738 TemporalCount,
2739 #[serde(rename = "TemporalMeasure")]
2741 TemporalMeasure,
2742}
2743impl CoordinateSystemSubtype {
2744 pub fn to_projection_transform(&self, _proj_transform: &mut ProjectionTransform) {
2746 match self {
2748 CoordinateSystemSubtype::Cartesian => {
2749 }
2752 _ => todo!(), }
2762 }
2763}
2764
2765#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2777#[serde(default)]
2778pub struct CoordinateSystem {
2779 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
2781 pub schema: Option<String>,
2782 #[serde(rename = "type")]
2784 pub r#type: Option<String>, pub name: Option<String>,
2787 pub subtype: CoordinateSystemSubtype,
2789 #[serde(skip_serializing_if = "Vec::is_empty")]
2791 pub axis: Vec<Axis>,
2792 #[serde(skip_serializing_if = "Option::is_none")]
2794 pub id: Option<Id>,
2795 #[serde(skip_serializing_if = "Vec::is_empty")]
2797 pub ids: Ids,
2798}
2799impl ToProjJSON for CoordinateSystem {
2800 fn set_id(&mut self, id: Id) {
2801 if !self.ids.is_empty() {
2803 self.ids.push(id);
2804 } else if let Some(i) = self.id.clone() {
2805 self.ids.extend(vec![i, id]);
2806 self.id = None;
2807 } else {
2808 self.id = Some(id);
2809 }
2810 }
2811 fn set_axis(&mut self, axis: Axis) {
2812 self.axis.push(axis);
2813 }
2814 fn set_unit(&mut self, unit: Unit) {
2815 for axis in self.axis.iter_mut() {
2816 axis.unit = Some(unit.clone());
2817 }
2818 }
2819}
2820impl CoordinateSystem {
2821 pub fn to_projection_transform(&self, proj_transform: &mut ProjectionTransform) {
2823 self.subtype.to_projection_transform(proj_transform);
2824 if !self.axis.is_empty() {
2825 let mut axiss = self.axis.clone();
2826 axiss.sort_by(|a, b| a.order.cmp(&b.order));
2827 let axis: Vec<AxisDirection> = axiss.iter().map(|a| a.direction).collect();
2828 let mut axis_converter = AxisSwapConverter::new(Rc::new(RefCell::new(Proj::default())));
2829 axis_converter.swap = axis.into();
2830 proj_transform.axisswap = Some(Box::new(axis_converter.into()));
2831 }
2832 }
2833}
2834
2835#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2839#[serde(default)]
2840pub struct Transformation {
2841 #[serde(rename = "type")]
2843 pub r#type: Option<String>, pub name: String,
2846 pub source_crs: CRS,
2848 pub target_crs: CRS,
2850 pub method: Method,
2852 #[serde(skip_serializing_if = "Vec::is_empty")]
2854 pub parameters: Vec<ParameterValue>,
2855 #[serde(skip_serializing_if = "Option::is_none")]
2857 pub interpolation_crs: Option<CRS>,
2858 #[serde(skip_serializing_if = "Option::is_none")]
2860 pub accuracy: Option<String>,
2861 #[serde(flatten, skip_serializing_if = "Option::is_none")]
2863 pub usage: Option<ObjectUsage>,
2864 #[serde(skip_serializing_if = "Vec::is_empty")]
2866 pub usages: Vec<ObjectUsage>,
2867}
2868impl ToProjJSON for Transformation {
2869 fn set_id(&mut self, id: Id) {
2870 if self.usage.is_none() && self.usages.is_empty() {
2871 self.usage = Some(ObjectUsage::default());
2872 }
2873 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
2874 u.set_id(id);
2875 }
2876 }
2877 fn set_usage(&mut self, usage: ObjectUsage) {
2878 if self.usages.is_empty() {
2880 if let Some(u) = self.usage.clone() {
2881 self.usages.extend(vec![u, usage]);
2882 self.usage = None;
2883 } else {
2884 self.usage = Some(usage);
2885 }
2886 } else {
2887 self.usages.push(usage);
2888 }
2889 }
2890 fn set_accuracy(&mut self, accuracy: String) {
2891 self.accuracy = Some(accuracy);
2892 }
2893 fn set_parameter(&mut self, parameter: ParameterValue) {
2894 self.parameters.push(parameter);
2895 }
2896 fn set_projection(&mut self, name: String) {
2897 self.method = Method { name, ..Default::default() };
2898 }
2899 fn set_method(&mut self, method: Method) {
2900 self.method = method;
2901 }
2902}
2903
2904#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2908#[serde(default)]
2909pub struct TemporalCRS {
2910 #[serde(rename = "type")]
2912 pub r#type: Option<String>, pub name: String,
2915 pub datum: TemporalDatum,
2917 #[serde(skip_serializing_if = "Option::is_none")]
2919 pub coordinate_system: Option<CoordinateSystem>,
2920 #[serde(flatten, skip_serializing_if = "Option::is_none")]
2922 pub usage: Option<ObjectUsage>,
2923 #[serde(skip_serializing_if = "Vec::is_empty")]
2925 pub usages: Vec<ObjectUsage>,
2926}
2927impl ToProjJSON for TemporalCRS {
2928 fn set_id(&mut self, id: Id) {
2929 if self.usage.is_none() && self.usages.is_empty() {
2930 self.usage = Some(ObjectUsage::default());
2931 }
2932 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
2933 u.set_id(id);
2934 }
2935 }
2936 fn set_usage(&mut self, usage: ObjectUsage) {
2937 if self.usages.is_empty() {
2939 if let Some(u) = self.usage.clone() {
2940 self.usages.extend(vec![u, usage]);
2941 self.usage = None;
2942 } else {
2943 self.usage = Some(usage);
2944 }
2945 } else {
2946 self.usages.push(usage);
2947 }
2948 }
2949 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
2950 self.coordinate_system = Some(cs);
2951 }
2952 fn set_axis(&mut self, axis: Axis) {
2954 if let Some(ref mut cs) = self.coordinate_system {
2955 cs.axis.push(axis);
2956 }
2957 }
2958 fn set_unit(&mut self, unit: Unit) {
2959 if let Some(ref mut cs) = self.coordinate_system {
2960 for axis in cs.axis.iter_mut() {
2961 axis.unit = Some(unit.clone());
2962 }
2963 }
2964 }
2965}
2966
2967#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
2971#[serde(default)]
2972pub struct TemporalDatum {
2973 #[serde(rename = "type")]
2975 pub r#type: Option<String>, pub name: String,
2978 pub calendar: String,
2980 pub time_origin: Option<String>,
2982 #[serde(flatten, skip_serializing_if = "Option::is_none")]
2984 pub usage: Option<ObjectUsage>,
2985 #[serde(skip_serializing_if = "Vec::is_empty")]
2987 pub usages: Vec<ObjectUsage>,
2988}
2989impl ToProjJSON for TemporalDatum {
2990 fn set_id(&mut self, id: Id) {
2991 if self.usage.is_none() && self.usages.is_empty() {
2992 self.usage = Some(ObjectUsage::default());
2993 }
2994 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
2995 u.set_id(id);
2996 }
2997 }
2998 fn set_usage(&mut self, usage: ObjectUsage) {
2999 if self.usages.is_empty() {
3001 if let Some(u) = self.usage.clone() {
3002 self.usages.extend(vec![u, usage]);
3003 self.usage = None;
3004 } else {
3005 self.usage = Some(usage);
3006 }
3007 } else {
3008 self.usages.push(usage);
3009 }
3010 }
3011}
3012
3013#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
3017#[serde(default)]
3018pub struct VerticalCRS {
3019 #[serde(rename = "type")]
3021 pub r#type: Option<String>, pub name: String,
3024 #[serde(skip_serializing_if = "Option::is_none")]
3028 pub datum: Option<Datum>,
3029 #[serde(skip_serializing_if = "Option::is_none")]
3031 pub datum_ensemble: Option<DatumEnsemble>,
3032 #[serde(skip_serializing_if = "Option::is_none")]
3034 pub coordinate_system: Option<CoordinateSystem>,
3035 #[serde(skip_serializing_if = "Option::is_none")]
3037 pub geoid_model: Option<GeoidModel>,
3038 #[serde(skip_serializing_if = "Option::is_none")]
3040 pub geoid_models: Option<Vec<GeoidModel>>,
3041 #[serde(skip_serializing_if = "Option::is_none")]
3043 pub deformation_models: Option<Vec<DeformationModel>>,
3044 #[serde(flatten, skip_serializing_if = "Option::is_none")]
3046 pub usage: Option<ObjectUsage>,
3047 #[serde(skip_serializing_if = "Vec::is_empty")]
3049 pub usages: Vec<ObjectUsage>,
3050}
3051impl ToProjJSON for VerticalCRS {
3052 fn set_id(&mut self, id: Id) {
3053 if self.usage.is_none() && self.usages.is_empty() {
3054 self.usage = Some(ObjectUsage::default());
3055 }
3056 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
3057 u.set_id(id);
3058 }
3059 }
3060 fn set_usage(&mut self, usage: ObjectUsage) {
3061 if self.usages.is_empty() {
3063 if let Some(u) = self.usage.clone() {
3064 self.usages.extend(vec![u, usage]);
3065 self.usage = None;
3066 } else {
3067 self.usage = Some(usage);
3068 }
3069 } else {
3070 self.usages.push(usage);
3071 }
3072 }
3073 fn set_coordinate_system(&mut self, cs: CoordinateSystem) {
3074 self.coordinate_system = Some(cs);
3075 }
3076 fn set_datum(&mut self, datum: Datum) {
3077 self.datum = Some(datum);
3078 }
3079 fn set_ensemble(&mut self, ensemble: DatumEnsemble) {
3080 self.datum_ensemble = Some(ensemble);
3081 }
3082 fn set_prime_meridian(&mut self, prime_meridian: PrimeMeridian) {
3084 if let Some(ref mut datum) = self.datum {
3085 datum.set_prime_meridian(prime_meridian);
3086 }
3087 }
3088 fn set_axis(&mut self, axis: Axis) {
3090 if let Some(ref mut cs) = self.coordinate_system {
3091 cs.axis.push(axis);
3092 }
3093 }
3094 fn set_unit(&mut self, unit: Unit) {
3095 if let Some(ref mut cs) = self.coordinate_system {
3096 for axis in cs.axis.iter_mut() {
3097 axis.unit = Some(unit.clone());
3098 }
3099 }
3100 }
3101}
3102
3103#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
3107#[serde(default)]
3108pub struct VerticalReferenceFrame {
3109 #[serde(rename = "type")]
3111 pub r#type: Option<String>, pub name: String,
3114 #[serde(skip_serializing_if = "Option::is_none")]
3116 pub anchor: Option<String>,
3117 #[serde(skip_serializing_if = "Option::is_none")]
3119 pub anchor_epoch: Option<f64>,
3120 #[serde(flatten, skip_serializing_if = "Option::is_none")]
3122 pub usage: Option<ObjectUsage>,
3123 #[serde(skip_serializing_if = "Vec::is_empty")]
3125 pub usages: Vec<ObjectUsage>,
3126}
3127impl ToProjJSON for VerticalReferenceFrame {
3128 fn set_anchor(&mut self, anchor: String) {
3129 self.anchor = Some(anchor);
3130 }
3131 fn set_id(&mut self, id: Id) {
3132 if self.usage.is_none() && self.usages.is_empty() {
3133 self.usage = Some(ObjectUsage::default());
3134 }
3135 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
3136 u.set_id(id);
3137 }
3138 }
3139 fn set_usage(&mut self, usage: ObjectUsage) {
3140 if self.usages.is_empty() {
3142 if let Some(u) = self.usage.clone() {
3143 self.usages.extend(vec![u, usage]);
3144 self.usage = None;
3145 } else {
3146 self.usage = Some(usage);
3147 }
3148 } else {
3149 self.usages.push(usage);
3150 }
3151 }
3152 fn set_epoch(&mut self, epoch: f64) {
3153 self.anchor_epoch = Some(epoch);
3154 }
3155}
3156
3157#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
3161#[serde(default)]
3162pub struct DynamicVerticalReferenceFrame {
3163 #[serde(rename = "type")]
3165 pub r#type: Option<String>, pub name: String,
3168 #[serde(skip_serializing_if = "Option::is_none")]
3170 pub anchor: Option<String>,
3171 #[serde(skip_serializing_if = "Option::is_none")]
3173 pub anchor_epoch: Option<f64>,
3174 pub frame_reference_epoch: f64,
3176 #[serde(flatten, skip_serializing_if = "Option::is_none")]
3178 pub usage: Option<ObjectUsage>,
3179 #[serde(skip_serializing_if = "Vec::is_empty")]
3181 pub usages: Vec<ObjectUsage>,
3182}
3183impl ToProjJSON for DynamicVerticalReferenceFrame {
3184 fn set_id(&mut self, id: Id) {
3185 if self.usage.is_none() && self.usages.is_empty() {
3186 self.usage = Some(ObjectUsage::default());
3187 }
3188 if let Some(u) = self.usage.as_mut().or_else(|| self.usages.last_mut()) {
3189 u.set_id(id);
3190 }
3191 }
3192 fn set_usage(&mut self, usage: ObjectUsage) {
3193 if self.usages.is_empty() {
3195 if let Some(u) = self.usage.clone() {
3196 self.usages.extend(vec![u, usage]);
3197 self.usage = None;
3198 } else {
3199 self.usage = Some(usage);
3200 }
3201 } else {
3202 self.usages.push(usage);
3203 }
3204 }
3205 fn set_anchor(&mut self, anchor: String) {
3206 self.anchor = Some(anchor);
3207 }
3208 fn set_epoch(&mut self, epoch: f64) {
3209 self.anchor_epoch = Some(epoch);
3210 }
3211 fn set_frame_epoch(&mut self, epoch: f64) {
3212 self.frame_reference_epoch = epoch;
3213 }
3214}
3215
3216#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
3220#[serde(default)]
3221pub struct GeoidModel {
3222 pub name: String,
3224 pub interpolation_crs: Option<Box<CRS>>,
3226 pub id: Option<Id>,
3228}
3229
3230#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
3244#[serde(default)]
3245pub struct ObjectUsage {
3246 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
3248 pub schema: Option<String>,
3249 #[serde(skip_serializing_if = "String::is_empty")]
3251 pub scope: String,
3252 #[serde(skip_serializing_if = "Option::is_none")]
3254 pub area: Option<String>,
3255 #[serde(skip_serializing_if = "Option::is_none")]
3257 pub bbox: Option<ProjBBox>,
3258 #[serde(skip_serializing_if = "Option::is_none")]
3260 pub vertical_extent: Option<VerticalExtent>,
3261 #[serde(skip_serializing_if = "Option::is_none")]
3263 pub temporal_extent: Option<TemporalExtent>,
3264 #[serde(skip_serializing_if = "Option::is_none")]
3266 pub remarks: Option<String>,
3267 #[serde(skip_serializing_if = "Option::is_none")]
3269 pub id: Option<Id>,
3270 #[serde(skip_serializing_if = "Vec::is_empty")]
3272 pub ids: Ids,
3273}
3274impl ToProjJSON for ObjectUsage {
3275 fn set_id(&mut self, id: Id) {
3276 if !self.ids.is_empty() {
3278 self.ids.push(id);
3279 } else if let Some(i) = self.id.clone() {
3280 self.ids.extend(vec![i, id]);
3281 self.id = None;
3282 } else {
3283 self.id = Some(id);
3284 }
3285 }
3286 fn set_temporal_extent(&mut self, extent: TemporalExtent) {
3287 self.temporal_extent = Some(extent);
3288 }
3289 fn set_vertical_extent(&mut self, extent: VerticalExtent) {
3290 self.vertical_extent = Some(extent);
3291 }
3292 fn set_bbox(&mut self, bbox: ProjBBox) {
3293 self.bbox = Some(bbox);
3294 }
3295 fn set_area(&mut self, area: Option<String>) {
3296 self.area = area;
3297 }
3298}