<div dir="ltr"><br><br>On Thu, Mar 12, 2020 at 12:34 PM Johannes Radinger <<a href="mailto:johannesradinger@gmail.com">johannesradinger@gmail.com</a>> wrote:<br>><br>> Thank you Markus,<br><div>> indeed your approach looks like what I need..The hint with v.net.components was the part that I was missing; <br></div><div><br></div><div>Note that v.net.components does not need a network prepared with <a href="http://v.net">v.net</a>, you can use the extract of all lines with the same stream order as it is.</div><div><br></div><div>Markus M<br></div><div><br></div><div>> I'll try as soon as possible and will report back on how this works. </div>> cheers,<br>> Johannes<br>><br>> On Wed, Mar 11, 2020 at 10:16 PM Markus Metz <<a href="mailto:markus.metz.giswork@gmail.com">markus.metz.giswork@gmail.com</a>> wrote:<br>>><br>>> Hi Johannes,<br>>><br>>> IIUC, what you want to do is an operation that involves topological relations of vector geometries (connected lines) and a common attribute. There is no easy common recipe for this.<br>>><br>>> Just a suggestion:<br>>> for each stream order:<br>>>   extract all lines with this stream order (v.extract)<br>>>   identify connected lines (<a href="http://v.net">v.net</a> + v.net.components)<br>>>   update a new attribute of the original lines with the comp attribute of the output of v.net.components plus some offset to separate different stream orders<br>>><br>>> HTH,<br>>><br>>> Markus M<br>>><br>>><br>>> On Tue, Mar 10, 2020 at 5:20 PM Johannes Radinger <<a href="mailto:johannesradinger@gmail.com">johannesradinger@gmail.com</a>> wrote:<br>>> ><br>>> > So...no also with GRASS-user as recipient...<br>>> ><br>>> > On 05.03.20 16:21, Micha Silver wrote:<br>>> > ><br>>> > > On 3/5/20 10:47 AM, Johannes Radinger wrote:<br>>> > >><br>>> > >> Hi Micha, hi all,<br>>> > >><br>>> > >> sorry for my late response...however, just today I managed to try<br>>> > >> your approach of building polylines to connect "touching stream<br>>> > >> lines"...but...<br>>> > >><br>>> > >> On 24.02.20 16:48, Micha Silver wrote:<br>>> > >>><br>>> > >>> On 24/02/2020 10:45, Johannes Radinger wrote:<br>>> > >>>> Hi all,<br>>> > >>>> I have a large river network dataset (lines). Now I'd to assign<br>>> > >>>> unique categories to each group of connected lines that have an<br>>> > >>>> attribute in common.<br>>> > >>>><br>>> > >>>> For example, my rivers are categorized based on some kind of stream<br>>> > >>>> order. I want to group all rivers that belong to stream order 2 and<br>>> > >>>> are spatially connected; each group should get a unique category<br>>> > >>>> value. I thought that I could first extract all rivers with a<br>>> > >>>> particular attribute (e.g. stream order = 2) which will provide me<br>>> > >>>> some scattered pattern of lines. Then I need a spatial join tool to<br>>> > >>>> make subgroups of lines that are connected. How can I achieve the<br>>> > >>>> latter? Any idea?<br>>> > >>><br>>> > ><br>>> > ><br>>> > >>><br>>> > >>> Here's a procedure that might work for you. Somewhat clunky, but I<br>>> > >>> think it gets what you want.<br>>> > >>><br>>> > >>> It's based on the v.build.polylines module to connect all touching<br>>> > >>> stream reaches. First extract each order from the stream vector into<br>>> > >>> a new vector. Then build polylines. Patch them all together. Now you<br>>> > >>> have a polyline vector with a single cat value for each set of<br>>> > >>> original stream reaches that had the same order and that were touching.<br>>> > >><br>>> > >> Unfortunately, the v.build.polylines tool does not work as it only<br>>> > >> does not connect multiple (intersecting) lines like in a river<br>>> > >> network. As an example I tried to build polylines from the stream<br>>> > >> network of the NC dataset. Yous suggested approach should result that<br>>> > >> each sub-network (i.e. river network that is not connected to another<br>>> > >> one) should get its own ID/cat...however, v.build.polylines results<br>>> > >> in a connected stream network that consists of multiple cats:<br>>> > >><br>>> > > Maybe I misunderstood your question. The steps I tried use a<br>>> > > stream_order column to group stream segments, then apply a new<br>>> > > attribute "merged_id" to those stream orders that touch. i.e. that<br>>> > > connect to the same confluence point.<br>>> > ><br>>> > ><br>>> > > Here's what I get using the nc_basic_spm mapset:<br>>> > ><br>>> > ><br>>> > > r.watershed elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas<br>>> > > stream=nc_str thresh=1000<br>>> > > r.stream.order stream_rast=nc_str direct=nc_fdir elev=elevation<br>>> > > accum=nc_facc stream_vect=nc_streams<br>>> > > ORDERS=`v.db.select -c nc_streams group=strahler column=strahler`<br>>> > > echo $ORDERS<br>>> > ><br>>> > > # Create a new stream vector for each stream order<br>>> > ><br>>> > > for o in $ORDERS; do<br>>> > ><br>>> > >     v.extract input=nc_streams output=streams_${o} where="strahler=${o}"<br>>> > ><br>>> > >     # Give each polyline it's own cat value<br>>> > ><br>>> > >     v.build.polylines input=streams_${o} output=streams_${o}_polyline<br>>> > > type=line cat=first<br>>> > ><br>>> > > done<br>>> > ><br>>> > ><br>>> > > # patch the stream orders back together<br>>> > ><br>>> > > POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`<br>>> > ><br>>> > > v.patch input=$POLYLINES output=streams_polylines<br>>> > ><br>>> > > v.db.addcolumn map=streams column="merged_id INTEGER"<br>>> > ><br>>> > ><br>>> > > # And use v.distance to update that merged_id column from cat values<br>>> > > in polylines vector<br>>> > > v.distance from=streams to=streams_polylines upload=cat column=merged_id<br>>> > > v.db.addcolumn map=nc_streams column="merged_id INTEGER"<br>>> > > v.distance from=nc_streams to=streams_polylines upload=cat<br>>> > > column=merged_id<br>>> > ><br>>> > > Now, all stream reaches that have the same order and are "touching"<br>>> > > have the same merged_id. See the attached image.<br>>> > ><br>>> > ><br>>> > > If that's not your purpose, then just ignore...<br>>> > ><br>>> > Micha thank you for your help and of course, you're fully correct!<br>>> > Merging lines that belong to the same stream order works in this case<br>>> > well...but this is because of the definition of the Strahler ordering<br>>> > system, where there is only one "touching node" (i.e. river junction) of<br>>> > two rivers of the same stream order (i.e. when two 2nd order streams<br>>> > meet, the become a 3rd order stream). Thus your solution works because<br>>> > of this specifics and might not work if streams are grouped based on a<br>>> > different (ordering) system.<br>>> ><br>>> > I was already thinking of the next step (beyond simple Strahler): As<br>>> > mentioned in my initial post I am dealing with "some kind" of stream<br>>> > order. It is similar to grouped stream orders (e.g. stream order 1-2 =<br>>> > "headwater streams"). I tried to somehow reproduce my situation based on<br>>> > your example of the NC dataset. What I basically did was to reassign a<br>>> > new stream order "99" to all former 1st and 2nd order streams. Then I<br>>> > did exactly what you did in your example, and of course I don't unique<br>>> > merged_ids for the subnetworks of touching lines (see attached Figs)<br>>> > that all belong the the same "order" 99 (the original strahler order 3<br>>> > works of course, see Fig.)...So is there a more general way (as said<br>>> > something like v.dissolve but for lines/networks?):<br>>> ><br>>> > #####################<br>>> > g.region raster=elevation<br>>> ><br>>> > r.watershed --o elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas<br>>> > stream=nc_str thresh=1000<br>>> > r.stream.order stream_rast=nc_str direct=nc_fdir elev=elevation<br>>> > accum=nc_facc stream_vect=nc_streams<br>>> ><br>>> > #ORDERS=`v.db.select -c nc_streams group=strahler column=strahler`<br>>> > #echo $ORDERS<br>>> ><br>>> > # Regroup orders 1-2 (to 99)<br>>> > v.db.addcolumn map=nc_streams@test2 columns="strahler_groups INTEGER"<br>>> > v.db.update map=nc_streams column=strahler_groups query_column=strahler<br>>> > v.db.update map=nc_streams column=strahler_groups value=99<br>>> > where="strahler=1 OR strahler=2"<br>>> ><br>>> > NEWORDERS=`v.db.select -c nc_streams group=strahler_groups<br>>> > column=strahler_groups`<br>>> > echo $NEWORDERS<br>>> ><br>>> > # Create a new stream vector for each stream order<br>>> > for o in $NEWORDERS; do<br>>> >      v.extract input=nc_streams output=streams_${o}<br>>> > where="strahler_groups=${o}"<br>>> >      # Give each polyline it's own cat value<br>>> >      v.build.polylines input=streams_${o} output=streams_${o}_polyline<br>>> > type=line cat=first<br>>> > done<br>>> ><br>>> > d.vect -c map=streams_99_polyline@test2<br>>> > #################<br>>> ><br>>> > Thank you very much!<br>>> ><br>>> > Cheers,<br>>> ><br>>> > Johannes<br>>> ><br>>> > ><br>>> > >> v.clean --overwrite input=streams@PERMANENT output=streams_break<br>>> > >> tool=break<br>>> > >> v.build.polylines --overwrite input=streams_break@test<br>>> > >> output=streams_poly cats=first type=line<br>>> > >> d.vect -c map=streams_poly<br>>> > >><br>>> > >> So what would be needed here is some kind of tool that connects all<br>>> > >> touching lines and assigns a common category value, similar to the<br>>> > >> v.dissolve tool for polygon features. I can imagine that such a task<br>>> > >> might be not that uncommon also in another context? Any suggestions<br>>> > >> how to achieve this in GRASS?<br>>> > >><br>>> > >> A workaround that came into my mind was to create buffers around<br>>> > >> lines in order to make areas out of lines. Subsequently these<br>>> > >> touching areas can be merged using v.dissolve and the information<br>>> > >> about the common category can be queried using v.distance.<br>>> > >> Nevertheless, a rather cumbersome way to just assign a common<br>>> > >> category value to all lines that are touching...<br>>> > >><br>>> > >> Any further ideas?<br>>> > >><br>>> > >> cheers,<br>>> > >><br>>> > >> Johannes<br>>> > >><br>>> > >>><br>>> > >>>> Cheers,<br>>> > >>>> Johannes<br>>> > >>>><br>>> > >>>> _______________________________________________<br>>> > >>>> grass-user mailing list<br>>> > >>>> <a href="mailto:grass-user@lists.osgeo.org">grass-user@lists.osgeo.org</a> <mailto:<a href="mailto:grass-user@lists.osgeo.org">grass-user@lists.osgeo.org</a>><br>>> > >>>> <a href="https://lists.osgeo.org/mailman/listinfo/grass-user">https://lists.osgeo.org/mailman/listinfo/grass-user</a><br>>> > >>><br>>> > _______________________________________________<br>>> > grass-user mailing list<br>>> > <a href="mailto:grass-user@lists.osgeo.org">grass-user@lists.osgeo.org</a><br>>> > <a href="https://lists.osgeo.org/mailman/listinfo/grass-user">https://lists.osgeo.org/mailman/listinfo/grass-user</a></div>