60 lines
2.2 KiB
Python
60 lines
2.2 KiB
Python
|
"""
|
||
|
This module contains the spatial lookup types, and the `get_geo_where_clause`
|
||
|
routine for MySQL.
|
||
|
|
||
|
Please note that MySQL only supports bounding box queries, also
|
||
|
known as MBRs (Minimum Bounding Rectangles). Moreover, spatial
|
||
|
indices may only be used on MyISAM tables -- if you need
|
||
|
transactions, take a look at PostGIS.
|
||
|
"""
|
||
|
from django.db import connection
|
||
|
qn = connection.ops.quote_name
|
||
|
|
||
|
# To ease implementation, WKT is passed to/from MySQL.
|
||
|
GEOM_FROM_TEXT = 'GeomFromText'
|
||
|
GEOM_FROM_WKB = 'GeomFromWKB'
|
||
|
GEOM_SELECT = 'AsText(%s)'
|
||
|
|
||
|
# WARNING: MySQL is NOT compliant w/the OpenGIS specification and
|
||
|
# _every_ one of these lookup types is on the _bounding box_ only.
|
||
|
MYSQL_GIS_FUNCTIONS = {
|
||
|
'bbcontains' : 'MBRContains', # For consistency w/PostGIS API
|
||
|
'bboverlaps' : 'MBROverlaps', # .. ..
|
||
|
'contained' : 'MBRWithin', # .. ..
|
||
|
'contains' : 'MBRContains',
|
||
|
'disjoint' : 'MBRDisjoint',
|
||
|
'equals' : 'MBREqual',
|
||
|
'exact' : 'MBREqual',
|
||
|
'intersects' : 'MBRIntersects',
|
||
|
'overlaps' : 'MBROverlaps',
|
||
|
'same_as' : 'MBREqual',
|
||
|
'touches' : 'MBRTouches',
|
||
|
'within' : 'MBRWithin',
|
||
|
}
|
||
|
|
||
|
# This lookup type does not require a mapping.
|
||
|
MISC_TERMS = ['isnull']
|
||
|
|
||
|
# Assacceptable lookup types for Oracle spatial.
|
||
|
MYSQL_GIS_TERMS = MYSQL_GIS_FUNCTIONS.keys()
|
||
|
MYSQL_GIS_TERMS += MISC_TERMS
|
||
|
MYSQL_GIS_TERMS = dict((term, None) for term in MYSQL_GIS_TERMS) # Making dictionary
|
||
|
|
||
|
def get_geo_where_clause(table_alias, name, lookup_type, geo_annot):
|
||
|
"Returns the SQL WHERE clause for use in MySQL spatial SQL construction."
|
||
|
# Getting the quoted field as `geo_col`.
|
||
|
geo_col = '%s.%s' % (qn(table_alias), qn(name))
|
||
|
|
||
|
# See if a MySQL Geometry function matches the lookup type next
|
||
|
lookup_info = MYSQL_GIS_FUNCTIONS.get(lookup_type, False)
|
||
|
if lookup_info:
|
||
|
return "%s(%s, %%s)" % (lookup_info, geo_col)
|
||
|
|
||
|
# Handling 'isnull' lookup type
|
||
|
# TODO: Is this needed because MySQL cannot handle NULL
|
||
|
# geometries in its spatial indices.
|
||
|
if lookup_type == 'isnull':
|
||
|
return "%s IS %sNULL" % (geo_col, (not geo_annot.value and 'NOT ' or ''))
|
||
|
|
||
|
raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type))
|