Skip to content

Commit 1df8983

Browse files
smithdc1felixxm
authored andcommitted
Refs #35058 -- Added support for measured geometries to GDAL LineString.
1 parent 41aaf5a commit 1df8983

File tree

5 files changed

+57
-11
lines changed

5 files changed

+57
-11
lines changed

django/contrib/gis/gdal/geometries.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -625,10 +625,14 @@ class LineString(OGRGeometry):
625625
def __getitem__(self, index):
626626
"Return the Point at the given index."
627627
if 0 <= index < self.point_count:
628-
x, y, z = c_double(), c_double(), c_double()
629-
capi.get_point(self.ptr, index, byref(x), byref(y), byref(z))
628+
x, y, z, m = c_double(), c_double(), c_double(), c_double()
629+
capi.get_point(self.ptr, index, byref(x), byref(y), byref(z), byref(m))
630+
if self.is_3d and self.is_measured:
631+
return x.value, y.value, z.value, m.value
630632
if self.is_3d:
631633
return x.value, y.value, z.value
634+
if self.is_measured:
635+
return x.value, y.value, m.value
632636
dim = self.coord_dim
633637
if dim == 1:
634638
return (x.value,)
@@ -673,6 +677,12 @@ def z(self):
673677
if self.is_3d:
674678
return self._listarr(capi.getz)
675679

680+
@property
681+
def m(self):
682+
"""Return the M coordinates in a list."""
683+
if self.is_measured:
684+
return self._listarr(capi.getm)
685+
676686

677687
# LinearRings are used in Polygons.
678688
class LinearRing(LineString):
@@ -789,9 +799,11 @@ class MultiPolygon(GeometryCollection):
789799
7: GeometryCollection,
790800
101: LinearRing,
791801
2001: Point, # POINT M
802+
2002: LineString, # LINESTRING M
792803
3001: Point, # POINT ZM
804+
3002: LineString, # LINESTRING ZM
793805
1 + OGRGeomType.wkb25bit: Point, # POINT Z
794-
2 + OGRGeomType.wkb25bit: LineString,
806+
2 + OGRGeomType.wkb25bit: LineString, # LINESTRING Z
795807
3 + OGRGeomType.wkb25bit: Polygon,
796808
4 + OGRGeomType.wkb25bit: MultiPoint,
797809
5 + OGRGeomType.wkb25bit: MultiLineString,

django/contrib/gis/gdal/prototypes/geom.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,15 @@ def topology_func(f):
137137
get_geom_type = int_output(lgdal.OGR_G_GetGeometryType, [c_void_p])
138138
get_point_count = int_output(lgdal.OGR_G_GetPointCount, [c_void_p])
139139
get_point = void_output(
140-
lgdal.OGR_G_GetPoint,
141-
[c_void_p, c_int, POINTER(c_double), POINTER(c_double), POINTER(c_double)],
140+
lgdal.OGR_G_GetPointZM,
141+
[
142+
c_void_p,
143+
c_int,
144+
POINTER(c_double),
145+
POINTER(c_double),
146+
POINTER(c_double),
147+
POINTER(c_double),
148+
],
142149
errcheck=False,
143150
)
144151
geom_close_rings = void_output(lgdal.OGR_G_CloseRings, [c_void_p], errcheck=False)

docs/ref/contrib/gis/gdal.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,17 @@ coordinate transformation:
936936
>>> OGRGeometry("LINESTRING (1 2 3,4 5 6)").z
937937
[3.0, 6.0]
938938

939+
.. attribute:: m
940+
941+
.. versionadded:: 5.1
942+
943+
Returns a list of M coordinates in this line or ``None`` if the line does
944+
not have M coordinates:
945+
946+
.. code-block:: pycon
947+
948+
>>> OGRGeometry("LINESTRING(0 1 2 10, 1 2 3 11, 2 3 4 12)").m
949+
[10.0, 11.0, 12.0]
939950

940951
.. class:: Polygon
941952

docs/releases/5.1.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,11 @@ Minor features
7878
* The new :meth:`.OGRGeometry.set_3d` method allows addition and removal of the
7979
``Z`` coordinate dimension.
8080

81-
* :class:`~django.contrib.gis.gdal.OGRGeometry` and
82-
:class:`~django.contrib.gis.gdal.Point` now support measured geometries
83-
via the new :attr:`.OGRGeometry.is_measured` and :attr:`.Point.m` properties,
84-
and the :meth:`.OGRGeometry.set_measured` method.
81+
* :class:`~django.contrib.gis.gdal.OGRGeometry`,
82+
:class:`~django.contrib.gis.gdal.Point`, and
83+
:class:`~django.contrib.gis.gdal.LineString` now support measured geometries
84+
via the new :attr:`.OGRGeometry.is_measured` and ``m`` properties, and the
85+
:meth:`.OGRGeometry.set_measured` method.
8586

8687
* :attr:`.OGRGeometry.centroid` is now available on all supported geometry
8788
types.

tests/gis_tests/gdal_tests/test_geom.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ def test_geometry_types(self):
673673
("TIN Z", 1016, False),
674674
("Triangle Z", 1017, False),
675675
("Point M", 2001, True),
676-
("LineString M", 2002, False),
676+
("LineString M", 2002, True),
677677
("Polygon M", 2003, False),
678678
("MultiPoint M", 2004, False),
679679
("MultiLineString M", 2005, False),
@@ -688,7 +688,7 @@ def test_geometry_types(self):
688688
("TIN M", 2016, False),
689689
("Triangle M", 2017, False),
690690
("Point ZM", 3001, True),
691-
("LineString ZM", 3002, False),
691+
("LineString ZM", 3002, True),
692692
("Polygon ZM", 3003, False),
693693
("MultiPoint ZM", 3004, False),
694694
("MultiLineString ZM", 3005, False),
@@ -900,6 +900,21 @@ def test_centroid(self):
900900
)
901901
self.assertEqual(geometrycollection.centroid.wkt, "POINT (110 30)")
902902

903+
def test_linestring_m_dimension(self):
904+
geom = OGRGeometry("LINESTRING(0 1 2 10, 1 2 3 11, 2 3 4 12)")
905+
self.assertIs(geom.is_measured, True)
906+
self.assertEqual(geom.m, [10.0, 11.0, 12.0])
907+
self.assertEqual(geom[0], (0.0, 1.0, 2.0, 10.0))
908+
909+
geom = OGRGeometry("LINESTRING M (0 1 10, 1 2 11)")
910+
self.assertIs(geom.is_measured, True)
911+
self.assertEqual(geom.m, [10.0, 11.0])
912+
self.assertEqual(geom[0], (0.0, 1.0, 10.0))
913+
914+
geom.set_measured(False)
915+
self.assertIs(geom.is_measured, False)
916+
self.assertIs(geom.m, None)
917+
903918

904919
class DeprecationTests(SimpleTestCase):
905920
def test_coord_setter_deprecation(self):

0 commit comments

Comments
 (0)