2

I am trying to add elevation to a 2D point in a QGIS 3 plugin, preferably in a concise and straightforward way. Not finding this easy.

I think part of the problem is that in QGIS 3, fromPoint() has been renamed to fromPointXY(). I am not very clear on how to create 3D point geometry.

I have tried a number of variations without finding one which works and have not been able to find a suitable example online.

Basically what I want to achieve is PointXY + elevation -> Point, which I would expect to be something like this:

z = 1.0 # or whatever

for l in selectedLayers: # for each selected layer
  if l.geometryType() == QgsWkbTypes.PointGeometry: # point layer

    l.startEditing()
    feat = l.getFeatures()

    for f in feat: # each feature

      # Get existing geometry...
      geom = f.geometry()
      pt = geom.asPoint() # returns PointXY

      # Replace with 3D geometry...
      pt3D = QgsPoint(pt.x(), pt.y(), z)
      geom = QgsGeometry.fromPointXY(pt3D) # error, because pt is 3D
      f.setGeometry(geom)

      l.updateFeature(f)

    l.commitChanges()

How do I do this?


For the benefit of others this is now resolved using the answer(s) below.

I am now adding the elevation like this:

f.setGeometry( QgsPoint(pt.x(), pt.y(), z) ) # x, y, z

It turns out that my problem was not so much adding the elevation, as knowing when I had successfully added it.

  • 1
    That contains 2 x ')' and 1 x '(' so syntactically I wouldn't expect that to work as written. It seems clear from the documentation that QgSPointXY is specifically a 2D point and does not support a z dimension. If you mean replace 'geom = QgsGeometry.fromPointXY(pt3D)' with something like 'geom = QgsGeometry.fromPointXY( QgsPointXY(1, 2), 3)' then no, that doesn't work. – wotnot Apr 9 at 7:31
  • 1
    QgsPointXY is specifically a 2D point and does not support a z dimension. This seems clear from the QGIS API documentation and I have tried it. 'pt3D = QgsPointXY((1,2), 3)' results in a TypeError. – wotnot Apr 9 at 7:44
  • Please write a self-answer in the area reserved for answers rather than in the area reserved for questions. – PolyGeo Apr 11 at 11:34
1

You don't need create a QgsGeometry object.

Add minimal sample for setGeometry 3D

feature = QgsFeature()
feature.setAttributes([lon, lat, alt])
feature.setGeometry(QgsPoint(lon, lat, alt))
layer.addFeatures([feature])

The original code is in my github,where a lot of layers are in 3d

https://github.com/All4Gis/QGISFMV/blob/35eb3f59b4d6423a375d7a04d54b6765dcc5c986/code/utils/QgsFmvLayers.py#L515

And for get to z value from feature,you can use something like that:

feature.geometry().vertexAt(0).z()
  • Thanks. Understood on the QgsGeometry object. It may be that I am successfully adding the elevation but I just cannot access the z value to check it. If I try to get the geometry using asPoint() it returns a 2D point and any z value is discarded. The API documentation is clear on this. So... how do I get the full coordinates of a 3D point?? I want to do something like this: 'QgsMessageLog.logMessage(str(f.geometry().z()))' but that doesn't work. I am getting 'AttributeError: 'QgsGeometry' object has no attribute 'z''. – wotnot Apr 9 at 14:36
  • update my answer – Fran Raga Apr 9 at 14:46
1

If you are looking at the Geometry of a feature you will have to do something like:

val_x = geom.get().x()
val_y = geom.get().y()
val_z = geom.get().z()

How to get the Z values of existing lineStringZ with pyqgis?

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.