Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.1.X] Fixed #11827: Can now calculate extent in Oracle on tables wi…

…th one point.

Backport of r11577 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@11578 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 6febb7ef1584b73d24b079463057740c98cddfb3 1 parent ba925de
Justin Bronn authored September 13, 2009
29  django/contrib/gis/db/models/sql/aggregates.py
@@ -16,7 +16,7 @@ def convert_geom(wkt, geo_field):
16 16
 
17 17
 if SpatialBackend.postgis:
18 18
     def convert_extent(box):
19  
-        # Box text will be something like "BOX(-90.0 30.0, -85.0 40.0)"; 
  19
+        # Box text will be something like "BOX(-90.0 30.0, -85.0 40.0)";
20 20
         # parsing out and returning as a 4-tuple.
21 21
         ll, ur = box[4:-1].split(',')
22 22
         xmin, ymin = map(float, ll.split())
@@ -32,19 +32,28 @@ def convert_geom(hex, geo_field):
32 32
 
33 33
     def convert_extent(clob):
34 34
         if clob:
35  
-            # Oracle returns a polygon for the extent, we construct
36  
-            # the 4-tuple from the coordinates in the polygon.
37  
-            poly = SpatialBackend.Geometry(clob.read())
38  
-            shell = poly.shell
39  
-            ll, ur = shell[0], shell[2]
  35
+            # Generally, Oracle returns a polygon for the extent -- however,
  36
+            # it can return a single point if there's only one Point in the
  37
+            # table.
  38
+            ext_geom = SpatialBackend.Geometry(clob.read())
  39
+            gtype = str(ext_geom.geom_type)
  40
+            if gtype == 'Polygon':
  41
+                # Construct the 4-tuple from the coordinates in the polygon.
  42
+                shell = ext_geom.shell
  43
+                ll, ur = shell[0][:2], shell[2][:2]
  44
+            elif gtype == 'Point':
  45
+                ll = ext_geom.coords[:2]
  46
+                ur = ll
  47
+            else:
  48
+                raise Exception('Unexpected geometry type returned for extent: %s' % gtype)
40 49
             xmin, ymin = ll
41 50
             xmax, ymax = ur
42 51
             return (xmin, ymin, xmax, ymax)
43 52
         else:
44 53
             return None
45  
-    
  54
+
46 55
     def convert_geom(clob, geo_field):
47  
-        if clob: 
  56
+        if clob:
48 57
             return SpatialBackend.Geometry(clob.read(), geo_field.srid)
49 58
         else:
50 59
             return None
@@ -73,7 +82,7 @@ def __init__(self, col, source=None, is_summary=False, **extra):
73 82
             self.extra.setdefault('tolerance', 0.05)
74 83
 
75 84
         # Can't use geographic aggregates on non-geometry fields.
76  
-        if not isinstance(self.source, GeometryField): 
  85
+        if not isinstance(self.source, GeometryField):
77 86
             raise ValueError('Geospatial aggregates only allowed on geometry fields.')
78 87
 
79 88
         # Making sure the SQL function is available for this spatial backend.
@@ -87,7 +96,7 @@ class Collect(GeoAggregate):
87 96
 class Extent(GeoAggregate):
88 97
     is_extent = True
89 98
     sql_function = SpatialBackend.extent
90  
-        
  99
+
91 100
 if SpatialBackend.oracle:
92 101
     # Have to change Extent's attributes here for Oracle.
93 102
     Extent.conversion_class = GeomField
8  django/contrib/gis/tests/geoapp/test_regress.py
... ...
@@ -1,6 +1,6 @@
1 1
 import os, unittest
2 2
 from django.contrib.gis.db.backend import SpatialBackend
3  
-from django.contrib.gis.tests.utils import no_mysql, no_oracle, no_postgis
  3
+from django.contrib.gis.tests.utils import no_mysql, no_oracle, no_postgis, no_spatialite
4 4
 from django.contrib.gis.shortcuts import render_to_kmz
5 5
 from models import City
6 6
 
@@ -27,3 +27,9 @@ def test02_kmz(self):
27 27
                   }]
28 28
         kmz = render_to_kmz('gis/kml/placemarks.kml', {'places' : places})
29 29
 
  30
+    @no_spatialite
  31
+    def test03_extent(self):
  32
+        "Testing `extent` on a table with a single point, see #11827."
  33
+        pnt = City.objects.get(name='Pueblo').point
  34
+        ref_ext = (pnt.x, pnt.y, pnt.x, pnt.y)
  35
+        self.assertEqual(ref_ext, City.objects.filter(name='Pueblo').extent())

0 notes on commit 6febb7e

Please sign in to comment.
Something went wrong with that request. Please try again.