1

I want to create a QGIS Plugin in which the user is clicking on the map to get the coordinates which are used to create a point feature. However until now the point feature is not shown in the map. Here is the code I use:

le_koord = self.dlg.lineedit_Koordinate.text()
try:
    le_koord = [float(coord.strip()) for coord in le_koord.split(',')]
except:
    QMessageBox.critical(self.iface.mainWindow(),
    'Fehler bei der Eingabe!',
    "Es müssen durch Komma getrennte Koordinaten Lat Long eingegeben werden!..")
    return
            
x_koord = float(le_koord[0])
y_koord = float(le_koord[1])
            
layer_out = QgsVectorLayer("Point? 
crs="+str(project.crs())+"field=address:string&field=license:string",
                           "Lage",
                           "memory")
caps = layer_out.dataProvider().capabilities()
            
if caps & QgsVectorDataProvider.AddFeatures:
    feature = QgsFeature(layer_out.fields())
    point_out = QgsPointXY(x_koord, y_koord)
    feature.setGeometry(QgsGeometry.fromPointXY(point_out))
    (res, outFeats) = layer_out.dataProvider().addFeatures([feature])

However, I only managed to make the point visible if I use project.addMapLayer(layer_out), but as this creates always a new version of the selected layer, it is not usable. I found this tutorial in which the same commands are used, but which is done directly in the Python console in QGIS.

I'm using QGIS 3.30 and Python 3.9 on Ubuntu 22.04.2 LTS.

4
  • ~~Try using the with edit(layer) context instead of going low-level through the data provider. Or call layer.triggerRepaint() when you are done.~~ Actually, the code does not show the layer being part of the project at all. May 26 at 7:32
  • 1
    PS you could use two QDoubleSpinBox widgets instead of a QLineEdit to get floating point numbers directly ;) May 26 at 7:32
  • Last but not least, aren't you creating a new layer each time anyways? How do you add it to the project? If you don't add it (and it is not in the layer tree), it won't appear in your map. May 26 at 7:34
  • @bugmenot123 Thanks a lot for your fast reply :) I just tried to use layer_out.triggerRepaint() but the feature is not appearing in the map. I want to create several points (later with distinct attributes) to the layer "Lage", as it is shown in the tutorial. Is this not possible, if I don't code directly in the Python Editor in QGIS? Thanks for the hint regarding QDoubleSpinBox, as soon I solved this problem, I will change it ;)
    – Dennis
    May 26 at 7:40

1 Answer 1

2

Your code creates a new layer every time it runs.

The code you show is inside a function that is called after self.dlg.lineedit_Koordinate has changed, right?

What your code does is it creates a new memory layer every time your function is called.

You need to create the layer once (probably inside the class constructor) as something like

self.layer_out = QgsVectorLayer("Point?crs="+str(project.crs())+"field=address:string&field=license:string",
"Lage",
"memory")

This layer needs to be added to the project.

Then inside the function that is triggered by user action just add to that layer (wrapped inside an edit context as mentioned in the comments):

feature = QgsFeature(self.layer_out.fields())
point_out = QgsPointXY(x_koord, y_koord)
feature.setGeometry(QgsGeometry.fromPointXY(point_out))
(res, outFeats) = self.layer_out.dataProvider().addFeatures([feature])
5
  • Thanks a lot for your answer! Yes that was my mistake, now I create self.layer_out at the beginning. But if I use this code for the project repeated times, I just realised I need to check if this layer is already created. If so, I need to use layers = QgsProject.instance().mapLayersByname('Lage') to access this layer and asign it to the variable by self.layer_out = layers[0] . Is this the best way to code it?
    – Dennis
    May 26 at 8:19
  • Is your code the only place the layer can be created, or can a project exists where there is already a correct "Lage" layer that needs to be added to?
    – til_b
    May 26 at 10:33
  • Yes, it is the code for a window to insert new data for the project. Hence it should be the only option to create a new layer, if it's necessary. The data is then stored in a PostgreSQL Database.
    – Dennis
    May 26 at 10:59
  • I would create the layer in the class constructor as self.layer_out = QgsVectorLayer(...). In subsequent calls of your class methods you can then be sure the layer exists. As far as I understand it there is no reason to go via QgsProject.instance().mapLayersByName().
    – til_b
    May 30 at 11:08
  • Maybe I have a wrong understanding in how it works. I followed your answer and it works fine, but if I only use self.layer_out = QgsVectorLayer(...), I do not know at this point, if the Layer exsists already in the Map or not, I just would make sure it exists in the Code. Hence, what I think, is that I need to check with layers = QgsProject.instance().mapLayersByname('Lage') if I need to add it with QgsProject.instance().addMapLayer(layer_out) to the map or not.
    – Dennis
    May 30 at 12:22

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.