Friday, 22 June 2018

qgis - Cannot get changeAttributeValues() to work in a loop


I'm trying to use QGIS to loop through a set of points, find their elevation from a DEM and use that value to update the point layer's attribute table. The loop works fine until I try to use changeAttributeValues(), and I can change the attribute values outside of the loop, but when I try to put the two together I cause a dump.


while provider.nextFeature(feat):
geom = feat.geometry()
x = geom.asPoint()
res, ident = rlayer.identify(QgsPoint(x))


for (k,v) in ident.iteritems():
elevation = float(v)
attrs = { 2 : elevation }
caps = vlayer.dataProvider().capabilities()
if caps & QgsVectorDataProvider.ChangeAttributeValues:
vlayer.dataProvider().changeAttributeValues({ fid : attrs })

This causes the following error in Linux:


*** glibc detected *** python2: free(): invalid pointer: 0x00000000024655b8 ***


Edit:


The problem isn't the loop, it is now I'm calling changeAttributeValues(). I've simplified the script down to just update a single point and it causes the same core dump. Here's the updated script:


#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from qgis.core import *
import qgis.utils

#initializes QGIS and points python to where it can find QGIS's stuff
QgsApplication.setPrefixPath("/usr/", True)

QgsApplication.initQgis()

vlayer = QgsVectorLayer("/gis/vector/elev_pts.shp", "elev_pts", "ogr")
if not vlayer.isValid():
print "Layer did not load!"

vlayer.dataProvider().changeAttributeValues({ 0: 2: 432.1 })

QgsApplication.exitQgis()

Answer




Figured it out, by using changeAttributeValue() instead of changeAttributeValues() I got the script to work. Here's a loop that works:


# Loop through each point feature
while provider.nextFeature(feat):
geom = feat.geometry()
x = geom.asPoint()

#Get the raster value of the cell under the vector point
res, ident = rlayer.identify(QgsPoint(x))

#The key is the raster band, and the value is the cell's raster value

for (k,v) in ident.iteritems():
elevation = float(v)

fid = int(feat.id())
vlayer.startEditing()
vlayer.changeAttributeValue(fid, 2, elevation)
vlayer.commitChanges()

This only works if the raster is a single band raster.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...