If you write directly to the dataprovider, there is no edit session management done by QGIS. Instead you should use the editing API by QgsVectorLayer, which will give you the expected results.
QGIS 2.0 (and 1.9 / master)
fid = 1 # feature id
attrs = { 0: 2,1: "B",2:"Dont!!!"} # attributes
vLayer.changeAttributeValues({ fid : attrs })
or a very intuitive method, if you already have a copy of the feature you are going to update
fid = 1 # feature id
feat = vLayer.getFeatures( QgsFeatureRequest().setFilterFid( fid ) ).next()
feat['number'] = 2
feat['char'] = 'B'
feat['advice'] = 'Dont!!!'
vLayer.updateFeature( feat )
QGIS 1.8
fid = 1 # feature id
attrs = { 0: QVariant(2),1: QVariant("B"),2:QVariant("Dont!!!")} # attributes
for attr, val in attrs.iteritems():
vLayer.changeAttributeValue( fid, attr, val )
There is no need to start an edit session if you use the vLayer.dataProvider().insertEditCommandHere()
methods, as the edit command will be executed immediately.
(This is a very common misconception and I guess it should be added to the QGIS documentation and pyqgis cookbook more prominently)
The documentation on pyqgis is not very self-explanatory, but i figured out how to properly call the associated interpolation classes (QgsInterpolator
, QgsTINInterpolator
, QgsIDWInterpolator
, QgsGridFileWriter
) from python. I am going to describe every step of the script in great detail:
Step 1:
Import the core and analysis module and get the desired vector layer for interpolation by selecting it with a mouseclick in the layer tab.
import qgis.core
import qgis.analysis
layer = qgis.utils.iface.activeLayer()
Step 2:
Prepare the interpolation classes with the necessary Parameters. The exact parameters for initialization of the LayerData struct can be found in the QGIS API docs (searchterm: QgsInterpolator).
layer_data = QgsInterpolator.LayerData()
layer_data.vectorLayer = layer
layer_data.zCoordInterpolation=False
layer_data.interpolationAttribute =0
layer_data.mInputType = 1
Please notice that I don't use the z Coordinate, I get the first available field (index = 0) as interpolation attribute, and use POINTS as input type.
Step 3:
Choose your interpolation engine. Here you can choose between the TIN-Interpolation method (QgsTINInterpolator
) and IDW-Interpolation (QgsIDWInterpolator
). I took the QgsTINInterpolator
in my code.
tin_interpolator = QgsTINInterpolator([layer_data])
Keep in mind that you have to pass a python list of layer_data
to the interpolation engine! This also allows you to add multiple layer_data scenarios.
Step 4:
Setup the parameters that are needed for the export of the interpolation-output (see documentation of QgsGridFileWriter
). Those include similar information as the interpolation gui (filepath, extent, resolution, number of colums and rows).
export_path ="C:/SomeFolder/output.asc"
rect = layer.extent()
res = 10
ncol = int( ( rect.xMaximum() - rect.xMinimum() ) / res )
nrows = int( (rect.yMaximum() - rect.yMinimum() ) / res)
output = QgsGridFileWriter(tin_interpolator,export_path,rect,ncol, nrows,res,res)
output.writeFile(True)
iface.addRasterLayer(export_path, "interpolation_output")
Be aware of the file extension of your output-raster as QgsGridFileWriter
only writes ASCII-grids (.asc
). The data gets written to disk by calling the writeFile()
method. After export you can add the grid-file as raster to the canvas.
Full script for reference:
import qgis.analysis
import qgis.core
layer = qgis.utils.iface.activeLayer()
layer_data = QgsInterpolator.LayerData()
layer_data.vectorLayer = layer
layer_data.zCoordInterpolation=False
layer_data.interpolationAttribute =0
layer_data.mInputType = 1
tin_interpolator = QgsTINInterpolator([layer_data])
export_path = "E:/GIS_Workbench/script_output/test.asc"
rect = layer.extent()
res = 10
ncol = int( ( rect.xMaximum() - rect.xMinimum() ) / res )
nrows = int( (rect.yMaximum() - rect.yMinimum() ) / res)
output = QgsGridFileWriter(tin_interpolator,export_path,rect,ncol,nrows,res,res)
output.writeFile(True)
Keep in mind that the QGIS-API is currently rewritten to version 3.0 and the used interpolation-classes are moved from qgis.analysis
to qgis.core
! This will have a huge impact on the functionality of this script so that it must be rewritten for version 3.0!
Best Answer
Look at Using Vector Layers: Adding and Removing Fields