summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/gis/db/models/query.py8
-rw-r--r--django/contrib/gis/tests/relatedapp/tests.py22
2 files changed, 29 insertions, 1 deletions
diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py
index 3d31f73c29..d055260a58 100644
--- a/django/contrib/gis/db/models/query.py
+++ b/django/contrib/gis/db/models/query.py
@@ -62,6 +62,14 @@ class GeoQuerySet(QuerySet):
"""
return self._geom_attribute('centroid', **kwargs)
+ def collect(self, **kwargs):
+ """
+ Performs an aggregate collect operation on the given geometry field.
+ This is analagous to a union operation, but much faster because
+ boundaries are not dissolved.
+ """
+ return self._spatial_aggregate(aggregates.Collect, **kwargs)
+
def difference(self, geom, **kwargs):
"""
Returns the spatial difference of the geographic field in a `difference`
diff --git a/django/contrib/gis/tests/relatedapp/tests.py b/django/contrib/gis/tests/relatedapp/tests.py
index 502a3c0be9..dcc5af1ac7 100644
--- a/django/contrib/gis/tests/relatedapp/tests.py
+++ b/django/contrib/gis/tests/relatedapp/tests.py
@@ -1,7 +1,7 @@
import os, unittest
from django.contrib.gis.geos import *
from django.contrib.gis.db.backend import SpatialBackend
-from django.contrib.gis.db.models import Count, Extent, F, Union
+from django.contrib.gis.db.models import Collect, Count, Extent, F, Union
from django.contrib.gis.tests.utils import no_mysql, no_oracle, no_spatialite
from django.conf import settings
from models import City, Location, DirectoryEntry, Parcel, Book, Author
@@ -264,6 +264,26 @@ class RelatedGeoModelTest(unittest.TestCase):
# Should be `None`, and not a 'dummy' model.
self.assertEqual(None, b.author)
+ @no_mysql
+ @no_oracle
+ @no_spatialite
+ def test14_collect(self):
+ "Testing the `collect` GeoQuerySet method and `Collect` aggregate."
+ # Reference query:
+ # SELECT AsText(ST_Collect("relatedapp_location"."point")) FROM "relatedapp_city" LEFT OUTER JOIN
+ # "relatedapp_location" ON ("relatedapp_city"."location_id" = "relatedapp_location"."id")
+ # WHERE "relatedapp_city"."state" = 'TX';
+ ref_geom = fromstr('MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,-95.363151 29.763374,-96.801611 32.782057)')
+
+ c1 = City.objects.filter(state='TX').collect(field_name='location__point')
+ c2 = City.objects.filter(state='TX').aggregate(Collect('location__point'))['location__point__collect']
+
+ for coll in (c1, c2):
+ # Even though Dallas and Ft. Worth share same point, Collect doesn't
+ # consolidate -- that's why 4 points in MultiPoint.
+ self.assertEqual(4, len(coll))
+ self.assertEqual(ref_geom, coll)
+
# TODO: Related tests for KML, GML, and distance lookups.
def suite():