app/django/contrib/gis/db/backend/mysql/query.py
changeset 323 ff1a9aa48cfd
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
       
     1 """
       
     2  This module contains the spatial lookup types, and the `get_geo_where_clause`
       
     3  routine for MySQL.
       
     4 
       
     5  Please note that MySQL only supports bounding box queries, also
       
     6  known as MBRs (Minimum Bounding Rectangles).  Moreover, spatial
       
     7  indices may only be used on MyISAM tables -- if you need 
       
     8  transactions, take a look at PostGIS.
       
     9 """
       
    10 from django.db import connection
       
    11 qn = connection.ops.quote_name
       
    12 
       
    13 # To ease implementation, WKT is passed to/from MySQL.
       
    14 GEOM_FROM_TEXT = 'GeomFromText'
       
    15 GEOM_FROM_WKB = 'GeomFromWKB'
       
    16 GEOM_SELECT = 'AsText(%s)'
       
    17 
       
    18 # WARNING: MySQL is NOT compliant w/the OpenGIS specification and
       
    19 # _every_ one of these lookup types is on the _bounding box_ only.
       
    20 MYSQL_GIS_FUNCTIONS = {
       
    21     'bbcontains' : 'MBRContains', # For consistency w/PostGIS API
       
    22     'bboverlaps' : 'MBROverlaps', # .. ..
       
    23     'contained' : 'MBRWithin',    # .. ..
       
    24     'contains' : 'MBRContains',
       
    25     'disjoint' : 'MBRDisjoint',
       
    26     'equals' : 'MBREqual',
       
    27     'exact' : 'MBREqual',
       
    28     'intersects' : 'MBRIntersects',
       
    29     'overlaps' : 'MBROverlaps',
       
    30     'same_as' : 'MBREqual',
       
    31     'touches' : 'MBRTouches',
       
    32     'within' : 'MBRWithin',
       
    33     }
       
    34 
       
    35 # This lookup type does not require a mapping.
       
    36 MISC_TERMS = ['isnull']
       
    37 
       
    38 # Assacceptable lookup types for Oracle spatial.
       
    39 MYSQL_GIS_TERMS  = MYSQL_GIS_FUNCTIONS.keys()
       
    40 MYSQL_GIS_TERMS += MISC_TERMS
       
    41 MYSQL_GIS_TERMS = dict((term, None) for term in MYSQL_GIS_TERMS) # Making dictionary 
       
    42 
       
    43 def get_geo_where_clause(table_alias, name, lookup_type, geo_annot):
       
    44     "Returns the SQL WHERE clause for use in MySQL spatial SQL construction."
       
    45     # Getting the quoted field as `geo_col`.
       
    46     geo_col = '%s.%s' % (qn(table_alias), qn(name))
       
    47 
       
    48     # See if a MySQL Geometry function matches the lookup type next
       
    49     lookup_info = MYSQL_GIS_FUNCTIONS.get(lookup_type, False)
       
    50     if lookup_info:
       
    51         return "%s(%s, %%s)" % (lookup_info, geo_col)
       
    52     
       
    53     # Handling 'isnull' lookup type
       
    54     # TODO: Is this needed because MySQL cannot handle NULL
       
    55     # geometries in its spatial indices.
       
    56     if lookup_type == 'isnull':
       
    57         return "%s IS %sNULL" % (geo_col, (not geo_annot.value and 'NOT ' or ''))
       
    58 
       
    59     raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type))