2

I have a GeoJSON file that I have loaded into QGIS as a LineString, and draped over a DEM using Drape (set Z value from raster)

enter image description here

I now want to round the Z-values to 4dp before exporting the modified file back to GeoJSON.

I've tried the following PyQGIS code:

layers = QgsProject.instance().mapLayersByName('Draped')
layer = layers[0]

layer.startEditing()
for f in layer.getFeatures():
    geom = f.geometry().get()
    for g in geom:
        g.setZ(round(g.z(),4))

layer.commitChanges()

The exported file still has the unrounded values, so I'm obviously missing something in the editing phase that commits the change.

Any suggestions?

4
  • 1
    What are you exporting to? A geopackage?
    – Bera
    Commented Apr 17, 2023 at 10:46
  • 1
    I suspect most data formats will include the full floating point precision by default
    – Ian Turton
    Commented Apr 17, 2023 at 10:49
  • Exporting back to GeoJSON, for use on the web. The 4dp is an attempt to keep the filesize smaller, amongst other things. The raw data is ~15dp. Commented Apr 17, 2023 at 10:50
  • @IanTurton - GeoJSON exported by QGIS definitely truncates the data. It doesn't retain the full floating point precision if it's not required. Commented Apr 17, 2023 at 11:48

1 Answer 1

1

I managed to achieve the desired outcome via a roundabout method:

  1. Iterating through the points of the original geometry of each feature
  2. Creating new Points, and setting the X, Y and Z values manually
  3. Adding these Points to a LineString
  4. Creating a new geometry from the LineString, and assigning it back to the feature

Code as follows:

    layers = QgsProject.instance().mapLayersByName('Draped')
    layer = layers[0]
    
    layer.startEditing()
    for f in layer.getFeatures():
        geom = f.geometry().constGet()
        ls = QgsLineString()
        for p in geom:
            pt = QgsPoint(0,0,0)
            pt.setX(p.x())
            pt.setY(p.y())
            pt.setZ(round(p.z(),4))
            ls.addVertex(pt)
        newgeom = QgsGeometry.fromPolyline(ls)
        layer.changeGeometry(f.id(), newgeom)
    
    layer.commitChanges()

This seems like a convoluted method to achieve a simple outcome, so improvements are welcome!

In theory, a similar approach could be used to make arbitrary modifications to the X, Y and Z values of lines (but again, it feels like there must be a better way!)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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