[GRASS-user] How to link or combine adjacent vector lines

Dear friends,

I have been trying for some hours now but could not find any solution.

We do have a shape file of a river network, but a bad one because single
rivers consist of multiple lines. Just think of the easiest example, a river
with one tributary. I would like to end up with an vector dataset that holds
2 lines for this example, one for the river and one for the tributary of
course. In my case, the dataset holds, just as an example, 10 lines, and a
distinct set of them makes either the river or the tributary. The lines of
each set are connected by the nodes of the single lines.

Any ideas how to get ride of this format are very welcome.

Thanks in advance,

Stefan

--
View this message in context: http://osgeo-org.1560.n6.nabble.com/How-to-link-or-combine-adjacent-vector-lines-tp4381557p4381557.html
Sent from the Grass - Users mailing list archive at Nabble.com.

Dear friends, 

I have been trying for some hours now but could not find any solution. 

We do have a shape file of a river network,  but a bad one because single
rivers consist of multiple lines. Just think of the easiest example, a river
with one tributary. I would like to end up with an vector dataset that holds
2 lines for this example, one for the river and one for the tributary of
course. In my case, the dataset holds, just as an example, 10 lines, and a
distinct set of them makes either the river or the tributary. The lines of
each set are connected by the nodes of the single lines. 

Any ideas how to get ride of this format are very welcome. 

You might be interested in this thread from a year ago.
http://osgeo-org.1560.n6.nabble.com/snap-point-to-line-break-line-at-given-points-tp3887413p3887413.html

The short story is that GRASS builds topology when importing a line vector. So each intersection of two lines (i.e. a tributary that branches off the main channel) will be made into a separate line. You can force GRASS to ignore topology, but you probably don’t want to. And a correct river network does indeed keep each stream reach as a separate line. (Then you can use the various river network modules r.stream.*). So maybe your original shapefile is not “bad”…

What you can do it add an additional column to the vector attrib table and indicate, in that column, which tributary each segment belongs to. THen you can select, display, label, calculate, etc based on this “tributary” attribute column. Would that help?

···
-- 
Micha Silver
GIS Consultant, Arava Development Co.
[http://www.surfaces.co.il](http://www.surfaces.co.il)

Sorry for the delay… and thanks for the fast answer.

Adding a column and then running a command in the sense of “v.dissolve” is not an option because there are just to many. I was thinking of a way that combines two lines into one if they share the same node. For the example mentioned the last time, this means, keeping the line as a single one until the tributary merges the main river. The main river might consist of more than one line, but a short tributary should not.

I hope I dont miss anything obvious … :wink:

Cheers,

Stefan

On Fri, 2012-02-10 at 17:04 +0200, Micha Silver wrote:

On 02/09/2012 11:59 PM, sluedtke wrote:

Dear friends, 

I have been trying for some hours now but could not find any solution. 

We do have a shape file of a river network,  but a bad one because single
rivers consist of multiple lines. Just think of the easiest example, a river
with one tributary. I would like to end up with an vector dataset that holds
2 lines for this example, one for the river and one for the tributary of
course. In my case, the dataset holds, just as an example, 10 lines, and a
distinct set of them makes either the river or the tributary. The lines of
each set are connected by the nodes of the single lines. 

Any ideas how to get ride of this format are very welcome. 

You might be interested in this thread from a year ago.
http://osgeo-org.1560.n6.nabble.com/snap-point-to-line-break-line-at-given-points-tp3887413p3887413.html

The short story is that GRASS builds topology when importing a line vector. So each intersection of two lines (i.e. a tributary that branches off the main channel) will be made into a separate line. You can force GRASS to ignore topology, but you probably don’t want to. And a correct river network does indeed keep each stream reach as a separate line. (Then you can use the various river network modules r.stream.*). So maybe your original shapefile is not “bad”…

What you can do it add an additional column to the vector attrib table and indicate, in that column, which tributary each segment belongs to. THen you can select, display, label, calculate, etc based on this “tributary” attribute column. Would that help?

Thanks in advance, 

Stefan

--
View this message in context: [http://osgeo-org.1560.n6.nabble.com/How-to-link-or-combine-adjacent-vector-lines-tp4381557p4381557.html](http://osgeo-org.1560.n6.nabble.com/How-to-link-or-combine-adjacent-vector-lines-tp4381557p4381557.html)
Sent from the Grass - Users mailing list archive at Nabble.com.
_______________________________________________
grass-user mailing list
[grass-user@lists.osgeo.org](mailto:grass-user@lists.osgeo.org)
[http://lists.osgeo.org/mailman/listinfo/grass-user](http://lists.osgeo.org/mailman/listinfo/grass-user)

This mail was received via Mail-SeCure System.

-- 
Micha Silver
GIS Consultant, Arava Development Co.
[http://www.surfaces.co.il](http://www.surfaces.co.il)

Sorry for the delay… and thanks for the fast answer.

Adding a column and then running a command in the sense of “v.dissolve” is not an option because there are just to many. I was thinking of a way that combines two lines into one if they share the same node. For the example mentioned the last time, this means, keeping the line as a single one until the tributary merges the main river. The main river might consist of more than one line, but a short tributary should not.

How will you (or the command) know which lines to combine?

There is: v.edit tool=merge or v.edit tool=connect
But AFAIK these will not allow you to break topology.

···
-- 
Micha Silver
GIS Consultant, Arava Development Co.
[http://www.surfaces.co.il](http://www.surfaces.co.il)

On Sat, 2012-02-11 at 21:26 +0200, Micha Silver wrote:

On 02/11/2012 08:49 PM, Stefan Luedtke wrote:

Sorry for the delay… and thanks for the fast answer.

Adding a column and then running a command in the sense of “v.dissolve” is not an option because there are just to many. I was thinking of a way that combines two lines into one if they share the same node. For the example mentioned the last time, this means, keeping the line as a single one until the tributary merges the main river. The main river might consist of more than one line, but a short tributary should not.

How will you (or the command) know which lines to combine?

That a difficult question, indeed. Maybe there is no way and I have to do it manually.
Anyway- thanks for you comments.

Take care.

There is: v.edit tool=merge or v.edit tool=connect
But AFAIK these will not allow you to break topology.

I hope I dont miss anything obvious … :wink:

Cheers,

Stefan

On Fri, 2012-02-10 at 17:04 +0200, Micha Silver wrote:

On 02/09/2012 11:59 PM, sluedtke wrote:

Dear friends, 

I have been trying for some hours now but could not find any solution. 

We do have a shape file of a river network,  but a bad one because single
rivers consist of multiple lines. Just think of the easiest example, a river
with one tributary. I would like to end up with an vector dataset that holds
2 lines for this example, one for the river and one for the tributary of
course. In my case, the dataset holds, just as an example, 10 lines, and a
distinct set of them makes either the river or the tributary. The lines of
each set are connected by the nodes of the single lines. 

Any ideas how to get ride of this format are very welcome. 

You might be interested in this thread from a year ago.
http://osgeo-org.1560.n6.nabble.com/snap-point-to-line-break-line-at-given-points-tp3887413p3887413.html

The short story is that GRASS builds topology when importing a line vector. So each intersection of two lines (i.e. a tributary that branches off the main channel) will be made into a separate line. You can force GRASS to ignore topology, but you probably don’t want to. And a correct river network does indeed keep each stream reach as a separate line. (Then you can use the various river network modules r.stream.*). So maybe your original shapefile is not “bad”…

What you can do it add an additional column to the vector attrib table and indicate, in that column, which tributary each segment belongs to. THen you can select, display, label, calculate, etc based on this “tributary” attribute column. Would that help?

Thanks in advance, 

Stefan

--
View this message in context: [http://osgeo-org.1560.n6.nabble.com/How-to-link-or-combine-adjacent-vector-lines-tp4381557p4381557.html](http://osgeo-org.1560.n6.nabble.com/How-to-link-or-combine-adjacent-vector-lines-tp4381557p4381557.html)
Sent from the Grass - Users mailing list archive at Nabble.com.
_______________________________________________
grass-user mailing list
[grass-user@lists.osgeo.org](mailto:grass-user@lists.osgeo.org)
[http://lists.osgeo.org/mailman/listinfo/grass-user](http://lists.osgeo.org/mailman/listinfo/grass-user)

This mail was received via Mail-SeCure System.

-- 
Micha Silver
GIS Consultant, Arava Development Co.
[http://www.surfaces.co.il](http://www.surfaces.co.il)

This mail was received via Mail-SeCure System.

-- 
Micha Silver
GIS Consultant, Arava Development Co.
[http://www.surfaces.co.il](http://www.surfaces.co.il)

sluedtke wrote:

I have been trying for some hours now but could not find any
solution.

We do have a shape file of a river network, but a bad one because single
rivers consist of multiple lines. Just think of the easiest example, a
river with one tributary. I would like to end up with an vector
dataset that holds 2 lines for this example, one for the river and one
for the tributary of course. In my case, the dataset holds, just as an
example, 10 lines, and a distinct set of them makes either the river or
the tributary. The lines of each set are connected by the nodes of the
single lines.

so you have a vector line map of a "braided river" (be it a real one or the
product of a computer surface water flow program which creates artifacts)
and you wish to generalize it into an idealized schematic vector network.
An interesting challenge.

I think the first step is to run v.buffer with a buffer distance greater
than half the maximum width of the parallel braids. The next step is the
reduction back to a center line, like r.thin but for vector areas. Often
you could do v.to.rast -> r.thin -> r.to.vect, but that doesn't work well
for rivers as they are usually long and thin: in order to fit the entire
length of the river into the raster array you need to make the cell res
very coarse compared to the width of the river.

so it becomes the classic "river mile" / "river centerline" problem, and
if you have a good solution to that (especially for cases when there are
shoals and islands in the middle of the river and you don't have full
riverbed bathymetry to find the thalweg) I'd be very interested to hear
about it.

the best I ever managed was v.to.rast at very high cell resolution then
r.cost to find distance from the riverbank, then r.param.scale feature
map to extract the ridgelines, then r.thin, and r.to.vect.
(instead of r.param.scale you could also use r.slope.aspect and look for
places where the slope of the cost-to-shore map is less than some small
threshold)

another idea is to make the crappy lo-res river centerline with r.thin,
then use v.lrs or v.transects(addons) to make step points, then run a
moving window along the river buffer area at high raster res, using one
of the g.region temporary zoom addon modules (g.region.point is one).
Then patch all the new vector segments together and run v.generalize to
smooth the result. I'm pretty confident that would work reasonably well,
but it wouldn't be very efficient.

It would be much more efficient to have a geometric solution than one
that needs rasterization, maybe something like filling the vector buffer
area with lots of little circles of varying sizes, merging as many of them
as possible, then extracting the center coord of each surviving big circle.

as I said earlier, it's an interesting problem..

Hamish

Hamish wrote:

so it becomes the classic "river mile" / "river centerline"
problem, and if you have a good solution to that (especially for cases
when there are shoals and islands in the middle of the river and you don't
have full riverbed bathymetry to find the thalweg) I'd be very
interested to hear about it.

see also
http://thread.gmane.org/gmane.comp.gis.grass.devel/36271
http://article.gmane.org/gmane.comp.gis.grass.devel/36294
http://article.gmane.org/gmane.comp.gis.grass.user/22097

Hamish

Hamish:
I’m not sure that the problem above is “braided streams”. From my reading (could be wrong - maybe sluedtke could clarify?) he just wants to merge all the reaches in one “tributary” to a single vector feature, and all the reaches in the “main river” to a single feature. Given the topology requirement that intersecting lines always meet at a node, I don’t see how to do this in GRASS.

On Sat, Feb 11, 2012 at 7:49 PM, Stefan Luedtke <sluedtke@gfz-potsdam.de> wrote:

Sorry for the delay... and thanks for the fast answer.

Adding a column and then running a command in the sense of "v.dissolve" is
not an option because there are just to many. I was thinking of a way that
combines two lines into one if they share the same node. For the example
mentioned the last time, this means, keeping the line as a single one until
the tributary merges the main river. The main river might consist of more
than one line, but a short tributary should not.

Maybe v.build.polylines is what you are looking for. If there are
attributes associated with the lines, the cats option should probably
be set to first or multi.

HTH,

Markus M

I hope I dont miss anything obvious .... :wink:

Cheers,

Stefan

On Fri, 2012-02-10 at 17:04 +0200, Micha Silver wrote:

On 02/09/2012 11:59 PM, sluedtke wrote:

Dear friends,

I have been trying for some hours now but could not find any solution.

We do have a shape file of a river network, but a bad one because single
rivers consist of multiple lines. Just think of the easiest example, a river
with one tributary. I would like to end up with an vector dataset that holds
2 lines for this example, one for the river and one for the tributary of
course. In my case, the dataset holds, just as an example, 10 lines, and a
distinct set of them makes either the river or the tributary. The lines of
each set are connected by the nodes of the single lines.

Any ideas how to get ride of this format are very welcome.

You might be interested in this thread from a year ago.
http://osgeo-org.1560.n6.nabble.com/snap-point-to-line-break-line-at-given-points-tp3887413p3887413.html

The short story is that GRASS builds topology when importing a line vector.
So each intersection of two lines (i.e. a tributary that branches off the
main channel) will be made into a separate line. You can force GRASS to
ignore topology, but you probably don't want to. And a correct river
network does indeed keep each stream reach as a separate line. (Then you can
use the various river network modules r.stream.*). So maybe your original
shapefile is not "bad"...

What you can do it add an additional column to the vector attrib table and
indicate, in that column, which tributary each segment belongs to. THen you
can select, display, label, calculate, etc based on this "tributary"
attribute column. Would that help?

Thanks in advance,

Stefan

--
View this message in context:
http://osgeo-org.1560.n6.nabble.com/How-to-link-or-combine-adjacent-vector-lines-tp4381557p4381557.html
Sent from the Grass - Users mailing list archive at Nabble.com.
_______________________________________________
grass-user mailing list
grass-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-user

This mail was received via Mail-SeCure System.

--
Micha Silver
GIS Consultant, Arava Development Co.
http://www.surfaces.co.il

_______________________________________________
grass-user mailing list
grass-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-user

Thanks for the detailed answer, but, my problem is much more trivial.

I attached a screenshot to make myself more clear.

/* The numbers refer to the categories of each line segment */

the tributary with cat 69 is fine, but the man channel consists of multiple lines, and, in fact, a lot of tributaries look similar. As I mentioned before, adding an additional column (to run kind of v.dissolve) is not really feasible because I have around 600 cat values.

The task would be, to tell GRASS, to combine all lines of the main channel, for this example. But I think that is quite ambitious- like Micha wrote in his post.

On Sat, 2012-02-11 at 15:19 -0800, Hamish wrote

sluedtke wrote:
> I have been trying for some hours now but could not find any
> solution. 
> 
> We do have a shape file of a river network,  but a bad one because single
> rivers consist of multiple lines. Just think of the easiest example, a
> river with one tributary. I would like to end up with an vector
> dataset that holds 2 lines for this example, one for the river and one
> for the tributary of course. In my case, the dataset holds, just as an
> example, 10 lines, and a distinct set of them makes either the river or
> the tributary. The lines of each set are connected by the nodes of the
> single lines. 

so you have a vector line map of a "braided river" (be it a real one or the
product of a computer surface water flow program which creates artifacts)
and you wish to generalize it into an idealized schematic vector network.
An interesting challenge.

I think the first step is to run v.buffer with a buffer distance greater
than half the maximum width of the parallel braids. The next step is the
reduction back to a center line, like r.thin but for vector areas. Often
you could do v.to.rast -> r.thin -> r.to.vect, but that doesn't work well
for rivers as they are usually long and thin: in order to fit the entire
length of the river into the raster array you need to make the cell res
very coarse compared to the width of the river.

so it becomes the classic "river mile" / "river centerline" problem, and
if you have a good solution to that (especially for cases when there are
shoals and islands in the middle of the river and you don't have full
riverbed bathymetry to find the thalweg) I'd be very interested to hear
about it.

the best I ever managed was v.to.rast at very high cell resolution then
r.cost to find distance from the riverbank, then r.param.scale feature
map to extract the ridgelines, then r.thin, and r.to.vect.
(instead of r.param.scale you could also use r.slope.aspect and look for
places where the slope of the cost-to-shore map is less than some small
threshold)

another idea is to make the crappy lo-res river centerline with r.thin,
then use v.lrs or v.transects(addons) to make step points, then run a
moving window along the river buffer area at high raster res, using one
of the g.region temporary zoom addon modules (g.region.point is one).
Then patch all the new vector segments together and run v.generalize to
smooth the result. I'm pretty confident that would work reasonably well,
but it wouldn't be very efficient.

It would be much more efficient to have a geometric solution than one
that needs rasterization, maybe something like filling the vector buffer
area with lots of little circles of varying sizes, merging as many of them
as possible, then extracting the center coord of each surviving big circle.

as I said earlier, it's an interesting problem..

Hamish

(attachments)

river_network_subset.png