Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IntersectionMatrix::is_covers() seems to be wrong? #1264

Closed
pkerichang opened this issue Nov 6, 2024 · 5 comments
Closed

IntersectionMatrix::is_covers() seems to be wrong? #1264

pkerichang opened this issue Nov 6, 2024 · 5 comments

Comments

@pkerichang
Copy link

So I have this simple test case, which fails:

#[test]
fn covers() {
    let box_1: Rect<f64> = Rect::new(Coord { x: -5.0, y: -4.0 }, Coord { x: 0.0, y: 0.0 });
    let box_2: Rect<f64> = Rect::new(Coord { x: -4.0, y: -4.0 }, Coord { x: -1.0, y: -4.0 });

    assert!(relate::Relate::relate(&box_1, &box_2).is_covers());
}

So box_2 is a 0-area rectangle (a degenerated line) that lies completely on the boundary of box_1. From the definition of "covers" on both the DE-9IM wiki article and also the georust documentation, it seems like this should return true, but currently it returns false.

Curiously, if box_2 is a point like Rect::new(Coord { x: -4.0, y: -4.0 }, Coord { x: --4.0, y: -4.0 }) instead, then is_covers() does return true. What's going on here?

@urschrei
Copy link
Member

urschrei commented Nov 6, 2024

JTS doesn't think covers is true either:

input:

POLYGON ((-5 -4, 0 -4, 0 0, -5 0, -5 -4))
POLYGON ((-4 -4, -3 -4, -2 -4, -1 -4, -4 -4))

Screenshot 2024-11-06 at 11 51 37

Could you verify that the polygon points I used to reproduce the geometries match yours? You may have to call to_polygon() and then print them.

@pkerichang
Copy link
Author

pkerichang commented Nov 6, 2024 via email

@urschrei
Copy link
Member

urschrei commented Nov 6, 2024

This is related to the fact that it's a Polygon and degenerate (though I can't find a reference at the moment); if you change the second geometry to a LineString:

LINESTRING (-4 -4, -3 -4, -2 -4, -1 -4)

The covers predicate is what you expect (true).

PostGIS (so GEOS) reproduces the same false predicate:

WITH poly1 AS (
    SELECT ST_GeomFromText('POLYGON ((-5 -4, 0 -4, 0 0, -5 0, -5 -4))') AS geom1
),
poly2 AS (
    SELECT ST_GeomFromText('POLYGON ((-4 -4, -3 -4, -2 -4, -1 -4, -4 -4))') AS geom2
)
SELECT ST_Covers(p1.geom1, p2.geom2) AS is_covering
FROM poly1 p1, poly2 p2;

@michaelkirk
Copy link
Member

For my own feeble brain, I simplified the case and drew it up.

IMG_4807

geo (mostly) follows OGC validity.

Rings may not self-intersect (they may neither touch nor cross themselves).

So this is an invalid polygon, and I don't really expect Topology algorithms to work with invalid geometries.

One work around for you would be to use HasDimensions::dimensions to detect degenerate Rects, and if encountered, convert it to a LineString and run Relate on that.

@urschrei
Copy link
Member

urschrei commented Nov 6, 2024

For some reason JTS didn't make it obvious that Polygon B was invalid, but yes that's very much the issue. I'm going to close this.

@urschrei urschrei closed this as completed Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants