7

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.

example

4
  • 1
    What have you tried so far and what does not work? Please also share images/screenshots of what you want to achieve. – Stefan May 6 '20 at 10:38
  • Is this a display issue, or do you need the length for further processing? – Erik May 6 '20 at 10:43
  • Here comes a question, what is your expectations about the result? should all neighbours + edge length be in one row or each relation should be splitted out? – Taras May 6 '20 at 10:57
  • I had already obtained the neighborhood of the polygon,need their length as a separate attribute – user3289662 May 6 '20 at 11:02
6

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.

input

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

output1

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

output2

4

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

enter image description here

1
  • Fair enough, similar to mine but does not include concatenation. I reckon that the author is tending to an aggregated result. – Taras May 6 '20 at 12:42

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.