Opened 8 years ago

Closed 7 years ago

#26920 closed Cleanup/optimization (fixed)

GEOSGeometry objects compare equal despite different SRID

Reported by: Raphael Das Gupta Owned by: nobody
Component: GIS Version: dev
Severity: Normal Keywords: geodjango, equality
Cc: Sergey Fedoseev, Claude Paroz, jackie.leng@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Raphael Das Gupta)

Checking equality of two django.contrib.gis.geos.Point objects (and presumably any other GEOSGeometry objects of equal type) does not take the geometries' SRIDs into consideration:

from django.contrib.gis.geos import Point

p0 = Point(5, 23)  # SRID implicitly None
p1 = Point(5, 23, srid=4326)
p2 = Point(5, 23, srid=32632)

assert p0.srid != p1.srid  # passes
assert p0.srid != p2.srid  # passes
assert p1.srid != p2.srid  # passes

assert p0 != p1  # AssertionError
assert p0 != p2  # AssertionError
assert p1 != p2  # AssertionError

The semantic of coordinates depends completely on the spatial reference system. The same numbers refer to completely different positions when interpreted in different coordinate systems. Therefore, I think the geometries should compare unequal if both have an SRID set and those SRIDs are different. Not sure what should happen when comparing geometries where exactly one of them has an SRID.

If the currently observed behaviour is the intended one (or if it is retained for backwards compatibility reasons), the documentation should point that out. It already points out that the "Equality operator doesn’t check spatial equality", but to me that only made clear that spatial equality does not imply GEOSGeometry object equality, but not that neither does GEOSGeometry object equality imply spatial equality. Also, equals(), which is mentioned in that admonition as an alternative, doesn't seem to care about SRID, either:

assert not p0.equals(p1)  # AssertionError
assert not p0.equals(p2)  # AssertionError
assert not p1.equals(p2)  # AssertionError

Change History (9)

comment:1 by Raphael Das Gupta, 8 years ago

Description: modified (diff)

comment:2 by Raphael Das Gupta, 8 years ago

Like with #25342, the behaviour of the == operator reflects that of the underlying `equalsExact` method (implementation for Point here; each geometry type seems to have its own implementation), but I'm not sure it should reflect that behaviour in this regard (ignoring the SRID), too.

comment:3 by Tim Graham, 8 years ago

Cc: Sergey Fedoseev Claude Paroz added

Claude and/or Sergey, can you advise?

comment:4 by Tim Graham, 8 years ago

Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization

Not sure about the appropriate resolution (maybe start a discussion on the geodjango mailing list if needed). Accepting the ticket at least on a documentation basis if there's no consensus to make code changes.

comment:5 by Jackie Leng, 7 years ago

Cc: jackie.leng@… added
Has patch: set
Version: 1.9master

I've submitted a patch for this issue: https://github.com/django/django/pull/7507. With this patch the equality check will take into account the srid (both for GEOSGeometry and EWKT).

comment:6 by Tim Graham, 7 years ago

Patch needs improvement: set

There are some test failures on MySQL. Even though this might be considered a bug fix, I wonder if it's a good candidate for mention in the release notes as a possible backwards-incompatible change?

comment:7 by Jackie Leng, 7 years ago

Patch needs improvement: unset

Added requested changes, but there is failure on Oracle.

comment:8 by Tim Graham, 7 years ago

Triage Stage: AcceptedReady for checkin

Looks good, pending a +1 from a GIS expert.

comment:9 by Claude Paroz <claude@…>, 7 years ago

Resolution: fixed
Status: newclosed

In 50613d95:

Fixed #26920 -- Made GEOSGeometry equality check consider the srid

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