#17635: Missing ability to cast georaphy to geometry when using GeoDjango and
PostgresSQL
-------------------------------------+-------------------------------------
Reporter: corentin.chary@… | Owner: nobody
Type: New feature | Status: new
Component: GIS | Version: SVN
Severity: Normal | Resolution:
Keywords: | Triage Stage: Design
Has patch: 0 | decision needed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by aaugustin):
* needs_better_patch: => 0
* needs_docs: => 0
* needs_tests: => 0
* stage: Unreviewed => Design decision needed
Old description:
> Looking at
> http://postgis.refractions.net/docs/ch08.html#PostGIS_TypeFunctionMatrix
> you will see that a lot of functions only work on geometric fields (ie:
> geography=False).
>
> That means something like Markers.objects.extent() won't work if the
> coordinate field of Marker have geography set to True because the
> underlying function (ST_Extent()) only work with geometric fields.
>
> A workaround (if you don't really care about precision) is to cast
> geography to geometry:
>
> SELECT ST_Extent(coordinates::geometry) FROM markers;
>
> That will perfectly work. However, you can't really do that with django.
> The best you can do seems to be:
>
> qs.extra(select={'extent':
> 'ST_Extent("coordinates"::geometry)'}).values('extent')
>
> But that's really far from perfect.
>
> Here are some propositions:
> - add a way to cast to geometry, that would allow to do:
> qs.extent(field_name=coordinates__geometry) (the trailing __geometry cast
> a GeometryField from geography to geometry)
> - another way to cast to geometry would be:
> qs.geometry('coordinates').extent()
> - automatically cast geography to geometry if a function only support
> geometry (hum...)
New description:
Looking at
http://postgis.refractions.net/docs/ch08.html#PostGIS_TypeFunctionMatrix
you will see that a lot of functions only work on geometric fields (ie:
geography=False).
That means something like Markers.objects.extent() won't work if the
coordinate field of Marker have geography set to True because the
underlying function (ST_Extent()) only work with geometric fields.
A workaround (if you don't really care about precision) is to cast
geography to geometry:
SELECT ST_Extent(coordinates::geometry) FROM markers;
That will perfectly work. However, you can't really do that with django.
The best you can do seems to be:
qs.extra(select={'extent':
'ST_Extent("coordinates"::geometry)'}).values('extent')
But that's really far from perfect.
Here are some propositions:
- add a way to cast to geometry, that would allow to do:
`qs.extent(field_name=coordinates__geometry)` (the trailing `__geometry`
cast a GeometryField from geography to geometry)
- another way to cast to geometry would be:
`qs.geometry('coordinates').extent()`
- automatically cast geography to geometry if a function only support
geometry (hum...)
--
Comment:
I've encountered the same problem (with `point_on_surface` and `envelope`)
and I didn't even manage to resolve it with Django's public APIs.
Here's what I ended up with:
{{{
class ZoneManager(gis_models.GeoManager):
def point_on_surface_and_envelope(self):
# Use a private API to adapt point_on_surface and envelope for a
# geographic field. See
django.contrib.gis.db.models.query.GeoQuerySet.
return self.all()._spatial_attribute('point_on_surface', {
'select_field' : GeomField(),
'procedure_fmt': '%(geo_col)s::geometry', # added
'::geometry'
})._spatial_attribute('envelope', {
'select_field' : GeomField(),
'procedure_fmt': '%(geo_col)s::geometry', # added
'::geometry'
})
}}}
Maybe I should have started with geometry fields instead of geography
fields, but I didn't expect to need these functions...
-----
While I'm interested in a solution to this problem, I'm not convinced we
should allow these kind of approximations.
Marking as DDN for now, the GIS maintainer may have a stronger opinion on
this matter.
--
Ticket URL: <https://code.djangoproject.com/ticket/17635#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.