Made gis_terms be a set, rather than a dict with None for all keys.
This commit is contained in:
parent
6634cb7b53
commit
a53d7a0a50
|
@ -3,10 +3,12 @@ Base/mixin classes for the spatial backend database operations and the
|
||||||
`SpatialRefSys` model the backend.
|
`SpatialRefSys` model the backend.
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django.contrib.gis import gdal
|
from django.contrib.gis import gdal
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
|
|
||||||
|
|
||||||
class BaseSpatialOperations(object):
|
class BaseSpatialOperations(object):
|
||||||
"""
|
"""
|
||||||
This module holds the base `BaseSpatialBackend` object, which is
|
This module holds the base `BaseSpatialBackend` object, which is
|
||||||
|
@ -18,7 +20,7 @@ class BaseSpatialOperations(object):
|
||||||
geometry_operators = {}
|
geometry_operators = {}
|
||||||
geography_operators = {}
|
geography_operators = {}
|
||||||
geography_functions = {}
|
geography_functions = {}
|
||||||
gis_terms = {}
|
gis_terms = set()
|
||||||
truncate_params = {}
|
truncate_params = {}
|
||||||
|
|
||||||
# Quick booleans for the type of this spatial backend, and
|
# Quick booleans for the type of this spatial backend, and
|
||||||
|
|
|
@ -3,7 +3,6 @@ from django.db.backends.mysql.base import DatabaseOperations
|
||||||
from django.contrib.gis.db.backends.adapter import WKTAdapter
|
from django.contrib.gis.db.backends.adapter import WKTAdapter
|
||||||
from django.contrib.gis.db.backends.base import BaseSpatialOperations
|
from django.contrib.gis.db.backends.base import BaseSpatialOperations
|
||||||
|
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
|
class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
|
|
||||||
|
@ -18,21 +17,21 @@ class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
Adaptor = Adapter # Backwards-compatibility alias.
|
Adaptor = Adapter # Backwards-compatibility alias.
|
||||||
|
|
||||||
geometry_functions = {
|
geometry_functions = {
|
||||||
'bbcontains' : 'MBRContains', # For consistency w/PostGIS API
|
'bbcontains': 'MBRContains', # For consistency w/PostGIS API
|
||||||
'bboverlaps' : 'MBROverlaps', # .. ..
|
'bboverlaps': 'MBROverlaps', # .. ..
|
||||||
'contained' : 'MBRWithin', # .. ..
|
'contained': 'MBRWithin', # .. ..
|
||||||
'contains' : 'MBRContains',
|
'contains': 'MBRContains',
|
||||||
'disjoint' : 'MBRDisjoint',
|
'disjoint': 'MBRDisjoint',
|
||||||
'equals' : 'MBREqual',
|
'equals': 'MBREqual',
|
||||||
'exact' : 'MBREqual',
|
'exact': 'MBREqual',
|
||||||
'intersects' : 'MBRIntersects',
|
'intersects': 'MBRIntersects',
|
||||||
'overlaps' : 'MBROverlaps',
|
'overlaps': 'MBROverlaps',
|
||||||
'same_as' : 'MBREqual',
|
'same_as': 'MBREqual',
|
||||||
'touches' : 'MBRTouches',
|
'touches': 'MBRTouches',
|
||||||
'within' : 'MBRWithin',
|
'within': 'MBRWithin',
|
||||||
}
|
}
|
||||||
|
|
||||||
gis_terms = dict([(term, None) for term in list(geometry_functions) + ['isnull']])
|
gis_terms = set(geometry_functions) | set(['isnull'])
|
||||||
|
|
||||||
def geo_db_type(self, f):
|
def geo_db_type(self, f):
|
||||||
return f.geom_type
|
return f.geom_type
|
||||||
|
|
|
@ -18,6 +18,7 @@ from django.contrib.gis.geometry.backend import Geometry
|
||||||
from django.contrib.gis.measure import Distance
|
from django.contrib.gis.measure import Distance
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
|
|
||||||
class SDOOperation(SpatialFunction):
|
class SDOOperation(SpatialFunction):
|
||||||
"Base class for SDO* Oracle operations."
|
"Base class for SDO* Oracle operations."
|
||||||
sql_template = "%(function)s(%(geo_col)s, %(geometry)s) %(operator)s '%(result)s'"
|
sql_template = "%(function)s(%(geo_col)s, %(geometry)s) %(operator)s '%(result)s'"
|
||||||
|
@ -32,6 +33,7 @@ class SDODistance(SpatialFunction):
|
||||||
sql_template = ('%(function)s(%(geo_col)s, %(geometry)s, %(tolerance)s) '
|
sql_template = ('%(function)s(%(geo_col)s, %(geometry)s, %(tolerance)s) '
|
||||||
'%(operator)s %(result)s')
|
'%(operator)s %(result)s')
|
||||||
dist_func = 'SDO_GEOM.SDO_DISTANCE'
|
dist_func = 'SDO_GEOM.SDO_DISTANCE'
|
||||||
|
|
||||||
def __init__(self, op, tolerance=0.05):
|
def __init__(self, op, tolerance=0.05):
|
||||||
super(SDODistance, self).__init__(self.dist_func,
|
super(SDODistance, self).__init__(self.dist_func,
|
||||||
tolerance=tolerance,
|
tolerance=tolerance,
|
||||||
|
@ -40,6 +42,7 @@ class SDODistance(SpatialFunction):
|
||||||
class SDODWithin(SpatialFunction):
|
class SDODWithin(SpatialFunction):
|
||||||
dwithin_func = 'SDO_WITHIN_DISTANCE'
|
dwithin_func = 'SDO_WITHIN_DISTANCE'
|
||||||
sql_template = "%(function)s(%(geo_col)s, %(geometry)s, %%s) = 'TRUE'"
|
sql_template = "%(function)s(%(geo_col)s, %(geometry)s, %%s) = 'TRUE'"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(SDODWithin, self).__init__(self.dwithin_func)
|
super(SDODWithin, self).__init__(self.dwithin_func)
|
||||||
|
|
||||||
|
@ -48,6 +51,7 @@ class SDOGeomRelate(SpatialFunction):
|
||||||
relate_func = 'SDO_GEOM.RELATE'
|
relate_func = 'SDO_GEOM.RELATE'
|
||||||
sql_template = ("%(function)s(%(geo_col)s, '%(mask)s', %(geometry)s, "
|
sql_template = ("%(function)s(%(geo_col)s, '%(mask)s', %(geometry)s, "
|
||||||
"%(tolerance)s) %(operator)s '%(mask)s'")
|
"%(tolerance)s) %(operator)s '%(mask)s'")
|
||||||
|
|
||||||
def __init__(self, mask, tolerance=0.05):
|
def __init__(self, mask, tolerance=0.05):
|
||||||
# SDO_GEOM.RELATE(...) has a peculiar argument order: column, mask, geom, tolerance.
|
# SDO_GEOM.RELATE(...) has a peculiar argument order: column, mask, geom, tolerance.
|
||||||
# Moreover, the runction result is the mask (e.g., 'DISJOINT' instead of 'TRUE').
|
# Moreover, the runction result is the mask (e.g., 'DISJOINT' instead of 'TRUE').
|
||||||
|
@ -60,6 +64,7 @@ class SDORelate(SpatialFunction):
|
||||||
mask_regex = re.compile(r'^(%s)(\+(%s))*$' % (masks, masks), re.I)
|
mask_regex = re.compile(r'^(%s)(\+(%s))*$' % (masks, masks), re.I)
|
||||||
sql_template = "%(function)s(%(geo_col)s, %(geometry)s, 'mask=%(mask)s') = 'TRUE'"
|
sql_template = "%(function)s(%(geo_col)s, %(geometry)s, 'mask=%(mask)s') = 'TRUE'"
|
||||||
relate_func = 'SDO_RELATE'
|
relate_func = 'SDO_RELATE'
|
||||||
|
|
||||||
def __init__(self, mask):
|
def __init__(self, mask):
|
||||||
if not self.mask_regex.match(mask):
|
if not self.mask_regex.match(mask):
|
||||||
raise ValueError('Invalid %s mask: "%s"' % (self.relate_func, mask))
|
raise ValueError('Invalid %s mask: "%s"' % (self.relate_func, mask))
|
||||||
|
@ -79,12 +84,12 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
Adaptor = Adapter # Backwards-compatibility alias.
|
Adaptor = Adapter # Backwards-compatibility alias.
|
||||||
|
|
||||||
area = 'SDO_GEOM.SDO_AREA'
|
area = 'SDO_GEOM.SDO_AREA'
|
||||||
gml= 'SDO_UTIL.TO_GMLGEOMETRY'
|
gml = 'SDO_UTIL.TO_GMLGEOMETRY'
|
||||||
centroid = 'SDO_GEOM.SDO_CENTROID'
|
centroid = 'SDO_GEOM.SDO_CENTROID'
|
||||||
difference = 'SDO_GEOM.SDO_DIFFERENCE'
|
difference = 'SDO_GEOM.SDO_DIFFERENCE'
|
||||||
distance = 'SDO_GEOM.SDO_DISTANCE'
|
distance = 'SDO_GEOM.SDO_DISTANCE'
|
||||||
extent= 'SDO_AGGR_MBR'
|
extent = 'SDO_AGGR_MBR'
|
||||||
intersection= 'SDO_GEOM.SDO_INTERSECTION'
|
intersection = 'SDO_GEOM.SDO_INTERSECTION'
|
||||||
length = 'SDO_GEOM.SDO_LENGTH'
|
length = 'SDO_GEOM.SDO_LENGTH'
|
||||||
num_geom = 'SDO_UTIL.GETNUMELEM'
|
num_geom = 'SDO_UTIL.GETNUMELEM'
|
||||||
num_points = 'SDO_UTIL.GETNUMVERTICES'
|
num_points = 'SDO_UTIL.GETNUMVERTICES'
|
||||||
|
@ -127,9 +132,8 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
}
|
}
|
||||||
geometry_functions.update(distance_functions)
|
geometry_functions.update(distance_functions)
|
||||||
|
|
||||||
gis_terms = ['isnull']
|
gis_terms = set(['isnull'])
|
||||||
gis_terms += list(geometry_functions)
|
gis_terms.update(geometry_functions)
|
||||||
gis_terms = dict([(term, None) for term in gis_terms])
|
|
||||||
|
|
||||||
truncate_params = {'relate' : None}
|
truncate_params = {'relate' : None}
|
||||||
|
|
||||||
|
@ -272,7 +276,8 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
given Aggregate instance.
|
given Aggregate instance.
|
||||||
"""
|
"""
|
||||||
agg_name = agg.__class__.__name__.lower()
|
agg_name = agg.__class__.__name__.lower()
|
||||||
if agg_name == 'union' : agg_name += 'agg'
|
if agg_name == 'union':
|
||||||
|
agg_name += 'agg'
|
||||||
if agg.is_extent:
|
if agg.is_extent:
|
||||||
sql_template = '%(function)s(%(field)s)'
|
sql_template = '%(function)s(%(field)s)'
|
||||||
else:
|
else:
|
||||||
|
@ -295,5 +300,5 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
"""
|
"""
|
||||||
# This code doesn't work for bulk insert cases.
|
# This code doesn't work for bulk insert cases.
|
||||||
assert len(placeholders) == 1
|
assert len(placeholders) == 1
|
||||||
return [[param for pholder,param
|
return [[param for pholder, param
|
||||||
in six.moves.zip(placeholders[0], params[0]) if pholder != 'NULL'], ]
|
in six.moves.zip(placeholders[0], params[0]) if pholder != 'NULL'], ]
|
||||||
|
|
|
@ -208,12 +208,12 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
# for the geography type.
|
# for the geography type.
|
||||||
self.geography_functions = self.distance_functions.copy()
|
self.geography_functions = self.distance_functions.copy()
|
||||||
self.geography_functions.update({
|
self.geography_functions.update({
|
||||||
'coveredby' : self.geometry_functions['coveredby'],
|
'coveredby': self.geometry_functions['coveredby'],
|
||||||
'covers' : self.geometry_functions['covers'],
|
'covers': self.geometry_functions['covers'],
|
||||||
'intersects' : self.geometry_functions['intersects'],
|
'intersects': self.geometry_functions['intersects'],
|
||||||
})
|
})
|
||||||
self.geography_operators = {
|
self.geography_operators = {
|
||||||
'bboverlaps' : PostGISOperator('&&'),
|
'bboverlaps': PostGISOperator('&&'),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Native geometry type support added in PostGIS 2.0.
|
# Native geometry type support added in PostGIS 2.0.
|
||||||
|
@ -221,10 +221,9 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
self.geometry = True
|
self.geometry = True
|
||||||
|
|
||||||
# Creating a dictionary lookup of all GIS terms for PostGIS.
|
# Creating a dictionary lookup of all GIS terms for PostGIS.
|
||||||
gis_terms = ['isnull']
|
self.gis_terms = set(['isnull'])
|
||||||
gis_terms += list(self.geometry_operators)
|
self.gis_terms.update(self.geometry_operators)
|
||||||
gis_terms += list(self.geometry_functions)
|
self.gis_terms.update(self.geometry_functions)
|
||||||
self.gis_terms = dict([(term, None) for term in gis_terms])
|
|
||||||
|
|
||||||
self.area = prefix + 'Area'
|
self.area = prefix + 'Area'
|
||||||
self.bounding_circle = BOUNDINGCIRCLE
|
self.bounding_circle = BOUNDINGCIRCLE
|
||||||
|
@ -247,7 +246,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
self.makeline = prefix + 'MakeLine'
|
self.makeline = prefix + 'MakeLine'
|
||||||
self.mem_size = prefix + 'mem_size'
|
self.mem_size = prefix + 'mem_size'
|
||||||
self.num_geom = prefix + 'NumGeometries'
|
self.num_geom = prefix + 'NumGeometries'
|
||||||
self.num_points =prefix + 'npoints'
|
self.num_points = prefix + 'npoints'
|
||||||
self.perimeter = prefix + 'Perimeter'
|
self.perimeter = prefix + 'Perimeter'
|
||||||
self.point_on_surface = prefix + 'PointOnSurface'
|
self.point_on_surface = prefix + 'PointOnSurface'
|
||||||
self.polygonize = prefix + 'Polygonize'
|
self.polygonize = prefix + 'Polygonize'
|
||||||
|
@ -324,7 +323,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
raise NotImplementedError('PostGIS 1.5 supports geography columns '
|
raise NotImplementedError('PostGIS 1.5 supports geography columns '
|
||||||
'only with an SRID of 4326.')
|
'only with an SRID of 4326.')
|
||||||
|
|
||||||
return 'geography(%s,%d)'% (f.geom_type, f.srid)
|
return 'geography(%s,%d)' % (f.geom_type, f.srid)
|
||||||
elif self.geometry:
|
elif self.geometry:
|
||||||
# Postgis 2.0 supports type-based geometries.
|
# Postgis 2.0 supports type-based geometries.
|
||||||
# TODO: Support 'M' extension.
|
# TODO: Support 'M' extension.
|
||||||
|
@ -565,7 +564,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
if not self.check_aggregate_support(agg):
|
if not self.check_aggregate_support(agg):
|
||||||
raise NotImplementedError('%s spatial aggregate is not implmented for this backend.' % agg_name)
|
raise NotImplementedError('%s spatial aggregate is not implmented for this backend.' % agg_name)
|
||||||
agg_name = agg_name.lower()
|
agg_name = agg_name.lower()
|
||||||
if agg_name == 'union': agg_name += 'agg'
|
if agg_name == 'union':
|
||||||
|
agg_name += 'agg'
|
||||||
sql_template = '%(function)s(%(field)s)'
|
sql_template = '%(function)s(%(field)s)'
|
||||||
sql_function = getattr(self, agg_name)
|
sql_function = getattr(self, agg_name)
|
||||||
return sql_template, sql_function
|
return sql_template, sql_function
|
||||||
|
|
|
@ -117,9 +117,8 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
super(DatabaseOperations, self).__init__(connection)
|
super(DatabaseOperations, self).__init__(connection)
|
||||||
|
|
||||||
# Creating the GIS terms dictionary.
|
# Creating the GIS terms dictionary.
|
||||||
gis_terms = ['isnull']
|
self.gis_terms = set(['isnull'])
|
||||||
gis_terms += self.geometry_functions.keys()
|
self.gis_terms.update(self.geometry_functions)
|
||||||
self.gis_terms = dict([(term, None) for term in gis_terms])
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def spatial_version(self):
|
def spatial_version(self):
|
||||||
|
|
Loading…
Reference in New Issue