[GIS] How to create a Qgis python script to manipulate fields with some parameters

field-calculatorfields-attributespyqgispythonqgis

I'm just beginning with QGIS.

I have a shape file with 10 fields field1, …, field10, and many thousands of data.

I will like to automatize the next sequence (in a python script or a model):

  • load the shape file
  • create a field field_add defined as field1 + field2
  • value in field3 is Text1, Text2, Text3 or Text4 (if Text1, coeff=a; if Text2, coeff=b; if Text3, coeff=c; if Text4, coeff=d; else coeff=e)
  • create a field field_age defined as field4 * coeff
  • create a field field_result defined as field_age^m * field_add^n
  • create a field field_class defined as 1 if field_result < floor1, 3 if field_result > floor2, else 2.

After that, I will visualize each polygon with its field_class color (white for 1, green for 2 and red for 3).

All the coefficients (a,b, c, d, e, m, n, floor1 and floor2) have to be changed quickly, to update the chart.

I insert part of the table:
enter image description here

Please, could anyone indicate to me the best way to proceed?

Best Answer

So, for the first python script for QGIS, I have:

from qgis.core import *
from PyQt4.QtCore import *
from PyQt4 import QtGui, QtCore
import math

COMP = 1.0
FACS = 0.0
ORIG = 1.0
OROM = 1.0
ORZE = 1.0

coeff_a = 1.6
coeff_b = 3

seuil_1 = 1000000
seuil_2 = 300000000

# supply path to where is your qgis installed
QgsApplication.setPrefixPath("/path/to/qgis/installation", True)

# load providers
QgsApplication.initQgis()

# To load the shapefile - for the first time only
#layer = QgsVectorLayer("./shape/Portefeuille/portefeuille_jointure.shp", "portefeuille", "ogr")
#QgsMapLayerRegistry.instance().addMapLayer(layer)
#
# To add columns :  - for the first time only
#caps = layer.dataProvider().capabilities()
#if caps & QgsVectorDataProvider.AddAttributes:
#  res = layer.dataProvider().addAttributes([QgsField("Delivrance", QVariant.Double)])
#if caps & QgsVectorDataProvider.AddAttributes:
#  res = layer.dataProvider().addAttributes([QgsField("Age_corr", QVariant.Double)])
#if caps & QgsVectorDataProvider.AddAttributes:
#  res = layer.dataProvider().addAttributes([QgsField("Parametre", QVariant.Double)])
#if caps & QgsVectorDataProvider.AddAttributes:
#  res = layer.dataProvider().addAttributes([QgsField("Classe", QVariant.Int)])
#
# To retain the right layer by its name:
layers = iface.legendInterface().layers()
for layer in layers:
    name = layer.name()
    if name.endswith('portefeuille'):
        provider = layer.dataProvider()

updateMap = {}
# To find the right id of the fields I need:
idORIGINE=provider.fields().indexFromName( 'ORIGINE' )
idAGE=provider.fields().indexFromName( 'AGE' )
idDEL_Z=provider.fields().indexFromName( 'DEL_Z' )
idCESS_Z=provider.fields().indexFromName( 'CESS_Z' )
idDEL_G=provider.fields().indexFromName( 'DEL_G' )
idCESS_G=provider.fields().indexFromName( 'CESS_G' )
idDEL_CL=provider.fields().indexFromName( 'DEL_CL' )
idCESS_CL=provider.fields().indexFromName( 'CESS_CL' )
idDelivrance=provider.fields().indexFromName( 'Delivrance' )
idAge_corr=provider.fields().indexFromName( 'Age_corr' )
idParametre=provider.fields().indexFromName( 'Parametre' )
idClasse=provider.fields().indexFromName( 'Classe' )

iter = provider.getFeatures()

# Loop on every feature to update somme attributes:
for feature in iter:
# Processing of Delivrance by addition:
    Delivrance = feature.attributes()[idDEL_Z] + feature.attributes()[idCESS_Z] + feature.attributes()[idDEL_G] + feature.attributes()[idCESS_G] + feature.attributes()[idDEL_CL] + feature.attributes()[idCESS_CL]

# Processing of 'Age_corr':
    coeff=0
    if feature.attributes()[idORIGINE] == "COMP":
        coeff=COMP
    if feature.attributes()[idORIGINE] == "FACS":
        coeff=FACS
    if feature.attributes()[idORIGINE] == "ORIG":
        coeff=ORIG
    if feature.attributes()[idORIGINE] == "OROM":
        coeff=OROM
    if feature.attributes()[idORIGINE] == "ORZE":
        coeff=ORZE
    Age_corr = (1+coeff)*feature.attributes()[idAGE]

# Processing of 'Parametre':
    Parametre = math.pow(Age_corr,coeff_b) * math.pow(Delivrance,coeff_a)

# Processing of Classe:
    Classe=2 # Default 
    if Parametre < seuil_1:
        Classe=1
    if Parametre > seuil_2:
        Classe=3
# To print the result, just for debug: 
#   print Classe
# To update the fields processed:
    updateMap[feature.id()] = {idDelivrance: Delivrance , idAge_corr: Age_corr , idParametre: Parametre , idClasse: Classe }

# To save the result
provider.changeAttributeValues( updateMap )

# I would like to update the map... Here it is:
iface.mapCanvas().refresh()

# I would like to refresh the number of features in the layer on the map...
# so I'm loofing for...

# Just to verify that the process ends
print "Done"

It's what I want for this first use of QGIS python script.

Related Question