I want to clip each line feature that is falling inside the polygons and want to save the line files with the name of ID which is in the polygon layer.
2 Answers
Try this way:
Calculate a field for the overlay layer that contains the id (i will call it id, you can use this expression
$id
to get the id).Intersect your base layer with the Intersection tool and remember to set the
OVERLAY_FIELDS
parameter to keep the id field from the overlay layer.Finally, run the Extract by attribute tool as batch process, set the parameters this way:
VALUE
: Click Autofill → Add Values By Expression, and paste this expression:
array_distinct( aggregate( layer:='Intersected_layer_id', aggregate:= 'array_agg', expression:="Id" ) )
What is this? here we are generating an array that contains every different value of the id
field from the Intersected_layer_id
layer, so you will have to replace in the expression Intersected_layer_id
with your layer id and id
with the name you used for the id in the first step. You will notice that now there are a lot of rows in the batch processing table.
INPUT
: set the first row (or second in the left numbering) with the intersected layer of the second step and then, use Autofill → Fill Down and all theINPUT_LAYER
column will be filled with intersected layer.OUTPUT
: to fill this column use Autofill → Calculate Values By Expression, use this expression:format('/path/to/output/folder/file_prefix_%1.shp', @VALUE)
, replace the path with the path of the folder where you want to store the outputs and set the file prefix to what ever prefix you want or remove it if you only need the id.Remove the last row because this was created by default.
-
Thanks @Mayo , I tried this expression- array_distinct(aggregate(layer:='feeder', aggregate:= 'array_agg', expression:="Image_ID")) and its shows expression is invalid– MapQuestMay 19, 2022 at 10:37
-
1The problem is the layer id, use the layer id not the name. An id looks like this: 'sigparques_cartografia_RUNAP_0f495568_2b75_4f4d_8442_83bc6d9f66e3'.– MayoMay 19, 2022 at 13:45
You can do this using pyQGIS:
canvas = iface.mapCanvas() # first, define the map canvas by referencing iface
layers = canvas.layers() # gather all layers into a list
for lyr in layers: # loop through layers
if lyr.name() == "MA_LIDAR_Year":
maLidarYear = lyr
elif lyr.name() == "MA_LidarIntersect_Feeders":
maIntersectFeeders = lyr
features = maLidarYear.getFeatures()
for ftr in features:
fid = ftr.id() # get feature id for filtering later
# filter layer to only current feature
maLidarYear.setSubsetString(f"fid = {fid}")
# clip maIntersectFeeders by current polygon
res = processing.run("native:clip", {
'INPUT': maIntersectFeeders,\
'OVERLAY': maLidarYear,\
'OUTPUT': 'TEMPORARY_OUTPUT'
})
clippedLines = res["OUTPUT"]
# set output name
outputName = f"ID_{fid}_Clipped"
clippedLines.setName(outputName)
QgsProject.instance().addMapLayer(clippedLines)
# finally, remove the filter from maLidarYear
maLidarYear.setSubsetString("")
It's a bit hard to know if this works without testing it, but hopefully this points you in the right direction.