4

Using native QGIS layer property definitions, I have successfully labelled each polygon in my layer with its area and perimeter.

Never satisfied, I now wish to label each side of each polygon with its length.

It would seem to be a common-enough requirement but I'm not getting good hits.

  • 1
    You have to unbuild polygons into edges – FelixIP Oct 7 '15 at 0:57
  • 2
    I think you will have to convert polygon to lines. And label it using $length expression. – spatialthoughts Oct 7 '15 at 2:38
  • How can we make it in Qgis 3.4 because seems Networks doesnt have the option split regard – Cristian Alvarez Ocares Apr 15 at 2:15
8

The "networks" plugin in QGIS has a facility to split polygons into individual line segments which you can then label with length. I discovered this by trying various search terms in the plugin installer menu. Searching for "split" there did the trick. Install "networks" from the plugins menu.

First convert your polygons to lines using the standard "Vector -> Geometry Tools -> Polygons to Lines" menu option, creating a new shapefile and layer in the process. This won't touch your polygons.

Then select the new lines layer, turn editing on via the pencil icon, and select all the features, then run the "Vector -> Networks -> Split" item. Now you have many line segments! Turn editing off, and save the changes.

Turn on labelling, and use $length for the label. There were too many decimals when I first did this, so I used substr($length, 1, 4) to get this:

labelled line segment lengths

You could also use round($length, 2) for the same effect, but if your line lengths are in thousands or millions of units then you'll still get long labels. You could scale them by 1000000 in the labelling expression, but you will have difficulty getting consistent length labels if your line lengths span several orders of magnitude. It is possible to write a custom python function for formatting numbers in scientific notation to a constant width, and I've just done that and it looks okay.

If you give your line layer an invisible line style then you'll just get your polygon styling with labels on the edges.

enter image description here

Note the 0.37 and 0.10 on the upper left feature seem to be labelling the same side, but that's because there's a node splitting that line. If this is a problem with your case then I suspect a generalisation with a very small, or even zero, tolerance should be enough to remove nodes where you have perfectly straight sides defined by more than one line segment. You can map the nodes of your polygons by using "Vector -> Geometry Tools -> Extract Nodes" to create a point shapefile if you can't see where they are.

  • could you add a point symbol on each node to show the splits? – Ian Turton Oct 7 '15 at 8:03
  • @iant yes, I can do this by adding a "marker line" symbol layer with the marker set to appear every vertex. Neater than making a new layer. – Spacedman Oct 7 '15 at 9:26
  • Thank-you @SpacedMan for pointing me to the Networks plug-in and the effort you put into this answer. – Bad Loser Oct 8 '15 at 7:24
4

If you want to automate that, it can all be done with Processing.

1) Convert to lines using the "Polygons to lines" algorithm

2) split single segments using the "Explode lines" algorithm

Style your layer as explained above, and save the style as a qml file

3) apply the style using the "Set style for vector layer" and the style that you just saved

Now if you put the three steps above in a model using the Processing modeler, you can create a new algorithm that takes a polygon layer and generates your labels in a single step

It should look something like this

enter image description here

  • I really like the Processing Modeller approach but it is causing me severe grief. According to this [wiki] (docs.qgis.org/2.6/en/docs/user_manual/processing_algs/qgis/…) the Set style for vector layer algorithm should have a definable output Styled layer. The dialog is allowing me to define the parameters Vector layer and Style file but that is all. Consequently the styling is never rendered and nor is it possible to follow the algorithm with another. Do you see the results of the styling on your canvas? – Bad Loser Oct 8 '15 at 7:57
  • Will open this as a new question in order to easily provide further data. – Bad Loser Oct 8 '15 at 20:40
  • New question link: gis.stackexchange.com/questions/165888/… – Bad Loser Oct 8 '15 at 21:54
  • hmm, it works fine here, but you are right that this is a strange case, since the output is hidden. Reason for this is that the output is the input itself, not a different file, so the UI should not let the user select the output filename. – Victor Olaya Oct 9 '15 at 10:50
3

All credit goes to Totò Fiandaca on Twitter for this solution: he has shared the QGIS 3 project (including style) showing how this can be accomplished using a combination of the geometry generator and font marker symbology.

Check out the download link in this Twitter thread.

How it works:

An explanation of how the dimension "labels" are done (from my understanding) - I believe the key part here is Step 2 in which each side is generated from consecutive nodes of the polygon.

  1. First he uses Geometry generator to generate the nodes of the polygon using nodes_to_points($geometry), which results in a multipoint geometry. This is made invisible.
  2. Then he uses Geometry generator again (in essence, generating a geometry from a generated geometry!) using the following expression:

    make_line( point_n( $geometry,(@geometry_part_num)),point_n( $geometry,(@geometry_part_num+1)))

    Because it is reading from a multipoint geometry, the expression can iterate through @geometry_part_num and therefore generates a separate line between each pair of nodes, as opposed to a continuous boundary. So if your polygon has 5 sides, you now have 5 separate lines generated.

  3. This line is then styled with a font marker symbology which allows for the placement of text above each segment and solves the problem of label placement with generated geometries.

    The font marker accepts expressions. So to display the length of each generated segment, he uses this expression:
    format_number(length(make_line( point_n( $geometry,(@geometry_part_num)),point_n( $geometry,(@geometry_part_num+1)))),2)||' m'

    The font marker is placed above the central point of each line, with a negative offset so that it appears outside the polygon.

Toto has also styled it with dimension leader lines a la CAD using offset lines and markers, which I encourage you to explore by inspecting the style in his .qgz project file from the download link above.

Apply it to your own data by copying the style from that project and pasting it to your polygon layer in your own project (if you are running Q 3.x. For QGIS 2.18 see below)

QGIS 2.18

Note that this style can also work in QGIS 2.18, however you need to do the following:

  1. Remove offset_curve() from the dimension leader line geometry generator expression as this function is not available in QGIS 2.18

  2. Instead, use the Line offset setting for all the nested symbology (the marker line demarcating either end of the dimension, and the arrow line).

You can also use this method in either version to make the line offset have a maximum and minimum scale, so that that the dimensions keep a pleasing distance from the edge of the polygon at smaller scales or when drawing small polygons.

See example screenshot from QGIS 2.18.

enter image description here

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.