google / s2geometry

Computational geometry and spatial indexing on the sphere
http://s2geometry.io/
Apache License 2.0
2.29k stars 302 forks source link

What is correct way to find point intersects with polygon? #306

Closed MBkkt closed 1 year ago

MBkkt commented 1 year ago

I thought polygon.Contains(polygon) should work.

But I saw cockroachdb code which use a.IntersectsCell(s2.CellFromPoint(vertex))

So now I'm not sure...

smcallis commented 1 year ago

You want to find out whether a polygon contains a point? S2Polygon::Contains or if you have an indexed shape, then s2contains_point_query. I'm not sure what those cockroachdb functions are from but it looks like they're creating a level 30 cell from a point and seeing if a intersects that which is a different request.

MBkkt commented 1 year ago

In many database geo indexes exist at least two types of supported operations: intersects, contains

It looks like correct way to determine polygon contains point just use such method.

But no exist method for the intersects, I thought polygon.intersects(point) should be equivalent polygon.contains(point).

But from other side, I don't sure about polygon borders, should they count or not?

Also today I saw cockroachdb code for polygon.intersects(point) (I understand it as same as you) and now I wondering, what is approach better suited for my purposes:

  1. Make it correct (it mostly means corresponding to other operation), have same behavior for different data
  2. Make it intuitive and useful (something like always false is not needed)
smcallis commented 1 year ago

Usually these database operations try to follow (mostly) the OGC simple features specification here. They define the semantics for contains and intersects. Intersects is pretty easy, polygon vertices and interior points would count for the intersection.

Contains is harder, because they have to have at least one point in common in the interior. Under that definition, polygon vertices would not count for a point, only interior points. Instead most people want the Covers predicate which doesn't have that quirk, it works they way most people want Contains to work so many databases use that behavior instead.

MBkkt commented 1 year ago

Thanks, I will read but if we return to S2:

If I understand correctly:

  1. S2Polygon.Contains(S2Point) return true for point in polygon, and for point which is one of loop points but return false for other (like loop edges point)
  2. S2LaxPolygon with S2ShapeIndex can work in closet border model?

What about 30 level cell intersects? Of course it's not really "point", something like small (cm^2) square.

But is edges of border count or not? (Maybe it's not important because is something like S2Cap(point, some epsilon), so if it's not intersects point also cannot intersects)

smcallis commented 1 year ago

We don't really have points on edges in S2, since edges are just implied by the vertices. S2Polygon.Contains will tell you one way or another whether a point is contained accurately. Points near an edge will fall back to symbolic perturbation if necessary to give an answer.

Using S2ContainsPointQuery yes you'd use the closed vertex model which includes the vertices, but the same logic as above will apply to edges.

You can use the level 30 cell technique, but polygon/cell intersection will be more expensive and it's not exact like the above techniques.

MBkkt commented 1 year ago

Thanks!