Non Overlapping Areas Determination from Multiple Layers with QGIS and PyQGIS - Tutorial

NonOverlappingAreasQGIS.PNG

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.

Saul Montoya

Saul Montoya es Ingeniero Civil graduado de la Pontificia Universidad Católica del Perú en Lima con estudios de postgrado en Manejo e Ingeniería de Recursos Hídricos (Programa WAREM) de la Universidad de Stuttgart con mención en Ingeniería de Aguas Subterráneas y Hidroinformática.

Smiley face

Subscribe to our free e-newsletter for tutorials, articles, webminars, courses and more.