Reputation: 95
I have a polygon as a string in wkt format:
polygon_as_string = 'POLYGON ((1190500.159499999 7144386.067199998, 1190487.2751 7144390.519699998,...,1190500.159499999 7144386.067199998))'
which I convert to a Shapely's Polygon
object:
import shapely.wkt
polygon = shapely.wkt.loads(polygon_as_string)
Then I check with within()
or with contains()
functions whether the point is in my polygon.
from shapely.geometry import Point, Polygon
point = Point(1190500.159499999, 7144386.067199998)
polygon.contains(point)
point.within(polygon)
Both functions return False
although I take the point which is actually inside of the polygon
.
What could be wrong here?
Upvotes: 2
Views: 3619
Reputation: 13697
You are using the wrong predicate to check if a point is inside or on the boundary of a polygon.
From documentation on contains
(which is inverse of within
):
object.contains(other)
ReturnsTrue
if no points of other lie in the exterior of the object and at least one point of the interior of other lies in the interior of object.
Instead, as your point lies on the boundary, you should use intersects
:
object.intersects(other)
ReturnsTrue
if the boundary or interior of the object intersect in any way with those of the other.In other words, geometric objects intersect if they have any boundary or interior point in common.
(emphasis mine).
>>> from shapely.geometry import Point, Polygon
>>> Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]).contains(Point(1, 1))
False
>>> Point(1, 1).within(Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]))
False
>>> Point(1, 1).intersects(Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]))
True
Note, however, that due to precision errors you indeed can have an unexpected result:
>>> Point(2/3, 2).intersects(Polygon([(0, 0), (1, 0), (1, 3)]))
False
>>> Point(2/3, 2).distance(Polygon([(0, 0), (1, 0), (1, 3)]))
>>> 0.0
In cases like this you might consider either checking the distance to the polygon as shown above, or dilating your polygon a bit using buffer
:
>>> Point(2/3, 2).intersects(Polygon([(0, 0), (1, 0), (1, 3)]).buffer(1e-9))
True
Upvotes: 10
Reputation: 1163
The reason could be that the point you are testing sits exactly on top of one of the vertices and due to rounding errors, the point actually moves a little bit and is not on the edge of the polygon anymore.
To check this hypothesis, try to move the test point a little bit towards the center of the polygon.
Upvotes: 0