Added SpatialFeatures.empty_intersection_returns_none.

This commit is contained in:
Tim Graham 2020-11-11 22:23:22 -05:00 committed by Mariusz Felisiak
parent 4c62cdaa10
commit 9f91122ed8
4 changed files with 20 additions and 10 deletions

View File

@ -54,6 +54,10 @@ class BaseSpatialFeatures:
# Set of options that AsGeoJSON() doesn't support.
unsupported_geojson_options = {}
# Does Intersection() return None (rather than an empty GeometryCollection)
# for empty results?
empty_intersection_returns_none = True
@property
def supports_bbcontains_lookup(self):
return 'bbcontains' in self.connection.ops.gis_operators

View File

@ -17,8 +17,11 @@ class DatabaseFeatures(BaseSpatialFeatures, MySQLDatabaseFeatures):
unsupported_geojson_options = {'crs'}
@cached_property
def supports_empty_geometry_collection(self):
return self.connection.mysql_version >= (5, 7, 5)
def empty_intersection_returns_none(self):
return (
not self.connection.mysql_is_mariadb and
self.connection.mysql_version < (5, 7, 5)
)
@cached_property
def supports_geometry_field_unique_index(self):

View File

@ -10,3 +10,4 @@ class DatabaseFeatures(BaseSpatialFeatures, Psycopg2DatabaseFeatures):
supports_3d_functions = True
supports_raster = True
supports_empty_geometries = True
empty_intersection_returns_none = False

View File

@ -12,7 +12,7 @@ from django.db import NotSupportedError, connection
from django.db.models import IntegerField, Sum, Value
from django.test import TestCase, skipUnlessDBFeature
from ..utils import FuncTestMixin, mariadb, mysql, oracle, postgis, spatialite
from ..utils import FuncTestMixin, mariadb, mysql, oracle, postgis
from .models import City, Country, CountryWebMercator, State, Track
@ -295,11 +295,10 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
geom = Point(5, 23, srid=4326)
qs = Country.objects.annotate(inter=functions.Intersection('mpoly', geom))
for c in qs:
if spatialite or (mysql and not connection.features.supports_empty_geometry_collection) or oracle:
# When the intersection is empty, some databases return None.
expected = None
else:
expected = c.mpoly.intersection(geom)
expected = (
None if connection.features.empty_intersection_returns_none
else c.mpoly.intersection(geom)
)
self.assertEqual(c.inter, expected)
@skipUnlessDBFeature("has_IsValid_function")
@ -570,8 +569,11 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
return
for c in qs:
self.assertTrue(c.mpoly.difference(geom).equals(c.difference))
if not (spatialite or mysql):
self.assertEqual(c.mpoly.intersection(geom), c.intersection)
expected_intersection = (
None if connection.features.empty_intersection_returns_none
else c.mpoly.intersection(geom)
)
self.assertEqual(c.intersection, expected_intersection)
self.assertTrue(c.mpoly.sym_difference(geom).equals(c.sym_difference))
self.assertTrue(c.mpoly.union(geom).equals(c.union))