3

After applying r.thin and then r.to.vect to a raster image the resulting vector layer contains hundreds of small "branches" that are not supposed to be there:

Vector layer showing unwanted branches

I've tried selecting and deleting these mini branches using a $length field in the layer's attribute table but that also deleted short segments in the main contours I want to keep.

A solution would be to identify all short paths where nodes_to_points = 2 and number of intersecting vertices = 1 as this would leave out the paths that are part of the contour (and therefore have 2 intersecting vertices).

Does anybody know how to write this as an expression in the Field Calculator or can think of a better way to remove my unwanted artefacts?

  • 1
    Try this v.clean with rmdangle parameter – Taras Jul 1 at 5:49
  • Thanks! That worked brilliantly. It's my first time posting here so how do I give you credit for your answer or label my question as "solved'? – Balthazar Jul 1 at 6:05
3

You can achieve the result that you are striving for with GRASS toolset v.clean for cleaning topology of a vector element. Probably, you will need to deploy rmdangle option.

rmdangle: remove dangles, threshold ignored if < 0

Check the following references for more details:

1

Tested on QGIS 2.18 and QGIS 3.4

Additionally, I can suggest using a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer....

Let's assume we have the following layer "line" with its Attribute table, see image below.

input1

With the following query, it is possible to clean up the line out of "tails"/"dangles".

SELECT l1.*
FROM line AS l1, line AS l2
WHERE st_intersects(start_point(l1.geometry),end_point(l2.geometry))
OR st_intersects(start_point(l2.geometry),end_point(l1.geometry))
GROUP BY l1.id

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

output1


Mind the fact that previous example will erase only "tails"/"dangles" that are not connected to the starting/points of line features. Additionally, you will need to adjust the query accordingly.

Let's assume we have the following layer "line" with its Attribute table, see image below.

input1

With the following query, it is possible to clean up the line out of "tails"/"dangles" that own two vertices.

SELECT l1.*
FROM line AS l1, line AS l2
WHERE ST_NumPoints(l1.geometry) > 2
AND (st_intersects(start_point(l1.geometry),end_point(l2.geometry))
OR st_intersects(start_point(l2.geometry),end_point(l1.geometry)))
GROUP BY l1.id

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

output2

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.