# 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)),'')
``````
• 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
)
)
)
``````