Fixed #35086 -- Added support for BoundedCircle on Spatialite 5.1+.

Spatialite 5.1 added support for BoundingCircle
(GEOSMinimumBoundingCircle). GEOS 3.7 is required which is lower than
Django's currently supported minmum of 3.8.

https://groups.google.com/g/spatialite-users/c/hAJ2SgitN4M

https://www.gaia-gis.it/gaia-sins/spatialite-sql-5.1.0.html
This commit is contained in:
David Smith 2024-01-04 20:50:14 +00:00 committed by Mariusz Felisiak
parent 9b056aa5af
commit 45f59d0eab
6 changed files with 26 additions and 5 deletions

View File

@ -66,6 +66,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
function_names = {
"AsWKB": "St_AsBinary",
"BoundingCircle": "GEOSMinimumBoundingCircle",
"ForcePolygonCW": "ST_ForceLHR",
"FromWKB": "ST_GeomFromWKB",
"FromWKT": "ST_GeomFromText",
@ -80,9 +81,11 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
@cached_property
def unsupported_functions(self):
unsupported = {"BoundingCircle", "GeometryDistance", "IsEmpty", "MemSize"}
unsupported = {"GeometryDistance", "IsEmpty", "MemSize"}
if not self.geom_lib_version():
unsupported |= {"Azimuth", "GeoHash", "MakeValid"}
if self.spatial_version < (5, 1):
unsupported |= {"BoundingCircle"}
return unsupported
@cached_property

View File

@ -274,6 +274,13 @@ class BoundingCircle(OracleToleranceMixin, GeomOutputGeoFunc):
compiler, connection, **extra_context
)
def as_sqlite(self, compiler, connection, **extra_context):
clone = self.copy()
clone.set_source_expressions([self.get_source_expressions()[0]])
return super(BoundingCircle, clone).as_sqlite(
compiler, connection, **extra_context
)
class Centroid(OracleToleranceMixin, GeomOutputGeoFunc):
arity = 1

View File

@ -397,7 +397,7 @@ Function PostGIS Oracle MariaDB MySQL
:class:`AsWKB` X X X X X
:class:`AsWKT` X X X X X
:class:`Azimuth` X X (LWGEOM/RTTOPO)
:class:`BoundingCircle` X X
:class:`BoundingCircle` X X X (≥ 5.1)
:class:`Centroid` X X X X X
:class:`ClosestPoint` X X
:class:`Difference` X X X X X

View File

@ -230,13 +230,18 @@ south = ``π``; west = ``3π/2``.
*Availability*: `PostGIS <https://postgis.net/docs/ST_MinimumBoundingCircle.html>`__,
`Oracle <https://docs.oracle.com/en/database/oracle/oracle-database/21/spatl/
SDO_GEOM-reference.html#GUID-82A61626-BB64-4793-B53D-A0DBEC91831A>`_
SDO_GEOM-reference.html#GUID-82A61626-BB64-4793-B53D-A0DBEC91831A>`_,
SpatiaLite 5.1+
Accepts a single geographic field or expression and returns the smallest circle
polygon that can fully contain the geometry.
The ``num_seg`` parameter is used only on PostGIS.
.. versionchanged:: 5.1
SpatiaLite 5.1+ support was added.
``Centroid``
============

View File

@ -53,7 +53,8 @@ Minor features
:mod:`django.contrib.gis`
~~~~~~~~~~~~~~~~~~~~~~~~~
* ...
* :class:`~django.contrib.gis.db.models.functions.BoundingCircle` is now
supported on SpatiaLite 5.1+.
:mod:`django.contrib.messages`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -258,7 +258,12 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
# num_seg is the number of segments per quarter circle.
return (4 * num_seg) + 1
expected_areas = (169, 136) if connection.ops.postgis else (171, 126)
if connection.ops.postgis:
expected_areas = (169, 136)
elif connection.ops.spatialite:
expected_areas = (168, 135)
else: # Oracle.
expected_areas = (171, 126)
qs = Country.objects.annotate(
circle=functions.BoundingCircle("mpoly")
).order_by("name")