Non Overlapping Areas Determination from Multiple Layers with QGIS and PyQGIS - Tutorial
/Geospatial process are involved in most part of our activities; because of that it is important to optimize the time spent by the GIS specialist and to improve the quality of the spatial analysis. PyQGIS is the Python extension in QGIS, this framework allows us to manage the QGIS tools together with Python functions and even with external Python packages improving the speed and quality of our geoprocessing and spatial representation.
In this tutorial we will show the complete procedure to determine the non overlapping areas of an area of interest from 7 different layers. The tutorial covers the following parts as PyQGIS scripts:
- Upload the Area of Interest and other layers on a QGIS project
- Clip all layers to the Area of Interest
- Perform a topological correction with Grass Gis
- Dissolve elements from the layers
- Determine the non overlapping areas
Tutorial
Code
This is the Python code used in the tutorial
Part 1
import os mainLayerFolder = 'C:\Users\Saul\Documents\Ih_AnalisisdeAreasNoSuperpuestasporMultiplesCapasconQGISyPyQGIS\Shp' listLayers = [] for item in os.listdir(mainLayerFolder + '/Layers/'): if item[-3:]=='shp': listLayers.append(item) dictLayers = {} for layer in listLayers: dictLayers[layer[:-4]] = iface.addVectorLayer(mainLayerFolder + '\\Layers\\' + layer , layer[:-4] , "ogr") areaOfInterest = iface.addVectorLayer(mainLayerFolder + '\\AreaofInterest\\AreaOfInterest.shp' ,'AreaOfInterest',"ogr")
Part 2
from processing.tools import * dictLayersClip = {} for layer in dictLayers.keys(): general.runalg("qgis:clip",\ dictLayers[layer],\ areaOfInterest,\ mainLayerFolder + '\\LayersClip\\'+layer+'_Clip.shp') dictLayersClip[layer+'_Clip'] = iface.addVectorLayer(mainLayerFolder + '\\LayersClip\\'+layer+'_Clip.shp',layer+'_Clip',"ogr")
Part 3
from processing.tools import * dictLayersClipClean = {} for layer in dictLayersClip.keys(): if dictLayersClip[layer].featureCount() > 0: extent = dictLayersClip[layer].extent() xmin = extent.xMinimum() xmax = extent.xMaximum() ymin = extent.yMinimum() ymax = extent.yMaximum() outputLayer = mainLayerFolder + '\\LayersClipClean\\'+layer+'_Clean.shp' general.runalg("grass7:v.clean",\ dictLayersClip[layer],\ 0,\ 0.1,\ "%f , %f, %f, %f "% (xmin , xmax , ymin , ymax),\ -1.0,\ 0.0001,\ outputLayer,\ None\ ) dictLayersClipClean[layer+'_Clean'] = iface.addVectorLayer(outputLayer , layer+'_Clean', "ogr")
Part 4
from processing.tools import * dictLayersClipCleanDiss = {} for layer in dictLayersClipClean.keys(): outputLayer = mainLayerFolder + '\\LayersClipCleanDiss\\'+layer+'_Diss.shp' print(outputLayer) general.runalg("qgis:dissolve",\ #areaOfInterest,\ dictLayersClipClean[layer],\ True,\ None, outputLayer) dictLayersClipCleanDiss[layer+'_Diss'] = iface.addVectorLayer(outputLayer , layer+'_Diss' , "ogr")
Part 5
from processing.tools import * dictInter = {} layerList = dictLayersClipCleanDiss.keys() for item in range(len(layerList)): outputFolder = mainLayerFolder + '\\LayersClipCleanDissInter\\' #outputLayer = outputFolder + 'Step' + str(item) + '_______' + layerList[item] + '_Inter.shp' outputLayer = outputFolder + 'Step' + str(item) + '.shp' print(outputLayer) if item == 0: general.runalg("qgis:difference",\ areaOfInterest,\ dictLayersClipCleanDiss[layerList[item]],\ True,\ outputLayer) elif item > 0: general.runalg("qgis:difference",\ dictInter['Step' + str(item-1)],\ dictLayersClipCleanDiss[layerList[item]],\ True,\ outputLayer) dictInter['Step' + str(item)]=iface.addVectorLayer(outputLayer , 'Step' + str(item), "ogr")
Input data
You can download the input files for this tutorial on this link.