parent
4f99ba84b3
commit
5e710cf4a5
|
@ -25,7 +25,7 @@ class BaseSpatialOperations:
|
|||
|
||||
# Blacklist/set of known unsupported functions of the backend
|
||||
unsupported_functions = {
|
||||
'Area', 'AsGeoJSON', 'AsGML', 'AsKML', 'AsSVG',
|
||||
'Area', 'AsGeoJSON', 'AsGML', 'AsKML', 'AsSVG', 'Azimuth',
|
||||
'BoundingCircle', 'Centroid', 'Difference', 'Distance', 'Envelope',
|
||||
'ForceRHR', 'GeoHash', 'Intersection', 'IsValid', 'Length',
|
||||
'LineLocatePoint', 'MakeValid', 'MemSize', 'NumGeometries',
|
||||
|
|
|
@ -72,7 +72,7 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
@cached_property
|
||||
def unsupported_functions(self):
|
||||
unsupported = {
|
||||
'AsGML', 'AsKML', 'AsSVG', 'BoundingCircle', 'ForceRHR',
|
||||
'AsGML', 'AsKML', 'AsSVG', 'Azimuth', 'BoundingCircle', 'ForceRHR',
|
||||
'LineLocatePoint', 'MakeValid', 'MemSize', 'Perimeter',
|
||||
'PointOnSurface', 'Reverse', 'Scale', 'SnapToGrid', 'Transform',
|
||||
'Translate',
|
||||
|
|
|
@ -111,9 +111,9 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
}
|
||||
|
||||
unsupported_functions = {
|
||||
'AsGeoJSON', 'AsKML', 'AsSVG', 'Envelope', 'ForceRHR', 'GeoHash',
|
||||
'LineLocatePoint', 'MakeValid', 'MemSize', 'Scale', 'SnapToGrid',
|
||||
'Translate',
|
||||
'AsGeoJSON', 'AsKML', 'AsSVG', 'Azimuth', 'Envelope', 'ForceRHR',
|
||||
'GeoHash', 'LineLocatePoint', 'MakeValid', 'MemSize', 'Scale',
|
||||
'SnapToGrid', 'Translate',
|
||||
}
|
||||
|
||||
def geo_quote_name(self, name):
|
||||
|
|
|
@ -93,7 +93,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
def unsupported_functions(self):
|
||||
unsupported = {'BoundingCircle', 'ForceRHR', 'MemSize'}
|
||||
if not self.lwgeom_version():
|
||||
unsupported |= {'GeoHash', 'IsValid', 'MakeValid'}
|
||||
unsupported |= {'Azimuth', 'GeoHash', 'IsValid', 'MakeValid'}
|
||||
return unsupported
|
||||
|
||||
@cached_property
|
||||
|
|
|
@ -162,6 +162,12 @@ class Area(OracleToleranceMixin, GeoFunc):
|
|||
return self.as_sql(compiler, connection, **extra_context)
|
||||
|
||||
|
||||
class Azimuth(GeoFunc):
|
||||
output_field_class = FloatField
|
||||
arity = 2
|
||||
geom_param_pos = (0, 1)
|
||||
|
||||
|
||||
class AsGeoJSON(GeoFunc):
|
||||
output_field_class = TextField
|
||||
|
||||
|
|
|
@ -376,6 +376,7 @@ Function PostGIS Oracle MySQL Spat
|
|||
:class:`AsGML` X X X
|
||||
:class:`AsKML` X X
|
||||
:class:`AsSVG` X X
|
||||
:class:`Azimuth` X X (LWGEOM)
|
||||
:class:`BoundingCircle` X X
|
||||
:class:`Centroid` X X X X
|
||||
:class:`Difference` X X X (≥ 5.6.1) X
|
||||
|
|
|
@ -23,11 +23,11 @@ Function's summary:
|
|||
================== ======================= ====================== =================== ================== =====================
|
||||
Measurement Relationships Operations Editors Output format Miscellaneous
|
||||
================== ======================= ====================== =================== ================== =====================
|
||||
:class:`Area` :class:`BoundingCircle` :class:`Difference` :class:`ForceRHR` :class:`AsGeoJSON` :class:`IsValid`
|
||||
:class:`Distance` :class:`Centroid` :class:`Intersection` :class:`MakeValid` :class:`AsGML` :class:`MemSize`
|
||||
:class:`Length` :class:`Envelope` :class:`SymDifference` :class:`Reverse` :class:`AsKML` :class:`NumGeometries`
|
||||
:class:`Perimeter` :class:`PointOnSurface` :class:`Union` :class:`Scale` :class:`AsSVG` :class:`NumPoints`
|
||||
.. :class:`SnapToGrid` :class:`GeoHash`
|
||||
:class:`Area` :class:`Azimuth` :class:`Difference` :class:`ForceRHR` :class:`AsGeoJSON` :class:`IsValid`
|
||||
:class:`Distance` :class:`BoundingCircle` :class:`Intersection` :class:`MakeValid` :class:`AsGML` :class:`MemSize`
|
||||
:class:`Length` :class:`Centroid` :class:`SymDifference` :class:`Reverse` :class:`AsKML` :class:`NumGeometries`
|
||||
:class:`Perimeter` :class:`Envelope` :class:`Union` :class:`Scale` :class:`AsSVG` :class:`NumPoints`
|
||||
.. :class:`PointOnSurface` :class:`SnapToGrid` :class:`GeoHash`
|
||||
.. :class:`Transform`
|
||||
.. :class:`Translate`
|
||||
================== ======================= ====================== =================== ================== =====================
|
||||
|
@ -173,6 +173,21 @@ Keyword Argument Description
|
|||
|
||||
__ http://www.w3.org/Graphics/SVG/
|
||||
|
||||
``Azimuth``
|
||||
===========
|
||||
|
||||
.. class:: Azimuth(point_a, point_b, **extra)
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
*Availability*: `PostGIS <https://postgis.net/docs/ST_Azimuth.html>`__,
|
||||
SpatiaLite (LWGEOM)
|
||||
|
||||
Returns the azimuth in radians of the segment defined by the given point
|
||||
geometries, or ``None`` if the two points are coincident. The azimuth is angle
|
||||
referenced from north and is positive clockwise: north = ``0``; east = ``π/2``;
|
||||
south = ``π``; west = ``3π/2``.
|
||||
|
||||
``BoundingCircle``
|
||||
==================
|
||||
|
||||
|
|
|
@ -68,8 +68,9 @@ Minor features
|
|||
:class:`~django.contrib.gis.db.models.functions.IsValid` function, and
|
||||
:lookup:`isvalid` lookup.
|
||||
|
||||
* Added the :class:`~django.contrib.gis.db.models.functions.LineLocatePoint`
|
||||
function, supported on PostGIS and SpatiaLite.
|
||||
* Added the :class:`~django.contrib.gis.db.models.functions.Azimuth` and
|
||||
:class:`~django.contrib.gis.db.models.functions.LineLocatePoint` functions,
|
||||
supported on PostGIS and SpatiaLite.
|
||||
|
||||
* Any :class:`~django.contrib.gis.geos.GEOSGeometry` imported from GeoJSON now
|
||||
has its SRID set.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import json
|
||||
import math
|
||||
import re
|
||||
from decimal import Decimal
|
||||
|
||||
|
@ -145,6 +146,15 @@ class GISFunctionsTests(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_Azimuth_function")
|
||||
def test_azimuth(self):
|
||||
# Returns the azimuth in radians.
|
||||
azimuth_expr = functions.Azimuth(Point(0, 0, srid=4326), Point(1, 1, srid=4326))
|
||||
self.assertAlmostEqual(City.objects.annotate(azimuth=azimuth_expr).first().azimuth, math.pi / 4)
|
||||
# Returns None if the two points are coincident.
|
||||
azimuth_expr = functions.Azimuth(Point(0, 0, srid=4326), Point(0, 0, srid=4326))
|
||||
self.assertIsNone(City.objects.annotate(azimuth=azimuth_expr).first().azimuth)
|
||||
|
||||
@skipUnlessDBFeature("has_BoundingCircle_function")
|
||||
def test_bounding_circle(self):
|
||||
def circle_num_points(num_seg):
|
||||
|
|
Loading…
Reference in New Issue