Fixed #30996 -- Added AsWKB and AsWKT GIS functions.
This commit is contained in:
parent
8929afb8ec
commit
a5855c8f0f
|
@ -65,6 +65,8 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
function_names = {
|
||||
'Area': 'SDO_GEOM.SDO_AREA',
|
||||
'AsGeoJSON': 'SDO_UTIL.TO_GEOJSON',
|
||||
'AsWKB': 'SDO_UTIL.TO_WKBGEOMETRY',
|
||||
'AsWKT': 'SDO_UTIL.TO_WKTGEOMETRY',
|
||||
'BoundingCircle': 'SDO_GEOM.SDO_MBC',
|
||||
'Centroid': 'SDO_GEOM.SDO_CENTROID',
|
||||
'Difference': 'SDO_GEOM.SDO_DIFFERENCE',
|
||||
|
|
|
@ -148,6 +148,8 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
@cached_property
|
||||
def function_names(self):
|
||||
function_names = {
|
||||
'AsWKB': 'ST_AsBinary',
|
||||
'AsWKT': 'ST_AsText',
|
||||
'BoundingCircle': 'ST_MinimumBoundingCircle',
|
||||
'NumPoints': 'ST_NPoints',
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
select = 'CAST (AsEWKB(%s) AS BLOB)'
|
||||
|
||||
function_names = {
|
||||
'AsWKB': 'St_AsBinary',
|
||||
'ForcePolygonCW': 'ST_ForceLHR',
|
||||
'Length': 'ST_Length',
|
||||
'LineLocatePoint': 'ST_Line_Locate_Point',
|
||||
|
|
|
@ -5,7 +5,7 @@ from django.contrib.gis.db.models.sql import AreaField, DistanceField
|
|||
from django.contrib.gis.geos import GEOSGeometry
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db.models import (
|
||||
BooleanField, FloatField, IntegerField, TextField, Transform,
|
||||
BinaryField, BooleanField, FloatField, IntegerField, TextField, Transform,
|
||||
)
|
||||
from django.db.models.expressions import Func, Value
|
||||
from django.db.models.functions import Cast
|
||||
|
@ -209,6 +209,16 @@ class AsSVG(GeoFunc):
|
|||
super().__init__(*expressions, **extra)
|
||||
|
||||
|
||||
class AsWKB(GeoFunc):
|
||||
output_field = BinaryField()
|
||||
arity = 1
|
||||
|
||||
|
||||
class AsWKT(GeoFunc):
|
||||
output_field = TextField()
|
||||
arity = 1
|
||||
|
||||
|
||||
class BoundingCircle(OracleToleranceMixin, GeoFunc):
|
||||
def __init__(self, expression, num_seg=48, **extra):
|
||||
super().__init__(expression, num_seg, **extra)
|
||||
|
|
|
@ -364,6 +364,8 @@ Function PostGIS Oracle MariaDB MySQL
|
|||
:class:`AsGML` X X X
|
||||
:class:`AsKML` X X
|
||||
:class:`AsSVG` X X
|
||||
:class:`AsWKB` X X X X X
|
||||
:class:`AsWKT` X X X X X
|
||||
:class:`Azimuth` X X (LWGEOM)
|
||||
:class:`BoundingCircle` X X
|
||||
:class:`Centroid` X X X X X
|
||||
|
|
|
@ -27,9 +27,9 @@ Measurement Relationships Operations Edi
|
|||
:class:`Distance` :class:`BoundingCircle` :class:`Intersection` :class:`MakeValid` :class:`AsGML` :class:`MemSize`
|
||||
:class:`GeometryDistance` :class:`Centroid` :class:`SymDifference` :class:`Reverse` :class:`AsKML` :class:`NumGeometries`
|
||||
:class:`Length` :class:`Envelope` :class:`Union` :class:`Scale` :class:`AsSVG` :class:`NumPoints`
|
||||
:class:`Perimeter` :class:`LineLocatePoint` :class:`SnapToGrid` :class:`GeoHash`
|
||||
.. :class:`PointOnSurface` :class:`Transform`
|
||||
.. :class:`Translate`
|
||||
:class:`Perimeter` :class:`LineLocatePoint` :class:`SnapToGrid` :class:`AsWKB`
|
||||
.. :class:`PointOnSurface` :class:`Transform` :class:`AsWKT`
|
||||
.. :class:`Translate` :class:`GeoHash`
|
||||
========================= ======================== ====================== ======================= ================== =====================
|
||||
|
||||
``Area``
|
||||
|
@ -168,6 +168,48 @@ Keyword Argument Description
|
|||
|
||||
__ https://www.w3.org/Graphics/SVG/
|
||||
|
||||
``AsWKB``
|
||||
=========
|
||||
|
||||
.. class:: AsWKB(expression, **extra)
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
*Availability*: MariaDB, `MySQL
|
||||
<https://dev.mysql.com/doc/refman/en/gis-format-conversion-functions.html#function_st-asbinary>`__,
|
||||
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.
|
||||
|
||||
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``
|
||||
=========
|
||||
|
||||
.. class:: AsWKT(expression, **extra)
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
*Availability*: MariaDB, `MySQL
|
||||
<https://dev.mysql.com/doc/refman/en/gis-format-conversion-functions.html#function_st-astext>`__,
|
||||
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.
|
||||
|
||||
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``
|
||||
===========
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ Minor features
|
|||
* :class:`~django.contrib.gis.db.models.functions.AsGeoJSON` is now supported
|
||||
on Oracle.
|
||||
|
||||
* Added the :class:`~django.contrib.gis.db.models.functions.AsWKB` and
|
||||
:class:`~django.contrib.gis.db.models.functions.AsWKT` functions.
|
||||
|
||||
:mod:`django.contrib.messages`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -147,6 +147,29 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
|
|||
self.assertEqual(svg1, City.objects.annotate(svg=functions.AsSVG('point')).get(name='Pueblo').svg)
|
||||
self.assertEqual(svg2, City.objects.annotate(svg=functions.AsSVG('point', relative=5)).get(name='Pueblo').svg)
|
||||
|
||||
@skipUnlessDBFeature('has_AsWKB_function')
|
||||
def test_aswkb(self):
|
||||
wkb = City.objects.annotate(
|
||||
wkb=functions.AsWKB(Point(1, 2, srid=4326)),
|
||||
).first().wkb
|
||||
# WKB is either XDR or NDR encoded.
|
||||
self.assertIn(
|
||||
bytes(wkb),
|
||||
(
|
||||
b'\x00\x00\x00\x00\x01?\xf0\x00\x00\x00\x00\x00\x00@\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00',
|
||||
b'\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00@',
|
||||
),
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature('has_AsWKT_function')
|
||||
def test_aswkt(self):
|
||||
wkt = City.objects.annotate(
|
||||
wkt=functions.AsWKT(Point(1, 2, srid=4326)),
|
||||
).first().wkt
|
||||
self.assertEqual(wkt, 'POINT (1.0 2.0)' if oracle else 'POINT(1 2)')
|
||||
|
||||
@skipUnlessDBFeature("has_Azimuth_function")
|
||||
def test_azimuth(self):
|
||||
# Returns the azimuth in radians.
|
||||
|
|
Loading…
Reference in New Issue