Skip to content
Advertisement

Accessing M-values associated to LINESTRING M and MULTILINESTRING M geometries

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)
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement