In this task we will select all the shapefiles in a folder and use python scripting to merge them with their attributes in a memory layer. The Processing algorithm Merge vector layers does the same thing, but we want to do it using Python.
The script is similar to that proposed in a previous task, but this time we don’t want to load the shapefiles in the Layers Panel before merging them.
We will use the datasets available from DIVA-GIS. First of all, download the administrative areas shapefiles for France, Germany and Switzerland; then, copy the shapefiles that will be merged in an external folder (in this task, for each country we will use the shapefile with “adm0” as final part of the filename which represents the boundaries of the country itself):
The following code does the work (if you don’t know how to create a custom script, please see here):
from qgis.core import * import os # Set the directory where the input files are stored directory = "C:/.../input_folder/" # Get the list of input files fileList = os.listdir(directory) # Copy the features from all the files in a new list feats =  for file in fileList: if file.endswith('.shp'): layer = QgsVectorLayer(directory + file, file, 'ogr') for feat in layer.getFeatures(): geom = feat.geometry() attrs = feat.attributes() feature = QgsFeature() feature.setGeometry(geom) feature.setAttributes(attrs) feats.append(feature) # Get the Coordinate Reference System and the list of fields from the last input file crs = layer.crs().toWkt() field_list = layer.dataProvider().fields().toList() # Create the merged layer by checking the geometry type of the input files (for other types, please see the API documentation) if layer.wkbType()==QGis.WKBPoint: v_layer = QgsVectorLayer('Point?crs=' + crs, 'Merged', "memory") if layer.wkbType()==QGis.WKBLineString: v_layer = QgsVectorLayer('LineString?crs=' + crs, 'Merged', "memory") if layer.wkbType()==QGis.WKBPolygon: v_layer = QgsVectorLayer('Polygon?crs=' + crs, 'Merged', "memory") # Add the features to the merged layer prov = v_layer.dataProvider() prov.addAttributes(field_list) v_layer.updateFields() v_layer.startEditing() prov.addFeatures(feats) v_layer.commitChanges() QgsMapLayerRegistry.instance().addMapLayer(v_layer)
This will be the result:
You can save the merged vector layer by right clicking on its name in the Layers Panel and then by clicking “Save as…”.
We need to make some remarks:
- the above code works for shapefiles that have same fields and the same type of geometry;
- the code checks for the most common geometry types (point, line, polygon) of the input layers before creating the merged shapefile. For other geometry types, please replace the lines 28-33 with proper (but similar) syntax taken from the QGIS API Documentation.