Saturday, 1 April 2017

Merging shapefiles with attributes using PyQGIS?


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?



Answer



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()

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...