6

I have some shapefiles. They are all the same kind of shape and all have the same attributes.

If I wanted to merge them manually the "Vector/Data management tools/merge shapefiles to one" works fine.

However, as per the question title, I'd like to do this using Python from a script.

I went hunting for the "merge shape files" in the hopes I could cobble it into my script but I couldn't find it.

I tried writing one myself iterating over the features and copying them into another layer as per the pyQGIS cookbook but lost the attributes along the way.

feature_list = inputlayer.getFeatures()
 for feature in feature_list:
 (res, outFeats) = outputlayer.dataProvider().addFeatures( [ feature ] )

I also tried writing a script using the iface copy features function with the same loss of attributes as a result.

qgis.utils.iface.setActiveLayer(importlayer)
importlayer.setSelectedFeatures(range(100))
#(there are exactly 100 features)
qgis.utils.iface.actionCopyFeatures().trigger()
iface.setActiveLayer( outputlayer )
outputlayer.startEditing()
qgis.utils.iface.actionPasteFeatures().trigger()

Can someone help me fix my code to retain the copied attributes or point me to a pyQGIS script to achieve this result?

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Mar 14, 2014 at 11:09

1 Answer 1

10

OK here's the answer. I have discovered the processing toolbox from which there was a simple solution: As per http://qgis.org/de/docs/user_manual/processing/console.html

From the console you can get a list of all the algorithms available which contain the word "merge" by typing:

import processing
processing.alglist("merge")

Then you could find out how to use the most appropriate function with:

processing.alghelp("qgis:mergevectorlayers")

Then simply use the algorithm in your script as follows:

processing.runalg("qgis:mergevectorlayers", layer1, layer2,"outputfilename.shp")

On the other hand manually merging shapes may still be useful. For those who still want to manually copy features from an input layer into some destination layer with attributes you need to first make sure the destination layer has those fields.

old_attribute_List = input_layer.dataProvider().fields().toList()
new_attribute_List=[]
for attrib in old_attribute_List:
 if destination_layer.fieldNameIndex(attrib.name())==-1:
 new_attribute_List.append(QgsField(attrib.name(),attrib.type()))
destination_layer_data_provider.addAttributes(new_attribute_List)
destination_layer.updateFields()

Then to manually copy over the features you can do:

destination_layer.startEditing()
cfeature = QgsFeature()
cfeatures=[]
xfeatures = input_layer.getFeatures()
for xfeature in xfeatures:
 xgeometry = xfeature.geometry()
 #GEOMETRY TRANSFORM GOES HERE IF DESTINATION CRS DIFFERS FROM INPUT CRS
 cfeature_Attributes=[]
 cfeature_Attributes.extend(xfeature.attributes())
 cfeature.setGeometry(xgeometry)
 cfeature.setAttributes(cfeature_Attributes)
 cfeatures.append(cfeature)
destination_layer_data_provider.addFeatures(cfeatures)
destination_layer_data_provider.commitChanges()
answered Mar 18, 2014 at 1:24
2
  • Note that now QgsVectorLayer has the .pendingFields() method which simplier to apply than the code above. See pyQGIS cookbook Commented Aug 21, 2017 at 21:03
  • Note also the differences between DataProvider.addFeatures() and QgsVectorLayer.addFeatures() as per gis.stackexchange.com/questions/266278/… Commented Feb 6, 2018 at 20:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.