Opened 10 years ago
Last modified 2 years 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 , 10 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 10 years ago
comment:3 by , 10 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 , 9 years ago
| Cc: | added |
|---|
comment:5 by , 3 years 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 , 2 years 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 , 2 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
I began by checking if the
Pointobject had the magic method__eq__.https://github.com/django/django/blob/master/django/contrib/gis/geos/point.py#L10
The
Pointobjects inheritsGEOSGeometrywhich 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_exactofGEOSGeometry.https://github.com/django/django/blob/master/django/contrib/gis/geos/geometry.py#L317
This calls
geos_equalsexacton 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.