@@ -2,6 +2,8 @@ use super::{Covers, impl_covers_from_intersects, impl_covers_from_relate};
22use crate :: { Contains , HasDimensions , geometry:: * } ;
33use crate :: { GeoFloat , GeoNum } ;
44
5+ // valid because RHS is point or multipoint
6+ // all exterior pts of RHS intersecting self means self covers RHS
57impl_covers_from_intersects ! ( LineString <T >, [ Point <T >, MultiPoint <T >] ) ;
68
79impl < T > Covers < Line < T > > for LineString < T >
1012{
1113 fn covers ( & self , rhs : & Line < T > ) -> bool {
1214 if rhs. start == rhs. end {
15+ // handle edge case where line might sit within a linestring's boundary
1316 self . covers ( & rhs. start )
1417 } else {
18+ // remaining scenarios are eqivalent to contains
1519 self . contains ( rhs)
1620 }
1721 }
@@ -36,11 +40,99 @@ Polygon<T>, MultiPolygon<T>,
3640Geometry <T >, GeometryCollection <T >
3741] ) ;
3842
43+ // valid because RHS is point or multipoint
44+ // all exterior pts of RHS intersecting self means self covers RHS
3945impl_covers_from_intersects ! ( MultiLineString <T >, [ Point <T >, MultiPoint <T >] ) ;
46+
4047impl_covers_from_relate ! ( MultiLineString <T >, [
4148Line <T >,
4249LineString <T >, MultiLineString <T >,
4350Rect <T >, Triangle <T >,
4451Polygon <T >, MultiPolygon <T >,
4552Geometry <T >, GeometryCollection <T >
4653] ) ;
54+
55+ #[ cfg( test) ]
56+ mod tests {
57+ use super :: * ;
58+ use crate :: algorithm:: convert:: Convert ;
59+ use crate :: wkt;
60+
61+ #[ test]
62+ fn test_rhs_empty ( ) {
63+ let s: LineString < f64 > = wkt ! ( LINESTRING ( 0 0 , 1 1 ) ) . convert ( ) ;
64+ assert ! ( !s. covers( & LineString :: empty( ) ) ) ;
65+ assert ! ( !s. covers( & Polygon :: empty( ) ) ) ;
66+ assert ! ( !s. covers( & MultiPoint :: empty( ) ) ) ;
67+ assert ! ( !s. covers( & MultiLineString :: empty( ) ) ) ;
68+ assert ! ( !s. covers( & MultiPolygon :: empty( ) ) ) ;
69+ assert ! ( !s. covers( & GeometryCollection :: empty( ) ) ) ;
70+
71+ let s: MultiLineString < f64 > = wkt ! ( MULTILINESTRING ( ( 0 0 , 1 1 ) ) ) . convert ( ) ;
72+ assert ! ( !s. covers( & LineString :: empty( ) ) ) ;
73+ assert ! ( !s. covers( & Polygon :: empty( ) ) ) ;
74+ assert ! ( !s. covers( & MultiPoint :: empty( ) ) ) ;
75+ assert ! ( !s. covers( & MultiLineString :: empty( ) ) ) ;
76+ assert ! ( !s. covers( & MultiPolygon :: empty( ) ) ) ;
77+ assert ! ( !s. covers( & GeometryCollection :: empty( ) ) ) ;
78+ }
79+
80+ #[ test]
81+ fn test_lhs_empty ( ) {
82+ let s: LineString < f64 > = LineString :: empty ( ) ;
83+ assert ! ( !s. covers( & wkt!( POINT ( 0 0 ) ) . convert( ) ) ) ;
84+ assert ! ( !s. covers( & wkt!( MULTIPOINT ( 0 0 , 1 1 ) ) . convert( ) ) ) ;
85+ assert ! ( !s. covers( & wkt!( LINE ( 0 0 , 1 1 ) ) . convert( ) ) ) ;
86+ assert ! ( !s. covers( & wkt!( LINESTRING ( 0 0 , 1 1 ) ) . convert( ) ) ) ;
87+ assert ! ( !s. covers( & wkt!( MULTILINESTRING ( ( 0 0 , 1 1 ) , ( 2 2 , 3 3 ) ) ) . convert( ) ) ) ;
88+ assert ! ( !s. covers( & wkt!( POLYGON ( ( 0 0 , 1 1 , 1 0 , 0 0 ) ) ) . convert( ) ) ) ;
89+ assert ! ( !s. covers( & wkt!( MULTIPOLYGON ( ( ( 0 0 , 1 0 , 1 1 , 0 1 , 0 0 ) ) ) ) . convert( ) ) ) ;
90+ assert ! ( !s. covers( & wkt!( RECT ( 0 0 , 1 1 ) ) . convert( ) ) ) ;
91+ assert ! ( !s. covers( & wkt!( TRIANGLE ( 0 0 , 0 1 , 1 1 ) ) . convert( ) ) ) ;
92+ assert ! ( !s. covers( & Into :: <Geometry >:: into( wkt!( POINT ( 0 0 ) ) . convert( ) ) ) ) ;
93+ assert ! ( !s. covers( & wkt!( GEOMETRYCOLLECTION ( POINT ( 0 0 ) ) ) . convert( ) ) ) ;
94+
95+ let s: MultiLineString < f64 > = MultiLineString :: empty ( ) ;
96+ assert ! ( !s. covers( & wkt!( POINT ( 0 0 ) ) . convert( ) ) ) ;
97+ assert ! ( !s. covers( & wkt!( MULTIPOINT ( 0 0 , 1 1 ) ) . convert( ) ) ) ;
98+ assert ! ( !s. covers( & wkt!( LINE ( 0 0 , 1 1 ) ) . convert( ) ) ) ;
99+ assert ! ( !s. covers( & wkt!( LINESTRING ( 0 0 , 1 1 ) ) . convert( ) ) ) ;
100+ assert ! ( !s. covers( & wkt!( MULTILINESTRING ( ( 0 0 , 1 1 ) , ( 2 2 , 3 3 ) ) ) . convert( ) ) ) ;
101+ assert ! ( !s. covers( & wkt!( POLYGON ( ( 0 0 , 1 1 , 1 0 , 0 0 ) ) ) . convert( ) ) ) ;
102+ assert ! ( !s. covers( & wkt!( MULTIPOLYGON ( ( ( 0 0 , 1 0 , 1 1 , 0 1 , 0 0 ) ) ) ) . convert( ) ) ) ;
103+ assert ! ( !s. covers( & wkt!( RECT ( 0 0 , 1 1 ) ) . convert( ) ) ) ;
104+ assert ! ( !s. covers( & wkt!( TRIANGLE ( 0 0 , 0 1 , 1 1 ) ) . convert( ) ) ) ;
105+ assert ! ( !s. covers( & Into :: <Geometry >:: into( wkt!( POINT ( 0 0 ) ) . convert( ) ) ) ) ;
106+ assert ! ( !s. covers( & wkt!( GEOMETRYCOLLECTION ( POINT ( 0 0 ) ) ) . convert( ) ) ) ;
107+ }
108+
109+ #[ test]
110+ fn differ_from_contains ( ) {
111+ // test that the edge case is covered by custom implementation
112+
113+ let ls: LineString < f64 > = wkt ! ( LINESTRING ( 0 0 , 1 1 ) ) . convert ( ) ;
114+ let ls_s: LineString < f64 > = wkt ! ( LINESTRING ( 0 0 , 0 0 ) ) . convert ( ) ;
115+ let ls_e: LineString < f64 > = wkt ! ( LINESTRING ( 1 1 , 1 1 ) ) . convert ( ) ;
116+ let ln_s: Line < f64 > = wkt ! ( LINE ( 0 0 , 0 0 ) ) . convert ( ) ;
117+ let ln_e: Line < f64 > = wkt ! ( LINE ( 1 1 , 1 1 ) ) . convert ( ) ;
118+ let pt_s: Point < f64 > = wkt ! ( POINT ( 0 0 ) ) . convert ( ) ;
119+ let pt_e: Point < f64 > = wkt ! ( POINT ( 1 1 ) ) . convert ( ) ;
120+
121+ assert ! ( ls. covers( & ls_s) ) ;
122+ assert ! ( ls. covers( & ls_e) ) ;
123+ assert ! ( ls. covers( & ln_s) ) ;
124+ assert ! ( ls. covers( & ln_e) ) ;
125+ assert ! ( ls. covers( & pt_s) ) ;
126+ assert ! ( ls. covers( & pt_e) ) ;
127+
128+ assert ! ( !ls. contains( & ls_s) ) ;
129+ assert ! ( !ls. contains( & ls_e) ) ;
130+ assert ! ( !ls. contains( & ln_s) ) ;
131+ assert ! ( !ls. contains( & ln_e) ) ;
132+ assert ! ( !ls. contains( & pt_s) ) ;
133+ assert ! ( !ls. contains( & pt_e) ) ;
134+
135+ }
136+
137+
138+ }
0 commit comments