Percentage of polygon in one shapefile within polygon of another

This is a relatively simple task using the geoprocessing tools included in QGIS.

  1. Calculate the area of your LSOA zones.

    • Open the LSOA layer attribute table.
    • Enable editing mode.
    • Open the field calculator.
    • Create a new field of type "Decimal number (real)" with the expression "$area".
    • Disable editing mode (saving edits).
  2. Merge the flood zone layer into a single multi-part feature.

    • Vector > Geometry Tools > Singleparts to Multipart.
    • Select "--- Merge all ---" for the Unique ID field.
  3. Intersect the LSOA zone layer with the multipart flood zone layer.

    • Vector > Geoprocessing Tools > Intersect.
    • Input layer is the LSOA zones, intersect layer is the flood zones.
  4. The resulting layer will be the parts of the LSOA zones (with the attributes from the LSOA zones layer) which overlapped with the flood zones layer. To calculate the proportion of each LSOA zone within a flood zone:

    • Calculate the area of the intersected features (as in step #1), then
    • Add another field, dividing the original (total) area by the intersected area. The result is a decimal between 0 and 1. Multiply by 100 to give a percentage.
  5. Join the original LSOA layer to the intersected layer, using the unique ID shared by both layers.

  6. Export the joined layer as a new shapefile.

  7. Delete the duplicated attributes.

Et voilà!

Without step #2, an individual feature would be created for each different flood zone feature for each LSOA feature. This probably isn't what you want if you're only interested in the total coverage for each LSOA zone. If you want to differentiate between fluvial / tidal / pluvial flooding (and the flood zone data supports it), you could convert singlepart s to multipart specifying the "TYPE" field as the Unique ID field.


You can use spatialite and some spatial SQL functions.

Select t1.geometry, t1.ID, area(t1.geometry), area(t2.geometry) ...... (anything you need to have in the table results)

(area(intersection(t1.geometry,t2.geometry))) as "Commun_AREA"

, ("Commun_AREA"*100/(area(t1.geometry))) as "Percent_AREA"

From lsoa as t1, flood_zone as t2

Where Intersects( t1.geometry,t2.geometry ) = 1

This seems like something that could be done much easier than the answers submitted. I would use a simple python script personally:

floodName = "the layer name here"
boundryName = "the layer name here"
fieldName = "the name of the field to contain the output 1/0"
minCoverage = 0.5 # the minimum amount of area covered to write 1
updateMap = [] # this will store values to be written    

# get layers
floodLayer = QgsMapLayerRegistry.instance().mapLayersByName(floodName)[0]
boundryLayer = QgsMapLayerRegistry.instance().mapLayersByName(boundryName)[0]
fieldIndex = boundryLayer.dataProvider().fieldNameIndex(fieldName)    

# iterate through boundries
for b in boundryLayer.getFeatures():
    # get only flood features that intersect with this feature's bounding box
    # this will make the script go way faster than it would otherwise
    request = QgsFeatureRequest().setFilterRect(b.geometry().boundingBox())
    floodGeom = geometry()
    floodFeat = QgsFeature()
    iter = floodLayer.getFeatures(request)
    iter.nextFeature(feat)
    while iter.nextFeature(feat):
        floodGeom = floodGeom.combine(feat.geometry())
    intersectGeom = b.geometry().intersection(feat.geometry())
    if intersectGeom.area() > minCoverage * b.geometry().area():
        updateMap[b.id()] = {fieldIndex : 1}
    else:
        updateMap[b.id()] = {fieldIndex : 0}

boundryLayer.dataProvider().changeAttributeValues(updateMap)

this only evaluates flood polygons that intersect with the bounding box of each boundry layer so it should be fairly quick to run, then it only updates one field in the existing layer (instead of a complex operation of making a whole new layer and copying old values then deleting)