Author: jbronn
Date: 2009-09-13 12:40:46 -0500 (Sun, 13 Sep 2009)
New Revision: 11577

Modified:
   django/trunk/django/contrib/gis/db/models/sql/aggregates.py
   django/trunk/django/contrib/gis/tests/geoapp/test_regress.py
Log:
Fixed #11827: Can now calculate extent in Oracle on tables with one point.


Modified: django/trunk/django/contrib/gis/db/models/sql/aggregates.py
===================================================================
--- django/trunk/django/contrib/gis/db/models/sql/aggregates.py 2009-09-13 
17:04:47 UTC (rev 11576)
+++ django/trunk/django/contrib/gis/db/models/sql/aggregates.py 2009-09-13 
17:40:46 UTC (rev 11577)
@@ -16,7 +16,7 @@
 
 if SpatialBackend.postgis:
     def convert_extent(box):
-        # Box text will be something like "BOX(-90.0 30.0, -85.0 40.0)"; 
+        # Box text will be something like "BOX(-90.0 30.0, -85.0 40.0)";
         # parsing out and returning as a 4-tuple.
         ll, ur = box[4:-1].split(',')
         xmin, ymin = map(float, ll.split())
@@ -32,19 +32,28 @@
 
     def convert_extent(clob):
         if clob:
-            # Oracle returns a polygon for the extent, we construct
-            # the 4-tuple from the coordinates in the polygon.
-            poly = SpatialBackend.Geometry(clob.read())
-            shell = poly.shell
-            ll, ur = shell[0], shell[2]
+            # Generally, Oracle returns a polygon for the extent -- however,
+            # it can return a single point if there's only one Point in the
+            # table.
+            ext_geom = SpatialBackend.Geometry(clob.read())
+            gtype = str(ext_geom.geom_type)
+            if gtype == 'Polygon':
+                # Construct the 4-tuple from the coordinates in the polygon.
+                shell = ext_geom.shell
+                ll, ur = shell[0][:2], shell[2][:2]
+            elif gtype == 'Point':
+                ll = ext_geom.coords[:2]
+                ur = ll
+            else:
+                raise Exception('Unexpected geometry type returned for extent: 
%s' % gtype)
             xmin, ymin = ll
             xmax, ymax = ur
             return (xmin, ymin, xmax, ymax)
         else:
             return None
-    
+
     def convert_geom(clob, geo_field):
-        if clob: 
+        if clob:
             return SpatialBackend.Geometry(clob.read(), geo_field.srid)
         else:
             return None
@@ -73,7 +82,7 @@
             self.extra.setdefault('tolerance', 0.05)
 
         # Can't use geographic aggregates on non-geometry fields.
-        if not isinstance(self.source, GeometryField): 
+        if not isinstance(self.source, GeometryField):
             raise ValueError('Geospatial aggregates only allowed on geometry 
fields.')
 
         # Making sure the SQL function is available for this spatial backend.
@@ -87,7 +96,7 @@
 class Extent(GeoAggregate):
     is_extent = True
     sql_function = SpatialBackend.extent
-        
+
 if SpatialBackend.oracle:
     # Have to change Extent's attributes here for Oracle.
     Extent.conversion_class = GeomField

Modified: django/trunk/django/contrib/gis/tests/geoapp/test_regress.py
===================================================================
--- django/trunk/django/contrib/gis/tests/geoapp/test_regress.py        
2009-09-13 17:04:47 UTC (rev 11576)
+++ django/trunk/django/contrib/gis/tests/geoapp/test_regress.py        
2009-09-13 17:40:46 UTC (rev 11577)
@@ -1,6 +1,6 @@
 import os, unittest
 from django.contrib.gis.db.backend import SpatialBackend
-from django.contrib.gis.tests.utils import no_mysql, no_oracle, no_postgis
+from django.contrib.gis.tests.utils import no_mysql, no_oracle, no_postgis, 
no_spatialite
 from django.contrib.gis.shortcuts import render_to_kmz
 from models import City
 
@@ -27,3 +27,9 @@
                   }]
         kmz = render_to_kmz('gis/kml/placemarks.kml', {'places' : places})
 
+    @no_spatialite
+    def test03_extent(self):
+        "Testing `extent` on a table with a single point, see #11827."
+        pnt = City.objects.get(name='Pueblo').point
+        ref_ext = (pnt.x, pnt.y, pnt.x, pnt.y)
+        self.assertEqual(ref_ext, City.objects.filter(name='Pueblo').extent())


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to