Opened 8 years ago
Closed 8 years ago
#27971 closed Bug (invalid)
GeoDjango LinearRing and Polygon handle contains/covers differently
Reported by: | Geoffrey Fairchild | Owned by: | nobody |
---|---|---|---|
Component: | GIS | Version: | 1.10 |
Severity: | Normal | Keywords: | GeoDjango, LinearRing, Polygon, covers, contains |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I'm running Python 3.6.0 and Django 1.10.6. I'm seeing a difference in how the LinearRing and Polygon types deal with the contains and covers methods. The gist is that LinearRing
objects seem not to properly handle contains
/covers
, while Polygon
objects do. See the following example:
> python Python 3.6.0 (default, Mar 6 2017, 11:41:46) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from django.contrib.gis.geos import GEOSGeometry >>> aruba = GEOSGeometry('SRID=4326;LINEARRING (-69.89912109375 12.45200195312499, -69.895703125 12.42299804687499, -69.94218749999999 12.43852539062499, -70.004150390625 12.50048828125, -70.06611328125 12.54697265624999, -70.05087890624999 12.59707031249999, -70.035107421875 12.61411132812499, -69.97314453125 12.567626953125, -69.91181640625 12.48046875, -69.89912109375 12.45200195312499)') >>> print(aruba) SRID=4326;LINEARRING (-69.89912109375 12.45200195312499, -69.895703125 12.42299804687499, -69.94218749999999 12.43852539062499, -70.004150390625 12.50048828125, -70.06611328125 12.54697265624999, -70.05087890624999 12.59707031249999, -70.035107421875 12.61411132812499, -69.97314453125 12.567626953125, -69.91181640625 12.48046875, -69.89912109375 12.45200195312499) >>> point = GEOSGeometry('POINT (-69.95647745161588 12.48564548990554)') >>> print(point) POINT (-69.95647745161588 12.48564548990554) >>> aruba.contains(point) False >>> aruba.covers(point) False >>> aruba = GEOSGeometry('SRID=4326;POLYGON ((-69.89912109375 12.45200195312499, -69.895703125 12.42299804687499, -69.94218749999999 12.43852539062499, -70.004150390625 12.50048828125, -70.06611328125 12.54697265624999, -70.05087890624999 12.59707031249999, -70.035107421875 12.61411132812499, -69.97314453125 12.567626953125, -69.91181640625 12.48046875, -69.89912109375 12.45200195312499))') >>> print(aruba) SRID=4326;POLYGON ((-69.89912109375 12.45200195312499, -69.895703125 12.42299804687499, -69.94218749999999 12.43852539062499, -70.004150390625 12.50048828125, -70.06611328125 12.54697265624999, -70.05087890624999 12.59707031249999, -70.035107421875 12.61411132812499, -69.97314453125 12.567626953125, -69.91181640625 12.48046875, -69.89912109375 12.45200195312499)) >>> aruba.contains(point) True >>> aruba.covers(point) True
For what it's worth, while writing this issue, I just discovered that Shapely, which also relies on GEOS, displays the same behavior:
> python Python 3.6.0 (default, Mar 6 2017, 11:41:46) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from shapely.geometry.polygon import LinearRing, Polygon >>> from shapely.geometry import Point >>> aruba = LinearRing([(-69.89912109375, 12.45200195312499), (-69.895703125, 12.42299804687499), (-69.94218749999999, 12.43852539062499), (-70.004150390625, 12.50048828125), (-70.06611328125, 12.54697265624999), (-70.05087890624999, 12.59707031249999), (-70.035107421875, 12.61411132812499), (-69.97314453125, 12.567626953125), (-69.91181640625, 12.48046875), (-69.89912109375, 12.45200195312499)]) >>> print(aruba) LINEARRING (-69.89912109375 12.45200195312499, -69.895703125 12.42299804687499, -69.94218749999999 12.43852539062499, -70.004150390625 12.50048828125, -70.06611328125 12.54697265624999, -70.05087890624999 12.59707031249999, -70.035107421875 12.61411132812499, -69.97314453125 12.567626953125, -69.91181640625 12.48046875, -69.89912109375 12.45200195312499) >>> point = Point(-69.95647745161588, 12.48564548990554) >>> print(point) POINT (-69.95647745161588 12.48564548990554) >>> aruba.contains(point) False >>> aruba = Polygon([(-69.89912109375, 12.45200195312499), (-69.895703125, 12.42299804687499), (-69.94218749999999, 12.43852539062499), (-70.004150390625, 12.50048828125), (-70.06611328125, 12.54697265624999), (-70.05087890624999, 12.59707031249999), (-70.035107421875, 12.61411132812499), (-69.97314453125, 12.567626953125), (-69.91181640625, 12.48046875), (-69.89912109375, 12.45200195312499)]) >>> print(aruba) POLYGON ((-69.89912109375 12.45200195312499, -69.895703125 12.42299804687499, -69.94218749999999 12.43852539062499, -70.004150390625 12.50048828125, -70.06611328125 12.54697265624999, -70.05087890624999 12.59707031249999, -70.035107421875 12.61411132812499, -69.97314453125 12.567626953125, -69.91181640625 12.48046875, -69.89912109375 12.45200195312499)) >>> aruba.contains(point) True
Is this a bug (perhaps a GEOS bug since both Shapely and GeoDjango display the same behavior), or is this to be expected (i.e., am I misunderstanding some fundamental concept about LinearRing
s)?
Change History (2)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
LinearRing is a line, so it doesn't contain or cover the specified point.
Look at http://bl.ocks.org/d/51034db6faf00af30734b1e7e1b2bf03
Search results for this topic seem sparse. Interestingly, I can compute centroids for both LinearRings and Polygons:
If I can compute a centroid, why can't I compute whether another geometry is interior to the LinearRing?