7

I try to run algorithms on layers but only on selected features with QgsProcessingFeatureSourceDefinition() in a loop and then write the result with QgsVectorFileWriter:

layer1 = QgsVectorLayer(path1, 'layer 1', 'ogr')
layer2 = QgsVectorLayer(path2, 'layer 2', 'ogr')

idx = layer2.dataProvider().fieldNameIndex('colL2')
col2values = layer2.uniqueValues(idx)

fields = layer1.dataProvider().fields()
writer = QgsVectorFileWriter(pathOutput, "CP1250", fields, QgsWkbTypes.LineString, layer1.crs(), "ESRI shapefile")

for value in col2values:
    # Layer 1 and Layer 2 have the same column name 'colL2' but Layer 1 values are longer
    
    selectLayer2 = QgsExpression(" \"colL2\" LIKE '" + str(value) + "' ")
    selectedLayer2 = layer2.getFeatures(QgsFeatureRequest(selectLayer2))
    idsLayer2 = [f.id() for f in selectedLayer2]
    layer2.selectByIds(idsLayer2)

    selectLayer1 = QgsExpression(" \"colL2\" LIKE '" + str(value) + "%' ")
    selectedLayer1 = layer1.getFeatures(QgsFeatureRequest(selectLayer1))
    idsLayer1 = [f.id() for f in selectedLayer1]
    layer1.selectByIds(idsLayer1)

    parameters = {
        'INPUT': QgsProcessingFeatureSourceDefinition(layer1.id(), True),
        'OUTPUT': 'memory:'
    }
    layer1_line = processing.run('qgis:polygonstolines', parameters)

    parameters = {
        'INPUT': QgsProcessingFeatureSourceDefinition(layer2.id(), True),
        'OUTPUT': 'memory:'
    }
    layer2_line = processing.run('qgis:polygonstolines', parameters)

    parameters = {
        'INPUT': layer1_line['OUTPUT'],
        'OVERLAY': layer2_line['OUTPUT'],
        'OUTPUT': 'memory:'
    }
    differenced = processing.run('qgis:difference', parameters)

    writer.addFeatures(differenced['OUTPUT'].getFeatures())

    layer1.removeSelection()
    layer2.removeSelection()

del writer

But I get the following error:

raise QgsProcessingException(msg)
_core.QgsProcessingException: Unable to execute algorithm
Could not load source layer for INPUT: layer_1_XXX not found

1 Answer 1

16

You need add the layer to project.

For add without showing it use:

QgsProject.instance().addMapLayer(layer1, False)

Example using only one layer:

layer1 = QgsVectorLayer(r"C:\test\grassland.shp", 'layer 1', 'ogr')
QgsProject.instance().addMapLayer(layer1, False)

parameters = {
    'INPUT': QgsProcessingFeatureSourceDefinition(layer1.id(), True),
    'OUTPUT': 'memory:'
}

layer1_line = processing.run('qgis:polygonstolines', parameters)
5
  • I try to use it with a temporary layer like following : 'OVERLAY': QgsProcessingFeatureSourceDefinition(layer['OUTPUT'].id(), True), but it returns Could not load source layer for OVERLAY : output_.... not found. Can't the layer be temporary ?
    – dmjf08
    Apr 10, 2019 at 12:33
  • yes, but you have to add it to the project QgsProject.instance().addMapLayer(layer['OUTPUT'], False) try that
    – Fran Raga
    Apr 10, 2019 at 13:25
  • It works but the output of the algorithm is not a QgsVectorLayer as usual, it's a string "output_...". How can I get the QgsVectorLayer ?
    – dmjf08
    Apr 24, 2019 at 16:53
  • If is a string,you need create a qgsvectorlayer using this string then
    – Fran Raga
    Apr 24, 2019 at 16:57
  • Okay thanks. Just to be sure : is that normal that I get QgsVectorLayer with for example qgis:intersection and with the same principle I get a string in the output of qgis:difference ?
    – dmjf08
    Apr 24, 2019 at 20:04

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.