|
9 | 9 | the backend.
|
10 | 10 | (3) The `parse_lookup` function, used for spatial SQL construction by
|
11 | 11 | the GeoQuerySet.
|
12 |
| - (4) The `create_spatial_db`, and `get_geo_where_clause` |
13 |
| - routines (needed by `parse_lookup`). |
| 12 | + (4) The `create_spatial_db`, and `get_geo_where_clause` |
| 13 | + (needed by `parse_lookup`) functions. |
14 | 14 | (5) The `SpatialBackend` object, which contains information specific
|
15 | 15 | to the spatial backend.
|
16 | 16 | """
|
17 |
| -from types import StringType, UnicodeType |
18 | 17 | from django.conf import settings
|
19 | 18 | from django.db import connection
|
20 | 19 | from django.db.models.query import field_choices, find_field, get_where_clause, \
|
21 | 20 | FieldFound, LOOKUP_SEPARATOR, QUERY_TERMS
|
22 | 21 | from django.utils.datastructures import SortedDict
|
23 |
| -from django.contrib.gis.geos import GEOSGeometry |
| 22 | +from django.contrib.gis.db.backend.util import gqn |
24 | 23 |
|
25 | 24 | # These routines (needed by GeoManager), default to False.
|
26 |
| -ASGML, ASKML, DISTANCE, EXTENT, TRANSFORM, UNION, VERSION = (False, False, False, False, False, False, False) |
| 25 | +ASGML, ASKML, DISTANCE, DISTANCE_SPHEROID, EXTENT, TRANSFORM, UNION, VERSION = tuple(False for i in range(8)) |
27 | 26 |
|
| 27 | +# Lookup types in which the rest of the parameters are not |
| 28 | +# needed to be substitute in the WHERE SQL (e.g., the 'relate' |
| 29 | +# operation on Oracle does not need the mask substituted back |
| 30 | +# into the query SQL.). |
| 31 | +LIMITED_WHERE = [] |
| 32 | + |
| 33 | +# Retrieving the necessary settings from the backend. |
28 | 34 | if settings.DATABASE_ENGINE == 'postgresql_psycopg2':
|
29 |
| - # PostGIS is the spatial database, getting the rquired modules, |
30 |
| - # renaming as necessary. |
31 |
| - from django.contrib.gis.db.backend.postgis import \ |
32 |
| - PostGISField as GeoBackendField, POSTGIS_TERMS as GIS_TERMS, \ |
33 |
| - create_spatial_db, get_geo_where_clause, \ |
34 |
| - ASGML, ASKML, DISTANCE, EXTENT, GEOM_SELECT, TRANSFORM, UNION, \ |
| 35 | + from django.contrib.gis.db.backend.postgis.adaptor import \ |
| 36 | + PostGISAdaptor as GeoAdaptor |
| 37 | + from django.contrib.gis.db.backend.postgis.field import \ |
| 38 | + PostGISField as GeoBackendField |
| 39 | + from django.contrib.gis.db.backend.postgis.creation import create_spatial_db |
| 40 | + from django.contrib.gis.db.backend.postgis.query import \ |
| 41 | + get_geo_where_clause, POSTGIS_TERMS as GIS_TERMS, \ |
| 42 | + ASGML, ASKML, DISTANCE, DISTANCE_SPHEROID, DISTANCE_FUNCTIONS, \ |
| 43 | + EXTENT, GEOM_SELECT, TRANSFORM, UNION, \ |
35 | 44 | MAJOR_VERSION, MINOR_VERSION1, MINOR_VERSION2
|
| 45 | + # PostGIS version info is needed to determine calling order of some |
| 46 | + # stored procedures (e.g., AsGML()). |
36 | 47 | VERSION = (MAJOR_VERSION, MINOR_VERSION1, MINOR_VERSION2)
|
37 | 48 | SPATIAL_BACKEND = 'postgis'
|
38 | 49 | elif settings.DATABASE_ENGINE == 'oracle':
|
39 |
| - from django.contrib.gis.db.backend.oracle import \ |
40 |
| - OracleSpatialField as GeoBackendField, \ |
41 |
| - ORACLE_SPATIAL_TERMS as GIS_TERMS, \ |
42 |
| - create_spatial_db, get_geo_where_clause, \ |
43 |
| - ASGML, DISTANCE, GEOM_SELECT, TRANSFORM, UNION |
| 50 | + from django.contrib.gis.db.backend.oracle.adaptor import \ |
| 51 | + OracleSpatialAdaptor as GeoAdaptor |
| 52 | + from django.contrib.gis.db.backend.oracle.field import \ |
| 53 | + OracleSpatialField as GeoBackendField |
| 54 | + from django.contrib.gis.db.backend.oracle.creation import create_spatial_db |
| 55 | + from django.contrib.gis.db.backend.oracle.query import \ |
| 56 | + get_geo_where_clause, ORACLE_SPATIAL_TERMS as GIS_TERMS, \ |
| 57 | + ASGML, DISTANCE, DISTANCE_FUNCTIONS, GEOM_SELECT, TRANSFORM, UNION |
44 | 58 | SPATIAL_BACKEND = 'oracle'
|
| 59 | + LIMITED_WHERE = ['relate'] |
45 | 60 | elif settings.DATABASE_ENGINE == 'mysql':
|
46 |
| - from django.contrib.gis.db.backend.mysql import \ |
47 |
| - MySQLGeoField as GeoBackendField, \ |
48 |
| - MYSQL_GIS_TERMS as GIS_TERMS, \ |
49 |
| - create_spatial_db, get_geo_where_clause, \ |
50 |
| - GEOM_SELECT |
| 61 | + from django.contrib.gis.db.backend.mysql.adaptor import \ |
| 62 | + MySQLAdaptor as GeoAdaptor |
| 63 | + from django.contrib.gis.db.backend.mysql.field import \ |
| 64 | + MySQLGeoField as GeoBackendField |
| 65 | + from django.contrib.gis.db.backend.mysql.creation import create_spatial_db |
| 66 | + from django.contrib.gis.db.backend.mysql.query import \ |
| 67 | + get_geo_where_clause, MYSQL_GIS_TERMS as GIS_TERMS, GEOM_SELECT |
| 68 | + DISTANCE_FUNCTIONS = {} |
51 | 69 | SPATIAL_BACKEND = 'mysql'
|
52 | 70 | else:
|
53 | 71 | raise NotImplementedError('No Geographic Backend exists for %s' % settings.DATABASE_ENGINE)
|
54 | 72 |
|
55 | 73 | class SpatialBackend(object):
|
56 |
| - "A container for properties of the Spatial Backend." |
| 74 | + "A container for properties of the SpatialBackend." |
| 75 | + # Stored procedure names used by the `GeoManager`. |
57 | 76 | as_kml = ASKML
|
58 | 77 | as_gml = ASGML
|
59 | 78 | distance = DISTANCE
|
| 79 | + distance_spheroid = DISTANCE_SPHEROID |
60 | 80 | extent = EXTENT
|
61 | 81 | name = SPATIAL_BACKEND
|
62 | 82 | select = GEOM_SELECT
|
63 | 83 | transform = TRANSFORM
|
64 | 84 | union = UNION
|
| 85 | + |
| 86 | + # Version information, if defined. |
65 | 87 | version = VERSION
|
| 88 | + |
| 89 | + # All valid GIS lookup terms, and distance functions. |
| 90 | + gis_terms = GIS_TERMS |
| 91 | + distance_functions = DISTANCE_FUNCTIONS |
| 92 | + |
| 93 | + # Lookup types where additional WHERE parameters are excluded. |
| 94 | + limited_where = LIMITED_WHERE |
| 95 | + |
| 96 | + # Class for the backend field. |
| 97 | + Field = GeoBackendField |
| 98 | + |
| 99 | + # Adaptor class used for quoting GEOS geometries in the database. |
| 100 | + Adaptor = GeoAdaptor |
66 | 101 |
|
67 | 102 | #### query.py overloaded functions ####
|
68 | 103 | # parse_lookup() and lookup_inner() are modified from their django/db/models/query.py
|
69 | 104 | # counterparts to support constructing SQL for geographic queries.
|
70 | 105 | #
|
71 |
| -# Status: Synced with r5982. |
| 106 | +# Status: Synced with r7098. |
72 | 107 | #
|
73 | 108 | def parse_lookup(kwarg_items, opts):
|
74 | 109 | # Helper function that handles converting API kwargs
|
@@ -290,16 +325,17 @@ def lookup_inner(path, lookup_type, value, opts, table, column):
|
290 | 325 | # If the field is a geometry field, then the WHERE clause will need to be obtained
|
291 | 326 | # with the get_geo_where_clause()
|
292 | 327 | if hasattr(field, '_geom'):
|
293 |
| - # Getting the preparation SQL object from the field. |
294 |
| - geo_prep = field.get_db_prep_lookup(lookup_type, value) |
| 328 | + # Getting additional SQL WHERE and params arrays associated with |
| 329 | + # the geographic field. |
| 330 | + geo_where, geo_params = field.get_db_prep_lookup(lookup_type, value) |
295 | 331 |
|
296 |
| - # Getting the adapted geometry from the field. |
297 |
| - gwc = get_geo_where_clause(lookup_type, current_table, column, value) |
| 332 | + # Getting the geographic WHERE clause. |
| 333 | + gwc = get_geo_where_clause(lookup_type, current_table, field, value) |
298 | 334 |
|
299 |
| - # Substituting in the the where parameters into the geographic where |
300 |
| - # clause, and extending the parameters. |
301 |
| - where.append(gwc % tuple(geo_prep.where)) |
302 |
| - params.extend(geo_prep.params) |
| 335 | + # Appending the geographic WHERE componnents and parameters onto |
| 336 | + # the where and params arrays. |
| 337 | + where.append(gwc % tuple(geo_where)) |
| 338 | + params.extend(geo_params) |
303 | 339 | else:
|
304 | 340 | where.append(get_where_clause(lookup_type, current_table + '.', column, value, db_type))
|
305 | 341 | params.extend(field.get_db_prep_lookup(lookup_type, value))
|
|
0 commit comments