5

I have just started using PyQGIS and need to loop over parcels in a vector layer to clip a raster layer.

For each parcel, I want to generate a .tif file with the feature.id() in the filename. I will also be saving the attributes in a separate .csv/.txt file by the same name. Because of this, I can't run the script using the iterator in the GUI.

This is what I have come up with thus far:

raster = 'C:/Datasets/orthophotos/OMWRGB21VL_K14_K15/OMWRGB21_VL_K14_K15.tif'
Lbgbrprc = 'C:/Datasets/Landbouwgebruikspercelen/Landbouwgebruikspercelen_2020/Shapefile/Lbgbrprc20_SintNiklaas.shp'
Lbgbrprc = QgsVectorLayer(Lbgbrprc, 'landbouw', 'ogr')
params = {
 'ALPHA_BAND' : False,
 'CROP_TO_CUTLINE' : True,
 'DATA_TYPE' : 0,
 'EXTRA' : '',
 'INPUT' : raster,
 'KEEP_RESOLUTION' : False,
 'MULTITHREADING' : False,
 'NODATA' : None,
 'OPTIONS' : '',
 'SET_RESOLUTION' : False,
 'SOURCE_CRS' : QgsCoordinateReferenceSystem('EPSG:31370'),
 'TARGET_CRS' : QgsCoordinateReferenceSystem('EPSG:31370'),
 'X_RESOLUTION' : None,
 'Y_RESOLUTION' : None
}
request = QgsFeatureRequest()
for feature in Lbgbrprc.getFeatures(request):
 if int(feature.id()) < 5:
 print(type(feature)) # <class 'qgis._core.QgsFeature'>
 params['MASK'] = feature
 params['OUTPUT'] = 'C:/Output/ortho_Lbgbrprc/{}.tif'.format(feature.id())
 
 processing.run("gdal:cliprasterbymasklayer", params)

This is the error I get:

Could not load source layer for MASK: invalid value

I think the issue is that the 'MASK' parameter needs to be a QgsVectorLayer not a QgsFeature, which is what "feature" is now. How do I go about this?

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Jan 4, 2023 at 13:09

1 Answer 1

9

Apparently, the type of Mask layer should be a [vector: polygon] i.e. QgsVectorLayer, see documentation.

Also, visible via processing.algorithmHelp("gdal:cliprasterbymasklayer"):

...
MASK: Mask layer
 Parameter type: QgsProcessingParameterFeatureSource
 Accepted data types:
 - str: layer ID
 - str: layer name
 - str: layer source
 - QgsProcessingFeatureSourceDefinition
 - QgsProperty
 - QgsVectorLayer
...

So, one shall modify this parameter:

params['MASK'] = feature

as was also mentioned by @MrXsquared to this:

params['MASK'] = Lbgbrprc.materialize(QgsFeatureRequest().setFilterFid(feature.id()))

Another option, that can be less resource-consuming, utilizes the QgsProcessingFeatureSourceDefinition class.

Input:

input

from os.path import abspath
from qgis import processing
from qgis.core import QgsProject
project_path = abspath('C:/Users/Taras/Downloads/GIS data/')
vector_layer = QgsProject.instance().mapLayersByName('Lbgbrprc21_selection')[0]
raster_layer = QgsProject.instance().mapLayersByName('OMWRGB14VL_K338z')[0]
params = {
 'ALPHA_BAND' : False,
 'CROP_TO_CUTLINE' : True,
 'DATA_TYPE' : 0,
 'EXTRA' : '',
 'INPUT' : raster_layer,
 'KEEP_RESOLUTION' : False,
 'MULTITHREADING' : False,
 'NODATA' : None,
 'OPTIONS' : '',
 'SET_RESOLUTION' : False,
 'SOURCE_CRS' : QgsCoordinateReferenceSystem('EPSG:31370'),
 'TARGET_CRS' : QgsCoordinateReferenceSystem('EPSG:31370'),
 'X_RESOLUTION' : None,
 'Y_RESOLUTION' : None
}
for feature in vector_layer.getFeatures():
 if int(feature.id()) < 5:
 vector_layer.select(feature.id())
 params['MASK'] = QgsProcessingFeatureSourceDefinition(vector_layer.id(), True)
 params['OUTPUT'] = f"{project_path}/{feature.id()}.tif"
 processing.run("gdal:cliprasterbymasklayer", params)
 vector_layer.removeSelection()

Outputs:

outputs


References:

answered Jan 4, 2023 at 13:30
7
  • Thank you so much! The first solution works. For the second approach, I get the error "Could not load source layer for MASK: landbouw_53536513_e03e_4466_bf80_58088bb4ac38 not found" Commented Jan 6, 2023 at 14:44
  • I just tested this with "native:countpointsinpolygon" and it works, with no errors. Maybe you can share a sample of your data? Commented Jan 8, 2023 at 12:19
  • I tried with a different polygon layer, I still get the same error. For now, I am working with the first solution, so my problem is fixed. Maybe when I learn more about pyQGIS, I will be able to see why I get that error. Thanks for all the help! Commented Jan 10, 2023 at 9:15
  • But can you share a sample of your data ? It shall work though. Please, do not forget about "What should I do when someone answers my question?" Commented Jan 10, 2023 at 13:18
  • I have uploaded a tiff file and a selection of the parcels to 1drv.ms/u/s!Ao2sPEougj-phzJjBa_F0crYACdM?e=U4bnlM Commented Jan 12, 2023 at 8:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.