﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
27971	GeoDjango LinearRing and Polygon handle contains/covers differently	Geoffrey Fairchild	nobody	"I'm running Python 3.6.0 and Django 1.10.6. I'm seeing a difference in how the [[https://docs.djangoproject.com/en/1.10/ref/contrib/gis/geos/#linearring|LinearRing]] and [[https://docs.djangoproject.com/en/1.10/ref/contrib/gis/geos/#polygon|Polygon]] types deal with the [[https://docs.djangoproject.com/en/1.10/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry.contains|contains]] and [[https://docs.djangoproject.com/en/1.10/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry.covers|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)?"	Bug	closed	GIS	1.10	Normal	invalid	GeoDjango, LinearRing, Polygon, covers, contains		Unreviewed	0	0	0	0	0	0
