#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.

Reply via email to