web/lib/django/contrib/gis/db/models/sql/aggregates.py
changeset 38 77b6da96e6f1
equal deleted inserted replaced
37:8d941af65caf 38:77b6da96e6f1
       
     1 from django.db.models.sql.aggregates import *
       
     2 from django.contrib.gis.db.models.fields import GeometryField
       
     3 from django.contrib.gis.db.models.sql.conversion import GeomField
       
     4 
       
     5 class GeoAggregate(Aggregate):
       
     6     # Default SQL template for spatial aggregates.
       
     7     sql_template = '%(function)s(%(field)s)'
       
     8 
       
     9     # Conversion class, if necessary.
       
    10     conversion_class = None
       
    11 
       
    12     # Flags for indicating the type of the aggregate.
       
    13     is_extent = False
       
    14 
       
    15     def __init__(self, col, source=None, is_summary=False, tolerance=0.05, **extra):
       
    16         super(GeoAggregate, self).__init__(col, source, is_summary, **extra)
       
    17 
       
    18         # Required by some Oracle aggregates.
       
    19         self.tolerance = tolerance
       
    20 
       
    21         # Can't use geographic aggregates on non-geometry fields.
       
    22         if not isinstance(self.source, GeometryField):
       
    23             raise ValueError('Geospatial aggregates only allowed on geometry fields.')
       
    24 
       
    25     def as_sql(self, qn, connection):
       
    26         "Return the aggregate, rendered as SQL."
       
    27 
       
    28         if connection.ops.oracle:
       
    29             self.extra['tolerance'] = self.tolerance
       
    30 
       
    31         if hasattr(self.col, 'as_sql'):
       
    32             field_name = self.col.as_sql(qn, connection)
       
    33         elif isinstance(self.col, (list, tuple)):
       
    34             field_name = '.'.join([qn(c) for c in self.col])
       
    35         else:
       
    36             field_name = self.col
       
    37 
       
    38         sql_template, sql_function = connection.ops.spatial_aggregate_sql(self)
       
    39 
       
    40         params = {
       
    41             'function': sql_function,
       
    42             'field': field_name
       
    43         }
       
    44         params.update(self.extra)
       
    45 
       
    46         return sql_template % params
       
    47 
       
    48 class Collect(GeoAggregate):
       
    49     pass
       
    50 
       
    51 class Extent(GeoAggregate):
       
    52     is_extent = '2D'
       
    53 
       
    54 class Extent3D(GeoAggregate):
       
    55     is_extent = '3D'
       
    56 
       
    57 class MakeLine(GeoAggregate):
       
    58     pass
       
    59 
       
    60 class Union(GeoAggregate):
       
    61     pass