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
Taras
  • 32,823
  • 4
  • 66
  • 137
dmjf08
  • 1,263
  • 7
  • 16

1 Answers1

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)
Taras
  • 32,823
  • 4
  • 66
  • 137
Fran Raga
  • 7,838
  • 3
  • 26
  • 47
  • 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 '19 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 '19 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 '19 at 16:53
  • If is a string,you need create a qgsvectorlayer using this string then – Fran Raga Apr 24 '19 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 '19 at 20:04