'Constructs spatial SQL from the given lookup value tuple a
(alias, col, db_type), the lookup type string, lookup value, and
the geometry field.'

def spatial_lookup_sql(self, lvalue, lookup_type, value, field, qn):

    (alias, col, db_type) = lvalue
    geo_col = ('%s.%s' % (qn(alias), qn(col)))
    if (lookup_type in self.geometry_operators):
        if (field.geography and (not (lookup_type in self.geography_operators))):
            raise ValueError(('PostGIS    geography    does    not    support    the    "%s"    lookup.' % lookup_type))
        op = self.geometry_operators[lookup_type]
        return op.as_sql(geo_col, self.get_geom_placeholder(field, value))
    elif (lookup_type in self.geometry_functions):
        if (field.geography and (not (lookup_type in self.geography_functions))):
            raise ValueError(('PostGIS    geography    type    does    not    support    the    "%s"    lookup.' % lookup_type))
        tmp = self.geometry_functions[lookup_type]
        if isinstance(tmp, tuple):
            (op, arg_type) = tmp
            if (not isinstance(value, (tuple, list))):
                raise ValueError(('Tuple    required    for    `%s`    lookup    type.' % lookup_type))
            geom = value[0]
            nparams = len(value)
            if (not self.num_params(lookup_type, nparams)):
                raise ValueError(('Incorrect    number    of    parameters    given    for    `%s`    lookup    type.' % lookup_type))
            if (not isinstance(value[1], arg_type)):
                raise ValueError(('Argument    type    should    be    %s,    got    %s    instead.' % (arg_type, type(value[1]))))
            if (lookup_type == 'relate'):
                op = op(self.geom_func_prefix, value[1])
            elif ((lookup_type in self.distance_functions) and (lookup_type != 'dwithin')):
                if ((not field.geography) and field.geodetic(self.connection)):
                    if (not self.connection.ops.geography):
                        if (field.geom_type != 'POINT'):
                            raise ValueError('PostGIS    spherical    operations    are    only    valid    on    PointFields.')
                        if (str(geom.geom_type) != 'Point'):
                            raise ValueError('PostGIS    geometry    distance    parameter    is    required    to    be    of    type    Point.')
                    if ((nparams == 3) and (value[2] == 'spheroid')):
                        op = op['spheroid']
                    else:
                        op = op['sphere']
                else:
                    op = op['cartesian']
        else:
            op = tmp
            geom = value
        return op.as_sql(geo_col, self.get_geom_placeholder(field, geom))
    elif (lookup_type == 'isnull'):
        return ('%s    IS    %sNULL' % (geo_col, (((not value) and 'NOT    ') or '')))
    raise TypeError(('Got    invalid    lookup_type:    %s' % repr(lookup_type)))
