How can I access a line geometry’s multiple M-values? Consider that the line geometry in question can be either a LINESTRING M or MULTILINESTRING M geometry that was created using osgeo
/ogr
.
Here’s a small reproducible example:
from osgeo import ogr line_wkt = 'LINESTRING M (0 0 5, 0 1 6, 1 1 10)' line_geom = ogr.CreateGeometryFromWkt(line_wkt) mline_wkt = 'MULTILINESTRING M ((0 0 5, 0 1 6, 1 1 10), (1 1 10, 2 1 20, 3 1 30))' mline_geom = ogr.CreateGeometryFromWkt(mline_wkt)
In the example above, the line_geom
and mline_geom
objects are successfully stored with their respective M-values, but I’m having a hard time accessing them.
I’m searching for a function that will return [5,6,10]
for the line_geom
object and [[5,6,10],[10,20,30]]
for the mline_geom
object.
Here are the alternatives I’ve tried but ultimately did not work:
Using the GetM()
method
The GetM()
method doesn’t seem to give me exactly what I want. For example, when I do line_geom.GetM()
, I just get back 5.0
. I think it just gives me the M-value for the first point in the line.
Also, when I try line_geom.GetM()
, I get back 0.0
and then a bunch of ERROR 6: Incompatible geometry for operation
.
Using the GetPoints()
method
I thought I would be able to iterate over a line’ points using the GetPoints()
method and access the M-values through there. Unfortunately, that didn’t work either – when I run line_geom.GetPoints()
, the resulting list does not contain the M-values: [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]
.
Also, when I try mline_geom.GetPoints()
, I just get a bunch of ERROR 6: Incompatible geometry for operation
.
Note
The solution needs to be in Python. I know that I can do a lot of stuff using ogr2ogr
‘s CLI, but this is a small part of something bigger and this needs to be in Python.
Advertisement
Answer
See the OGR Geometry docs:
GetM(Geometry self, int point=0)
By default, just calling line_geom.GetM()
will return the measure for the first point – default point=0
argument.
For the multilinestring, you need to get each individual geometry, before getting the points and measures.
line_wkt = 'LINESTRING M (0 0 5, 0 1 6, 1 1 10)' line_geom = ogr.CreateGeometryFromWkt(line_wkt) for i, point in enumerate(line_geom.GetPoints()): print(line_geom.GetM(i), point) mline_wkt = 'MULTILINESTRING M ((0 0 5, 0 1 6, 1 1 10), (1 1 10, 2 1 20, 3 1 30))' mline_geom = ogr.CreateGeometryFromWkt(mline_wkt) for j in range(mline_geom.GetGeometryCount()): geom = mline_geom.GetGeometryRef(j) for i, point in enumerate(geom.GetPoints()): print(geom.GetM(i), point)
Output:
5.0 (0.0, 0.0) 6.0 (0.0, 1.0) 10.0 (1.0, 1.0) 5.0 (0.0, 0.0) 6.0 (0.0, 1.0) 10.0 (1.0, 1.0) 10.0 (1.0, 1.0) 20.0 (2.0, 1.0) 30.0 (3.0, 1.0)