Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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()
share|improve this question
    
Is that if meant to be inside the for? –  Nathan W Oct 2 '12 at 22:08
1  
Sorry, no. The indents got thrown off for the if statement when I brought it in. It's there to make sure I can change the attributes on the vector layer, it's not needed for this but I put it in there in case I decide to expand this into a plugin later. –  HeyOverThere Oct 3 '12 at 0:46

2 Answers 2

up vote 0 down vote accepted

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.

share|improve this answer

What I see from your code: attrs is a dict that always has the key 2. When you use changeAttributeValues you also pass a dict to the function (which might be correct but is very unusual). But

({ fid : attrs }) equals ({ fid : { 2 : elevation }}) 

Is this maybe causing the problem?

share|improve this answer
    
I was working off of an example from the pyqgis cookbook and they show to use a dict as the second parameter. The 2 in this case is the index for the field to be modified and the second element, in this case the value of elevation, is the new value for that field. Fid here is the feature ID for the feature getting the new value. –  HeyOverThere Oct 3 '12 at 12:45
    
So if you hard code the call, e.g. vlayer.dataProvider().changeAttributeValues({ fid : {2: 4.0}}) it works? And what does fid = feat.id() return by the way? –  LarsVegas Oct 3 '12 at 13:19
    
Yeah, I just tried it in the Python console and it updated the correct record with the correct value. fid = feat.id() returned type long, changed it to fid = int(feat.id()) and it still core dumps. –  HeyOverThere Oct 3 '12 at 13:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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