Opened 9 years ago
Last modified 16 months ago
#25342 assigned Bug
Altitude of Point object for equality check
Reported by: | Bhargav Kowshik | Owned by: | Olivier Tabone |
---|---|---|---|
Component: | GIS | Version: | dev |
Severity: | Normal | Keywords: | geodjango, equality |
Cc: | olivier.tabone@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Checking equality of two django.contrib.gis.geos.Point objects does not take into consideration the altitude of the point.
from django.contrib.gis.geos import Point p1 = Point(x=1, y=1, z=1, srid=4326) print p1 == p1 # True p2 = Point(x=1.1, y=1, z=1, srid=4326) print p1 == p2 # False p3 = Point(x=1, y=1, z=2, srid=4326) print p1 == p3 # True. Is this a bug?
Change History (9)
comment:1 by , 9 years ago
Description: | modified (diff) |
---|
comment:2 by , 9 years ago
comment:3 by , 9 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Version: | 1.7 → master |
This is most probably a GEOS issue, where the Z dimension support is rather new.
Keeping open until we find where the problem really lies.
Here is some interesting GEOS code:
https://svn.osgeo.org/geos/trunk/src/geom/
comment:4 by , 8 years ago
Cc: | added |
---|
comment:5 by , 20 months ago
GEOS is going to introduce a new API for a comparison considering a possible 3rd dimension (GEOSEqualsIdentical
) to not break backwards compatibility. It will be included in the not-yet-released GEOS 3.12.0.
https://github.com/libgeos/geos/commit/85a1779e18
We will have to decide at some point if we want to break (and document) backwards compatibility by using the new API in the basic equality operator, or introduce a new API too.
comment:6 by , 16 months ago
Prior 3.12.0, GEOS already has multiple equality functions:
GEOSEquals
(which uses topological equality, returning true for different representations of the same structure)GEOSEqualsExact
(which uses pointwise equality, but allows for a distance tolerance and ignores Z/M values)
currently, django uses GEOSEqualsExact in the __eq__() method which is not a good fit regarding equality semantics when z is used (thus this ticket).
GEOSEquals()
does not work in 3D as documented which is not a good fit regarding equality semantics either.
GEOS 3.12 introduces GEOSEqualsIdentical
which is a good fit for python's equality semantic in 2D and 3D.
I would suggest:
- implementing the
GEOSGeometryBase.equals_identical()
method, available if GEOS >= 3.12.0. That should be an easy call, pure additive. (new ticket ?) - raising a warning if
GEOSGeometryBase.__eq__()
is called with one operand having a third dimension (geom.hasZ == True
). To fix this warning, one should either use an explicit comparaison method (GEOSGeometryBase.equals()
,GEOSGeometryBase.equals_exact()
,GEOSGeometryBase.equals_identical()
) or use a 2D point. - when GEOS 3.12 becomes the minimum supported version, use GEOSEqualsIdentical to perform
GEOSGeometryBase.__eq__()
. This will give some time for one to adapt their code bases.
What do you think ?
comment:8 by , 16 months ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
I began by checking if the
Point
object had the magic method__eq__
.https://github.com/django/django/blob/master/django/contrib/gis/geos/point.py#L10
The
Point
objects inheritsGEOSGeometry
which in-turn has the magic method__eq__
.https://github.com/django/django/blob/master/django/contrib/gis/geos/geometry.py#L166
This in-turn calls
equals_exact
ofGEOSGeometry
.https://github.com/django/django/blob/master/django/contrib/gis/geos/geometry.py#L317
This calls
geos_equalsexact
on the page below.https://github.com/django/django/blob/8047e3666b0b50bb04e6f16c2a4fb21ddfd5713f/django/contrib/gis/geos/prototypes/predicates.py#L36
I don't understand what happens after this.