Calculating length of common boundary lines of two polygon in QGIS

I have a map consisting various district. How can I estimate the length of the common boundary shared by any two corresponding districts/polygons in QGIS?

For example if a polygon "A" shares a common boundary with polygons, "B", "C" and "D". Then what would be the length of the boundary between polygon "A-B", "A-C" and "A-D"?

I have calculated the neighboring polygon using the following in field calculator

``````aggregate(
layer:='file_districts',
aggregate:='concatenate',
expression:= DIST_ID,
concatenator:=', ',
filter:=touches(\$geometry, geometry(@parent))
)
``````

Now i want to estimate the length of each of the neighbor polygon.

• What have you tried so far and what does not work? Please also share images/screenshots of what you want to achieve. May 6, 2020 at 10:38
• Is this a display issue, or do you need the length for further processing?
– Erik
May 6, 2020 at 10:43
• I had already obtained the neighborhood of the polygon,need their length as a separate attribute May 6, 2020 at 11:02
• Please, do not forget about "What should I do when someone answers my question?" Oct 13, 2021 at 10:36

Preamble: this solution was being written before the moment when the author demonstrated his efforts in the field calculator.

In QGIS I can suggest using a "Virtual Layer" through `Layer > Add Layer > Add/Edit Virtual Layer...`.

Let's assume we have a layer `'units_1'` (yellow) with its corresponding attribute tables accordingly, see image below.

Case 1. With aggregation

With the following query, it is possible to estimate the length of the common boundary shared by any two corresponding districts/polygons.

``````SELECT
u11.*,
GROUP_CONCAT(u12.id || ', len:' || round(st_length(st_intersection(u11.geometry, u12.geometry)), 4), "; ") AS "neighbor_info"
FROM
"unit_1" AS u11, "unit_1" AS u12
WHERE
st_intersects(u11.geometry, u12.geometry)
AND u11.id <> u12.id
GROUP BY
u11.id
ORDER BY
u11.id ASC
``````

The output Virtual Layer with its Attribute table will look as following

Case 2. Without aggregation

In case if no aggregation has to be conducted then proceed with the following query

``````SELECT
u11.*,
u12.id || ', len:' || round(st_length(st_intersection(u11.geometry, u12.geometry)), 4) AS "neighbor_info"
FROM
"unit_1" AS u11, "unit_1" AS u12
WHERE
st_intersects(u11.geometry, u12.geometry)
AND u11.id <> u12.id
ORDER BY
u11.id ASC
``````

Then the new output Virtual Layer with its Attribute table will look as following

Similar to @Taras's answer, you can create a virtual layer to get the actual border lines, and then compute their length (or display them, or label them, or ...)

Go to the menu `Layer > Add Layer > Add/Edit Virtual Layer...` and enter the following query.

``````select a.id as poly1_id, b.id as poly2_id,
st_intersection(a.geometry, b.geometry) as geometry,
st_length(st_intersection(a.geometry, b.geometry)) as border_length
from my_layer a
join my_layer b
ON st_intersects(a.geometry, b.geometry)
AND a.id < b.id
``````

Note that if your layer is in lat/longs (4326), the you should use `st_length(st_intersection(a.geometry, b.geometry),true) as border_length` instead. This version of `st_length` will return a distance in meters instead of degrees.

Calculate the length of the border the current polygon shares with all bordering polygons, use this expression that creates an array:

``````
array_foreach (
overlay_touches (@layer, \$geometry),
length (intersection (\$geometry, @element))
)

``````

Convert it to a string with `array_to_string()`, add the `\$id` to identify the polygons and add other modifications (see below).

A polygon layer with an expression-generated label, based on the expression from above, that generates a text-string list of length with all neighboring polygons (see below for the exact expression used here):

• The expression used to generate the red line in the screenshot, using Geometry generator:

``````if (\$id = 1, intersection ( \$geometry, overlay_touches (@layer, \$geometry)[0]),'')
``````
• To generate the length of the common boundary line of polygons `b` and `c`, stored in the field named `name`, use this expression (change layer name and value in lines 2 and 6):

``````if (
name = 'b',
length(
intersection (
\$geometry,
geometry (get_feature (@layer, 'name', 'c'))
)
),
''
)
``````
• The expression used to generate the label in the screenshot - can be used without changes on any polygon layer:

`````` 'Length border of polygon '  ||
\$id || ' with: '  ||  '\n'  ||
array_to_string (
array_foreach (
overlay_touches (@layer, \$id),
'   - polygon'  ||
@element || ': ' ||
round (
length (
intersection (
\$geometry,
geometry (
get_feature_by_id (
@layer,
@element
)
)
)
),
3
)
)
)
``````