3

I would like to give each of these polylines an "ID" e.g. 1,2,3,4 etc. from left to right (West to East) or more accurately off a bearing of 125°.

How can I achieve this in QGIS?

Data: https://we.tl/t-SzWkhwRO0D

QGIS

7
  • 2
    Welcome to GIS SE! We're a little different from other sites; this isn't a discussion forum but a Q&A site. Your questions should as much as possible describe not just what you want to do, but precisely what you have tried and where you are stuck trying that. Please check out our short tour for more about how the site works. Thanks.
    – PolyGeo
    Mar 23, 2021 at 8:26
  • Well, you can simply add the ID field and fill it manually.
    – Erik
    Mar 23, 2021 at 8:47
  • The example I have shown is a small sample, I have thousands of polylines. Unfortunately manual inputting would takes a while!
    – Curtis
    Mar 23, 2021 at 9:02
  • 1
    How to give an ID for the 2 "lines" after the selected one on your screenshot ? If you virtually extend them, they overlap so, same distance from "start". Same ID ? Mar 23, 2021 at 9:04
  • 1
    You could try an SQL approach as used here: gis.stackexchange.com/questions/317604/…
    – MrXsquared
    Mar 23, 2021 at 15:00

3 Answers 3

3

You can try the 'Add autoincremental field' with x(centroid($geometry)) expression for a 'Sort expression', see image below

result

2
  • 1
    Thanks Taras, this worked! I fear for more complicated datasets it will require little more work but it's a good start. Thanks!
    – Curtis
    Mar 23, 2021 at 10:22
  • But will not work very well with a bearing of 180° ! Mar 23, 2021 at 10:52
3

EDIT : delete centroid layer creation and add it in the QGIS expression


The best solution I could find is :

  1. Create a line that has a perpendicular orientation with the "lines" and with a length greater than the "line" layer extend;

  2. Get this line coordinates and / or get the WKT : 'LineString(181748.27971816 823480.02355376, 182605.02880682 822909.74994162)';

  3. In the "line" layer, create a new field with this expression by replacing the line WKT :

with_variable(
  'line',
  geom_from_wkt(
    'LineString(181748.27971816 823480.02355376, 182605.02880682 822909.74994162)' -- replace your WKT lineString here
  ),
  with_variable(
    'pts_on_line',
    aggregate(
      @layer,
      'array_agg',
      round(line_locate_point(@line, centroid($geometry)), 3)
    ), -- array of distance of features centroids projected on the line
    array_find(
      array_sort(@pts_on_line), -- sort array by distance
      round(line_locate_point(@line, centroid($geometry)), 3) -- find the current feature centroid projection distance in the array
    ) -- to start number at 1, you can add here : + 1
))

The above expression will number in order the "line" features. Unfortunately, for same "distance" lines, it will number it with different numbers (centroids coordinates imprecision due to not perfect "lines" in the base layer).

5
  • Thanks, I will give this a go and report back.
    – Curtis
    Mar 23, 2021 at 10:22
  • This works great, thanks. Only question is how can I get it starting it at 1 and not 0?
    – Curtis
    Mar 23, 2021 at 10:51
  • Look at the expression code, I put a comment to add a + 1 to start at 1. Mar 23, 2021 at 10:53
  • Haha didn't see that, thank you!!!
    – Curtis
    Mar 23, 2021 at 11:00
  • I updated the code to directly create a field in your "line" layer. Mar 23, 2021 at 11:15
2

Outline algorithm:

  • Get the X and Y coordinates of the centroids of each feature.

  • Use a rotation matrix to rotate the centroids by 125 degrees.

  • Order by X coordinate (assuming I've got the rotation the right way round) and label 1:N

Depending on how you do this (python function, manual clicking of menu options) you then have to relate those points back to the line features, so you may need to keep a separate ID column to match them.

Seeing someone use the Autoincremental field has inspired me to try that. By putting just the Y coordinate of the rotation matrix in the sort expression you can do this. Use:

 x(centroid($geometry)) *sin(pi()*125/180) + y(centroid($geometry)) * cos(pi()*125/180)

which is the Y coordinate of the centroid rotated 125 degrees.

and then you get this:

enter image description here

the labels here aren't consecutive because the segments above are interweaved between them. Here they are:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.