Made isvalid lookup use IsValid function to decrease code redundancy.
This commit is contained in:
parent
1d070d027c
commit
9cd6ba991f
|
@ -68,7 +68,7 @@ class BaseSpatialFeatures:
|
|||
|
||||
@property
|
||||
def supports_isvalid_lookup(self):
|
||||
return 'isvalid' in self.connection.ops.gis_operators
|
||||
return self.has_IsValid_function
|
||||
|
||||
# Is the aggregate supported by the database?
|
||||
@property
|
||||
|
|
|
@ -51,10 +51,6 @@ class SDORelate(SpatialOperator):
|
|||
return super().as_sql(connection, lookup, template_params, sql_params)
|
||||
|
||||
|
||||
class SDOIsValid(SpatialOperator):
|
||||
sql_template = "%%(func)s(%%(lhs)s, %s) = 'TRUE'" % DEFAULT_TOLERANCE
|
||||
|
||||
|
||||
class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
||||
|
||||
name = 'oracle'
|
||||
|
@ -100,7 +96,6 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
'covers': SDOOperator(func='SDO_COVERS'),
|
||||
'disjoint': SDODisjoint(),
|
||||
'intersects': SDOOperator(func='SDO_OVERLAPBDYINTERSECT'), # TODO: Is this really the same as ST_Intersects()?
|
||||
'isvalid': SDOIsValid(func='SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT'),
|
||||
'equals': SDOOperator(func='SDO_EQUAL'),
|
||||
'exact': SDOOperator(func='SDO_EQUAL'),
|
||||
'overlaps': SDOOperator(func='SDO_OVERLAPS'),
|
||||
|
|
|
@ -134,7 +134,6 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
'disjoint': PostGISOperator(func='ST_Disjoint', raster=BILATERAL),
|
||||
'equals': PostGISOperator(func='ST_Equals'),
|
||||
'intersects': PostGISOperator(func='ST_Intersects', geography=True, raster=BILATERAL),
|
||||
'isvalid': PostGISOperator(func='ST_IsValid'),
|
||||
'overlaps': PostGISOperator(func='ST_Overlaps', raster=BILATERAL),
|
||||
'relate': PostGISOperator(func='ST_Relate'),
|
||||
'touches': PostGISOperator(func='ST_Touches', raster=BILATERAL),
|
||||
|
|
|
@ -48,8 +48,6 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
select = 'AsText(%s)'
|
||||
|
||||
gis_operators = {
|
||||
# Unary predicates
|
||||
'isvalid': SpatialOperator(func='IsValid'),
|
||||
# Binary predicates
|
||||
'equals': SpatialOperator(func='Equals'),
|
||||
'disjoint': SpatialOperator(func='Disjoint'),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.db.models import * # NOQA isort:skip
|
||||
from django.db.models import __all__ as models_all # isort:skip
|
||||
import django.contrib.gis.db.models.functions # NOQA
|
||||
import django.contrib.gis.db.models.lookups # NOQA
|
||||
from django.contrib.gis.db.models.aggregates import * # NOQA
|
||||
from django.contrib.gis.db.models.aggregates import __all__ as aggregates_all
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
from decimal import Decimal
|
||||
|
||||
from django.contrib.gis.db.models.fields import GeometryField, RasterField
|
||||
from django.contrib.gis.db.models.fields import (
|
||||
BaseSpatialField, GeometryField, RasterField,
|
||||
)
|
||||
from django.contrib.gis.db.models.sql import AreaField
|
||||
from django.contrib.gis.geometry.backend import Geometry
|
||||
from django.contrib.gis.measure import (
|
||||
Area as AreaMeasure, Distance as DistanceMeasure,
|
||||
)
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db.models import BooleanField, FloatField, IntegerField, TextField
|
||||
from django.db.models import (
|
||||
BooleanField, FloatField, IntegerField, TextField, Transform,
|
||||
)
|
||||
from django.db.models.expressions import Func, Value
|
||||
|
||||
NUMERIC_TYPES = (int, float, Decimal)
|
||||
|
||||
|
||||
class GeoFunc(Func):
|
||||
class GeoFuncMixin:
|
||||
function = None
|
||||
output_field_class = None
|
||||
geom_param_pos = 0
|
||||
|
@ -70,6 +74,10 @@ class GeoFunc(Func):
|
|||
return value
|
||||
|
||||
|
||||
class GeoFunc(GeoFuncMixin, Func):
|
||||
pass
|
||||
|
||||
|
||||
class GeomValue(Value):
|
||||
geography = False
|
||||
|
||||
|
@ -319,8 +327,10 @@ class Intersection(OracleToleranceMixin, GeoFuncWithGeoParam):
|
|||
arity = 2
|
||||
|
||||
|
||||
class IsValid(OracleToleranceMixin, GeoFunc):
|
||||
output_field_class = BooleanField
|
||||
@BaseSpatialField.register_lookup
|
||||
class IsValid(OracleToleranceMixin, GeoFuncMixin, Transform):
|
||||
lookup_name = 'isvalid'
|
||||
output_field = BooleanField()
|
||||
|
||||
def as_oracle(self, compiler, connection, **extra_context):
|
||||
sql, params = super().as_oracle(compiler, connection, **extra_context)
|
||||
|
|
|
@ -261,22 +261,6 @@ class IntersectsLookup(GISLookup):
|
|||
lookup_name = 'intersects'
|
||||
|
||||
|
||||
@BaseSpatialField.register_lookup
|
||||
class IsValidLookup(GISLookup):
|
||||
lookup_name = 'isvalid'
|
||||
sql_template = '%(func)s(%(lhs)s)'
|
||||
|
||||
def as_sql(self, compiler, connection):
|
||||
if self.lhs.field.geom_type == 'RASTER':
|
||||
raise ValueError('The isvalid lookup is only available on geometry fields.')
|
||||
gis_op = connection.ops.gis_operators[self.lookup_name]
|
||||
sql, params = self.process_lhs(compiler, connection)
|
||||
sql, params = gis_op.as_sql(connection, self, {'func': gis_op.func, 'lhs': sql}, params)
|
||||
if not self.rhs:
|
||||
sql = 'NOT ' + sql
|
||||
return sql, params
|
||||
|
||||
|
||||
@BaseSpatialField.register_lookup
|
||||
class OverlapsLookup(GISLookup):
|
||||
lookup_name = 'overlaps'
|
||||
|
|
|
@ -271,8 +271,8 @@ class RasterFieldTest(TransactionTestCase):
|
|||
|
||||
def test_isvalid_lookup_with_raster_error(self):
|
||||
qs = RasterModel.objects.filter(rast__isvalid=True)
|
||||
msg = 'The isvalid lookup is only available on geometry fields.'
|
||||
with self.assertRaisesMessage(ValueError, msg):
|
||||
msg = 'Geometry functions not supported for raster fields.'
|
||||
with self.assertRaisesMessage(TypeError, msg):
|
||||
qs.count()
|
||||
|
||||
def test_result_of_gis_lookup_with_rasters(self):
|
||||
|
|
Loading…
Reference in New Issue