Geographic Information Systems Asked on July 13, 2021
I am following the QGIS Cookbook and this post where it concerns reading attributes from layers. I would like to exploit this method and implement it into a standalone script.
Essentially, I want to read the first feature of a shapefile from a field called Rank
, take the value of this feature (all values in the Rank
field are the exact same) and include it into a QGIS algorithm.
I wonder if there’s an alternative to using layer.getFeatures()
as, I believe, this is used with the canvas when QGIS is running. I have the following basic script but doesn’t like fname.getFeatures()
:
path_dir = home + "DesktopTest"
path_res = path_dir + "Results"
for fname in glob.glob(path_dir + "*.shp"):
for feature in fname.getFeatures():
fid = 1
iterator = fname.getFeatures(QgsFeatureRequest().setFilterFid(fid))
idx = fname.fieldNameIndex('Rank')
Rank_value = idx[1]
#Do some processing, finish with field calculator algorithm
general.runalg("qgis:fieldcalculator", fname, 'Rank', 1, 10, 0, False, Rank_value, path_res + fname)
Is this the correct method or would it be much easier to read the Rank_value
from a shapefile and write to another programatically?
EDIT:
Following @gcarrillo’s answer, the script does not produce any results. I have modified the script to match the one suggested but not sure why no output files are produced.
To try and clarify exactly what I’m looking for:
Rank
field of a shapefile is read.Rank
field for this newly clipped shapefile is updated with the value read at the start.Next shapefile…
path_dir = home + "DesktopTest"
path_res = path_dir + "Results"
for fname in glob.glob(path_dir + "*.shp"):
vLayer = QgsVectorLayer(fname,"any name","ogr")
idx = fname.fieldNameIndex('Rank')
Rank_value = vLayer.uniqueValues(idx)[0]
outputs_1=general.runalg("qgis:creategrid", 1000, 1000, 24108, 18351.157175, 258293.802316, 665638.226408, 1, 'EPSG:7405', None)
outputs_2=general.runalg("qgis:clip", outputs_1['SAVENAME'], fname, None)
outputs_3=general.runalg("qgis:fieldcalculator", outputs_2, 'Rank', 1, 10, 0, False, Rank_value, path_res + fname)
I've tested the following script on GNU/Linux, QGIS v.2.8.1, Processing v.2.6 and Processing v.2.9.1.
import sys,os,glob
from qgis.core import *
from PyQt4.QtGui import *
app = QApplication([])
QgsApplication.setPrefixPath("/usr", True) # Adjust it to your path
QgsApplication.initQgis()
path_dir = "/docs/borrar/test/"
path_res = path_dir + "results/"
sys.path.append("/usr/share/qgis/python/plugins/") # Where Processing is installed
from processing.core.Processing import Processing
Processing.initialize()
from processing.tools import *
for fname in glob.glob(path_dir + "*.shp"):
vLayer = QgsVectorLayer(fname,"any name","ogr")
idx = vLayer.fieldNameIndex('rank')
Rank_value = vLayer.uniqueValues(idx)[0] # uV returns a list, get the 1st element
#Do some processing, finish with field calculator algorithm
outputs_1=general.runalg("qgis:creategrid",1,"-956314.538361,3285493.72235,-53712.3143749,1885220.75154",250000,250000,None)
outputs_2=general.runalg("qgis:clip", outputs_1['OUTPUT'], fname, None)
general.runalg("qgis:advancedpythonfieldcalculator", outputs_2['OUTPUT'], 'rank', 1, 10, 3, False, "value=%f" % Rank_value, path_res + os.path.basename(fname))
QgsApplication.exitQgis()
As you can see, the syntax of the qgis:creategrid
algorithm differs from your version and from the version we ran at Import error for qgis.core when running OSGeo4w shell script. Additionally, I ended up using the qgis:advancedpythonfieldcalculator
algorithm, which provides a help.
Hope you can make it to work in your environment, pay attention to paths.
Correct answer by Germán Carrillo on July 13, 2021
For the first question:
You need to create a QgsVectorLayer
object from your Shapefile path. Only then you can access the getFeatures()
function. That is:
for fname in glob.glob(path_dir + "*.shp"):
for feature in QgsVectorLayer(fname,"any name","ogr").getFeatures():
My recommended way of doing it
You don't actually need to access getFeatures() nor to use a for. You can accomplish what you want with this code:
path_dir = home + "DesktopTest"
path_res = path_dir + "Results"
for fname in glob.glob(path_dir + "*.shp"):
vLayer = QgsVectorLayer(fname,"any name","ogr")
idx = vLayer.fieldNameIndex('Rank')
Rank_value = vLayer.uniqueValues(idx)[0] # uV returns a list, get the 1st element
#Do some processing, finish with field calculator algorithm
general.runalg("qgis:fieldcalculator", fname, 'Rank', 1, 10, 0, False, Rank_value, path_res + os.path.basename(fname))
Since you'll be using QgsVectorLayer
, don't forget to set the prefix path before initializing QGIS, as you did at Getting random values from geometryType() in a standalone PyQGIS script.
Answered by Germán Carrillo on July 13, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP