1
0
mirror of https://github.com/django/django.git synced 2025-06-05 03:29:12 +00:00

Refs #35783 -- Added NumDimensions geographic database function.

This commit is contained in:
David Smith 2024-09-23 18:21:02 +01:00
parent 3d819e2324
commit 3b7c018ceb
10 changed files with 57 additions and 4 deletions

View File

@ -57,6 +57,7 @@ class BaseSpatialOperations:
"LineLocatePoint", "LineLocatePoint",
"MakeValid", "MakeValid",
"MemSize", "MemSize",
"NumDimensions",
"NumGeometries", "NumGeometries",
"NumPoints", "NumPoints",
"Perimeter", "Perimeter",

View File

@ -100,6 +100,7 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
"LineLocatePoint", "LineLocatePoint",
"MakeValid", "MakeValid",
"MemSize", "MemSize",
"NumDimensions",
"Perimeter", "Perimeter",
"PointOnSurface", "PointOnSurface",
"Reverse", "Reverse",

View File

@ -129,6 +129,7 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
"LineLocatePoint", "LineLocatePoint",
"MakeValid", "MakeValid",
"MemSize", "MemSize",
"NumDimensions",
"Scale", "Scale",
"SnapToGrid", "SnapToGrid",
"Translate", "Translate",

View File

@ -176,6 +176,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
"BoundingCircle": "ST_MinimumBoundingCircle", "BoundingCircle": "ST_MinimumBoundingCircle",
"FromWKB": "ST_GeomFromWKB", "FromWKB": "ST_GeomFromWKB",
"FromWKT": "ST_GeomFromText", "FromWKT": "ST_GeomFromText",
"NumDimensions": "ST_NDims",
"NumPoints": "ST_NPoints", "NumPoints": "ST_NPoints",
} }
return function_names return function_names

View File

@ -73,6 +73,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
"FromWKT": "ST_GeomFromText", "FromWKT": "ST_GeomFromText",
"Length": "ST_Length", "Length": "ST_Length",
"LineLocatePoint": "ST_Line_Locate_Point", "LineLocatePoint": "ST_Line_Locate_Point",
"NumDimensions": "ST_NDims",
"NumPoints": "ST_NPoints", "NumPoints": "ST_NPoints",
"Reverse": "ST_Reverse", "Reverse": "ST_Reverse",
"Scale": "ScaleCoords", "Scale": "ScaleCoords",

View File

@ -491,6 +491,11 @@ class MemSize(GeoFunc):
arity = 1 arity = 1
class NumDimensions(GeoFunc):
output_field = IntegerField()
arity = 1
class NumGeometries(GeoFunc): class NumGeometries(GeoFunc):
output_field = IntegerField() output_field = IntegerField()
arity = 1 arity = 1

View File

@ -414,6 +414,7 @@ Function PostGIS Oracle MariaDB MySQL
:class:`LineLocatePoint` X X :class:`LineLocatePoint` X X
:class:`MakeValid` X X (LWGEOM/RTTOPO) :class:`MakeValid` X X (LWGEOM/RTTOPO)
:class:`MemSize` X :class:`MemSize` X
:class:`NumDimensions` X X
:class:`NumGeometries` X X X X X :class:`NumGeometries` X X X X X
:class:`NumPoints` X X X X X :class:`NumPoints` X X X X X
:class:`Perimeter` X X X :class:`Perimeter` X X X

View File

@ -28,9 +28,9 @@ Measurement Relationships Operations Edi
:class:`Area` :class:`Azimuth` :class:`Difference` :class:`ForcePolygonCW` :class:`AsGeoJSON` :class:`IsEmpty` :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:`Distance` :class:`BoundingCircle` :class:`Intersection` :class:`MakeValid` :class:`AsGML` :class:`IsValid`
:class:`GeometryDistance` :class:`Centroid` :class:`SymDifference` :class:`Reverse` :class:`AsKML` :class:`MemSize` :class:`GeometryDistance` :class:`Centroid` :class:`SymDifference` :class:`Reverse` :class:`AsKML` :class:`MemSize`
:class:`Length` :class:`ClosestPoint` :class:`Union` :class:`Scale` :class:`AsSVG` :class:`NumGeometries` :class:`Length` :class:`ClosestPoint` :class:`Union` :class:`Scale` :class:`AsSVG` :class:`NumDimensions`
:class:`Perimeter` :class:`Envelope` :class:`SnapToGrid` :class:`FromWKB` :class:`AsWKB` :class:`NumPoints` :class:`Perimeter` :class:`Envelope` :class:`SnapToGrid` :class:`FromWKB` :class:`AsWKB` :class:`NumGeometries`
:class:`LineLocatePoint` :class:`Transform` :class:`FromWKT` :class:`AsWKT` :class:`LineLocatePoint` :class:`Transform` :class:`FromWKT` :class:`AsWKT` :class:`NumPoints`
:class:`PointOnSurface` :class:`Translate` :class:`GeoHash` :class:`PointOnSurface` :class:`Translate` :class:`GeoHash`
========================= ======================== ====================== ======================= ================== ================== ====================== ========================= ======================== ====================== ======================= ================== ================== ======================
@ -513,6 +513,19 @@ multipolygon and the result might be of lower dimension than the input.
Accepts a single geographic field or expression and returns the memory size Accepts a single geographic field or expression and returns the memory size
(number of bytes) that the geometry field takes. (number of bytes) that the geometry field takes.
``NumDimensions``
=================
.. class:: NumDimensions(expression, **extra)
.. versionadded:: 5.2
*Availability*: `PostGIS <https://postgis.net/docs/ST_NDims.html>`__,
SpatiaLite
Accepts a single geometry field or expression and returns the number of
dimensions used by the geometry.
``NumGeometries`` ``NumGeometries``
================= =================

View File

@ -132,6 +132,10 @@ Minor features
:class:`~django.contrib.gis.db.models.functions.IsValid` database functions :class:`~django.contrib.gis.db.models.functions.IsValid` database functions
are now supported on MariaDB 11.7+. are now supported on MariaDB 11.7+.
* :class:`~django.contrib.gis.db.models.functions.NumDimensions` was added for
PostGIS and SpatiaLite backends which returns the number of dimensions used
by a geometry.
:mod:`django.contrib.messages` :mod:`django.contrib.messages`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -11,7 +11,15 @@ from django.db.models import IntegerField, Sum, Value
from django.test import TestCase, skipUnlessDBFeature from django.test import TestCase, skipUnlessDBFeature
from ..utils import FuncTestMixin from ..utils import FuncTestMixin
from .models import City, Country, CountryWebMercator, ManyPointModel, State, Track from .models import (
City,
Country,
CountryWebMercator,
ManyPointModel,
State,
ThreeDimensionalFeature,
Track,
)
class GISFunctionsTests(FuncTestMixin, TestCase): class GISFunctionsTests(FuncTestMixin, TestCase):
@ -576,6 +584,23 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
else: else:
self.assertEqual(1, city.num_geom) self.assertEqual(1, city.num_geom)
@skipUnlessDBFeature("has_NumDimensions_function")
def test_num_dimensions(self):
for c in Country.objects.annotate(num_dims=functions.NumDimensions("mpoly")):
self.assertEqual(2, c.num_dims)
ThreeDimensionalFeature.objects.create(
name="London", geom=Point(-0.126418, 51.500832, 0)
)
qs = ThreeDimensionalFeature.objects.annotate(
num_dims=functions.NumDimensions("geom")
)
self.assertEqual(qs[0].num_dims, 3)
msg = "'NumDimensions' takes exactly 1 argument (2 given)"
with self.assertRaisesMessage(TypeError, msg):
Country.objects.annotate(num_dims=functions.NumDimensions("point", "error"))
@skipUnlessDBFeature("has_NumPoint_function") @skipUnlessDBFeature("has_NumPoint_function")
def test_num_points(self): def test_num_points(self):
coords = [(-95.363151, 29.763374), (-95.448601, 29.713803)] coords = [(-95.363151, 29.763374), (-95.448601, 29.713803)]