Browse Source

Fixed #34686 -- Added support for GEOS 3.12.

Olivier Tabone 1 year ago
parent
commit
f46a6b2816

+ 13 - 2
django/contrib/gis/geos/prototypes/io.py

@@ -14,6 +14,7 @@ from django.contrib.gis.geos.prototypes.errcheck import (
 )
 from django.contrib.gis.geos.prototypes.geom import c_uchar_p, geos_char_p
 from django.utils.encoding import force_bytes
+from django.utils.functional import SimpleLazyObject
 
 
 # ### The WKB/WKT Reader/Writer structures and pointers ###
@@ -178,17 +179,27 @@ class _WKBReader(IOBase):
             raise TypeError
 
 
+def default_trim_value():
+    """
+    GEOS changed the default value in 3.12.0. Can be replaced by True when
+    3.12.0 becomes the minimum supported version.
+    """
+    return geos_version_tuple() >= (3, 12)
+
+
+DEFAULT_TRIM_VALUE = SimpleLazyObject(default_trim_value)
+
+
 # ### WKB/WKT Writer Classes ###
 class WKTWriter(IOBase):
     _constructor = wkt_writer_create
     ptr_type = WKT_WRITE_PTR
     destructor = wkt_writer_destroy
-
-    _trim = False
     _precision = None
 
     def __init__(self, dim=2, trim=False, precision=None):
         super().__init__()
+        self._trim = DEFAULT_TRIM_VALUE
         self.trim = trim
         if precision is not None:
             self.precision = precision

+ 2 - 1
docs/ref/contrib/gis/install/geolibs.txt

@@ -8,7 +8,7 @@ geospatial libraries:
 ========================  ====================================  ================================  ===========================================
 Program                   Description                           Required                          Supported Versions
 ========================  ====================================  ================================  ===========================================
-:doc:`GEOS <../geos>`     Geometry Engine Open Source           Yes                               3.11, 3.10, 3.9, 3.8
+:doc:`GEOS <../geos>`     Geometry Engine Open Source           Yes                               3.12, 3.11, 3.10, 3.9, 3.8
 `PROJ`_                   Cartographic Projections library      Yes (PostgreSQL and SQLite only)  9.x, 8.x, 7.x, 6.x, 5.x
 :doc:`GDAL <../gdal>`     Geospatial Data Abstraction Library   Yes                               3.7, 3.6, 3.5, 3.4, 3.3, 3.2, 3.1, 3.0, 2.4
 :doc:`GeoIP <../geoip2>`  IP-based geolocation library          No                                2
@@ -25,6 +25,7 @@ totally fine with GeoDjango. Your mileage may vary.
     GEOS 3.9.0 2020-12-14
     GEOS 3.10.0 2021-10-20
     GEOS 3.11.0 2022-07-01
+    GEOS 3.12.0 2023-06-27
     GDAL 2.4.0 2018-12
     GDAL 3.0.0 2019-05
     GDAL 3.1.0 2020-05-07

+ 2 - 0
docs/releases/5.0.txt

@@ -190,6 +190,8 @@ Minor features
 
 * Added support for GDAL 3.7.
 
+* Added support for GEOS 3.12.
+
 :mod:`django.contrib.messages`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

+ 7 - 0
tests/gis_tests/geoapp/models.py

@@ -73,6 +73,13 @@ class Feature(NamedModel):
     geom = models.GeometryField()
 
 
+class ThreeDimensionalFeature(NamedModel):
+    geom = models.GeometryField(dim=3)
+
+    class Meta:
+        required_db_features = {"supports_3d_storage"}
+
+
 class MinusOneSRID(models.Model):
     geom = models.PointField(srid=-1)  # Minus one SRID.
 

+ 8 - 1
tests/gis_tests/geoapp/tests.py

@@ -31,6 +31,7 @@ from .models import (
     NonConcreteModel,
     PennsylvaniaCity,
     State,
+    ThreeDimensionalFeature,
     Track,
 )
 
@@ -252,7 +253,13 @@ class GeoModelTest(TestCase):
         ]
         for klass in geometry_classes:
             g = klass(srid=4326)
-            feature = Feature.objects.create(name="Empty %s" % klass.__name__, geom=g)
+            model_class = Feature
+            if g.hasz:
+                if not connection.features.supports_3d_storage:
+                    continue
+                else:
+                    model_class = ThreeDimensionalFeature
+            feature = model_class.objects.create(name=f"Empty {klass.__name__}", geom=g)
             feature.refresh_from_db()
             if klass is LinearRing:
                 # LinearRing isn't representable in WKB, so GEOSGeomtry.wkb

+ 6 - 5
tests/gis_tests/relatedapp/tests.py

@@ -323,14 +323,15 @@ class RelatedGeoModelTest(TestCase):
         )
         city = qs.get(name="Aurora")
         self.assertEqual(
-            city.parcel_center.wkt, "MULTIPOINT (1.7128 -2.006, 4.7128 5.006)"
+            city.parcel_center.wkt,
+            GEOSGeometry("MULTIPOINT (1.7128 -2.006, 4.7128 5.006)"),
         )
         self.assertIsNone(city.parcel_center_nonexistent)
         self.assertIn(
             city.parcel_center_single.wkt,
             [
-                "MULTIPOINT (1.7128 -2.006)",
-                "POINT (1.7128 -2.006)",  # SpatiaLite collapse to POINT.
+                GEOSGeometry("MULTIPOINT (1.7128 -2.006)"),
+                GEOSGeometry("POINT (1.7128 -2.006)"),  # SpatiaLite collapse to POINT.
             ],
         )
 
@@ -410,8 +411,8 @@ class RelatedGeoModelTest(TestCase):
         self.assertIn(
             city.parcel_point_union.wkt,
             [
-                "MULTIPOINT (12.75 10.05, 3.7128 -5.006)",
-                "MULTIPOINT (3.7128 -5.006, 12.75 10.05)",
+                GEOSGeometry("MULTIPOINT (12.75 10.05, 3.7128 -5.006)"),
+                GEOSGeometry("MULTIPOINT (3.7128 -5.006, 12.75 10.05)"),
             ],
         )
         self.assertIsNone(city.parcel_point_nonexistent)