33
44use geo:: { Coord , Point } ;
55
6- use crate :: curves:: { Curve , SphericalLineStringCurve } ;
7- use crate :: lrm_scale:: Anchor ;
6+ use crate :: curves:: { Curve , PlanarLineStringCurve , SphericalLineStringCurve } ;
87use crate :: lrm_scale:: LrmScaleMeasure ;
9- use crate :: lrs:: { self , TraversalPosition } ;
10- use crate :: lrs:: { LrsBase , LrsError } ;
11-
12- type Lrs = lrs:: Lrs < SphericalLineStringCurve > ;
8+ use crate :: lrm_scale:: { Anchor , LrmScaleError } ;
9+ use crate :: lrs:: { Lrm , LrmHandle , LrmProjection , Lrs , LrsError } ;
10+ use crate :: lrs:: { LrsBase , TraversalPosition } ;
1311
1412/// Struct exposed to js.
15- pub struct ExtLrs {
16- /// The linear referencing system
17- pub lrs : Lrs ,
13+ pub enum ExtLrs {
14+ /// LRS with spherical coordinates.
15+ Spherical ( Lrs < SphericalLineStringCurve > ) ,
16+ /// LRS with planar coordinates.
17+ Planar ( Lrs < PlanarLineStringCurve > ) ,
1818}
1919
2020impl ExtLrs {
2121 /// Load the data.
22- pub fn load ( data : & [ u8 ] ) -> Result < ExtLrs , String > {
23- Lrs :: from_bytes ( data)
24- . map ( |lrs| Self { lrs } )
25- . map_err ( |err| err. to_string ( ) )
22+ pub fn load ( data : & [ u8 ] , planar : bool ) -> Result < ExtLrs , String > {
23+ if planar {
24+ Lrs :: < PlanarLineStringCurve > :: from_bytes ( data) . map ( |lrs| ExtLrs :: Planar ( lrs) )
25+ } else {
26+ Lrs :: < SphericalLineStringCurve > :: from_bytes ( data) . map ( |lrs| ExtLrs :: Spherical ( lrs) )
27+ }
28+ . map_err ( |err| err. to_string ( ) )
2629 }
2730
2831 /// How many LRMs compose the LRS.
2932 pub fn lrm_len ( & self ) -> usize {
30- self . lrs . lrm_len ( )
33+ match self {
34+ ExtLrs :: Spherical ( lrs) => lrs. lrm_len ( ) ,
35+ ExtLrs :: Planar ( lrs) => lrs. lrm_len ( ) ,
36+ }
37+ }
38+
39+ /// Given a ID returns the corresponding lrs index (or None if not found)
40+ pub fn find_lrm ( & self , lrm_id : & str ) -> Option < usize > {
41+ match self {
42+ ExtLrs :: Spherical ( lrs) => lrs. get_lrm ( lrm_id) . map ( |handle| handle. 0 ) ,
43+ ExtLrs :: Planar ( lrs) => lrs. get_lrm ( lrm_id) . map ( |handle| handle. 0 ) ,
44+ }
45+ }
46+
47+ fn get_lrm ( & self , index : usize ) -> & Lrm {
48+ match self {
49+ ExtLrs :: Spherical ( lrs) => & lrs. lrms [ index] ,
50+ ExtLrs :: Planar ( lrs) => & lrs. lrms [ index] ,
51+ }
3152 }
3253
3354 /// Return the geometry of the LRM.
3455 pub fn get_lrm_geom ( & self , index : usize ) -> Result < Vec < geo:: Coord > , String > {
35- let lrm = self . lrs . lrms . get ( index) . ok_or ( "Invalid index" ) ?;
36- self . lrs
37- . get_linestring ( lrm. reference_traversal )
38- . map_err ( |err| err. to_string ( ) )
39- . map ( |linestring| linestring. 0 )
56+ let lrm = self . get_lrm ( index) ;
57+ match self {
58+ ExtLrs :: Spherical ( lrs) => lrs. get_linestring ( lrm. reference_traversal ) ,
59+ ExtLrs :: Planar ( lrs) => lrs. get_linestring ( lrm. reference_traversal ) ,
60+ }
61+ . map_err ( |err| err. to_string ( ) )
62+ . map ( |linestring| linestring. 0 )
4063 }
4164
4265 /// `id` of the [`LrmScale`].
4366 pub fn get_lrm_scale_id ( & self , index : usize ) -> String {
44- self . lrs . lrms [ index] . scale . id . clone ( )
67+ self . get_lrm ( index) . scale . id . clone ( )
4568 }
4669
4770 /// All the [`Anchor`]s of a LRM.
4871 pub fn get_anchors ( & self , lrm_index : usize ) -> Vec < Anchor > {
49- self . lrs . lrms [ lrm_index] . scale . anchors . to_vec ( )
72+ self . get_lrm ( lrm_index) . scale . anchors . to_vec ( )
5073 }
5174
5275 /// Get the position given a [`LrmScaleMeasure`].
5376 pub fn resolve ( & self , lrm_index : usize , measure : & LrmScaleMeasure ) -> Result < Point , LrsError > {
54- let lrm = & self . lrs . lrms [ lrm_index] ;
77+ let lrm = self . get_lrm ( lrm_index) ;
5578 let curve_position = lrm. scale . locate_point ( measure) ?. clamp ( 0. , 1.0 ) ;
5679
5780 let traversal_position = TraversalPosition {
5881 curve_position,
5982 traversal : lrm. reference_traversal ,
6083 } ;
61- self . lrs . locate_traversal ( traversal_position)
84+ match self {
85+ ExtLrs :: Spherical ( lrs) => lrs. locate_traversal ( traversal_position) ,
86+ ExtLrs :: Planar ( lrs) => lrs. locate_traversal ( traversal_position) ,
87+ }
6288 }
6389
6490 /// Given two [`LrmScaleMeasure`]s, return a range of [`LineString`].
@@ -68,9 +94,8 @@ impl ExtLrs {
6894 from : & LrmScaleMeasure ,
6995 to : & LrmScaleMeasure ,
7096 ) -> Result < Vec < Coord > , String > {
71- let lrm = & self . lrs . lrms [ lrm_index] ;
97+ let lrm = self . get_lrm ( lrm_index) ;
7298 let scale = & lrm. scale ;
73- let curve = & self . lrs . traversals [ lrm. reference_traversal . 0 ] . curve ;
7499 let from = scale
75100 . locate_point ( from)
76101 . map_err ( |e| e. to_string ( ) ) ?
@@ -80,9 +105,37 @@ impl ExtLrs {
80105 . map_err ( |e| e. to_string ( ) ) ?
81106 . clamp ( 0. , 1. ) ;
82107
83- match curve. sublinestring ( from, to) {
108+ let sublinestring = match self {
109+ ExtLrs :: Spherical ( lrs) => lrs. traversals [ lrm. reference_traversal . 0 ]
110+ . curve
111+ . sublinestring ( from, to) ,
112+ ExtLrs :: Planar ( lrs) => lrs. traversals [ lrm. reference_traversal . 0 ]
113+ . curve
114+ . sublinestring ( from, to) ,
115+ } ;
116+
117+ match sublinestring {
84118 Some ( linestring) => Ok ( linestring. 0 ) ,
85119 None => Err ( "Could not find sublinestring" . to_string ( ) ) ,
86120 }
87121 }
122+
123+ /// Given a point, return the [`LrmProjection`]s.
124+ pub fn lookup ( & self , point : Point , lrm_handle : LrmHandle ) -> Vec < LrmProjection > {
125+ match self {
126+ ExtLrs :: Spherical ( lrs) => lrs. lookup ( point. into ( ) , lrm_handle) ,
127+ ExtLrs :: Planar ( lrs) => lrs. lookup ( point. into ( ) , lrm_handle) ,
128+ }
129+ }
130+
131+ /// Get the positon along the curve given a [`LrmScaleMeasure`]
132+ /// The value will be between 0.0 and 1.0, both included
133+ pub fn locate_point (
134+ & self ,
135+ lrm_index : usize ,
136+ measure : & LrmScaleMeasure ,
137+ ) -> Result < f64 , LrmScaleError > {
138+ let lrm = self . get_lrm ( lrm_index) ;
139+ lrm. scale . locate_point ( measure)
140+ }
88141}
0 commit comments