I have two vector layers

  • a landcover map showing the different habitats in a region
  • a grid of 4 x 4 km squares that covers the region

vector layer

grid layer

I have to calculate the percentage of landcover in each grid square, so the percentage of what is in the landcover layer for each individual 4 x 4 km square.

How to achieve this in QGIS?

  • 2
    Both interesting, but I think this should definitely asked as two separate questions. Apr 18 '18 at 12:56

Prerequisition: Your grid has a unique id attribute to identify the grid cells. If not so, you may create one using QGIS Field calculator like this:

enter image description here

Now you can intersect you landcover and grid with the Intersection-Tool (Processing Toolbox, search inters....):

enter image description here

It's easily configured and will assign the attributes of the grid cells (especially the id, see above)

enter image description here

You may verify this by setting up a categorized style on the id attribute of the resulting Intersection Layer.

enter image description here

Then run QGIS Dissolve (Processing Toolbox, again) on the result:

enter image description here

The QGIS Dissolve algorithm has the great advantage of being able to dissolve on various attributes. Dissolve on the referred id and your landuse classification attribute (mine is called name). Don't forget to uncheck 'Dissolve all':

enter image description here

In the resulting Layer, you can select a feature and see what happened, one multipolygon per landuse category and grid cell! Yay!!! (Note that the Dissolve Tool description is a bit misleading here, because it talks just about adjacent polygons...)

enter image description here

Now you're nearly done. The percentage area is simply calculated with the above mentioned Field Calculator by dividing each features $area by the grid cells area (mine are 1000 x 1000 = 1000000 map units). Because of possibly very small landuse areas I select a relatively high precision (6 digits) for the area percentage:

enter image description here

Having done so, save edits to your layer and have a look at the attribute table of the Dissolved Layer (note the attributes name,id and area_perc):

enter image description here

So far so good. The next step would be to create an attribute on the grid for each landuse category and fill in the area_perc values in order to e.g. draw pie charts etc.

Here we go. This little python script (quick and dirty I must confess...) accomplishes this task:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#---------Schnittstelle definieren
##Create Attributes from Attribute values=name
##Field_to_query_attribute_values_from=field Attribute_value_provider
##Percent_values=field Attribute_value_provider
##Matching_field=field Attributes_to_create

from PyQt4 import QtCore
from qgis.core import *
from processing import *

attrib_val_provider = processing.getObject(Attribute_value_provider)
layer_to_change = processing.getObject(Attributes_to_create)

#create attributes 
attr_id =     attrib_val_provider.fieldNameIndex(Field_to_query_attribute_values_from)
values = attrib_val_provider.uniqueValues(attr_id)
attributes = [QgsField(name, QVariant.Double) for name in values]

#assign attribute values to the new features
attr_id = layer_to_change.fieldNameIndex(Matching_field)
ids = layer_to_change.uniqueValues(attr_id)
for id in ids:
    # get feature from layer 2 to modify
    expr = QgsExpression('"{0}" = {1}'.format(Matching_field, id)) 
    feat = [f for f in layer_to_change.getFeatures(QgsFeatureRequest(expr))][0]
    fid = feat.id()
    attrs = {}
    for name in values:
        # get area percentage from layer 1
        expr = QgsExpression('"{0}" = \'{1}\' and "{2}" = {3}'.format(Field_to_query_attribute_values_from, name, Matching_field, id))
        feats = [f for f in attrib_val_provider.getFeatures(QgsFeatureRequest(expr))] #result should be only 1 feature
        if len(feats) == 1:
            area_perc = feats[0][Percent_values]
        elif len(feats) == 0:
            area_perc = 0.0
        attrs[layer_to_change.fieldNameIndex(name)] = area_perc * 100
    layer_to_change.dataProvider().changeAttributeValues({fid : attrs})
    progress.setText('id {0} processed.'.format(id))

Copy+paste it, save it under the_name_you_like.py and add it to your processing scripts in the Processing toolbox under Scripts|Tools|Add script from file (select the file you just saved).

enter image description here

It should then be found under [giswg]:

enter image description here

Doubleclick to execute and select the appropriate parameters:

  • landuse layer
  • landuse category attribute
  • area percentage attribute
  • grid layer
  • id attribute of grid cells

enter image description here

The log should do something like shown below during and after execution:

enter image description here

In the case of success, your grid layers attribute table should look something like shown below. Important Note: The percent values ranging from 0...100% come from the script, not from the field calculator above (0...1). This can either be done (if necessary) by the script OR the field calculator, not by both of them.

enter image description here

The values from 0...100% are required to create pie chart diagrams for the grid cells for example:

enter image description here

  • +1 impressive / eindrucksvoll
    – Taras
    Sep 16 '19 at 9:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.