mirror of
https://github.com/django/django.git
synced 2024-11-24 20:07:01 +01:00
Refs #33783 -- Added IsEmpty GIS database function and __isempty lookup on SpatiaLite.
This commit is contained in:
parent
43287cbb87
commit
1e67d1a061
@ -82,7 +82,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||
|
||||
@cached_property
|
||||
def unsupported_functions(self):
|
||||
unsupported = {"GeometryDistance", "IsEmpty", "MemSize"}
|
||||
unsupported = {"GeometryDistance", "MemSize"}
|
||||
if not self.geom_lib_version():
|
||||
unsupported |= {"Azimuth", "GeoHash", "MakeValid"}
|
||||
if self.spatial_version < (5, 1):
|
||||
|
@ -359,7 +359,7 @@ Lookup Type PostGIS Oracle MariaDB MySQL [#]_ S
|
||||
:lookup:`equals` X X X X X C
|
||||
:lookup:`exact <same_as>` X X X X X B
|
||||
:lookup:`intersects` X X X X X B
|
||||
:lookup:`isempty` X
|
||||
:lookup:`isempty` X X
|
||||
:lookup:`isvalid` X X X (≥ 11.7) X X
|
||||
:lookup:`overlaps` X X X X X B
|
||||
:lookup:`relate` X X X X C
|
||||
@ -408,7 +408,7 @@ Function PostGIS Oracle MariaDB MySQL
|
||||
:class:`FromWKT` X X X X X
|
||||
:class:`GeoHash` X X (≥ 11.7) X X (LWGEOM/RTTOPO)
|
||||
:class:`Intersection` X X X X X
|
||||
:class:`IsEmpty` X
|
||||
:class:`IsEmpty` X X
|
||||
:class:`IsValid` X X X (≥ 11.7) X X
|
||||
:class:`Length` X X X X X
|
||||
:class:`LineLocatePoint` X X
|
||||
|
@ -438,11 +438,16 @@ intersection between them.
|
||||
|
||||
.. class:: IsEmpty(expr)
|
||||
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_IsEmpty.html>`__
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_IsEmpty.html>`__,
|
||||
SpatiaLite
|
||||
|
||||
Accepts a geographic field or expression and tests if the value is an empty
|
||||
geometry. Returns ``True`` if its value is empty and ``False`` otherwise.
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
Support for SpatiaLite was added.
|
||||
|
||||
``IsValid``
|
||||
===========
|
||||
|
||||
|
@ -362,7 +362,8 @@ SpatiaLite ``Intersects(poly, geom)``
|
||||
``isempty``
|
||||
-----------
|
||||
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_IsEmpty.html>`__
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_IsEmpty.html>`__,
|
||||
SpatiaLite
|
||||
|
||||
Tests if the geometry is empty.
|
||||
|
||||
@ -372,6 +373,10 @@ Example::
|
||||
|
||||
.. fieldlookup:: isvalid
|
||||
|
||||
.. versionchanged:: 5.2
|
||||
|
||||
Support for SpatiaLite was added.
|
||||
|
||||
``isvalid``
|
||||
-----------
|
||||
|
||||
|
@ -108,6 +108,10 @@ Minor features
|
||||
:class:`~django.contrib.gis.db.models.functions.IsValid` database functions
|
||||
are now supported on MariaDB 11.7+.
|
||||
|
||||
* The :lookup:`isempty` lookup and
|
||||
:class:`~django.contrib.gis.db.models.functions.IsEmpty` expression are now
|
||||
supported on SpatiaLite.
|
||||
|
||||
:mod:`django.contrib.messages`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -28,6 +28,13 @@ class City(NamedModel):
|
||||
app_label = "geoapp"
|
||||
|
||||
|
||||
class Town(NamedModel):
|
||||
point = models.PointField(null=True)
|
||||
|
||||
class Meta:
|
||||
app_label = "geoapp"
|
||||
|
||||
|
||||
# This is an inherited model from City
|
||||
class PennsylvaniaCity(City):
|
||||
county = models.CharField(max_length=30)
|
||||
|
@ -11,7 +11,15 @@ from django.db.models import IntegerField, Sum, Value
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
|
||||
from ..utils import FuncTestMixin
|
||||
from .models import City, Country, CountryWebMercator, ManyPointModel, State, Track
|
||||
from .models import (
|
||||
City,
|
||||
Country,
|
||||
CountryWebMercator,
|
||||
ManyPointModel,
|
||||
State,
|
||||
Town,
|
||||
Track,
|
||||
)
|
||||
|
||||
|
||||
class GISFunctionsTests(FuncTestMixin, TestCase):
|
||||
@ -413,7 +421,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
|
||||
self.assertIs(c.inter.empty, True)
|
||||
|
||||
@skipUnlessDBFeature("supports_empty_geometries", "has_IsEmpty_function")
|
||||
def test_isempty(self):
|
||||
def test_isempty_empty_geometry(self):
|
||||
empty = City.objects.create(name="Nowhere", point=Point(srid=4326))
|
||||
City.objects.create(name="Somewhere", point=Point(6.825, 47.1, srid=4326))
|
||||
self.assertSequenceEqual(
|
||||
@ -424,6 +432,29 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
|
||||
)
|
||||
self.assertSequenceEqual(City.objects.filter(point__isempty=True), [empty])
|
||||
|
||||
@skipUnlessDBFeature("has_IsEmpty_function")
|
||||
def test_isempty_null_geometry(self):
|
||||
null_geometry = Town.objects.create(name="Nowhere", point=None)
|
||||
Town.objects.create(name="Somewhere", point=Point(6.825, 47.1, srid=4326))
|
||||
if connection.ops.spatialite:
|
||||
self.assertSequenceEqual(
|
||||
Town.objects.annotate(isempty=functions.IsEmpty("point")).filter(
|
||||
isempty=True
|
||||
),
|
||||
[null_geometry],
|
||||
)
|
||||
self.assertSequenceEqual(
|
||||
Town.objects.filter(point__isempty=True), [null_geometry]
|
||||
)
|
||||
else:
|
||||
self.assertSequenceEqual(
|
||||
Town.objects.annotate(isempty=functions.IsEmpty("point")).filter(
|
||||
isempty=True
|
||||
),
|
||||
[],
|
||||
)
|
||||
self.assertSequenceEqual(Town.objects.filter(point__isempty=True), [])
|
||||
|
||||
@skipUnlessDBFeature("has_IsValid_function")
|
||||
def test_isvalid(self):
|
||||
valid_geom = fromstr("POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))")
|
||||
|
Loading…
Reference in New Issue
Block a user