diff --git a/src/methods/geom_relations/overlaps.jl b/src/methods/geom_relations/overlaps.jl index 8cb966a0b..8e7a07153 100644 --- a/src/methods/geom_relations/overlaps.jl +++ b/src/methods/geom_relations/overlaps.jl @@ -50,6 +50,14 @@ a point, an edge, or area for points, lines, and polygons/multipolygons respectively, without being contained. =# + +const OVERLAPS_POINT_ALLOWS = (in_allow = true, on_allow = true, out_allow = true) +const OVERLAPS_CURVE_ALLOWS = (over_allow = true, cross_allow = true, on_allow = true, out_allow = true) +const OVERLAPS_POLYGON_ALLOWS = (in_allow = true, on_allow = true, out_allow = true) +const OVERLAPS_REQUIRES = (in_require = true, on_require = false, out_require = false) +const OVERLAPS_EXACT = (exact = _False(),) + + """ overlaps(geom1, geom2)::Bool @@ -76,6 +84,14 @@ overlaps(geom1, geom2)::Bool = overlaps( geom2, ) + +# # Convert features to geometries +overlaps(::GI.FeatureTrait, g1, ::Any, g2) = overlaps(GI.geometry(g1), g2) +overlaps(::Any, g1, t2::GI.FeatureTrait, g2) = overlaps(g1, GI.geometry(g2)) +overlaps(::FeatureTrait, g1, ::FeatureTrait, g2) = overlaps(GI.geometry(g1), GI.geometry(g2)) + + + """ overlaps(::GI.AbstractTrait, geom1, ::GI.AbstractTrait, geom2)::Bool @@ -122,6 +138,10 @@ outside of the other line, return true. Else false. overlaps(::GI.LineTrait, line1, ::GI.LineTrait, line) = _overlaps((a1, a2), (b1, b2)) +# The code below is more robust, +# but fails when a linestring is contained within another linestring. +# TODO: make this work better, maybe with full de9im support... +#= """ overlaps( ::Union{GI.LineStringTrait, GI.LinearRing}, line1, @@ -132,8 +152,50 @@ If the curves overlap, meaning that at least one edge of each curve overlaps, return true. Else false. """ function overlaps( - ::Union{GI.LineStringTrait, GI.LinearRing}, line1, - ::Union{GI.LineStringTrait, GI.LinearRing}, line2, + ::Union{GI.LineStringTrait, GI.LineTrait}, line1, + ::Union{GI.LineStringTrait, GI.LineTrait}, line2, +) + return !equals(line1, line2) && _line_curve_process( + line1, line2; + OVERLAPS_CURVE_ALLOWS..., + OVERLAPS_REQUIRES..., + OVERLAPS_EXACT..., + closed_line = false, + closed_curve = false, + ) +end + +function overlaps( + ::GI.LinearRingTrait, ring1, + ::Union{GI.LineStringTrait, GI.LineTrait}, line2, +) + return !equals(ring1, line2) && _line_curve_process( + ring1, line2; + OVERLAPS_CURVE_ALLOWS..., + OVERLAPS_REQUIRES..., + OVERLAPS_EXACT..., + closed_line = true, + closed_curve = false, + ) +end + +function overlaps( + ::Union{GI.LineStringTrait, GI.LineTrait}, line1, + ::GI.LinearRingTrait, ring2, +) + return !equals(line1, ring2) && _line_curve_process( + line1, ring2; OVERLAPS_CURVE_ALLOWS..., OVERLAPS_REQUIRES..., OVERLAPS_EXACT..., + closed_line = false, + closed_curve = true, + ) +end + +=# +# This is the old code which was previously working. + +function overlaps( + ::Union{GI.LineStringTrait, GI.LinearRingTrait}, line1, + ::Union{GI.LineStringTrait, GI.LinearRingTrait}, line2, ) edges_a, edges_b = map(sort! ∘ to_edges, (line1, line2)) for edge_a in edges_a @@ -144,24 +206,19 @@ function overlaps( return false end -""" - overlaps( - trait_a::GI.PolygonTrait, poly_a, - trait_b::GI.PolygonTrait, poly_b, - )::Bool - -If the two polygons intersect with one another, but are not equal, return true. -Else false. -""" function overlaps( - trait_a::GI.PolygonTrait, poly_a, - trait_b::GI.PolygonTrait, poly_b, + ::GI.PolygonTrait, poly1, + ::GI.PolygonTrait, poly2, ) - edges_a, edges_b = map(sort! ∘ to_edges, (poly_a, poly_b)) - return _line_intersects(edges_a, edges_b) && - !equals(trait_a, poly_a, trait_b, poly_b) + return !equals(poly1, poly2) && _polygon_polygon_process( + poly1, poly2; + OVERLAPS_POLYGON_ALLOWS..., + OVERLAPS_REQUIRES..., + OVERLAPS_EXACT..., + ) end + """ overlaps( ::GI.PolygonTrait, poly1, diff --git a/test/methods/geom_relations.jl b/test/methods/geom_relations.jl index 0435c10fe..793f7983c 100644 --- a/test/methods/geom_relations.jl +++ b/test/methods/geom_relations.jl @@ -55,6 +55,11 @@ p10 = LG.Polygon([ [[0.15, 0.55], [0.15, 0.95], [0.55, 0.95], [0.55, 0.55], [0.15, 0.55]] ]) p11 = LG.Polygon(r3) +"Rectangle going from 0,0 to 1,1" +p12 = GI.Polygon([Tuple{Float64, Float64}[(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]]) +"Pentagon - take a rectangle going from (1, 0) to (2, 1), and add a point at (0.5, 0.5)" +p13 = GI.Polygon([Tuple{Float64, Float64}[(1, 0), (2, 0), (2, 1), (1, 1), (0.5, 0.5), (1, 0)]]) + mpt1 = LG.MultiPoint([pt1, pt2]) mpt2 = LG.MultiPoint([pt2, pt3]) @@ -149,6 +154,7 @@ test_pairs = [ (p6, p1, "p6", "p1", "Polygon inside of other polygon's hole"), (p7, p1, "p7", "p1", "Polygons overlap"), (p10, p1, "p10", "p1", "Polygon's with nested holes"), + (p12, p13, "p12", "p13", "Polygons only intersect at vertices, but intersect and overlap"), # Multigeometries (mpt1, mpt1, "mpt1", "mpt1", "Same set of points for multipoints"), (mpt1, mpt2, "mpt1", "mpt2", "Some point matches, others are different"),