1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

gis: Fixed spatial aggregates when an ordering was specified (thanks ingenieroariel); added bboverlaps to MySQL lookup types for API consistency.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@7699 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2008-06-19 06:00:13 +00:00
parent 2eeb84bd55
commit 6b12a135d6
4 changed files with 21 additions and 5 deletions

View File

@ -19,7 +19,8 @@ GEOM_SELECT = 'AsText(%s)'
# _every_ one of these lookup types is on the _bounding box_ only. # _every_ one of these lookup types is on the _bounding box_ only.
MYSQL_GIS_FUNCTIONS = { MYSQL_GIS_FUNCTIONS = {
'bbcontains' : 'MBRContains', # For consistency w/PostGIS API 'bbcontains' : 'MBRContains', # For consistency w/PostGIS API
'contained' : 'MBRWithin', # (ditto) 'bboverlaps' : 'MBROverlaps', # .. ..
'contained' : 'MBRWithin', # .. ..
'contains' : 'MBRContains', 'contains' : 'MBRContains',
'disjoint' : 'MBRDisjoint', 'disjoint' : 'MBRDisjoint',
'equals' : 'MBREqual', 'equals' : 'MBREqual',

View File

@ -601,14 +601,16 @@ class GeoQuerySet(QuerySet):
column. Takes into account if the geographic field is in a column. Takes into account if the geographic field is in a
ForeignKey relation to the current model. ForeignKey relation to the current model.
""" """
# If this is an aggregate spatial query, the flag needs to be
# set on the `GeoQuery` object of this queryset.
if aggregate: self.query.aggregate = True
# Is this operation going to be on a related geographic field? # Is this operation going to be on a related geographic field?
if not geo_field in self.model._meta.fields: if not geo_field in self.model._meta.fields:
# If so, it'll have to be added to the select related information # If so, it'll have to be added to the select related information
# (e.g., if 'location__point' was given as the field name). # (e.g., if 'location__point' was given as the field name).
self.query.add_select_related([field_name]) self.query.add_select_related([field_name])
self.query.pre_sql_setup() self.query.pre_sql_setup()
# Can't non-aggregate and aggregate selections together.
if aggregate: self.query.aggregate = True
rel_table, rel_col = self.query.related_select_cols[self.query.related_select_fields.index(geo_field)] rel_table, rel_col = self.query.related_select_cols[self.query.related_select_fields.index(geo_field)]
return self.query._field_column(geo_field, rel_table) return self.query._field_column(geo_field, rel_table)
else: else:

View File

@ -147,6 +147,16 @@ class GeoQuery(sql.Query):
col_aliases.add(field.column) col_aliases.add(field.column)
return result, aliases return result, aliases
def get_ordering(self):
"""
This routine is overridden to disable ordering for aggregate
spatial queries.
"""
if not self.aggregate:
return super(GeoQuery, self).get_ordering()
else:
return ()
def resolve_columns(self, row, fields=()): def resolve_columns(self, row, fields=()):
""" """
This routine is necessary so that distances and geometries returned This routine is necessary so that distances and geometries returned

View File

@ -431,8 +431,11 @@ class GeoModelTest(unittest.TestCase):
union2 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374,-98.493183 29.424170)') union2 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374,-98.493183 29.424170)')
qs = City.objects.filter(point__within=tx) qs = City.objects.filter(point__within=tx)
self.assertRaises(TypeError, qs.unionagg, 'name') self.assertRaises(TypeError, qs.unionagg, 'name')
u1 = qs.unionagg(field_name='point') # Using `field_name` keyword argument in one query and specifying an
u2 = qs.unionagg() # order in the other (which should not be used because this is
# an aggregate method on a spatial column)
u1 = qs.unionagg(field_name='point')
u2 = qs.order_by('name').unionagg()
tol = 0.00001 tol = 0.00001
if SpatialBackend.oracle: if SpatialBackend.oracle:
union = union2 union = union2