3

How can I turn all features of my polyline (postgis and/or shapefile) into one direction - it doesn't matter what direction. I know how to switch the direction of lines but I have no idea how to bring all lines (I have thousands of them) into one single direction.

enter image description here

EDIT:

A line can have only two directions, the one or the other like 0 or 1. I want them all to have the direction 0 OR 1. For example the left line in the image is in direction 1 the middle line is in direction 0 and the right one is in direction 1. Now I want the middle line to direction 1 OR the right and left line to direction 0. So that all lines have the same direction 1 OR 0.

geom;given_direction;wanted_direction
line;1;1
line;0;1
line;1;1
line;1;1
line;0;1
line;1;1
MartinMap
  • 8,262
  • 7
  • 50
  • 114
  • 1
    (Possible Duplicate) Did you try this: http://gis.stackexchange.com/questions/9261/how-can-i-switch-line-direction-in-qgis – tobias47n9e Feb 22 '14 at 19:52
  • this is switching the direction of every line to its opposite but I want all lines into ONE direction. (Or I am wrong?) – MartinMap Feb 23 '14 at 12:10
  • you have to know which ones you wanna change, otherwise, it'll change the entire collection. – OLS Feb 23 '14 at 12:15
  • If line 1, 3, and 4 is in direction 'A' and line 2 and 5 in direction 'B' I need all changed to direction 'A' OR 'B'. – MartinMap Feb 23 '14 at 12:23
  • you need to know the order of the segments. than you can figure out their direction and than reverse the ones you need. use startpoint / endpoint of each segment to figure out which ones you need to reverse – OLS Feb 23 '14 at 12:26
  • I'm unclear how you are defining "one single direction" - can you perhaps provide diagrams of a few more examples? – PolyGeo Mar 16 '14 at 11:19
  • I added some infos – MartinMap Mar 16 '14 at 11:40
  • if there was some attribute about the start point that made you know it was the start than I see a way. Otherwise like others this doesn't make any sense since direction is arbitrary if there's no rule as to what the right way is. – wildintellect Mar 17 '14 at 17:38
  • I'm willing to bet there are far more end points (outfalls or whatever) than start points. Make a list of all the end points. Now every line that has an end that is not connected to another line and neither point on that line is in our list of outfalls is now a 'most upstream line' (MUL). From this list of MULs, find the end that is connected to another line, and orient the line to that point. Travel down this network, orienting the new lines to the upstream direction. When you reach a node where more than two lines connect, you will have to save as a multi-node. I'm sure the rest is trivial – ike Mar 17 '14 at 21:31
  • Once the count of hits at a specific multi-node is equal is equal to n-1, where n is the number of lines with start or stop points at the multi-node, then the remaining line that has not yet been traversed is the exit line. Travel down the remaining network until complete. – ike Mar 17 '14 at 21:43
  • 1
    Can you please add a sample file? This way it might be easier to help. – ustroetz Mar 19 '14 at 08:18

4 Answers4

5

I assume with "one direction" you mean that every segment of a collection of polylines should show into one direction. Also there is a need, that the segments in the collection are in the right order following a single path.

Given this, things are easy: You are searching for pretty much the same thing, I did a couple of months ago. The StackOverflow Community helped me out with this... look here.

Things are getting harder if you have to collect the connected polylines first: A possible algorithm could be:

  1. Take first polyline A.
  2. Save Start Point in a variable
  3. Save End Point in a variable
  4. Take next polyline B
  5. compare A.endPoint with B.startPoint: if equals then merge A and B to A and start over with 3.
  6. comapre A.startPoint with B.endPoint: if equals then merge B and A to A and start over with 2.
  7. compare A.endPoint with B.endPoint: if equals then merge A and B.reverse() to A and start over with 3.
  8. compare A.startPoint with B.startPoint: if equals then merge B.reverse() and A to A and start over with 2.
  9. Do this until no unordered polylines are left.

In this algorithm it doesn't matter if you merge all Coordinates into one big linestring, or into a 2 dimensional sorted array which is in fact a multilinestring.

Jürgen Zornig
  • 1,643
  • 12
  • 31
2

It is not possible to have a single orientation ("from points" connected to "end points" for all your lines) of all your lines if you have loops, which is probably your case because you work with a road network. Therefore you should decide of a rule that would help you set the orientation (for instance, switch all lines where the X coordinate of the end point is larger than the X coordinate of the from point or (better) do this based on the network distance, or the elevation...).

Based on the above statement, I suggest that you only solve you orientation for pseudo nodes. A quick fix is to use Vector -> Geometry Tools -> Singleparts to multipart in order to remove those pseudo-nodes. Otherwise Jürgen Zornig method is best (and you can adapt based on iterative selection because your lines are unlikely to be ordered.)

radouxju
  • 49,636
  • 2
  • 71
  • 144
1

ST_LineMerge can do this job, if the lines are collected in a MULTILINESTRING and share a common start/end vertex.

Example 1 (linestrings with the same direction)

SELECT ST_AsText(ST_LineMerge(
ST_GeomFromText('MULTILINESTRING((-29 -27,-30 -29.7,-36 -31,-45 -33),(-45 -33,-46 -32))')
        )
);
st_astext
--------------------------------------------------------------------------------------------------
LINESTRING(-29 -27,-30 -29.7,-36 -31,-45 -33,-46 -32)
(1 row)

Example 2 (linestrings with different directions)

SELECT ST_AsText(ST_LineMerge(
ST_GeomFromText('MULTILINESTRING((-29 -27,-30 -29.7,-36 -31,-45 -33),(-46 -32,-45 -33))')
        )
);
st_astext
--------------------------------------------------------------------------------------------------
LINESTRING(-46 -32,-45 -33,-36 -31,-30 -29.7,-29 -27)
(1 row)
Antonio Falciano
  • 14,333
  • 2
  • 36
  • 66
-1

First, you have to know which lingstrings you wanna reverse, and than you need to reverse them. I don't know how to do it via QGIS but if you have database side (POSTGRES / POSTGIS) than you can use ST_Reverse

You can also convert the linestring to array and reverse it

list.reverse()
OLS
  • 197
  • 1
  • 11