4

How can I access (read/write) m values of a line Shapefile using pyqgis?

I know how to do it with arcpy cursors (http://resources.arcgis.com/en/help/main/10.1/index.html#/Reading_geometries/002z0000001t000000/ ) but I don't know how to do it with pyqgis.

Is it possible with the QGIS python library?

9
+200

Assuming you have a QgsGeometry object (eg the geometry returned when calling QgsFeature.geometry()), you can access it's raw geometry info by calling QgsGeometry.geometry() in QGIS 2.x or QgsGeometry.constGet() in QGIS 3 respectively. This returns the relevant QgsAbstractGeometry subclass for the geometry type. These subclasses have methods for reading points from the geometry as QgsPointV2 objects (QgsPoint in QGIS 3), which you can then directly retrieve the z or m values from. Sometimes (as is the case with QgsLineStringV2 you can even directly access the z/m values from the subclass itself.

Here's an example for QGIS 2.x:

g = feature.geometry()
line = g.geometry() #line returns a QgsLineStringV2 object
m = line.mAt(0) # m value of first vertex
z = line.zAt(0) # z value of first vertex

And another example for QGIS 3:

g = feature.geometry()
line = g.constGet() #line returns a QgsLineString object
m = line.mAt(0) # m value of first vertex
z = line.zAt(0) # z value of first vertex

An important thing to note is that only very recent gdal versions support m values, and older versions read in m values as z values. This will affect your results if using a file based format (eg shapefiles) in QGIS.

2

if you do look into OGR - a great resource is the cookbook. One example of writing z (m) values into a shapefile might be something like:

def mkline():
    drv=ogr.GetDriverByName('ESRI Shapefile')
    ds=drv.CreateDataSource('test.shp')
    lyr=ds.CreateLayer('test',ogr.wkbLineString25D)
    flddef=ogr.FieldDefn('Name',ogr.OFTString)
    flddef.SetWidth(32)
    lyr.CreateField(flddef)

    feat=ogr.Feature(lyr.GetLayerDefn())
    feat.SetField('Name','someDescriptor')
    line=ogr.Geometry(ogr.wkbLineString25D)
    line.AddPoint(1116651.439379124, 637392.6969887456, 100.) # x, y , z
    line.AddPoint(1188804.0108498496, 652655.7409537067, 200.)
    line.AddPoint(1226730.3625203592, 634155.0816022386, 300.)
    line.AddPoint(1281307.30760719, 636467.6640211721, 400.)
    feat.SetGeometry(line)
    lyr.CreateFeature(feat)

feat=None
ds=None
  • Thanks for the example! I will try to code it into the z-coordinate. – root676 Apr 6 '15 at 8:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.