I am using PostGIS and QGIS 2.2.

I have a shapefile of rivers and a shapefile of state parks and other polygons. I would like to show the user a simplified version of a stream as a straight line, with the edges of the stream line highlighted where it intersects a polygon.

Here is a picture of my map in QGIS: a normal map of a stream Ignore the tributaries - they are well named and easily culled :)

Here is the simplified version I would like:

A String Map of the stream

In order to create the above image, I would imagine I need to split the stream into several lines. In the above example, I would need six. Blue, Green, Blue, Green, Blue, and Green again. Each of these segments would have a distance and a type (blue, or green). The total distance would be normalized to unit length, and all the segments would be displayed for the user.

Another solution would be to simply track the Green segments, each with two offsets: a point, and an end point. In this case, there would only be three segments, and they would show where they started and stopped. This would work well if I wanted multiple types.

It was fun to find the distance of the stream inside of polygons vs outside using ST_Intersect and ST_Length. However, that was simply a ratio of inside vs outside. My solution needs both length and order. I think I need to split the line into several smaller lines - both inside and outside the polygons.

I think my solution needs to satisfy the following properties:

  • Length of each segment must be preserved
  • Order of segments must be preserved

1 Answer 1


I'll give you the parts, but you'll have to put them together yourself:

  • Use ST_Intersection(ST_ExteriorRing(pal.geom), river.geom) to get the POINTs at which the land crosses the river.
  • Use ST_LineMerge to build all the river lines up into a SINGLE river line
  • If the river direction is backwards us ST_Reverse to make sure it goes in an upstream direction
  • Use ST_Line_Locate_Point to calculate the proportion up the river each land crossing point is
  • Celebrate
  • Your outline was correct, especially the ST_LineLocate, which turned my points into floating points between 0..1. Now I've successfully tabulated the data to have the beginning and end of each publicly-accessible section. In fact, it turns out there were FOUR sections - one tiny little sliver of non-public land no more than 20 meters long! However, I couldn't use the ST_ExteriorRing because that would miss the corner case in which the stream is entirely contained in public land.
    – standers
    Commented Mar 2, 2014 at 18:28

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.