@@ -185,13 +185,15 @@ impl Curve for PlanarLineStringCurve {
185
185
fn intersect_segment ( & self , segment : Line ) -> Option < Point > {
186
186
self . geom
187
187
. 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
+ }
195
197
} )
196
198
. next ( )
197
199
}
@@ -210,7 +212,10 @@ impl Curve for PlanarLineStringCurve {
210
212
. ok_or ( CurveError :: NotFiniteCoordinates ) ?;
211
213
212
214
// 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
+ ) ;
214
219
215
220
// 90° clockwise rotation
216
221
let normal = ( -tangent. 1 , tangent. 0 ) ;
@@ -293,7 +298,9 @@ impl Curve for SphericalLineStringCurve {
293
298
}
294
299
295
300
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
+ {
297
304
return false ;
298
305
}
299
306
for coord in self . geom . coords ( ) {
@@ -311,7 +318,9 @@ impl Curve for SphericalLineStringCurve {
311
318
312
319
match self . geom . haversine_closest_point ( & point) {
313
320
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 ;
315
324
316
325
let begin = self . geom . coords ( ) . next ( ) . unwrap ( ) ;
317
326
let end = self . geom . coords ( ) . next_back ( ) . unwrap ( ) ;
@@ -324,11 +333,11 @@ impl Curve for SphericalLineStringCurve {
324
333
325
334
Ok ( CurveProjection {
326
335
distance_along_curve,
327
- offset
336
+ offset,
328
337
} )
329
338
}
330
339
geo:: Closest :: Intersection ( _) => Err ( CurveError :: InvalidGeometry ) ,
331
- geo:: Closest :: Indeterminate => Err ( CurveError :: NotFiniteCoordinates )
340
+ geo:: Closest :: Indeterminate => Err ( CurveError :: NotFiniteCoordinates ) ,
332
341
}
333
342
}
334
343
@@ -381,17 +390,15 @@ impl Curve for SphericalLineStringCurve {
381
390
self . geom
382
391
. densify_haversine ( self . densify_by )
383
392
. 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
+ }
395
402
} )
396
403
. next ( )
397
404
}
@@ -467,7 +474,11 @@ mod tests {
467
474
#[ test]
468
475
fn planar_fragmented ( ) {
469
476
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
+ ) ;
471
482
assert_eq ! ( 2 , c. len( ) ) ;
472
483
assert_eq ! ( framentation_max_length, c[ 0 ] . length( ) ) ;
473
484
}
@@ -571,59 +582,86 @@ mod tests {
571
582
#[ test]
572
583
fn spherical_fragmented ( ) {
573
584
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
+ ) ;
575
590
576
591
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
+ ) ;
578
597
// 1e-7 means we lose 0.1 micrometer per segment
579
598
}
580
599
581
600
#[ test]
582
601
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
+ ) ;
584
606
assert_relative_eq ! ( 5837283.441678336 , paris_to_new_york. length( ) ) ; // 5837283.441678336 using [`HaversineLength`] and 5852969.839293494 using [`GeodesicLength`]
585
607
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
+ ) ;
587
612
assert_relative_eq ! ( 883505.2931188548 , lille_to_perpignan. length( ) ) ; // 883505.2931188548 using [`HaversineLength`] and 883260.051153502 using [`GeodesicLength`]
588
613
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
+ ) ;
590
618
assert_relative_eq ! ( 785636.8730262491 , brest_to_nancy. length( ) ) ; // 785636.8730262491 using [`HaversineLength`] and 787994.4363866252 using [`GeodesicLength`]
591
619
}
592
620
593
621
#[ test]
594
622
fn spherical_is_valid ( ) {
595
623
// 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. ) ;
597
626
assert ! ( curve. is_valid( ) ) ;
598
627
599
628
// 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. ) ;
601
631
assert ! ( !curve. is_valid( ) ) ;
602
632
603
633
// 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. ) ;
605
636
assert ! ( !curve. is_valid( ) ) ;
606
637
607
638
// 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. ) ;
609
641
assert ! ( !curve. is_valid( ) ) ;
610
642
611
643
// 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. ) ;
613
646
assert ! ( !curve. is_valid( ) ) ;
614
647
615
648
// 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. ) ;
617
651
assert ! ( !curve. is_valid( ) ) ;
618
652
619
653
// 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. ) ;
621
656
assert ! ( !curve. is_valid( ) ) ;
622
657
}
623
658
624
659
#[ test]
625
660
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
+ ) ;
627
665
628
666
// Point is located on the right (north) of the curve
629
667
let projected = paris_to_new_york. project ( point ! { x: -6.705403880820967 , y: 51.42135181702875 } ) . unwrap ( ) ;
@@ -642,7 +680,10 @@ mod tests {
642
680
assert_eq ! ( 625592.3211438804 , projected. offset) ;
643
681
644
682
// ################################################################################
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
+ ) ;
646
687
647
688
// Point is located on the left (north) of the curve
648
689
let projected = new_york_to_paris. project ( point ! { x: -6.705403880820967 , y: 51.42135181702875 } ) . unwrap ( ) ;
@@ -717,7 +758,7 @@ mod tests {
717
758
#[ test]
718
759
fn spherical_intersect_segment ( ) {
719
760
// Note: following tests have been computed with a maximum length of curve of 100m, otherwise the curve is densified.
720
-
761
+
721
762
// Intersection
722
763
let paris_to_new_york = SphericalLineStringCurve :: new ( line_string ! [ ( x: PARIS_LON , y: PARIS_LAT ) , ( x: NEW_YORK_LON , y: NEW_YORK_LAT ) ] , 1. ) ;
723
764
let segment = Line :: new ( coord ! { x: -36.76627263796084 , y: 69.72980545457074 } , coord ! { x: -53.52127629098692 , y: 15.34337895024332 } ) ;
@@ -728,7 +769,7 @@ mod tests {
728
769
assert ! ( paris_to_new_york. intersect_segment( segment) . is_none( ) ) ;
729
770
730
771
// TODO: Collinear
731
- // Notes:
772
+ // Notes:
732
773
// - because of the haversine densification, the geometry is slightly different and includes more points
733
774
// than before, thus creating intersection(s) point(s).
734
775
// - is very rare in reality
0 commit comments