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 Bhargav Kowshik)

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 Bhargav Kowshik, 9 years ago

Description: modified (diff)

comment:2 by Bhargav Kowshik, 9 years ago

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 inherits GEOSGeometry 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 of GEOSGeometry.
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.

comment:3 by Claude Paroz, 9 years ago

Triage Stage: UnreviewedAccepted
Version: 1.7master

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 Olivier Tabone, 8 years ago

Cc: olivier.tabone@… added

comment:5 by Claude Paroz, 19 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 Olivier Tabone, 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:7 by Claude Paroz, 16 months ago

Looks like a good plan to me!

comment:8 by Olivier Tabone, 16 months ago

Owner: changed from nobody to Olivier Tabone
Status: newassigned

comment:9 by Olivier Tabone, 16 months ago

ticket for GEOSGeometryBase.equals_identical() implementation: #34739

Note: See TracTickets for help on using tickets.
Back to Top