Django

Code

Show
Ignore:
Timestamp:
02/10/08 20:25:01 (10 months ago)
Author:
jbronn
Message:

gis: Fixed 6414, and applied DRY to spatial backend internals. Changes include:

(1) Support for distance calculations on geometry fields with geodetic coordinate systems (e.g., WGS84, the default).
(2) The get_db_prep_save and get_db_prep_lookup have been moved from the spatial backends to common implementations in GeometryField.
(3) Simplified SQL construction for GeoQuerySet methods.
(4) SpatialBackend now contains all spatial backend dependent settings.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/gis/django/contrib/gis/db/backend/oracle/field.py

    r6919 r7104  
    1 import re 
    2 from types import StringType, UnicodeType 
    31from django.db import connection 
    42from django.db.backends.util import truncate_name 
    53from django.db.models.fields import Field # Django base Field class 
    6 from django.contrib.gis.geos import GEOSGeometry 
    7 from django.contrib.gis.db.backend.util import GeoFieldSQL 
    8 from django.contrib.gis.db.backend.oracle.adaptor import OracleSpatialAdaptor 
    9 from django.contrib.gis.db.backend.oracle.query import ORACLE_SPATIAL_TERMS, DISTANCE_FUNCTIONS, TRANSFORM 
     4from django.contrib.gis.db.backend.util import gqn 
     5from django.contrib.gis.db.backend.oracle.query import TRANSFORM 
    106 
    117# Quotename & geographic quotename, respectively. 
    128qn = connection.ops.quote_name 
    13 def gqn(value): 
    14     if isinstance(value, UnicodeType): value = value.encode('ascii') 
    15     return "'%s'" % value 
    169 
    1710class OracleSpatialField(Field): 
     
    9689        return 'MDSYS.SDO_GEOMETRY' 
    9790         
    98     def get_db_prep_lookup(self, lookup_type, value): 
    99         """ 
    100         Returns field's value prepared for database lookup, accepts WKT and  
    101         GEOS Geometries for the value. 
    102         """ 
    103         if lookup_type in ORACLE_SPATIAL_TERMS: 
    104             # special case for isnull lookup 
    105             if lookup_type == 'isnull': return GeoFieldSQL([], []) 
    106  
    107             # Get the geometry with SRID; defaults SRID to that 
    108             # of the field if it is None 
    109             geom = self.get_geometry(value) 
    110              
    111             # The adaptor will be used by psycopg2 for quoting the WKT. 
    112             adapt = OracleSpatialAdaptor(geom) 
    113  
    114             if geom.srid != self._srid: 
    115                 # Adding the necessary string substitutions and parameters 
    116                 # to perform a geometry transformation. 
    117                 where = ['%s(SDO_GEOMETRY(%%s, %s), %%s)' % (TRANSFORM, geom.srid)] 
    118                 params = [adapt, self._srid] 
    119             else: 
    120                 where = ['SDO_GEOMETRY(%%s, %s)' % geom.srid] 
    121                 params = [adapt] 
    122  
    123             if isinstance(value, tuple): 
    124                 if lookup_type in DISTANCE_FUNCTIONS or lookup_type == 'dwithin': 
    125                     # Getting the distance parameter in the units of the field 
    126                     where += [self.get_distance(value[1])] 
    127                 elif lookup_type == 'relate': 
    128                     # No extra where parameters for SDO_RELATE queries. 
    129                     pass 
    130                 else: 
    131                     where += map(gqn, value[1:]) 
    132             return GeoFieldSQL(where, params) 
    133         else: 
    134             raise TypeError("Field has invalid lookup: %s" % lookup_type) 
    135  
    136     def get_db_prep_save(self, value): 
    137         "Prepares the value for saving in the database." 
    138         if not bool(value): 
    139             # Return an empty string for NULL -- but this doesn't work yet. 
    140             return '' 
    141         if isinstance(value, GEOSGeometry): 
    142             return OracleSpatialAdaptor(value) 
    143         else: 
    144             raise TypeError('Geometry Proxy should only return GEOSGeometry objects.') 
    145  
    14691    def get_placeholder(self, value): 
    14792        """ 
     
    15095        SDO_CS.TRANSFORM() function call. 
    15196        """ 
    152         if isinstance(value, GEOSGeometry) and value.srid != self._srid: 
     97        if value is None: 
     98            return '%s' 
     99        elif value.srid != self._srid: 
    153100            # Adding Transform() to the SQL placeholder. 
    154101            return '%s(SDO_GEOMETRY(%%s, %s), %s)' % (TRANSFORM, value.srid, self._srid) 
    155         elif value is None: 
    156             return '%s' 
    157102        else: 
    158103            return 'SDO_GEOMETRY(%%s, %s)' % self._srid