Skip to content

Commit 9f4518f

Browse files
committed
Orientation should be done by the user, not the crate
We now have only one `add_lrm` method in the builder.
1 parent a5ec68e commit 9f4518f

File tree

3 files changed

+25
-92
lines changed

3 files changed

+25
-92
lines changed

python/src/lib.rs

+9-20
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ impl Builder {
335335
self.inner.add_traversal(traversal_id, &segments);
336336
}
337337

338-
pub fn add_lrm_with_distances(
338+
pub fn add_lrm(
339339
&mut self,
340340
id: &str,
341341
traversal_index: usize,
@@ -344,25 +344,7 @@ impl Builder {
344344
) {
345345
let anchors: Vec<_> = anchors.into_iter().map(|anchor| anchor.into()).collect();
346346
self.inner
347-
.add_lrm_with_distances(id, traversal_index, &anchors, properties)
348-
}
349-
350-
pub fn add_lrm_with_distances_with_orientation(
351-
&mut self,
352-
id: &str,
353-
traversal_index: usize,
354-
reference_traversal_index: usize,
355-
anchors: Vec<AnchorOnLrm>,
356-
properties: Properties,
357-
) {
358-
let anchors: Vec<_> = anchors.into_iter().map(|anchor| anchor.into()).collect();
359-
self.inner.add_lrm_with_distances_with_orientation(
360-
id,
361-
traversal_index,
362-
reference_traversal_index,
363-
&anchors,
364-
properties,
365-
)
347+
.add_lrm(id, traversal_index, &anchors, properties)
366348
}
367349

368350
pub fn get_traversal_indexes(&mut self) -> std::collections::HashMap<String, usize> {
@@ -396,6 +378,13 @@ impl Builder {
396378
self.inner.get_node_coord(node_index).into()
397379
}
398380

381+
pub fn project(&self, lrm_index: usize, point: Point) -> Option<f64> {
382+
self.inner
383+
.project(lrm_index, geo_types::point! {x: point.x, y: point.y})
384+
.map(|p| p.distance_along_curve)
385+
.ok()
386+
}
387+
399388
pub fn reverse(&mut self, lrm_index: usize) {
400389
self.inner.reverse(lrm_index)
401390
}

src/builder.rs

+15-71
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use std::collections::HashMap;
55
use std::path::Path;
66

77
use flatbuffers::{ForwardsUOffset, Vector, WIPOffset};
8-
use geo::{point, Coord, LineLocatePoint};
8+
use geo::Coord;
99

10-
use crate::curves::{Curve, SphericalLineStringCurve};
10+
use crate::curves::{Curve, CurveError, CurveProjection, SphericalLineStringCurve};
1111

1212
use crate::lrs_generated::{self, *};
1313
use crate::osm_helpers::sort_edges;
@@ -260,8 +260,9 @@ impl<'fbb> Builder<'fbb> {
260260
self.temp_traversal.len() - 1
261261
}
262262

263-
/// Private function to add lrm
264-
fn add_lrm(
263+
/// Create a linear referencing method where the distance is provided.
264+
/// The [`Anchor`]s will be projected on the [`Curve`].
265+
pub fn add_lrm(
265266
&mut self,
266267
id: &str,
267268
traversal_index: usize,
@@ -288,73 +289,6 @@ impl<'fbb> Builder<'fbb> {
288289
.push(LinearReferencingMethod::create(&mut self.fbb, &args));
289290
}
290291

291-
/// Create a linear referencing method where the distance is provided.
292-
/// The [`Anchor`]s will be projected on the [`Curve`].
293-
pub fn add_lrm_with_distances(
294-
&mut self,
295-
id: &str,
296-
traversal_index: usize,
297-
anchors: &[AnchorOnLrm],
298-
properties: Properties,
299-
) {
300-
// Heuristic to know if the traversal needs to be reversed
301-
let anchor_coords: Vec<_> = anchors
302-
.iter()
303-
.filter_map(|anchor| match self.temp_anchors[anchor.anchor_index] {
304-
AnchorPosition::Curve(_) => None,
305-
AnchorPosition::Geographical(coord) => Some(coord),
306-
})
307-
.collect();
308-
if let [first_coord, .., last_coord] = anchor_coords[..] {
309-
if let [first_anchor, .., last_anchor] = anchors {
310-
let curve = &mut self.temp_traversal[traversal_index].curve;
311-
let projected_first = curve
312-
.project(first_coord.into())
313-
.expect("could not project anchor");
314-
let projected_last = curve
315-
.project(last_coord.into())
316-
.expect("could not project anchor");
317-
318-
let anchor_ord = first_anchor
319-
.distance_along_lrm
320-
.total_cmp(&last_anchor.distance_along_lrm);
321-
let projection_ord = projected_first
322-
.distance_along_curve
323-
.total_cmp(&projected_last.distance_along_curve);
324-
if anchor_ord != projection_ord {
325-
self.temp_traversal[traversal_index].reverse()
326-
}
327-
}
328-
}
329-
self.add_lrm(id, traversal_index, anchors, properties)
330-
}
331-
332-
/// Create a linear referencing method where the distance is provided.
333-
/// Compared to `Builder::add_lrm_with_distances`, this function takes a reference_traversal_index
334-
/// That is used to help orient the curve
335-
pub fn add_lrm_with_distances_with_orientation(
336-
&mut self,
337-
id: &str,
338-
traversal_index: usize,
339-
reference_traversal_index: usize,
340-
anchors: &[AnchorOnLrm],
341-
properties: Properties,
342-
) {
343-
if let [first_point, .., last_point] =
344-
&self.temp_traversal[traversal_index].curve.geom.0[..]
345-
{
346-
let first = point! {x: first_point.x, y: first_point.y};
347-
let last = point! {x: last_point.x, y: last_point.y};
348-
let reference_curve = &self.temp_traversal[reference_traversal_index].curve.geom;
349-
let first_distance = reference_curve.line_locate_point(&first);
350-
let last_distance = reference_curve.line_locate_point(&last);
351-
352-
if first_distance > last_distance {
353-
self.temp_traversal[traversal_index].reverse()
354-
}
355-
}
356-
self.add_lrm(id, traversal_index, anchors, properties)
357-
}
358292
/// Private helper that projects [`Anchor`]s onto a [`Curve`].
359293
fn project_anchors(
360294
&mut self,
@@ -552,6 +486,16 @@ impl<'fbb> Builder<'fbb> {
552486
geo::EuclideanDistance::euclidean_distance(a, b)
553487
}
554488

489+
/// Returns the position along the curve of the traversal
490+
/// The value will be between 0.0 and 1.0, both included
491+
pub fn project(
492+
&self,
493+
lrm_index: usize,
494+
point: geo::Point,
495+
) -> Result<CurveProjection, CurveError> {
496+
self.temp_traversal[lrm_index].curve.project(point)
497+
}
498+
555499
/// Reverses the direction of the traversal
556500
pub fn reverse(&mut self, lrm_index: usize) {
557501
self.temp_traversal[lrm_index].reverse();

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn read_and_write_lrs() {
4444
anchor_index,
4545
distance_along_lrm: 12.0,
4646
};
47-
builder.add_lrm_with_distances("lrm", traversal, &[anchor_on_lrm], properties!());
47+
builder.add_lrm("lrm", traversal, &[anchor_on_lrm], properties!());
4848

4949
let buffer = builder.build_data(properties!("source" => "example"));
5050
let lrs = lrs::Lrs::<SphericalLineStringCurve>::from_bytes(buffer).unwrap();

0 commit comments

Comments
 (0)