mirror of
https://github.com/django/django.git
synced 2025-09-24 23:49:12 +00:00
Refs #33783 -- Added IsEmpty GIS database function and __isempty lookup on SpatiaLite.
This commit is contained in:
parent
6fe96639ba
commit
e20e189045
@ -73,6 +73,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||
"ForcePolygonCW": "ST_ForceLHR",
|
||||
"FromWKB": "ST_GeomFromWKB",
|
||||
"FromWKT": "ST_GeomFromText",
|
||||
"IsEmpty": "ST_IsEmpty",
|
||||
"Length": "ST_Length",
|
||||
"LineLocatePoint": "ST_Line_Locate_Point",
|
||||
"NumPoints": "ST_NPoints",
|
||||
@ -84,7 +85,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||
|
||||
@cached_property
|
||||
def unsupported_functions(self):
|
||||
unsupported = {"GeometryDistance", "IsEmpty", "MemSize", "Rotate"}
|
||||
unsupported = {"GeometryDistance", "MemSize", "Rotate"}
|
||||
if not self.geom_lib_version():
|
||||
unsupported |= {"Azimuth", "GeoHash", "MakeValid"}
|
||||
if self.spatial_version < (5, 1):
|
||||
|
@ -451,6 +451,10 @@ class IsEmpty(GeoFuncMixin, Transform):
|
||||
lookup_name = "isempty"
|
||||
output_field = BooleanField()
|
||||
|
||||
def as_sqlite(self, compiler, connection, **extra_context):
|
||||
sql, params = super().as_sql(compiler, connection, **extra_context)
|
||||
return "NULLIF(%s, -1)" % sql, params
|
||||
|
||||
|
||||
@BaseSpatialField.register_lookup
|
||||
class IsValid(OracleToleranceMixin, GeoFuncMixin, Transform):
|
||||
|
@ -363,7 +363,7 @@ Lookup Type PostGIS Oracle MariaDB MySQL [#]_
|
||||
:lookup:`exact <same_as>` X X X X X B
|
||||
:lookup:`geom_type` X X (≥ 23c) X X X
|
||||
:lookup:`intersects` X X X X X B
|
||||
:lookup:`isempty` X
|
||||
:lookup:`isempty` X X
|
||||
:lookup:`isvalid` X X X (≥ 12.0.1) X X
|
||||
:lookup:`overlaps` X X X X X B
|
||||
:lookup:`relate` X X X X C
|
||||
@ -414,7 +414,7 @@ Function PostGIS Oracle MariaDB MySQL
|
||||
:class:`GeometryDistance` X
|
||||
:class:`GeometryType` X X (≥ 23c) X X X
|
||||
:class:`Intersection` X X X X X
|
||||
:class:`IsEmpty` X
|
||||
:class:`IsEmpty` X X
|
||||
:class:`IsValid` X X X (≥ 12.0.1) X X
|
||||
:class:`Length` X X X X X
|
||||
:class:`LineLocatePoint` X X
|
||||
|
@ -621,11 +621,16 @@ Miscellaneous
|
||||
|
||||
.. 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:: 6.1
|
||||
|
||||
SpatiaLite support was added.
|
||||
|
||||
``IsValid``
|
||||
-----------
|
||||
|
||||
|
@ -361,7 +361,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.
|
||||
|
||||
@ -369,6 +370,10 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__isempty=True)
|
||||
|
||||
.. versionchanged:: 6.1
|
||||
|
||||
SpatiaLite support was added.
|
||||
|
||||
.. fieldlookup:: isvalid
|
||||
|
||||
``isvalid``
|
||||
|
@ -53,7 +53,9 @@ Minor features
|
||||
:mod:`django.contrib.gis`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* The :lookup:`isempty` lookup and
|
||||
:class:`IsEmpty() <django.contrib.gis.db.models.functions.IsEmpty>`
|
||||
database function are now supported on SpatiaLite.
|
||||
|
||||
:mod:`django.contrib.messages`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -431,7 +431,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_geometry_empty(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(
|
||||
@ -442,6 +442,18 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
|
||||
)
|
||||
self.assertSequenceEqual(City.objects.filter(point__isempty=True), [empty])
|
||||
|
||||
@skipUnlessDBFeature("has_IsEmpty_function")
|
||||
def test_isempty_geometry_null(self):
|
||||
nowhere = State.objects.create(name="Nowhere", poly=None)
|
||||
qs = State.objects.annotate(isempty=functions.IsEmpty("poly"))
|
||||
self.assertSequenceEqual(qs.filter(isempty=None), [nowhere])
|
||||
self.assertSequenceEqual(
|
||||
qs.filter(isempty=False).order_by("name").values_list("name", flat=True),
|
||||
["Colorado", "Kansas"],
|
||||
)
|
||||
self.assertSequenceEqual(qs.filter(isempty=True), [])
|
||||
self.assertSequenceEqual(State.objects.filter(poly__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…
x
Reference in New Issue
Block a user