1

I've been using PyQGIS for a few of weeks. I'd write a script which shows all earthshakes responding to given parameters, so I wrote this code:

from PyQt5.QtGui import *
from PyQt5.QtCore import QVariant
import processing
layerTerremoti = QgsVectorLayer("LayerGIS/totaleepicentriterremotiinunareadi200kmdatoscanaliguria.gpkg", "Terremoti", "ogr")
terrSelezionati = QgsVectorLayer("LayerGIS/terrSelezionati.shp")
with edit(terrSelezionati):
    for feat in terrSelezionati.getFeatures():
        terrSelezionati.deleteFeature(feat.id())

        
layer = qgis.utils.iface.activeLayer()
widgetGetBuff = iface.messageBar().createMessage("Buffer Layer", "Show Me")
widgetGetIntervalloInizio = iface.messageBar().createMessage("IntervalloInizio", "Show me")
widgetGetIntervalloFine = iface.messageBar().createMessage("IntervalloFine", "Show me")
elementi_selezionati = layer.selectedFeatures()

buffDist, ok = QInputDialog().getInt(widgetGetBuff, "Inserimento parametro buffer", "inserisci distanza buffer in Km", 0, 10, 200, QLineEdit.Normal)
if ok and buffDist:
    rangeInizio, ok = QInputDialog().getInt(widgetGetIntervalloInizio, "Inserimento 
    parametro intervallo", "Inserisci prima data del range temporale", 1000, 1000, 2010, 
    QLineEdit.Normal)
    rangeFine, ok = QInputDialog().getInt(widgetGetIntervalloFine, "Inserimento parametro 
    intervallo", "Inserisci seconda data del range temporale", 1001, 1100, 2020, 
    QLineEdit.Normal)
    aRispettoLayer = QgsVectorLayer('Polygon?crs=EPSG:3003', 'areaRispetto', 'memory')
    vpr = terrSelezionati.dataProvider()
    pr = aRispettoLayer.dataProvider()
    count = 0
    for i in elementi_selezionati:
        buff = i.geometry().buffer(buffDist*1000,18)
        b = QgsFeature()
        b.setGeometry(buff)
        pr.addFeatures([b])
    
    for ftre in layerTerremoti.getFeatures():

        if (ftre['Anno'] >= rangeInizio) and (ftre['Anno'] <= rangeFine):
            count = count +1
            QgsFeature(ftre)
            vpr.addFeatures([ftre])
        
    terrSelezionati.updateExtents()

    outres = processing.run("gdal:clipvectorbypolygon", {
        'INPUT': terrSelezionati,
        'MASK' : aRispettoLayer,
        'OUTPUT': 'LayerGIS/terremotiRitag.shp'
    })
    terremotiRitagliati = 
    QgsVectorLayer('LayerGIS/terremotiRitag.shp',"TerrRitagliati","ogr")
    tr = terremotiRitagliati.dataProvider()
    tr.addAttributes([QgsField("Anno", QVariant.Int)])
    terremotiRitagliati.updateFields()
    indCampo = terremotiRitagliati.fields().indexOf("Anno")
    
    conto = 0
    confronto = 0
    for f in terremotiRitagliati.getFeatures():
        
        conto = conto + 1
        
        tr.addFeatures([f])
        terremotiRitagliati.updateFeature(f)
    print("conto")
    print(conto)
    for el in layerTerremoti.getFeatures():
        confronto = el['N15']
            
        
        terremotiRitagliati.startEditing()
        for g in terremotiRitagliati.getFeatures():
            if confronto == g['id']:
                terremotiRitagliati.changeAttributeValue(g.id(), indCampo , el['Anno'])
                terremotiRitagliati.updateFeature(g)
                print(g["Anno"])
        terremotiRitagliati.commitChanges()
    countMsg = QMessageBox()
    
    if conto> 0:
        countMsg.setText("Sono stati trovati " + str(conto) + " terremoti tra il " +  
        str(rangeInizio) + "e il " + str(rangeFine))
    else:
        countMsg.setText("Non sono stati trovati terremoti avvenuti tra il " + 
        str(rangeInizio) + " e il " + str(rangeFine))
    countMsg.show()

    QgsProject.instance().addMapLayers([terremotiRitagliati])
    QgsProject.instance().addMapLayers([aRispettoLayer])
    
    
    iface.mapCanvas().zoomToSelected()

The last code rows are salient. The problem is attribute "Anno" doesn't update, so the attributes table of the layer "terremotiRitagliati" shows all values of column "Anno" as NULL. Why happens that?

New contributor
ytreka is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
1
  • Is it possible for you to share your data .shp and .gpkg? Otherwise, check the spacing, I do not like that everything is outside the with edit(terrSelezionati):
    – Taras
    Commented Jun 11 at 17:48

1 Answer 1

0

Doing changeAttributeValue() and then updateFeature() resets the feature's attribute values inside the layer meaning that you override your updated value with the previous one, doing nothing.

x = QgsVectorLayer("Point", "test", "memory")
x.dataProvider().addAttributes([QgsField("test", QVariant.String, "", 10)])
x.updateFields()

f =QgsFeature.new(x.fields(), QgsGeometry.from_point(QgsPointXY(1,1)), {"test": "A"})
x.add_features([f])

print(f["test"]) 
# --> "A"

# Your code
with edit(x):
    f = next(x.getFeatures())
    x.changeAttributeValue(f.id(), x.get_field_index("test"), "B")
    x.updateFeature(f)
print(next(x.getFeatures())["test"])
# --> A

# What you need
with edit(x):
    f = next(x.getFeatures())
    x.changeAttributeValue(f.id(), x.get_field_index("test"), "B")
print(next(x.getFeatures())["test"])
# --> B

# or 
with edit(x):
    f = next(x.getFeatures())
    f["test"] = "B"
    x.updateFeature(f)
print(next(x.getFeatures())["test"])
# --> B

Either works.

So, I think it would work for you by changing:

        terremotiRitagliati.startEditing()
        for g in terremotiRitagliati.getFeatures():
            if confronto == g['id']:
                terremotiRitagliati.changeAttributeValue(g.id(), indCampo , el['Anno'])
                terremotiRitagliati.updateFeature(g)
                print(g["Anno"])
        terremotiRitagliati.commitChanges()

by remove the updateFeature call

        terremotiRitagliati.startEditing()
        for g in terremotiRitagliati.getFeatures():
            if confronto == g['id']:
                terremotiRitagliati.changeAttributeValue(g.id(), indCampo , el['Anno'])
                print(g["Anno"])
        terremotiRitagliati.commitChanges()

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.