1
0
mirror of https://github.com/django/django.git synced 2025-01-18 22:33:44 +00:00

Refs #35058 -- Added support for measured geometries to GDAL LineString.

This commit is contained in:
David Smith 2024-01-25 12:55:45 +00:00 committed by Mariusz Felisiak
parent 41aaf5aafa
commit 1df8983aa3
5 changed files with 57 additions and 11 deletions

View File

@ -625,10 +625,14 @@ class LineString(OGRGeometry):
def __getitem__(self, index):
"Return the Point at the given index."
if 0 <= index < self.point_count:
x, y, z = c_double(), c_double(), c_double()
capi.get_point(self.ptr, index, byref(x), byref(y), byref(z))
x, y, z, m = c_double(), c_double(), c_double(), c_double()
capi.get_point(self.ptr, index, byref(x), byref(y), byref(z), byref(m))
if self.is_3d and self.is_measured:
return x.value, y.value, z.value, m.value
if self.is_3d:
return x.value, y.value, z.value
if self.is_measured:
return x.value, y.value, m.value
dim = self.coord_dim
if dim == 1:
return (x.value,)
@ -673,6 +677,12 @@ class LineString(OGRGeometry):
if self.is_3d:
return self._listarr(capi.getz)
@property
def m(self):
"""Return the M coordinates in a list."""
if self.is_measured:
return self._listarr(capi.getm)
# LinearRings are used in Polygons.
class LinearRing(LineString):
@ -789,9 +799,11 @@ GEO_CLASSES = {
7: GeometryCollection,
101: LinearRing,
2001: Point, # POINT M
2002: LineString, # LINESTRING M
3001: Point, # POINT ZM
3002: LineString, # LINESTRING ZM
1 + OGRGeomType.wkb25bit: Point, # POINT Z
2 + OGRGeomType.wkb25bit: LineString,
2 + OGRGeomType.wkb25bit: LineString, # LINESTRING Z
3 + OGRGeomType.wkb25bit: Polygon,
4 + OGRGeomType.wkb25bit: MultiPoint,
5 + OGRGeomType.wkb25bit: MultiLineString,

View File

@ -137,8 +137,15 @@ get_geom_name = const_string_output(
get_geom_type = int_output(lgdal.OGR_G_GetGeometryType, [c_void_p])
get_point_count = int_output(lgdal.OGR_G_GetPointCount, [c_void_p])
get_point = void_output(
lgdal.OGR_G_GetPoint,
[c_void_p, c_int, POINTER(c_double), POINTER(c_double), POINTER(c_double)],
lgdal.OGR_G_GetPointZM,
[
c_void_p,
c_int,
POINTER(c_double),
POINTER(c_double),
POINTER(c_double),
POINTER(c_double),
],
errcheck=False,
)
geom_close_rings = void_output(lgdal.OGR_G_CloseRings, [c_void_p], errcheck=False)

View File

@ -936,6 +936,17 @@ coordinate transformation:
>>> OGRGeometry("LINESTRING (1 2 3,4 5 6)").z
[3.0, 6.0]
.. attribute:: m
.. versionadded:: 5.1
Returns a list of M coordinates in this line or ``None`` if the line does
not have M coordinates:
.. code-block:: pycon
>>> OGRGeometry("LINESTRING(0 1 2 10, 1 2 3 11, 2 3 4 12)").m
[10.0, 11.0, 12.0]
.. class:: Polygon

View File

@ -78,10 +78,11 @@ Minor features
* The new :meth:`.OGRGeometry.set_3d` method allows addition and removal of the
``Z`` coordinate dimension.
* :class:`~django.contrib.gis.gdal.OGRGeometry` and
:class:`~django.contrib.gis.gdal.Point` now support measured geometries
via the new :attr:`.OGRGeometry.is_measured` and :attr:`.Point.m` properties,
and the :meth:`.OGRGeometry.set_measured` method.
* :class:`~django.contrib.gis.gdal.OGRGeometry`,
:class:`~django.contrib.gis.gdal.Point`, and
:class:`~django.contrib.gis.gdal.LineString` now support measured geometries
via the new :attr:`.OGRGeometry.is_measured` and ``m`` properties, and the
:meth:`.OGRGeometry.set_measured` method.
* :attr:`.OGRGeometry.centroid` is now available on all supported geometry
types.

View File

@ -673,7 +673,7 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
("TIN Z", 1016, False),
("Triangle Z", 1017, False),
("Point M", 2001, True),
("LineString M", 2002, False),
("LineString M", 2002, True),
("Polygon M", 2003, False),
("MultiPoint M", 2004, False),
("MultiLineString M", 2005, False),
@ -688,7 +688,7 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
("TIN M", 2016, False),
("Triangle M", 2017, False),
("Point ZM", 3001, True),
("LineString ZM", 3002, False),
("LineString ZM", 3002, True),
("Polygon ZM", 3003, False),
("MultiPoint ZM", 3004, False),
("MultiLineString ZM", 3005, False),
@ -900,6 +900,21 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
)
self.assertEqual(geometrycollection.centroid.wkt, "POINT (110 30)")
def test_linestring_m_dimension(self):
geom = OGRGeometry("LINESTRING(0 1 2 10, 1 2 3 11, 2 3 4 12)")
self.assertIs(geom.is_measured, True)
self.assertEqual(geom.m, [10.0, 11.0, 12.0])
self.assertEqual(geom[0], (0.0, 1.0, 2.0, 10.0))
geom = OGRGeometry("LINESTRING M (0 1 10, 1 2 11)")
self.assertIs(geom.is_measured, True)
self.assertEqual(geom.m, [10.0, 11.0])
self.assertEqual(geom[0], (0.0, 1.0, 10.0))
geom.set_measured(False)
self.assertIs(geom.is_measured, False)
self.assertIs(geom.m, None)
class DeprecationTests(SimpleTestCase):
def test_coord_setter_deprecation(self):