django1/django/contrib/gis/db/backends/mysql/operations.py

92 lines
3.3 KiB
Python
Raw Normal View History

from django.contrib.gis.db.backends.base.adapter import WKTAdapter
from django.contrib.gis.db.backends.base.operations import \
BaseSpatialOperations
from django.contrib.gis.db.backends.utils import SpatialOperator
from django.contrib.gis.db.models import aggregates
from django.db.backends.mysql.operations import DatabaseOperations
2015-01-25 07:03:02 +08:00
from django.utils.functional import cached_property
class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
mysql = True
name = 'mysql'
Adapter = WKTAdapter
@cached_property
def select(self):
if self.connection.mysql_version < (5, 6, 0):
return 'AsText(%s)'
return 'ST_AsText(%s)'
@cached_property
def from_wkb(self):
if self.connection.mysql_version < (5, 6, 0):
return 'GeomFromWKB'
return 'ST_GeomFromWKB'
@cached_property
def from_text(self):
if self.connection.mysql_version < (5, 6, 0):
return 'GeomFromText'
return 'ST_GeomFromText'
gis_operators = {
'bbcontains': SpatialOperator(func='MBRContains'), # For consistency w/PostGIS API
'bboverlaps': SpatialOperator(func='MBROverlaps'), # .. ..
'contained': SpatialOperator(func='MBRWithin'), # .. ..
'contains': SpatialOperator(func='MBRContains'),
'disjoint': SpatialOperator(func='MBRDisjoint'),
'equals': SpatialOperator(func='MBREqual'),
'exact': SpatialOperator(func='MBREqual'),
'intersects': SpatialOperator(func='MBRIntersects'),
'overlaps': SpatialOperator(func='MBROverlaps'),
'same_as': SpatialOperator(func='MBREqual'),
'touches': SpatialOperator(func='MBRTouches'),
'within': SpatialOperator(func='MBRWithin'),
}
@cached_property
def function_names(self):
return {
'Difference': 'ST_Difference',
'Distance': 'ST_Distance',
'Intersection': 'ST_Intersection',
'Length': 'GLength' if self.connection.mysql_version < (5, 6, 0) else 'ST_Length',
'SymDifference': 'ST_SymDifference',
'Union': 'ST_Union',
}
2015-01-25 07:03:02 +08:00
disallowed_aggregates = (
aggregates.Collect, aggregates.Extent, aggregates.Extent3D,
aggregates.MakeLine, aggregates.Union,
)
@cached_property
def unsupported_functions(self):
unsupported = {
'AsGeoJSON', 'AsGML', 'AsKML', 'AsSVG', 'BoundingCircle',
'ForceRHR', 'GeoHash', 'MemSize',
2015-01-25 07:03:02 +08:00
'Perimeter', 'PointOnSurface', 'Reverse', 'Scale', 'SnapToGrid',
'Transform', 'Translate',
2015-01-25 07:03:02 +08:00
}
if self.connection.mysql_version < (5, 6, 1):
unsupported.update({'Difference', 'Distance', 'Intersection', 'SymDifference', 'Union'})
2015-01-25 07:03:02 +08:00
return unsupported
def geo_db_type(self, f):
return f.geom_type
2014-11-16 09:56:42 +08:00
def get_geom_placeholder(self, f, value, compiler):
"""
The placeholder here has to include MySQL's WKT constructor. Because
MySQL does not support spatial transformations, there is no need to
modify the placeholder based on the contents of the given value.
"""
if hasattr(value, 'as_sql'):
2014-11-16 09:56:42 +08:00
placeholder, _ = compiler.compile(value)
else:
placeholder = '%s(%%s)' % self.from_text
return placeholder