# Calculating the percentage of overlapping areas from different layers in QGIS

I work with QGIS 3.16 Hannover and I have three polygon layers `'A', 'B', 'C'` with multiple geometries in each.

In the image, layer `'A'` has the bold polygons and, for each of them (meaning within each of them), I need to calculate the percentage of the area of all the blue polygons (layer `'B'`) that is covered by the squared polygons (layer `'C'`) Following the guidelines given by @MrXsquared in this post, I built the following code in the field calculator for layer `'A'`, but it returns null or wrong values

``````area(
intersection(
(buffer(collect_geometries(overlay_intersects('B', \$geometry)),0)),
(buffer(collect_geometries(overlay_intersects('C', \$geometry)),0))))
*100/area(buffer(collect_geometries(overlay_intersects('B', \$geometry)),0))
``````

Any idea of what's wrong?

• Could you provide a screenshot how the layers look like and indicate which kind of overlapping you want to calculate? Or do you have some sample data you could share? What do you mean by "doesn't work properly" - what does not work? Apr 2, 2021 at 19:43
• You want to calculate the area where all three layer overlap, but as percentage related to the area of each feature of layer A? Apr 2, 2021 at 19:50
• I have edited the question. Hope it is clearer now. Apr 2, 2021 at 20:04
• Thanks for providing more details, hope my solution provides what you're looking for. Apr 2, 2021 at 20:34

The problem with the expression you provided was that the `intersection ()` part only calculated the overlap of C and B, notwithstanding if they are inside A or not. You have to add another overlap, pseudocode: `overlap of A with ( overlap of B and C)` - you had only the part inside the paranthesis.

To create the overlap you're interested in, the expression looks like (for the area and percentage see below):

``````intersection (
\$geometry ,
intersection(
buffer(
collect_geometries(
overlay_intersects(
'B',
\$geometry
)
),
0
),
buffer(
collect_geometries(
overlay_intersects(
'C',
\$geometry
)
),
0
)
)
)
``````

Screenshot: A= black lines; B: blue; C: green; red: overlap calculated with the expression above: So based on this, calculating the percentage of ovelapping for each polygon of A is easy - pseudocode: `area of the overlap created above / area of each polygon of A * 100`. In fact, buffering by 0 is not necessary, you can leave this part away. Thus the expression to calculate the percentage looks like this:

``````area (
intersection (
\$geometry ,
intersection(
collect_geometries(
overlay_intersects(
'B',
\$geometry
)
),
collect_geometries(
overlay_intersects(
'C',
\$geometry
)
)
)
)
)
/area(\$geometry)*100
``````

Screenshot: the label is created dynamically with the expression above (+ a `round()` to round to one decimal). Polygon A on the right (balck outlined) contains four overlapping areas (red), the polygon at the bottom left 2, the other two just one red area. The percentage is calculated as the sum of all red areas inside a polygon, whereas the area of the black outlined polygon A features is 100% for each polygon: If however the percentage of ovelapping you need is not for each polygon of A, but for the area of the blue polygons that are within each polygon of A, than replace the last line `/area(\$geometry)*100` with this expression:

``````/area (
intersection (
\$geometry ,
collect_geometries(
overlay_intersects(
'B',
\$geometry
)
)
)
)*100
``````

After some tries, the final expression that works for the date of the OP includes the buffers of 0:

``````area (
buffer(
intersection (
\$geometry ,
buffer (
intersection(
buffer(
collect_geometries(
overlay_intersects(
'B',
\$geometry
)
),
0
),
buffer(
collect_geometries(
overlay_intersects(
'C',
\$geometry
)
),0
)
),0
)
),0
)
)/area(
buffer(
collect_geometries(
overlay_intersects(
'B',
\$geometry
)
),0
)
)*100
``````
• Many thanks indeed for such a detailed explanation. However, the percentage of ovelapping that I need is not for each polygon of A, but for the area of the blue polygons that are within each polygon of A. The pseudocode: area of the overlap in red / overlap of A and B (* 100). So, if I'm not mistaken, the code for the overlap of A and B would be `intersection(collect_geometries(overlay_intersects('B', \$geometry)`. BTW, the "* 100", shouldn't it be in the numerator? Apr 2, 2021 at 22:01
• Updated that part. if `*100` is in the numerator or not does not play a role: test the preview of the expression editor for something like `10*5/2` and `10/2*5` - the result is the same. Apr 2, 2021 at 22:21
• By the way: are all the layers in the same CRS? Apr 2, 2021 at 22:23
• Yes, they are in the same CRS Apr 3, 2021 at 17:27
• OK, pasted your solution to my answer. In the case of my test-polygons, aplying the buffer does not play a role - I'm not sure why in your case this is crucial. This shows that a soution might depend on the kind of data you have - so adding some sample data to a question can be helpful as creating own test data will not always reflect the problem in it's whole complexity. Glad you resolved your problem. Apr 4, 2021 at 20:33