GIS lookup support added
This commit is contained in:
parent
760e28e72b
commit
074e0f5aca
|
@ -49,9 +49,7 @@ class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
|
|||
return placeholder
|
||||
|
||||
def spatial_lookup_sql(self, lvalue, lookup_type, value, field, qn):
|
||||
alias, col, db_type = lvalue
|
||||
|
||||
geo_col = '%s.%s' % (qn(alias), qn(col))
|
||||
geo_col, db_type = lvalue
|
||||
|
||||
lookup_info = self.geometry_functions.get(lookup_type, False)
|
||||
if lookup_info:
|
||||
|
|
|
@ -231,10 +231,7 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
|
|||
|
||||
def spatial_lookup_sql(self, lvalue, lookup_type, value, field, qn):
|
||||
"Returns the SQL WHERE clause for use in Oracle spatial SQL construction."
|
||||
alias, col, db_type = lvalue
|
||||
|
||||
# Getting the quoted table name as `geo_col`.
|
||||
geo_col = '%s.%s' % (qn(alias), qn(col))
|
||||
geo_col, db_type = lvalue
|
||||
|
||||
# See if a Oracle Geometry function matches the lookup type next
|
||||
lookup_info = self.geometry_functions.get(lookup_type, False)
|
||||
|
|
|
@ -478,10 +478,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
|||
(alias, col, db_type), the lookup type string, lookup value, and
|
||||
the geometry field.
|
||||
"""
|
||||
alias, col, db_type = lvalue
|
||||
|
||||
# Getting the quoted geometry column.
|
||||
geo_col = '%s.%s' % (qn(alias), qn(col))
|
||||
geo_col, db_type = lvalue
|
||||
|
||||
if lookup_type in self.geometry_operators:
|
||||
if field.geography and not lookup_type in self.geography_operators:
|
||||
|
|
|
@ -324,10 +324,7 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
|
|||
[a tuple of (alias, column, db_type)], lookup type, lookup
|
||||
value, the model field, and the quoting function.
|
||||
"""
|
||||
alias, col, db_type = lvalue
|
||||
|
||||
# Getting the quoted field as `geo_col`.
|
||||
geo_col = '%s.%s' % (qn(alias), qn(col))
|
||||
geo_col, db_type = lvalue
|
||||
|
||||
if lookup_type in self.geometry_functions:
|
||||
# See if a SpatiaLite geometry function matches the lookup type.
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
from django.db.models.sql.constants import QUERY_TERMS
|
||||
|
||||
ALL_TERMS = set([
|
||||
'bbcontains', 'bboverlaps', 'contained', 'contains',
|
||||
'contains_properly', 'coveredby', 'covers', 'crosses', 'disjoint',
|
||||
'distance_gt', 'distance_gte', 'distance_lt', 'distance_lte',
|
||||
'dwithin', 'equals', 'exact',
|
||||
'intersects', 'overlaps', 'relate', 'same_as', 'touches', 'within',
|
||||
'left', 'right', 'overlaps_left', 'overlaps_right',
|
||||
'overlaps_above', 'overlaps_below',
|
||||
'strictly_above', 'strictly_below'
|
||||
])
|
||||
GIS_LOOKUPS = ALL_TERMS.copy()
|
||||
ALL_TERMS.update(QUERY_TERMS)
|
||||
|
||||
__all__ = ['ALL_TERMS', 'GIS_LOOKUPS']
|
|
@ -2,6 +2,8 @@ from django.db.models.fields import Field
|
|||
from django.db.models.sql.expressions import SQLEvaluator
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.gis import forms
|
||||
from django.contrib.gis.db.models.constants import GIS_LOOKUPS
|
||||
from django.contrib.gis.db.models.lookups import GISLookup
|
||||
from django.contrib.gis.db.models.proxy import GeometryProxy
|
||||
from django.contrib.gis.geometry.backend import Geometry, GeometryException
|
||||
from django.utils import six
|
||||
|
@ -284,6 +286,10 @@ class GeometryField(Field):
|
|||
"""
|
||||
return connection.ops.get_geom_placeholder(self, value)
|
||||
|
||||
for lookup_name in GIS_LOOKUPS:
|
||||
lookup = type(lookup_name, (GISLookup,), {'lookup_name': lookup_name})
|
||||
GeometryField.register_lookup(lookup)
|
||||
|
||||
|
||||
# The OpenGIS Geometry Type Fields
|
||||
class PointField(GeometryField):
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
from django.db.models.lookups import Lookup
|
||||
from django.db.models.sql.expressions import SQLEvaluator
|
||||
|
||||
|
||||
class GISLookup(Lookup):
|
||||
def as_sql(self, qn, connection):
|
||||
from django.contrib.gis.db.models.sql import GeoWhereNode
|
||||
# We use the same approach as was used by GeoWhereNode. It would
|
||||
# be a good idea to upgrade GIS to use similar code that is used
|
||||
# for other lookups.
|
||||
if isinstance(self.rhs, SQLEvaluator):
|
||||
# Make sure the F Expression destination field exists, and
|
||||
# set an `srid` attribute with the same as that of the
|
||||
# destination.
|
||||
geo_fld = GeoWhereNode._check_geo_field(self.rhs.opts, self.rhs.expression.name)
|
||||
if not geo_fld:
|
||||
raise ValueError('No geographic field found in expression.')
|
||||
self.rhs.srid = geo_fld.srid
|
||||
db_type = self.lhs.output_type.db_type(connection=connection)
|
||||
params = self.lhs.output_type.get_db_prep_lookup(
|
||||
self.lookup_name, self.rhs, connection=connection)
|
||||
lhs_sql, lhs_params = self.process_lhs(qn, connection)
|
||||
# lhs_params not currently supported.
|
||||
assert not lhs_params
|
||||
data = (lhs_sql, db_type)
|
||||
spatial_sql, spatial_params = connection.ops.spatial_lookup_sql(
|
||||
data, self.lookup_name, self.rhs, self.lhs.output_type, qn)
|
||||
return spatial_sql, spatial_params + params
|
|
@ -1,6 +1,7 @@
|
|||
from django.db import connections
|
||||
from django.db.models.query import sql
|
||||
|
||||
from django.contrib.gis.db.models.constants import ALL_TERMS
|
||||
from django.contrib.gis.db.models.fields import GeometryField
|
||||
from django.contrib.gis.db.models.sql import aggregates as gis_aggregates
|
||||
from django.contrib.gis.db.models.sql.conversion import AreaField, DistanceField, GeomField
|
||||
|
@ -9,19 +10,6 @@ from django.contrib.gis.geometry.backend import Geometry
|
|||
from django.contrib.gis.measure import Area, Distance
|
||||
|
||||
|
||||
ALL_TERMS = set([
|
||||
'bbcontains', 'bboverlaps', 'contained', 'contains',
|
||||
'contains_properly', 'coveredby', 'covers', 'crosses', 'disjoint',
|
||||
'distance_gt', 'distance_gte', 'distance_lt', 'distance_lte',
|
||||
'dwithin', 'equals', 'exact',
|
||||
'intersects', 'overlaps', 'relate', 'same_as', 'touches', 'within',
|
||||
'left', 'right', 'overlaps_left', 'overlaps_right',
|
||||
'overlaps_above', 'overlaps_below',
|
||||
'strictly_above', 'strictly_below'
|
||||
])
|
||||
ALL_TERMS.update(sql.constants.QUERY_TERMS)
|
||||
|
||||
|
||||
class GeoQuery(sql.Query):
|
||||
"""
|
||||
A single spatial SQL query.
|
||||
|
|
Loading…
Reference in New Issue