6

The python version of QgsPoint takes just two floating point parameters, unlike the C++ equivalent. The QGIS API docs for QgsPoint gives this example:

pt_z = QgsPoint(120, 343, 77)
pt.exportToWkt() # PointZ(120 343 77)

Here is an excerpt from the error message in a python script

point = QgsPoint( wp.longitude, wp.latitude, 0.0 )
TypeError: arguments did not match any overloaded call:
QgsPoint(): too many arguments
QgsPoint(QgsPoint): argument 1 has unexpected type 'float'
QgsPoint(float, float): too many arguments

The call works fine without the third parameter.

How do I add 3D points from a python script?

0

2 Answers 2

8

For QGIS v3.x

You can use QgsPoint directly:

zPoint = QgsPoint(-74, 4, 2600) # x, y, z
zPoint.z()  # Prints 2600.0

Should you need a QgsGeometry object, just use:

my_geom = QgsGeometry(QgsPoint(-74, 4, 2600))

For QGIS < v3.0 and >= v2.10

You need to use QgsPointV2:

zPoint = QgsPointV2( QgsWKBTypes.PointZ, -74, 4, 2600 ) # type, x, y, z
zPoint.z()  # Prints 2600.0

This is an example with a memory layer using QGIS 2.14 (based on the PyQGIS Cookbook):

from PyQt4.QtCore import QVariant

# create layer
vl = QgsVectorLayer( "Point", "Points with Z", "memory" )
pr = vl.dataProvider()

# add fields
pr.addAttributes( [QgsField("name", QVariant.String),
                    QgsField("age",  QVariant.Int),
                    QgsField("size", QVariant.Double)] )
vl.updateFields() 
QgsMapLayerRegistry.instance().addMapLayer( vl )

# add a feature
fet = QgsFeature()
fet.setGeometry( QgsGeometry( QgsPointV2( QgsWKBTypes.PointZ, -74, 4, 2600 ) ) )
fet.setAttributes( ["Johny", 2, 0.3] )
pr.addFeatures( [fet] )
vl.updateExtents()

# Read feature's geometry
f = iface.activeLayer().getFeatures().next()
g = f.geometry()
g.geometry().z()  # Prints 2600.0
g.geometry().asWkt() # Prints u'PointZ (-74 4 2600)'
g.exportToWkt()  # Prints u'PointZ (-74 4 2600)'
3
  • This works fine, thanks! but now I get errors from using coordinate transforms because transform is not expecting an argument of type Pointz. I did try calling transformV2 in case there was one, but no. Roll on V3.0! Jul 31, 2017 at 5:10
  • What if you call transform(x, y) and then use the transformed point to create a new QgsPointV2 adding Z? Ah!, and QGIS 3 is here already: qgis.org/en/site/forusers/alldownloads.html (just look for the 2.99 version, which is the current development version) :) Jul 31, 2017 at 14:28
  • 1
    Doh! why didn't I think of that! Yes it works fine. On QGIS 3.0 I can see I will have to get that Intel NUC running Ubuntu Server on the desk and running a desktop version or install a linux VM on my Mac mini. Or (Horrors ;) buy a cheap laptop running windows 10. Aug 1, 2017 at 7:42
0

In QGIS 3, this was working for me. I had a long troubleshooting session to figure out that the brackets needed to go inside the addFeatures(). I truncated the code a bit so it would fit here.

struct_layer.startEditing()
this_struct = QgsFeature()
fields = struct_layer.fields()
this_struct.setFields(fields)
x_pos = 26131826.00
y_pos = 643499.00
z_pos = 777.00
this_struct.setGeometry(QgsGeometry(QgsPoint(x_pos, y_pos, z_pos)))

struct_data.addFeatures([this_struct])    
struct_layer.updateExtents()              
struct_layer.commitChanges()
struct_layer.triggerRepaint()

Your Answer

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

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