diff -r b758351d191f -r cc9b7e14412b web/lib/django/contrib/gis/db/backend/spatialite/query.py --- a/web/lib/django/contrib/gis/db/backend/spatialite/query.py Wed May 19 17:43:59 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -""" - This module contains the spatial lookup types, and the get_geo_where_clause() - routine for SpatiaLite. -""" -import re -from decimal import Decimal -from django.db import connection -from django.contrib.gis.measure import Distance -from django.contrib.gis.db.backend.util import SpatialOperation, SpatialFunction -qn = connection.ops.quote_name - -GEOM_SELECT = 'AsText(%s)' - -# Dummy func, in case we need it later: -def get_func(str): - return str - -# Functions used by the GeoManager & GeoQuerySet -AREA = get_func('Area') -ASSVG = get_func('AsSVG') -CENTROID = get_func('Centroid') -CONTAINED = get_func('MbrWithin') -DIFFERENCE = get_func('Difference') -DISTANCE = get_func('Distance') -ENVELOPE = get_func('Envelope') -GEOM_FROM_TEXT = get_func('GeomFromText') -GEOM_FROM_WKB = get_func('GeomFromWKB') -INTERSECTION = get_func('Intersection') -LENGTH = get_func('GLength') # OpenGis defines Length, but this conflicts with an SQLite reserved keyword -NUM_GEOM = get_func('NumGeometries') -NUM_POINTS = get_func('NumPoints') -POINT_ON_SURFACE = get_func('PointOnSurface') -SCALE = get_func('ScaleCoords') -SYM_DIFFERENCE = get_func('SymDifference') -TRANSFORM = get_func('Transform') -TRANSLATE = get_func('ShiftCoords') -UNION = 'GUnion'# OpenGis defines Union, but this conflicts with an SQLite reserved keyword -UNIONAGG = 'GUnion' - -#### Classes used in constructing SpatiaLite spatial SQL #### -class SpatiaLiteOperator(SpatialOperation): - "For SpatiaLite operators (e.g. `&&`, `~`)." - def __init__(self, operator): - super(SpatiaLiteOperator, self).__init__(operator=operator, beg_subst='%s %s %%s') - -class SpatiaLiteFunction(SpatialFunction): - "For SpatiaLite function calls." - def __init__(self, function, **kwargs): - super(SpatiaLiteFunction, self).__init__(get_func(function), **kwargs) - -class SpatiaLiteFunctionParam(SpatiaLiteFunction): - "For SpatiaLite functions that take another parameter." - def __init__(self, func): - super(SpatiaLiteFunctionParam, self).__init__(func, end_subst=', %%s)') - -class SpatiaLiteDistance(SpatiaLiteFunction): - "For SpatiaLite distance operations." - dist_func = 'Distance' - def __init__(self, operator): - super(SpatiaLiteDistance, self).__init__(self.dist_func, end_subst=') %s %s', - operator=operator, result='%%s') - -class SpatiaLiteRelate(SpatiaLiteFunctionParam): - "For SpatiaLite Relate(, ) calls." - pattern_regex = re.compile(r'^[012TF\*]{9}$') - def __init__(self, pattern): - if not self.pattern_regex.match(pattern): - raise ValueError('Invalid intersection matrix pattern "%s".' % pattern) - super(SpatiaLiteRelate, self).__init__('Relate') - - -SPATIALITE_GEOMETRY_FUNCTIONS = { - 'equals' : SpatiaLiteFunction('Equals'), - 'disjoint' : SpatiaLiteFunction('Disjoint'), - 'touches' : SpatiaLiteFunction('Touches'), - 'crosses' : SpatiaLiteFunction('Crosses'), - 'within' : SpatiaLiteFunction('Within'), - 'overlaps' : SpatiaLiteFunction('Overlaps'), - 'contains' : SpatiaLiteFunction('Contains'), - 'intersects' : SpatiaLiteFunction('Intersects'), - 'relate' : (SpatiaLiteRelate, basestring), - # Retruns true if B's bounding box completely contains A's bounding box. - 'contained' : SpatiaLiteFunction('MbrWithin'), - # Returns true if A's bounding box completely contains B's bounding box. - 'bbcontains' : SpatiaLiteFunction('MbrContains'), - # Returns true if A's bounding box overlaps B's bounding box. - 'bboverlaps' : SpatiaLiteFunction('MbrOverlaps'), - # These are implemented here as synonyms for Equals - 'same_as' : SpatiaLiteFunction('Equals'), - 'exact' : SpatiaLiteFunction('Equals'), - } - -# Valid distance types and substitutions -dtypes = (Decimal, Distance, float, int, long) -def get_dist_ops(operator): - "Returns operations for regular distances; spherical distances are not currently supported." - return (SpatiaLiteDistance(operator),) -DISTANCE_FUNCTIONS = { - 'distance_gt' : (get_dist_ops('>'), dtypes), - 'distance_gte' : (get_dist_ops('>='), dtypes), - 'distance_lt' : (get_dist_ops('<'), dtypes), - 'distance_lte' : (get_dist_ops('<='), dtypes), - } - -# Distance functions are a part of SpatiaLite geometry functions. -SPATIALITE_GEOMETRY_FUNCTIONS.update(DISTANCE_FUNCTIONS) - -# Any other lookup types that do not require a mapping. -MISC_TERMS = ['isnull'] - -# These are the SpatiaLite-customized QUERY_TERMS -- a list of the lookup types -# allowed for geographic queries. -SPATIALITE_TERMS = SPATIALITE_GEOMETRY_FUNCTIONS.keys() # Getting the Geometry Functions -SPATIALITE_TERMS += MISC_TERMS # Adding any other miscellaneous terms (e.g., 'isnull') -SPATIALITE_TERMS = dict((term, None) for term in SPATIALITE_TERMS) # Making a dictionary for fast lookups - -#### The `get_geo_where_clause` function for SpatiaLite. #### -def get_geo_where_clause(table_alias, name, lookup_type, geo_annot): - "Returns the SQL WHERE clause for use in SpatiaLite SQL construction." - # Getting the quoted field as `geo_col`. - geo_col = '%s.%s' % (qn(table_alias), qn(name)) - if lookup_type in SPATIALITE_GEOMETRY_FUNCTIONS: - # See if a SpatiaLite geometry function matches the lookup type. - tmp = SPATIALITE_GEOMETRY_FUNCTIONS[lookup_type] - - # Lookup types that are tuples take tuple arguments, e.g., 'relate' and - # distance lookups. - if isinstance(tmp, tuple): - # First element of tuple is the SpatiaLiteOperation instance, and the - # second element is either the type or a tuple of acceptable types - # that may passed in as further parameters for the lookup type. - op, arg_type = tmp - - # Ensuring that a tuple _value_ was passed in from the user - if not isinstance(geo_annot.value, (tuple, list)): - raise TypeError('Tuple required for `%s` lookup type.' % lookup_type) - - # Number of valid tuple parameters depends on the lookup type. - if len(geo_annot.value) != 2: - raise ValueError('Incorrect number of parameters given for `%s` lookup type.' % lookup_type) - - # Ensuring the argument type matches what we expect. - if not isinstance(geo_annot.value[1], arg_type): - raise TypeError('Argument type should be %s, got %s instead.' % (arg_type, type(geo_annot.value[1]))) - - # For lookup type `relate`, the op instance is not yet created (has - # to be instantiated here to check the pattern parameter). - if lookup_type == 'relate': - op = op(geo_annot.value[1]) - elif lookup_type in DISTANCE_FUNCTIONS: - op = op[0] - else: - op = tmp - # Calling the `as_sql` function on the operation instance. - return op.as_sql(geo_col) - elif lookup_type == 'isnull': - # Handling 'isnull' lookup type - return "%s IS %sNULL" % (geo_col, (not geo_annot.value and 'NOT ' or '')) - - raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type))