Selaa lähdekoodia

Refs #31014 -- Added srid argument to FromWKB/FromWKT() GIS functions.

Claude Paroz 1 vuosi sitten
vanhempi
commit
10b31eea33

+ 19 - 6
django/contrib/gis/db/models/functions.py

@@ -367,15 +367,28 @@ class ForcePolygonCW(GeomOutputGeoFunc):
 
 
 class FromWKB(GeoFunc):
-    output_field = GeometryField(srid=0)
-    arity = 1
+    arity = 2
     geom_param_pos = ()
 
+    def __init__(self, expression, srid=0, **extra):
+        expressions = [
+            expression,
+            self._handle_param(srid, "srid", int),
+        ]
+        if "output_field" not in extra:
+            extra["output_field"] = GeometryField(srid=srid)
+        super().__init__(*expressions, **extra)
+
+    def as_oracle(self, compiler, connection, **extra_context):
+        # Oracle doesn't support the srid parameter.
+        source_expressions = self.get_source_expressions()
+        clone = self.copy()
+        clone.set_source_expressions(source_expressions[:1])
+        return super(FromWKB, clone).as_sql(compiler, connection, **extra_context)
 
-class FromWKT(GeoFunc):
-    output_field = GeometryField(srid=0)
-    arity = 1
-    geom_param_pos = ()
+
+class FromWKT(FromWKB):
+    pass
 
 
 class GeoHash(GeoFunc):

+ 16 - 4
docs/ref/contrib/gis/functions.txt

@@ -359,24 +359,36 @@ are returned unchanged.
 ``FromWKB``
 ===========
 
-.. class:: FromWKB(expression, **extra)
+.. class:: FromWKB(expression, srid=0, **extra)
 
 *Availability*: MariaDB, `MySQL
 <https://dev.mysql.com/doc/refman/en/gis-wkb-functions.html#function_st-geomfromwkb>`__,
 Oracle, `PostGIS <https://postgis.net/docs/ST_GeomFromWKB.html>`__, SpatiaLite
 
-Creates geometry from `Well-known binary (WKB)`_ representation.
+Creates geometry from `Well-known binary (WKB)`_ representation. The optional
+``srid`` argument allows to specify the SRID of the resulting geometry.
+``srid`` is ignored on Oracle.
+
+.. versionchanged:: 5.1
+
+    The ``srid`` argument was added.
 
 ``FromWKT``
 ===========
 
-.. class:: FromWKT(expression, **extra)
+.. class:: FromWKT(expression, srid=0, **extra)
 
 *Availability*: MariaDB, `MySQL
 <https://dev.mysql.com/doc/refman/en/gis-wkt-functions.html#function_st-geomfromtext>`__,
 Oracle, `PostGIS <https://postgis.net/docs/ST_GeomFromText.html>`__, SpatiaLite
 
-Creates geometry from `Well-known text (WKT)`_ representation.
+Creates geometry from `Well-known text (WKT)`_ representation. The optional
+``srid`` argument allows to specify the SRID of the resulting geometry.
+``srid`` is ignored on Oracle.
+
+.. versionchanged:: 5.1
+
+    The ``srid`` argument was added.
 
 ``GeoHash``
 ===========

+ 5 - 0
docs/releases/5.1.txt

@@ -101,6 +101,11 @@ Minor features
 * :attr:`.OGRGeometry.centroid` is now available on all supported geometry
   types.
 
+* :class:`FromWKB() <django.contrib.gis.db.models.functions.FromWKB>` and
+  :class:`FromWKT() <django.contrib.gis.db.models.functions.FromWKT>` functions
+  now support the optional ``srid`` argument (except for Oracle where it is
+  ignored).
+
 :mod:`django.contrib.messages`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

+ 10 - 6
tests/gis_tests/geoapp/test_functions.py

@@ -348,20 +348,24 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
     @skipUnlessDBFeature("has_FromWKB_function")
     def test_fromwkb(self):
         g = Point(56.811078, 60.608647)
-        g2 = City.objects.values_list(
+        pt1, pt2 = City.objects.values_list(
             functions.FromWKB(Value(g.wkb.tobytes())),
-            flat=True,
+            functions.FromWKB(Value(g.wkb.tobytes()), srid=4326),
         )[0]
-        self.assertIs(g.equals_exact(g2, 0.00001), True)
+        self.assertIs(g.equals_exact(pt1, 0.00001), True)
+        self.assertIsNone(pt1.srid)
+        self.assertEqual(pt2.srid, 4326)
 
     @skipUnlessDBFeature("has_FromWKT_function")
     def test_fromwkt(self):
         g = Point(56.811078, 60.608647)
-        g2 = City.objects.values_list(
+        pt1, pt2 = City.objects.values_list(
             functions.FromWKT(Value(g.wkt)),
-            flat=True,
+            functions.FromWKT(Value(g.wkt), srid=4326),
         )[0]
-        self.assertIs(g.equals_exact(g2, 0.00001), True)
+        self.assertIs(g.equals_exact(pt1, 0.00001), True)
+        self.assertIsNone(pt1.srid)
+        self.assertEqual(pt2.srid, 4326)
 
     @skipUnlessDBFeature("has_GeoHash_function")
     def test_geohash(self):