-
Notifications
You must be signed in to change notification settings - Fork 6
/
mod.rs
106 lines (93 loc) · 3.59 KB
/
mod.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 crate::prelude::*;
pub mod coor2d;
pub mod coor32;
pub mod coor3d;
pub mod coor4d;
pub mod set;
/// Methods for changing the coordinate representation of angles.
/// Dimensionality untold, the methods operate on the first two
/// dimensions only.
pub trait AngularUnits {
/// Transform the first two elements of a coordinate tuple from degrees to radians
fn to_radians(self) -> Self;
/// Transform the first two elements of a coordinate tuple from radians to degrees
fn to_degrees(self) -> Self;
/// Transform the first two elements of a coordinate tuple from radians to seconds
/// of arc.
fn to_arcsec(self) -> Self;
/// Transform the internal lon/lat(/h/t)-in-radians to lat/lon(/h/t)-in-degrees
fn to_geo(self) -> Self;
}
/// For Rust Geodesy, the ISO-19111 concept of `DirectPosition` is represented
/// as a `geodesy::Coo4D`.
///
/// The strict connection between the ISO19107 "DirectPosition" datatype
/// and the ISO19111/OGC Topic 2 "CoordinateSet" interface (i.e. trait)
/// is unclear to me: The DirectPosition, according to 19107, includes
/// metadata which in the 19111 CoordinateSet interface is lifted from the
/// DirectPosition to the CoordinateSet level. Nevertheless, the interface
/// consists of an array of DirectPositions, and further derives from the
/// CoordinateMetadata interface...
#[allow(dead_code)]
type DirectPosition = Coor4D;
// ----- Coordinate Metadata --------------------------------------------------
/// OGC 18-005r5, section 7.4 https://docs.ogc.org/as/18-005r5/18-005r5.html#12
#[derive(Debug, Default, PartialEq, PartialOrd, Copy, Clone)]
pub struct DataEpoch(f64);
/// The metadataidentifier (CRS id) is represented by an UUID placeholder
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
pub struct MdIdentifier(uuid::Uuid);
/// CRS given as a register item
#[derive(Debug, Default, PartialEq, PartialOrd, Clone)]
pub enum Crs {
#[default]
Unknown,
RegisterItem(String, String),
}
// ----- Interface: Coordinate Metadata ---------------------------------------
/// The ISO-19111 Coordinate Metadata gamut includes an optional
/// epoch and one of two possible ways of representing the CRS
pub trait CoordinateMetadata {
fn crs_id(&self) -> Option<MdIdentifier> {
None
}
fn crs(&self) -> Option<Crs> {
Some(Crs::Unknown)
}
fn coordinate_epoch(&self) -> Option<DataEpoch> {
None
}
// constraints
fn is_valid(&self) -> bool {
if self.crs_id().is_none() && self.crs().is_none() {
return false;
}
true
// TODO: check for coordinate_epoch.is_some() for dynamic crs
}
}
// Preliminary empty blanket implementation: Defaults for all items, for all types
impl<T> CoordinateMetadata for T where T: ?Sized {}
/// CoordinateSet is the fundamental coordinate access interface in ISO-19111.
///
/// Here it is implemented simply as an accessor trait, that allows us to
/// access any user provided data model by iterating over its elements,
/// represented as a `Coor4D`
pub trait CoordinateSet: CoordinateMetadata {
/// Number of coordinate tuples in the set
fn len(&self) -> usize;
/// Access the `index`th coordinate tuple
fn get_coord(&self, index: usize) -> Coor4D;
/// Overwrite the `index`th coordinate tuple
fn set_coord(&mut self, index: usize, value: &Coor4D);
fn is_empty(&self) -> bool {
self.len() == 0
}
/// Set all coordinate tuples in the set to NaN
fn stomp(&mut self) {
let nanny = Coor4D::nan();
for i in 0..self.len() {
self.set_coord(i, &nanny);
}
}
}