4

I'm trying to count the number of entities but each time I have this error:

`AttributeError: 'dict' object has no attribute 'featureCount'

while I have only one selected layer

uri = r"C:\impression_plan\FicheCana.shp"
layer = QgsVectorLayer(uri, "", "ogr")


layer_split = processing.runAndLoadResults("native:splitfeaturesbycharacter",
                        {'INPUT': layer, 
                         'FIELD':'NOM_CONCAT',
                         'CHAR':', ',
                         'REGEX': False,
                         'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
        

#dissolve features based on values in an attribute table field
layer_circuit=processing.runAndLoadResults("native:dissolve", 
                        {'INPUT':layer_split, 
                        'FIELD':'NOM_CONCAT', 
                        'OUTPUT':'C:\impression_plan\circuit.shp'})

iter = layer_circuit.featureCount()
print(iter)
6

runAndLoadResults is returning a dictionary. And for some reason, it is not returning a layer when you add ['OUTPUT'] at the end like run does:

lyr = processing.runAndLoadResults("native:dissolve", {'INPUT':'/home/bera/GIS/Data/testdata/ak_riks_2.shp','FIELD':[],'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
print(type(lyr))
<class 'str'>

But you can do:

vlayer = processing.run("native:dissolve", {'INPUT':'/home/bera/GIS/Data/testdata/ak_riks_2.shp','FIELD':[],'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
QgsProject.instance().addMapLayer(vlayer)
cnt = vlayer.featureCount() #(Dont name a variable iter, it is the name of an existing function)
print(cnt)
1
1
8

Use the following structure:

#dissolve features based on values in an attribute table field
layer_circuit = processing.runAndLoadResults(
                  "native:dissolve", 
                  {'INPUT':layer_split, 
                   'FIELD':'NOM_CONCAT', 
                   'OUTPUT':'C:/impression_plan/circuit.shp'})

layer =  QgsProject.instance().mapLayersByName("circuit")[0]

print(layer.featureCount())

Explanation:
Processing tools in PyQGIS return a dictionary that contains an "OUTPUT" for key, and a value ({"OUTPUT": value}). The type of value mainly depends on two facts, (1) the processing tool used and (2) the tool's "OUTPUT" parameter (please note that this is not the same as "OUTPUT" in the dictionary above). In your case, we are interested in "OUTPUT" parameter.

  • If you use a file path for "OUTPUT" parameter, value will be a file path string.

    result = processing.runAndLoadResults("alg_name", {other parameters,
                                                       "OUTPUT":'c:/foo/bar.shp'})
    
    # result -> {'OUTPUT': 'c:/foo/bar.shp'}
    # 'c:/foo/bar.shp' is a string and a file path
    

    A new layer named bar is added to the project and you have to get the layer reference using its name.

    layer = QgsProject.instance().mapLayersByName("bar")[0]
    print(layer.featureCount())
    
  • If you use "TEMPORARY_OUTPUT" (or "memory:") for "OUTPUT" parameter, value will be the ID of new layer.

    result = processing.runAndLoadResults("alg_name", {other parameters,
                                                       "OUTPUT":'TEMPORARY_OUTPUT'})
    
    # result -> {'OUTPUT': 'foo_bar_0aefc...'}
    # 'foo_bar_0aefc...' is a string and refers the ID of new layer.
    

    In this case, you get the layer reference using mapLayer method.

    layer_id = result["OUTPUT"]
    layer = QgsProject.instance().mapLayer(layer_id)
    print(layer.featureCount())
    

For more information, check this answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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