Skip to content

Commit 5974e37

Browse files
committed
update LineStringCurve occurrences in PlanarLineStringCurve
1 parent 66c052d commit 5974e37

File tree

2 files changed

+85
-44
lines changed

2 files changed

+85
-44
lines changed

src/curves.rs

+81-40
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,15 @@ impl Curve for PlanarLineStringCurve {
185185
fn intersect_segment(&self, segment: Line) -> Option<Point> {
186186
self.geom
187187
.lines()
188-
.flat_map(|curve_line| match geo::line_intersection::line_intersection(segment, curve_line) {
189-
Some(LineIntersection::SinglePoint {
190-
intersection,
191-
is_proper: _,
192-
}) => Some(intersection.into()),
193-
Some(LineIntersection::Collinear { intersection: _ }) => None,
194-
None => None,
188+
.flat_map(|curve_line| {
189+
match geo::line_intersection::line_intersection(segment, curve_line) {
190+
Some(LineIntersection::SinglePoint {
191+
intersection,
192+
is_proper: _,
193+
}) => Some(intersection.into()),
194+
Some(LineIntersection::Collinear { intersection: _ }) => None,
195+
None => None,
196+
}
195197
})
196198
.next()
197199
}
@@ -210,7 +212,10 @@ impl Curve for PlanarLineStringCurve {
210212
.ok_or(CurveError::NotFiniteCoordinates)?;
211213

212214
// translate to (0, 0) and normalize by the length of the curve to get unit vector of tangent
213-
let tangent = ((line.end.x - line.start.x) / self.length, (line.end.y - line.start.y) / self.length);
215+
let tangent = (
216+
(line.end.x - line.start.x) / self.length,
217+
(line.end.y - line.start.y) / self.length
218+
);
214219

215220
// 90° clockwise rotation
216221
let normal = (-tangent.1, tangent.0);
@@ -293,7 +298,9 @@ impl Curve for SphericalLineStringCurve {
293298
}
294299

295300
fn is_valid(&self) -> bool {
296-
if !(self.geom.coords_count() >= 2 && (self.geom.coords_count() > 2 || !self.geom.is_closed())) {
301+
if !(self.geom.coords_count() >= 2
302+
&& (self.geom.coords_count() > 2 || !self.geom.is_closed()))
303+
{
297304
return false;
298305
}
299306
for coord in self.geom.coords() {
@@ -311,7 +318,9 @@ impl Curve for SphericalLineStringCurve {
311318

312319
match self.geom.haversine_closest_point(&point) {
313320
geo::Closest::SinglePoint(closest_point) => {
314-
let distance_along_curve = closest_point.haversine_distance(&self.geom.points().next().unwrap()) + self.start_offset;
321+
let distance_along_curve = closest_point
322+
.haversine_distance(&self.geom.points().next().unwrap())
323+
+ self.start_offset;
315324

316325
let begin = self.geom.coords().next().unwrap();
317326
let end = self.geom.coords().next_back().unwrap();
@@ -324,11 +333,11 @@ impl Curve for SphericalLineStringCurve {
324333

325334
Ok(CurveProjection {
326335
distance_along_curve,
327-
offset
336+
offset,
328337
})
329338
}
330339
geo::Closest::Intersection(_) => Err(CurveError::InvalidGeometry),
331-
geo::Closest::Indeterminate => Err(CurveError::NotFiniteCoordinates)
340+
geo::Closest::Indeterminate => Err(CurveError::NotFiniteCoordinates),
332341
}
333342
}
334343

@@ -381,17 +390,15 @@ impl Curve for SphericalLineStringCurve {
381390
self.geom
382391
.densify_haversine(self.densify_by)
383392
.lines()
384-
.flat_map(|curve_line| match geo::line_intersection::line_intersection(segment, curve_line) {
385-
Some(LineIntersection::SinglePoint {
386-
intersection,
387-
is_proper: _,
388-
}) => {
389-
Some(intersection.into())
390-
},
391-
Some(LineIntersection::Collinear { intersection: _ }) => {
392-
None
393-
},
394-
None => None,
393+
.flat_map(|curve_line| {
394+
match geo::line_intersection::line_intersection(segment, curve_line) {
395+
Some(LineIntersection::SinglePoint {
396+
intersection,
397+
is_proper: _,
398+
}) => Some(intersection.into()),
399+
Some(LineIntersection::Collinear { intersection: _ }) => None,
400+
None => None,
401+
}
395402
})
396403
.next()
397404
}
@@ -467,7 +474,11 @@ mod tests {
467474
#[test]
468475
fn planar_fragmented() {
469476
let framentation_max_length = 1.;
470-
let c = PlanarLineStringCurve::new_fragmented(line_string![(x: 0., y: 0.), (x: 2., y: 0.)], framentation_max_length, 1.);
477+
let c = PlanarLineStringCurve::new_fragmented(
478+
line_string![(x: 0., y: 0.), (x: 2., y: 0.)],
479+
framentation_max_length,
480+
1.,
481+
);
471482
assert_eq!(2, c.len());
472483
assert_eq!(framentation_max_length, c[0].length());
473484
}
@@ -571,59 +582,86 @@ mod tests {
571582
#[test]
572583
fn spherical_fragmented() {
573584
let framentation_max_length = 1.;
574-
let paris_to_new_york = SphericalLineStringCurve::new_fragmented(line_string![(x: PARIS_LON, y: PARIS_LAT), (x: NEW_YORK_LON, y: NEW_YORK_LAT)], framentation_max_length, 1.);
585+
let paris_to_new_york = SphericalLineStringCurve::new_fragmented(
586+
line_string![(x: PARIS_LON, y: PARIS_LAT), (x: NEW_YORK_LON, y: NEW_YORK_LAT)],
587+
framentation_max_length,
588+
1.,
589+
);
575590

576591
assert_eq!(5837284, paris_to_new_york.len());
577-
assert_relative_eq!(framentation_max_length, paris_to_new_york[0].length(), epsilon = 1e-7);
592+
assert_relative_eq!(
593+
framentation_max_length,
594+
paris_to_new_york[0].length(),
595+
epsilon = 1e-7
596+
);
578597
// 1e-7 means we lose 0.1 micrometer per segment
579598
}
580599

581600
#[test]
582601
fn spherical_length() {
583-
let paris_to_new_york = SphericalLineStringCurve::new(line_string![(x: PARIS_LON, y: PARIS_LAT), (x: NEW_YORK_LON, y: NEW_YORK_LAT)], 1.);
602+
let paris_to_new_york = SphericalLineStringCurve::new(
603+
line_string![(x: PARIS_LON, y: PARIS_LAT), (x: NEW_YORK_LON, y: NEW_YORK_LAT)],
604+
1.
605+
);
584606
assert_relative_eq!(5837283.441678336, paris_to_new_york.length()); // 5837283.441678336 using [`HaversineLength`] and 5852969.839293494 using [`GeodesicLength`]
585607

586-
let lille_to_perpignan = SphericalLineStringCurve::new(line_string![(x: LILLE_LON, y: LILLE_LAT), (x: PERPIGNAN_LON, y: PERPIGNAN_LAT)], 1.);
608+
let lille_to_perpignan = SphericalLineStringCurve::new(
609+
line_string![(x: LILLE_LON, y: LILLE_LAT), (x: PERPIGNAN_LON, y: PERPIGNAN_LAT)],
610+
1.
611+
);
587612
assert_relative_eq!(883505.2931188548, lille_to_perpignan.length()); // 883505.2931188548 using [`HaversineLength`] and 883260.051153502 using [`GeodesicLength`]
588613

589-
let brest_to_nancy = SphericalLineStringCurve::new(line_string![(x: BREST_LON, y: BREST_LAT), (x: NANCY_LON, y: NANCY_LAT)], 1.);
614+
let brest_to_nancy = SphericalLineStringCurve::new(
615+
line_string![(x: BREST_LON, y: BREST_LAT), (x: NANCY_LON, y: NANCY_LAT)],
616+
1.
617+
);
590618
assert_relative_eq!(785636.8730262491, brest_to_nancy.length()); // 785636.8730262491 using [`HaversineLength`] and 787994.4363866252 using [`GeodesicLength`]
591619
}
592620

593621
#[test]
594622
fn spherical_is_valid() {
595623
// Valid curve
596-
let curve = SphericalLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 1., y: 1.)], 1.);
624+
let curve =
625+
SphericalLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 1., y: 1.)], 1.);
597626
assert!(curve.is_valid());
598627

599628
// Invalid curve: too few coordinates
600-
let curve = SphericalLineStringCurve::new(line_string![(x: 0., y: 0.)], 1.);
629+
let curve =
630+
SphericalLineStringCurve::new(line_string![(x: 0., y: 0.)], 1.);
601631
assert!(!curve.is_valid());
602632

603633
// Invalid curve: closed LineString with only 2 coordinates
604-
let curve = SphericalLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 0., y: 0.)], 1.);
634+
let curve =
635+
SphericalLineStringCurve::new(line_string![(x: 0., y: 0.), (x: 0., y: 0.)], 1.);
605636
assert!(!curve.is_valid());
606637

607638
// Invalid curve: longitude > 180.
608-
let curve = SphericalLineStringCurve::new(line_string![(x: 180.1, y: 0.), (x: 0., y: 0.)], 1.);
639+
let curve =
640+
SphericalLineStringCurve::new(line_string![(x: 180.1, y: 0.), (x: 0., y: 0.)], 1.);
609641
assert!(!curve.is_valid());
610642

611643
// Invalid curve: longitude < -180.
612-
let curve = SphericalLineStringCurve::new(line_string![(x: -180.1, y: 0.), (x: 0., y: 0.)], 1.);
644+
let curve =
645+
SphericalLineStringCurve::new(line_string![(x: -180.1, y: 0.), (x: 0., y: 0.)], 1.);
613646
assert!(!curve.is_valid());
614647

615648
// Invalid curve: latitude > 90.
616-
let curve = SphericalLineStringCurve::new(line_string![(x: 0., y: 90.1), (x: 0., y: 0.)], 1.);
649+
let curve =
650+
SphericalLineStringCurve::new(line_string![(x: 0., y: 90.1), (x: 0., y: 0.)], 1.);
617651
assert!(!curve.is_valid());
618652

619653
// Invalid curve: latitude > 180.
620-
let curve = SphericalLineStringCurve::new(line_string![(x: 0., y: -90.1), (x: 0., y: 0.)], 1.);
654+
let curve =
655+
SphericalLineStringCurve::new(line_string![(x: 0., y: -90.1), (x: 0., y: 0.)], 1.);
621656
assert!(!curve.is_valid());
622657
}
623658

624659
#[test]
625660
fn spherical_projection() {
626-
let mut paris_to_new_york = SphericalLineStringCurve::new(line_string![(x: PARIS_LON, y: PARIS_LAT), (x: NEW_YORK_LON, y: NEW_YORK_LAT)], 1.);
661+
let mut paris_to_new_york = SphericalLineStringCurve::new(
662+
line_string![(x: PARIS_LON, y: PARIS_LAT), (x: NEW_YORK_LON, y: NEW_YORK_LAT)],
663+
1.,
664+
);
627665

628666
// Point is located on the right (north) of the curve
629667
let projected = paris_to_new_york.project(point! {x: -6.705403880820967, y: 51.42135181702875}).unwrap();
@@ -642,7 +680,10 @@ mod tests {
642680
assert_eq!(625592.3211438804, projected.offset);
643681

644682
// ################################################################################
645-
let mut new_york_to_paris = SphericalLineStringCurve::new(line_string![(x: NEW_YORK_LON, y: NEW_YORK_LAT), (x: PARIS_LON, y: PARIS_LAT)], 1.);
683+
let mut new_york_to_paris = SphericalLineStringCurve::new(
684+
line_string![(x: NEW_YORK_LON, y: NEW_YORK_LAT), (x: PARIS_LON, y: PARIS_LAT)],
685+
1.,
686+
);
646687

647688
// Point is located on the left (north) of the curve
648689
let projected = new_york_to_paris.project(point! {x: -6.705403880820967, y: 51.42135181702875}).unwrap();
@@ -717,7 +758,7 @@ mod tests {
717758
#[test]
718759
fn spherical_intersect_segment() {
719760
// Note: following tests have been computed with a maximum length of curve of 100m, otherwise the curve is densified.
720-
761+
721762
// Intersection
722763
let paris_to_new_york = SphericalLineStringCurve::new(line_string![(x: PARIS_LON, y: PARIS_LAT), (x: NEW_YORK_LON, y: NEW_YORK_LAT)], 1.);
723764
let segment = Line::new(coord! {x: -36.76627263796084, y: 69.72980545457074}, coord! {x: -53.52127629098692, y: 15.34337895024332});
@@ -728,7 +769,7 @@ mod tests {
728769
assert!(paris_to_new_york.intersect_segment(segment).is_none());
729770

730771
// TODO: Collinear
731-
// Notes:
772+
// Notes:
732773
// - because of the haversine densification, the geometry is slightly different and includes more points
733774
// than before, thus creating intersection(s) point(s).
734775
// - is very rare in reality

src/lrs.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -563,19 +563,19 @@ impl<CurveImpl: Curve> Lrs<CurveImpl> {
563563
mod tests {
564564
use geo::line_string;
565565

566-
use crate::curves::LineStringCurve;
566+
use crate::curves::PlanarLineStringCurve;
567567

568568
use super::*;
569569

570-
fn lrs() -> Lrs<LineStringCurve> {
570+
fn lrs() -> Lrs<PlanarLineStringCurve> {
571571
let traversal = Traversal {
572-
curve: LineStringCurve::new(line_string![(x: 0., y:0.), (x: 200., y:0.)], 1.),
572+
curve: PlanarLineStringCurve::new(line_string![(x: 0., y:0.), (x: 200., y:0.)], 1.),
573573
id: "curve".to_owned(),
574574
lrms: vec![LrmHandle(0), LrmHandle(1)],
575575
};
576576

577577
let traversal2 = Traversal {
578-
curve: LineStringCurve::new(line_string![(x: 0., y:-1.), (x: 200., y:-1.)], 1.),
578+
curve: PlanarLineStringCurve::new(line_string![(x: 0., y:-1.), (x: 200., y:-1.)], 1.),
579579
id: "curve".to_owned(),
580580
lrms: vec![LrmHandle(1)],
581581
};

0 commit comments

Comments
 (0)