Skip to content

Commit 630b766

Browse files
committed
1-to-1 lrm and traversal: an lrm can now have only one traversal
We had the notion of reference_traversal, and the flatbuffers already only hold one traversal per Lrm Signed-off-by: Tristram Gräbener <tristram+git@tristramg.eu>
1 parent 2711e42 commit 630b766

2 files changed

Lines changed: 51 additions & 84 deletions

File tree

src/lrs.rs

Lines changed: 48 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,8 @@ pub struct NodeHandle(pub usize);
3535
pub struct Lrm {
3636
/// The scale of this [`Lrm`].
3737
pub scale: LrmScale,
38-
/// The [`Traversal`] that is the reference of this [`Lrm`].
39-
pub reference_traversal: TraversalHandle,
40-
/// All the [`Traversal`]s where this [`Lrm`] applies.
41-
pub traversals: Vec<TraversalHandle>,
38+
/// The [`Traversal`] that where this [`Lrm`] applies.
39+
pub traversal: TraversalHandle,
4240
/// Metadata to describe the Lrm
4341
pub properties: Properties,
4442
}
@@ -240,12 +238,12 @@ impl<CurveImpl: Curve> Lrs<CurveImpl> {
240238
.iter()
241239
.enumerate()
242240
{
243-
let reference_traversal_idx = raw_lrm.traversal_index() as usize;
241+
let traversal_idx = raw_lrm.traversal_index() as usize;
244242
let curve = &result
245243
.traversals
246-
.get(reference_traversal_idx)
244+
.get(traversal_idx)
247245
.ok_or(LrsError::IncompleteArchive(format!(
248-
"traversal {reference_traversal_idx} from lrm {lrm_idx}"
246+
"traversal {traversal_idx} from lrm {lrm_idx}"
249247
)))?
250248
.curve;
251249

@@ -294,11 +292,14 @@ impl<CurveImpl: Curve> Lrs<CurveImpl> {
294292
id: raw_lrm.id().to_owned(),
295293
anchors,
296294
},
297-
reference_traversal: TraversalHandle(reference_traversal_idx),
298-
traversals: vec![TraversalHandle(reference_traversal_idx)],
295+
traversal: TraversalHandle(traversal_idx),
299296
properties: from_fb(raw_lrm.properties()),
300297
};
301298

299+
result.traversals[traversal_idx]
300+
.lrms
301+
.push(LrmHandle(lrm_idx));
302+
302303
result.lrms.push(lrm);
303304
}
304305

@@ -376,25 +377,18 @@ pub trait LrsBase {
376377
/// it will be segmentized as a [`LineString`] and might not be as acurate as the underlying representation
377378
fn get_linestring(&self, traversal: TraversalHandle) -> Result<LineString, LrsError>;
378379

379-
/// Projects a [`Point`] on all applicable [`Traversal`]s to a given [`Lrm`].
380+
/// Projects a [`Point`] on the [`Traversal`]s to a given [`Lrm`].
380381
/// The [`Point`] must be in the bounding box of the [`Curve`] of the [`Traversal`].
381-
/// The result is sorted by `orthogonal_offset`: the nearest [`Lrm`] to the [`Point`] is the first item.
382-
fn lookup(&self, point: Point, lrm: LrmHandle) -> Vec<LrmProjection>;
382+
fn lookup(&self, point: Point, lrm: LrmHandle) -> Result<LrmProjection, LrsError>;
383383
/// Projects a [`Point`] on all [`Lrm`] where the [`Point`] is in the bounding box.
384384
/// The result is sorted by `orthogonal_offset`: the nearest [`Lrm`] to the [`Point`] is the first item.
385385
fn lookup_lrms(&self, point: Point) -> Vec<LrmProjection>;
386386

387387
/// Given a [`TraversalPosition`], returns it geographical position ([`Point`]).
388388
fn locate_traversal(&self, position: TraversalPosition) -> Result<Point, LrsError>;
389389

390-
/// And [`Lrm`] can be used on many [`Traversal`]s.
391-
/// For example, for both directions of a highway.
392-
/// This method returns all applicable [`TraversalHandle`]s to that [`Traversal`].
393-
fn get_lrm_applicable_traversals(&self, lrm: LrmHandle) -> &[TraversalHandle];
394-
/// An [`Lrm`] has a reference [`Traversal`]
395-
/// For example, for the centerline of a highway, or a specific track.
396-
/// This methods returns the [`TraversalHandle`].
397-
fn get_lrm_reference_traversal(&self, lrm: LrmHandle) -> TraversalHandle;
390+
/// This methods returns the [`TraversalHandle`] of the [`Lrm`].
391+
fn get_lrm_traversal(&self, lrm: LrmHandle) -> TraversalHandle;
398392

399393
/// A [`Traversal`] can be use for multiple [`Lrm`]s.
400394
/// For example, a highway could have milestones referenced in `miles` AND `kilometers`.
@@ -457,29 +451,18 @@ impl<CurveImpl: Curve> LrsBase for Lrs<CurveImpl> {
457451
.map(TraversalHandle)
458452
}
459453

460-
fn lookup(&self, point: Point, lrm_handle: LrmHandle) -> Vec<LrmProjection> {
454+
fn lookup(&self, point: Point, lrm_handle: LrmHandle) -> Result<LrmProjection, LrsError> {
461455
let lrm = &self.lrms[lrm_handle.0];
462-
let mut result: Vec<_> = self
463-
.get_lrm_applicable_traversals(lrm_handle)
464-
.iter()
465-
.flat_map(|t| self.traversals[t.0].curve.project(point))
466-
.flat_map(|projection| {
467-
let measure = lrm.scale.locate_anchor(projection.distance_along_curve)?;
468-
Ok::<LrmProjection, LrsError>(LrmProjection {
469-
measure: LrmMeasure {
470-
lrm: lrm_handle,
471-
measure,
472-
},
473-
orthogonal_offset: projection.offset,
474-
})
475-
})
476-
.collect();
477-
result.sort_by(|a, b| {
478-
a.orthogonal_offset
479-
.partial_cmp(&b.orthogonal_offset)
480-
.unwrap_or(Ordering::Equal)
481-
});
482-
result
456+
let traversal = &self.traversals[lrm.traversal.0];
457+
let projection = traversal.curve.project(point)?;
458+
let measure = lrm.scale.locate_anchor(projection.distance_along_curve)?;
459+
Ok(LrmProjection {
460+
measure: LrmMeasure {
461+
lrm: lrm_handle,
462+
measure,
463+
},
464+
orthogonal_offset: projection.offset,
465+
})
483466
}
484467

485468
fn lookup_lrms(&self, point: Point) -> Vec<LrmProjection> {
@@ -503,12 +486,8 @@ impl<CurveImpl: Curve> LrsBase for Lrs<CurveImpl> {
503486
.resolve(position.curve_position)?)
504487
}
505488

506-
fn get_lrm_applicable_traversals(&self, lrm: LrmHandle) -> &[TraversalHandle] {
507-
&self.lrms[lrm.0].traversals
508-
}
509-
510-
fn get_lrm_reference_traversal(&self, lrm: LrmHandle) -> TraversalHandle {
511-
self.lrms[lrm.0].reference_traversal
489+
fn get_lrm_traversal(&self, lrm: LrmHandle) -> TraversalHandle {
490+
self.lrms[lrm.0].traversal
512491
}
513492

514493
fn get_traversal_lrms(&self, traversal: TraversalHandle) -> &[LrmHandle] {
@@ -702,16 +681,14 @@ mod tests {
702681
};
703682

704683
let lrm = Lrm {
705-
reference_traversal: TraversalHandle(0),
706684
scale: crate::lrm_scale::tests::scale(),
707-
traversals: vec![TraversalHandle(0)],
685+
traversal: TraversalHandle(0),
708686
properties: properties!("some key" => "some value"),
709687
};
710688

711689
let mut lrm2 = Lrm {
712-
reference_traversal: TraversalHandle(0),
690+
traversal: TraversalHandle(1),
713691
scale: crate::lrm_scale::tests::scale(),
714-
traversals: vec![TraversalHandle(0), TraversalHandle(1)],
715692
properties: properties!(),
716693
};
717694
"id2".clone_into(&mut lrm2.scale.id);
@@ -745,34 +722,34 @@ mod tests {
745722
#[test]
746723
fn lookup_single_lrm() {
747724
let lrs = lrs();
748-
let result = lrs.lookup(point! {x: 50., y:0.5}, lrs.get_lrm("id").unwrap());
749-
assert_eq!(result.len(), 1);
750-
assert_eq!(result[0].orthogonal_offset, 0.5);
751-
assert_eq!(result[0].measure.measure.scale_offset, 5.);
725+
let result = lrs
726+
.lookup(point! {x: 50., y:0.5}, lrs.get_lrm("id").unwrap())
727+
.unwrap();
728+
assert_eq!(result.orthogonal_offset, 0.5);
729+
assert_eq!(result.measure.measure.scale_offset, 5.);
752730
}
753731

754732
#[test]
755733
fn lookup_multiple_lrm() {
756734
let lrs = lrs();
757-
let result = lrs.lookup(point! {x: 50., y:0.5}, lrs.get_lrm("id2").unwrap());
758-
assert_eq!(result.len(), 2);
759-
assert_eq!(result[0].orthogonal_offset, 0.5);
760-
assert_eq!(result[0].measure.measure.scale_offset, 5.);
761-
assert_eq!(result[0].measure.measure.anchor_name, "a");
762-
assert_eq!(result[1].orthogonal_offset, 1.5);
763-
assert_eq!(result[1].measure.measure.scale_offset, 5.);
735+
let result = lrs
736+
.lookup(point! {x: 50., y:0.5}, lrs.get_lrm("id2").unwrap())
737+
.unwrap();
738+
assert_eq!(result.orthogonal_offset, 1.5);
739+
assert_eq!(result.measure.measure.scale_offset, 5.);
740+
assert_eq!(result.measure.measure.anchor_name, "a");
741+
assert_eq!(result.orthogonal_offset, 1.5);
742+
assert_eq!(result.measure.measure.scale_offset, 5.);
764743
}
765744

766745
#[test]
767746
fn lookup_lrms() {
768747
let result = lrs().lookup_lrms(point! {x: 50., y:0.5});
769-
assert_eq!(result.len(), 3);
748+
assert_eq!(result.len(), 2);
770749
assert_eq!(result[0].orthogonal_offset, 0.5);
771750
assert_eq!(result[0].measure.measure.scale_offset, 5.);
772-
assert_eq!(result[1].orthogonal_offset, 0.5);
751+
assert_eq!(result[1].orthogonal_offset, 1.5);
773752
assert_eq!(result[1].measure.measure.scale_offset, 5.);
774-
assert_eq!(result[2].orthogonal_offset, 1.5);
775-
assert_eq!(result[2].measure.measure.scale_offset, 5.);
776753
}
777754

778755
#[test]
@@ -795,21 +772,11 @@ mod tests {
795772
}
796773

797774
#[test]
798-
fn get_lrm_applicable_traversals() {
799-
let lrs = lrs();
800-
let result = lrs.get_lrm_applicable_traversals(LrmHandle(0));
801-
assert_eq!(result.len(), 1);
802-
803-
let result = lrs.get_lrm_applicable_traversals(LrmHandle(1));
804-
assert_eq!(result.len(), 2);
805-
}
806-
807-
#[test]
808-
fn get_lrm_reference_traversal() {
809-
let result = lrs().get_lrm_reference_traversal(LrmHandle(0));
810-
assert_eq!(TraversalHandle(0), result);
811-
let result = lrs().get_lrm_reference_traversal(LrmHandle(1));
775+
fn get_lrm_traversal() {
776+
let result = lrs().get_lrm_traversal(LrmHandle(0));
812777
assert_eq!(TraversalHandle(0), result);
778+
let result = lrs().get_lrm_traversal(LrmHandle(1));
779+
assert_eq!(TraversalHandle(1), result);
813780
}
814781

815782
#[test]

src/lrs_ext.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl ExtLrs {
3535
pub fn get_lrm_geom(&self, index: usize) -> Result<Vec<geo::Coord>, String> {
3636
let lrm = self.lrs.lrms.get(index).ok_or("Invalid index")?;
3737
self.lrs
38-
.get_linestring(lrm.reference_traversal)
38+
.get_linestring(lrm.traversal)
3939
.map_err(|err| err.to_string())
4040
.map(|linestring| linestring.0)
4141
}
@@ -57,7 +57,7 @@ impl ExtLrs {
5757

5858
let traversal_position = TraversalPosition {
5959
curve_position,
60-
traversal: lrm.reference_traversal,
60+
traversal: lrm.traversal,
6161
};
6262
self.lrs.locate_traversal(traversal_position)
6363
}
@@ -71,7 +71,7 @@ impl ExtLrs {
7171
) -> Result<Vec<Coord>, String> {
7272
let lrm = &self.lrs.lrms[lrm_index];
7373
let scale = &lrm.scale;
74-
let curve = &self.lrs.traversals[lrm.reference_traversal.0].curve;
74+
let curve = &self.lrs.traversals[lrm.traversal.0].curve;
7575
let from = scale
7676
.locate_point(from)
7777
.map_err(|e| e.to_string())?

0 commit comments

Comments
 (0)