Am I correct? If so, I may attempt a patch or at least a workaround.
Thanks!
Ref: http://postgis.net/docs/manual-1.3/ch06.html#ST_OrderingEquals
--
Ticket URL: <https://code.djangoproject.com/ticket/25446>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
Old description:
> Unless I'm missing something, Django 1.8 provides no facility in the ORM
> to use the ST_OrderingEquals() function to compare two geometries. I
> would like to use this function in a query.
>
> Am I correct? If so, I may attempt a patch or at least a workaround.
>
> Thanks!
>
> Ref: http://postgis.net/docs/manual-1.3/ch06.html#ST_OrderingEquals
New description:
Unless I'm missing something, Django 1.8 provides no facility in the ORM
to use the ST_OrderingEquals() function to compare two geometries. I would
like to use this function in a query.
Am I correct? If so, I may attempt a patch or at least a workaround.
Thanks!
Ref: http://postgis.net/docs/manual-1.3/ch06.html#ST_OrderingEquals
P.S. It's another question entirely whether the '__exact' lookup should
use this function. For comparison, two LineString objects with opposite
vertex ordering are not considered equal, so why should they be considered
equal at the DB level?
--
Comment:
For other users who may find this, here's my workaround that allows me to
find the geometry that matches an input geometry, both in vertex values
and in vertex ordering. A Django wizard may be able to improve this and I
would welcome any criticism.
{{{
class SegmentModel(models.Model):
...
@classmethod
def get_or_create_for_line(cls, line):
from django.contrib.gis.db.backends.postgis.adapter import
PostGISAdapter
sql = 'SELECT * FROM ride_segment WHERE line ~= {line_serialized}
AND ST_OrderingEquals(line, {line_serialized})'.format(
line_serialized=str(PostGISAdapter(line)))
segments = list(cls.objects.raw(sql))
if len(segments) > 1:
from django.db import IntegrityError
raise IntegrityError('Multiple segments for line
{}'.format(line.ewkt))
elif len(segments) == 0:
return (True, cls.objects.create(line=line))
else:
return (False, segments[0])
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25446#comment:1>
* version: 1.8 => master
* type: Bug => New feature
* stage: Unreviewed => Accepted
Comment:
You are right in that GeoDjango doesn't support this lookup. In Django
1.9, GIS lookups/functions have seen many refactorings which should allow
you to more easily add your own lookups.
While studying your use case, I've seen a limitation in current lookup
implementation (#25448). After fixing this one, you should be able to add
your custom lookup like this (not portable way):
{{{
from django.contrib.gis.db.models import GeometryField
from django.contrib.gis.db.models.lookups import GisLookup
class OrderingEqualsLookup(GISLookup):
lookup_name = 'ST_OrderingEquals'
GeometryField.register_lookup(OrderingEqualsLookup)
}}}
For Django 1.8, keep your workaround...
We should at least document that.
--
Ticket URL: <https://code.djangoproject.com/ticket/25446#comment:2>
Comment (by ezheidtmann):
Thank you! I updated the workaround to fix a couple edge cases. And I will
look forward to 1.9.
While we're on the topic, what do you think about changing the "exact"
lookup to use ST_OrderingEquals? This would match the behavior of GEOS
LineString objects but I am not sure of the broader implications of that
change. Perhaps SpatiaLite does not offer an equivalent, so we cannot bake
it into Django?
Thanks,
-Evan
--
Ticket URL: <https://code.djangoproject.com/ticket/25446#comment:3>
Comment (by claudep):
It may make sense. I do recognize that using the bounding box comparison
for `exact` (~= PostGIS operator) is at least misleading... A cross-
backends summary would be nice. But as usual, the backwards compatibility
is important, we cannot suddenly change the operator used by a comparison.
Read also http://workshops.boundlessgeo.com/postgis-intro/equality.html
--
Ticket URL: <https://code.djangoproject.com/ticket/25446#comment:4>