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?
1 Answer 1
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:
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:
References:
-
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"Suzanna Cuypers– Suzanna Cuypers2023年01月06日 14:44:34 +00:00Commented 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?2023年01月08日 12:19:11 +00:00Commented 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!Suzanna Cuypers– Suzanna Cuypers2023年01月10日 09:15:32 +00:00Commented 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?"2023年01月10日 13:18:17 +00:00Commented 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=U4bnlMSuzanna Cuypers– Suzanna Cuypers2023年01月12日 08:57:25 +00:00Commented Jan 12, 2023 at 8:57
Explore related questions
See similar questions with these tags.