mirror of https://github.com/django/django.git
Refs #31014 -- Added FromWKB and FromWKT GIS database functions.
Co-authored-by: Ondřej Böhm <ondrej.bohm@firma.seznam.cz> Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com> Co-authored-by: Sergey Fedoseev <fedoseev.sergey@gmail.com>
This commit is contained in:
parent
72efd840a8
commit
552384fa97
|
@ -45,6 +45,8 @@ class BaseSpatialOperations:
|
|||
"Difference",
|
||||
"Distance",
|
||||
"Envelope",
|
||||
"FromWKB",
|
||||
"FromWKT",
|
||||
"GeoHash",
|
||||
"GeometryDistance",
|
||||
"Intersection",
|
||||
|
|
|
@ -62,6 +62,11 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
models.Union,
|
||||
)
|
||||
|
||||
function_names = {
|
||||
"FromWKB": "ST_GeomFromWKB",
|
||||
"FromWKT": "ST_GeomFromText",
|
||||
}
|
||||
|
||||
@cached_property
|
||||
def unsupported_functions(self):
|
||||
unsupported = {
|
||||
|
|
|
@ -76,6 +76,8 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
"Difference": "SDO_GEOM.SDO_DIFFERENCE",
|
||||
"Distance": "SDO_GEOM.SDO_DISTANCE",
|
||||
"Envelope": "SDO_GEOM_MBR",
|
||||
"FromWKB": "SDO_UTIL.FROM_WKBGEOMETRY",
|
||||
"FromWKT": "SDO_UTIL.FROM_WKTGEOMETRY",
|
||||
"Intersection": "SDO_GEOM.SDO_INTERSECTION",
|
||||
"IsValid": "SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT",
|
||||
"Length": "SDO_GEOM.SDO_LENGTH",
|
||||
|
|
|
@ -172,6 +172,8 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
"AsWKB": "ST_AsBinary",
|
||||
"AsWKT": "ST_AsText",
|
||||
"BoundingCircle": "ST_MinimumBoundingCircle",
|
||||
"FromWKB": "ST_GeomFromWKB",
|
||||
"FromWKT": "ST_GeomFromText",
|
||||
"NumPoints": "ST_NPoints",
|
||||
}
|
||||
return function_names
|
||||
|
|
|
@ -67,6 +67,8 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
function_names = {
|
||||
"AsWKB": "St_AsBinary",
|
||||
"ForcePolygonCW": "ST_ForceLHR",
|
||||
"FromWKB": "ST_GeomFromWKB",
|
||||
"FromWKT": "ST_GeomFromText",
|
||||
"Length": "ST_Length",
|
||||
"LineLocatePoint": "ST_Line_Locate_Point",
|
||||
"NumPoints": "ST_NPoints",
|
||||
|
|
|
@ -69,6 +69,8 @@ class GeoFuncMixin:
|
|||
|
||||
def resolve_expression(self, *args, **kwargs):
|
||||
res = super().resolve_expression(*args, **kwargs)
|
||||
if not self.geom_param_pos:
|
||||
return res
|
||||
|
||||
# Ensure that expressions are geometric.
|
||||
source_fields = res.get_source_fields()
|
||||
|
@ -351,6 +353,18 @@ class ForcePolygonCW(GeomOutputGeoFunc):
|
|||
arity = 1
|
||||
|
||||
|
||||
class FromWKB(GeoFunc):
|
||||
output_field = GeometryField(srid=0)
|
||||
arity = 1
|
||||
geom_param_pos = ()
|
||||
|
||||
|
||||
class FromWKT(GeoFunc):
|
||||
output_field = GeometryField(srid=0)
|
||||
arity = 1
|
||||
geom_param_pos = ()
|
||||
|
||||
|
||||
class GeoHash(GeoFunc):
|
||||
output_field = TextField()
|
||||
|
||||
|
|
|
@ -360,6 +360,8 @@ Function PostGIS Oracle MariaDB MySQL
|
|||
:class:`Distance` X X X X X
|
||||
:class:`Envelope` X X X X X
|
||||
:class:`ForcePolygonCW` X X
|
||||
:class:`FromWKB` X X X X X
|
||||
:class:`FromWKT` X X X X X
|
||||
:class:`GeoHash` X X X (LWGEOM/RTTOPO)
|
||||
:class:`Intersection` X X X X X
|
||||
:class:`IsEmpty` X
|
||||
|
|
|
@ -20,17 +20,17 @@ get a ``NotImplementedError`` exception.
|
|||
|
||||
Function's summary:
|
||||
|
||||
========================= ======================== ====================== ======================= ================== =====================
|
||||
Measurement Relationships Operations Editors Output format Miscellaneous
|
||||
========================= ======================== ====================== ======================= ================== =====================
|
||||
:class:`Area` :class:`Azimuth` :class:`Difference` :class:`ForcePolygonCW` :class:`AsGeoJSON` :class:`IsEmpty`
|
||||
:class:`Distance` :class:`BoundingCircle` :class:`Intersection` :class:`MakeValid` :class:`AsGML` :class:`IsValid`
|
||||
:class:`GeometryDistance` :class:`Centroid` :class:`SymDifference` :class:`Reverse` :class:`AsKML` :class:`MemSize`
|
||||
:class:`Length` :class:`Envelope` :class:`Union` :class:`Scale` :class:`AsSVG` :class:`NumGeometries`
|
||||
:class:`Perimeter` :class:`LineLocatePoint` :class:`SnapToGrid` :class:`AsWKB` :class:`NumPoints`
|
||||
.. :class:`PointOnSurface` :class:`Transform` :class:`AsWKT`
|
||||
.. :class:`Translate` :class:`GeoHash`
|
||||
========================= ======================== ====================== ======================= ================== =====================
|
||||
========================= ======================== ====================== ======================= ================== ================== ======================
|
||||
Measurement Relationships Operations Editors Input format Output format Miscellaneous
|
||||
========================= ======================== ====================== ======================= ================== ================== ======================
|
||||
:class:`Area` :class:`Azimuth` :class:`Difference` :class:`ForcePolygonCW` :class:`AsGeoJSON` :class:`IsEmpty`
|
||||
:class:`Distance` :class:`BoundingCircle` :class:`Intersection` :class:`MakeValid` :class:`AsGML` :class:`IsValid`
|
||||
:class:`GeometryDistance` :class:`Centroid` :class:`SymDifference` :class:`Reverse` :class:`AsKML` :class:`MemSize`
|
||||
:class:`Length` :class:`Envelope` :class:`Union` :class:`Scale` :class:`AsSVG` :class:`NumGeometries`
|
||||
:class:`Perimeter` :class:`LineLocatePoint` :class:`SnapToGrid` :class:`FromWKB` :class:`AsWKB` :class:`NumPoints`
|
||||
:class:`PointOnSurface` :class:`Transform` :class:`FromWKT` :class:`AsWKT`
|
||||
:class:`Translate` :class:`GeoHash`
|
||||
========================= ======================== ====================== ======================= ================== ================== ======================
|
||||
|
||||
``Area``
|
||||
========
|
||||
|
@ -174,15 +174,13 @@ __ https://www.w3.org/Graphics/SVG/
|
|||
Oracle, `PostGIS <https://postgis.net/docs/ST_AsBinary.html>`__, SpatiaLite
|
||||
|
||||
Accepts a single geographic field or expression and returns a `Well-known
|
||||
binary (WKB)`__ representation of the geometry.
|
||||
binary (WKB)`_ representation of the geometry.
|
||||
|
||||
Example::
|
||||
|
||||
>>> bytes(City.objects.annotate(wkb=AsWKB('point')).get(name='Chelyabinsk').wkb)
|
||||
b'\x01\x01\x00\x00\x00]3\xf9f\x9b\x91K@\x00X\x1d9\xd2\xb9N@'
|
||||
|
||||
__ https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary
|
||||
|
||||
``AsWKT``
|
||||
=========
|
||||
|
||||
|
@ -193,15 +191,13 @@ __ https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well
|
|||
Oracle, `PostGIS <https://postgis.net/docs/ST_AsText.html>`__, SpatiaLite
|
||||
|
||||
Accepts a single geographic field or expression and returns a `Well-known text
|
||||
(WKT)`__ representation of the geometry.
|
||||
(WKT)`_ representation of the geometry.
|
||||
|
||||
Example::
|
||||
|
||||
>>> City.objects.annotate(wkt=AsWKT('point')).get(name='Chelyabinsk').wkt
|
||||
'POINT (55.137555 61.451728)'
|
||||
|
||||
__ https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry
|
||||
|
||||
``Azimuth``
|
||||
===========
|
||||
|
||||
|
@ -327,6 +323,32 @@ of the polygon/multipolygon in which all exterior rings are oriented clockwise
|
|||
and all interior rings are oriented counterclockwise. Non-polygonal geometries
|
||||
are returned unchanged.
|
||||
|
||||
``FromWKB``
|
||||
===========
|
||||
|
||||
.. versionadded:: 4.2
|
||||
|
||||
.. class:: FromWKB(expression, **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.
|
||||
|
||||
``FromWKT``
|
||||
===========
|
||||
|
||||
.. versionadded:: 4.2
|
||||
|
||||
.. class:: FromWKT(expression, **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.
|
||||
|
||||
``GeoHash``
|
||||
===========
|
||||
|
||||
|
@ -596,3 +618,6 @@ parameters.
|
|||
|
||||
Accepts two geographic fields or expressions and returns the union of both
|
||||
geometries.
|
||||
|
||||
.. _`Well-known binary (WKB)`: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary
|
||||
.. _`Well-known text (WKT)`: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry
|
||||
|
|
|
@ -167,6 +167,11 @@ Minor features
|
|||
:class:`IsEmpty() <django.contrib.gis.db.models.functions.IsEmpty>`
|
||||
expression allow filtering empty geometries on PostGIS.
|
||||
|
||||
* The new :class:`FromWKB() <django.contrib.gis.db.models.functions.FromWKB>`
|
||||
and :class:`FromWKT() <django.contrib.gis.db.models.functions.FromWKT>`
|
||||
functions allow creating geometries from Well-known binary (WKB) and
|
||||
Well-known text (WKT) representations.
|
||||
|
||||
:mod:`django.contrib.messages`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -326,6 +326,24 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
|
|||
).get(name="Foo")
|
||||
self.assertEqual(rhr_rings, st.force_polygon_cw.coords)
|
||||
|
||||
@skipUnlessDBFeature("has_FromWKB_function")
|
||||
def test_fromwkb(self):
|
||||
g = Point(56.811078, 60.608647)
|
||||
g2 = City.objects.values_list(
|
||||
functions.FromWKB(Value(g.wkb.tobytes())),
|
||||
flat=True,
|
||||
)[0]
|
||||
self.assertIs(g.equals_exact(g2, 0.00001), True)
|
||||
|
||||
@skipUnlessDBFeature("has_FromWKT_function")
|
||||
def test_fromwkt(self):
|
||||
g = Point(56.811078, 60.608647)
|
||||
g2 = City.objects.values_list(
|
||||
functions.FromWKT(Value(g.wkt)),
|
||||
flat=True,
|
||||
)[0]
|
||||
self.assertIs(g.equals_exact(g2, 0.00001), True)
|
||||
|
||||
@skipUnlessDBFeature("has_GeoHash_function")
|
||||
def test_geohash(self):
|
||||
# Reference query:
|
||||
|
|
Loading…
Reference in New Issue