1

I am developing a plugin for Qgis. I have three layers that contain polygon geometries, and that need to be combined in one layer. During this process, I also collect all the attributes from the input features and write them into the output layer. However, the input layers have different attribute sets. The code, which I have written sets attributes to a feature based on the position of attributes, which vary for different input layers. So the question is:

How can I set the attributes to a QgsFeature in the output layer based on the name of the field that this attribute had in the input layer?

Here is the code that does the job now, but mixes the attribute values in the output layer:

# 1) Create a temporary output layer
output_layer = QgsVectorLayer("Polygon?crs=epsg:4326", "Combined polygons", "memory")

# 2) Create a list of layers. Layers are retrieved from the plugin dialog earlier in
#the code. There are more than two layers. Here, for simplicity, working with 
#only two of them
input_layers= [(input1,"Polygons_before"),(input2, "Polygons_after")]
output_layer_provider = output_layer.dataProvider()

new_field_inserted=False # This will be used later for inserting a new field

# 3)Iterate through the input layers to combine them in one layer
for layer, name in input_layers:
     collected_features = []

     #Get the input layer attribute fields
     layer_attr = layer.dataProvider().fields().toList()

     #Add a new field for distinguishing features from different input
     # layers in the output layer. 
     if new_field_inserted==False:
        new_field = QgsField("mask_type", QVariant.String, "text", 50)
        layer_attr.insert(1, new_field)
        new_field_inserted = True # Set this variable to True to avoid inserting the field miltiple times.

     #Add input attribute fields to output layer
     output_layer_provider.addAttributes(layer_attr)
     output_layer.updateFields()

     #Get the input features
     features = layer.getFeatures()

     #Collect input features in a list
     for feat in features:
         geom = feat.geometry()
         attr = feat.attributes()
         attr.insert(1,name)
         feature = QgsFeature()
         feature.setGeometry(geom)
         feature.setAttributes(attr)
         collected_features.append(feature)

      #Add collected features to the output layer
      output_layer_provider.addFeatures(collected_features)

 QgsProject.instance().addMapLayer(output_layer)
  • I understand that those layers don't have any relationship key, right? – Fran Raga Apr 26 at 10:11
  • No, they don't. – Jovid Apr 26 at 10:14
  • Is there any reason for not to use this qgis algorithm native: mergevectorlayers? – Fran Raga Apr 26 at 10:24
  • Yes, the reason is that a new field shoud be added to attribute table in the output file. This field will be filled with a specific name for features from different layer so that the input features can be distinguished from each other in the input layer. I modfifed the code to show this. – Jovid Apr 26 at 10:39
  • mergevectorlayers add a new field, identified the source layer and another with the path to the layer – Fran Raga Apr 26 at 10:45

Your Answer

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

Browse other questions tagged or ask your own question.