Re: [GRASS-user] Merge spatially connected features

2020-03-16 Thread Johannes Radinger
On Thu, Mar 12, 2020 at 10:48 PM Markus Metz 
wrote:

>
>
> On Thu, Mar 12, 2020 at 12:34 PM Johannes Radinger <
> johannesradin...@gmail.com> wrote:
> >
> > Thank you Markus,
> > indeed your approach looks like what I need..The hint with
> v.net.components was the part that I was missing;
>
> Note that v.net.components does not need a network prepared with v.net,
> you can use the extract of all lines with the same stream order as it is.
>
> I just tested your suggested approach using v.net.components
(without running v.net before)...works really smoothly and very fast and I
get to the desired results of extracting subnets. Thanks a lot Markus for
this hint!

/Johannes



> Markus M
>
> > I'll try as soon as possible and will report back on how this works.
> > cheers,
> > Johannes
> >
> > On Wed, Mar 11, 2020 at 10:16 PM Markus Metz <
> markus.metz.gisw...@gmail.com> wrote:
> >>
> >> Hi Johannes,
> >>
> >> 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.
> >>
> >> Just a suggestion:
> >> for each stream order:
> >>   extract all lines with this stream order (v.extract)
> >>   identify connected lines (v.net + v.net.components)
> >>   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
> >>
> >> HTH,
> >>
> >> Markus M
> >>
> >>
> >> On Tue, Mar 10, 2020 at 5:20 PM Johannes Radinger <
> johannesradin...@gmail.com> wrote:
> >> >
> >> > So...no also with GRASS-user as recipient...
> >> >
> >> > On 05.03.20 16:21, Micha Silver wrote:
> >> > >
> >> > > On 3/5/20 10:47 AM, Johannes Radinger wrote:
> >> > >>
> >> > >> Hi Micha, hi all,
> >> > >>
> >> > >> sorry for my late response...however, just today I managed to try
> >> > >> your approach of building polylines to connect "touching stream
> >> > >> lines"...but...
> >> > >>
> >> > >> On 24.02.20 16:48, Micha Silver wrote:
> >> > >>>
> >> > >>> On 24/02/2020 10:45, Johannes Radinger wrote:
> >> >  Hi all,
> >> >  I have a large river network dataset (lines). Now I'd to assign
> >> >  unique categories to each group of connected lines that have an
> >> >  attribute in common.
> >> > 
> >> >  For example, my rivers are categorized based on some kind of
> stream
> >> >  order. I want to group all rivers that belong to stream order 2
> and
> >> >  are spatially connected; each group should get a unique category
> >> >  value. I thought that I could first extract all rivers with a
> >> >  particular attribute (e.g. stream order = 2) which will provide
> me
> >> >  some scattered pattern of lines. Then I need a spatial join tool
> to
> >> >  make subgroups of lines that are connected. How can I achieve the
> >> >  latter? Any idea?
> >> > >>>
> >> > >
> >> > >
> >> > >>>
> >> > >>> Here's a procedure that might work for you. Somewhat clunky, but I
> >> > >>> think it gets what you want.
> >> > >>>
> >> > >>> It's based on the v.build.polylines module to connect all touching
> >> > >>> stream reaches. First extract each order from the stream vector
> into
> >> > >>> a new vector. Then build polylines. Patch them all together. Now
> you
> >> > >>> have a polyline vector with a single cat value for each set of
> >> > >>> original stream reaches that had the same order and that were
> touching.
> >> > >>
> >> > >> Unfortunately, the v.build.polylines tool does not work as it only
> >> > >> does not connect multiple (intersecting) lines like in a river
> >> > >> network. As an example I tried to build polylines from the stream
> >> > >> network of the NC dataset. Yous suggested approach should result
> that
> >> > >> each sub-network (i.e. river network that is not connected to
> another
> >> > >> one) should get its own ID/cat...however, v.build.polylines results
> >> > >> in a connected stream network that consists of multiple cats:
> >> > >>
> >> > > Maybe I misunderstood your question. The steps I tried use a
> >> > > stream_order column to group stream segments, then apply a new
> >> > > attribute "merged_id" to those stream orders that touch. i.e. that
> >> > > connect to the same confluence point.
> >> > >
> >> > >
> >> > > Here's what I get using the nc_basic_spm mapset:
> >> > >
> >> > >
> >> > > r.watershed elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas
> >> > > stream=nc_str thresh=1000
> >> > > r.stream.order stream_rast=nc_str direct=nc_fdir elev=elevation
> >> > > accum=nc_facc stream_vect=nc_streams
> >> > > ORDERS=`v.db.select -c nc_streams group=strahler column=strahler`
> >> > > echo $ORDERS
> >> > >
> >> > > # Create a new stream vector for each stream order
> >> > >
> >> > > for o in $ORDERS; do
> >> > >
> >> > > v.extract input=nc_streams output=streams_${o}
> where="strahler=${o}"
> >> > >
> >> > > # Give each polyline it's own cat value
> 

Re: [GRASS-user] Merge spatially connected features

2020-03-12 Thread Markus Metz
On Thu, Mar 12, 2020 at 12:34 PM Johannes Radinger <
johannesradin...@gmail.com> wrote:
>
> Thank you Markus,
> indeed your approach looks like what I need..The hint with
v.net.components was the part that I was missing;

Note that v.net.components does not need a network prepared with v.net, you
can use the extract of all lines with the same stream order as it is.

Markus M

> I'll try as soon as possible and will report back on how this works.
> cheers,
> Johannes
>
> On Wed, Mar 11, 2020 at 10:16 PM Markus Metz <
markus.metz.gisw...@gmail.com> wrote:
>>
>> Hi Johannes,
>>
>> 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.
>>
>> Just a suggestion:
>> for each stream order:
>>   extract all lines with this stream order (v.extract)
>>   identify connected lines (v.net + v.net.components)
>>   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
>>
>> HTH,
>>
>> Markus M
>>
>>
>> On Tue, Mar 10, 2020 at 5:20 PM Johannes Radinger <
johannesradin...@gmail.com> wrote:
>> >
>> > So...no also with GRASS-user as recipient...
>> >
>> > On 05.03.20 16:21, Micha Silver wrote:
>> > >
>> > > On 3/5/20 10:47 AM, Johannes Radinger wrote:
>> > >>
>> > >> Hi Micha, hi all,
>> > >>
>> > >> sorry for my late response...however, just today I managed to try
>> > >> your approach of building polylines to connect "touching stream
>> > >> lines"...but...
>> > >>
>> > >> On 24.02.20 16:48, Micha Silver wrote:
>> > >>>
>> > >>> On 24/02/2020 10:45, Johannes Radinger wrote:
>> >  Hi all,
>> >  I have a large river network dataset (lines). Now I'd to assign
>> >  unique categories to each group of connected lines that have an
>> >  attribute in common.
>> > 
>> >  For example, my rivers are categorized based on some kind of
stream
>> >  order. I want to group all rivers that belong to stream order 2
and
>> >  are spatially connected; each group should get a unique category
>> >  value. I thought that I could first extract all rivers with a
>> >  particular attribute (e.g. stream order = 2) which will provide me
>> >  some scattered pattern of lines. Then I need a spatial join tool
to
>> >  make subgroups of lines that are connected. How can I achieve the
>> >  latter? Any idea?
>> > >>>
>> > >
>> > >
>> > >>>
>> > >>> Here's a procedure that might work for you. Somewhat clunky, but I
>> > >>> think it gets what you want.
>> > >>>
>> > >>> It's based on the v.build.polylines module to connect all touching
>> > >>> stream reaches. First extract each order from the stream vector
into
>> > >>> a new vector. Then build polylines. Patch them all together. Now
you
>> > >>> have a polyline vector with a single cat value for each set of
>> > >>> original stream reaches that had the same order and that were
touching.
>> > >>
>> > >> Unfortunately, the v.build.polylines tool does not work as it only
>> > >> does not connect multiple (intersecting) lines like in a river
>> > >> network. As an example I tried to build polylines from the stream
>> > >> network of the NC dataset. Yous suggested approach should result
that
>> > >> each sub-network (i.e. river network that is not connected to
another
>> > >> one) should get its own ID/cat...however, v.build.polylines results
>> > >> in a connected stream network that consists of multiple cats:
>> > >>
>> > > Maybe I misunderstood your question. The steps I tried use a
>> > > stream_order column to group stream segments, then apply a new
>> > > attribute "merged_id" to those stream orders that touch. i.e. that
>> > > connect to the same confluence point.
>> > >
>> > >
>> > > Here's what I get using the nc_basic_spm mapset:
>> > >
>> > >
>> > > r.watershed elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas
>> > > stream=nc_str thresh=1000
>> > > r.stream.order stream_rast=nc_str direct=nc_fdir elev=elevation
>> > > accum=nc_facc stream_vect=nc_streams
>> > > ORDERS=`v.db.select -c nc_streams group=strahler column=strahler`
>> > > echo $ORDERS
>> > >
>> > > # Create a new stream vector for each stream order
>> > >
>> > > for o in $ORDERS; do
>> > >
>> > > v.extract input=nc_streams output=streams_${o}
where="strahler=${o}"
>> > >
>> > > # Give each polyline it's own cat value
>> > >
>> > > v.build.polylines input=streams_${o} output=streams_${o}_polyline
>> > > type=line cat=first
>> > >
>> > > done
>> > >
>> > >
>> > > # patch the stream orders back together
>> > >
>> > > POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`
>> > >
>> > > v.patch input=$POLYLINES output=streams_polylines
>> > >
>> > > v.db.addcolumn map=streams column="merged_id INTEGER"
>> > >
>> > >
>> > > # And use v.distance to update that merged_id column from cat values
>> > > in polylines vector
>> > > v.distance 

Re: [GRASS-user] Merge spatially connected features

2020-03-12 Thread Johannes Radinger
Thank you Markus,
indeed your approach looks like what I need..The hint with v.net.components
was the part that I was missing; I'll try as soon as possible and will
report back on how this works.
cheers,
Johannes

On Wed, Mar 11, 2020 at 10:16 PM Markus Metz 
wrote:

> Hi Johannes,
>
> 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.
>
> Just a suggestion:
> for each stream order:
>   extract all lines with this stream order (v.extract)
>   identify connected lines (v.net + v.net.components)
>   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
>
> HTH,
>
> Markus M
>
>
> On Tue, Mar 10, 2020 at 5:20 PM Johannes Radinger <
> johannesradin...@gmail.com> wrote:
> >
> > So...no also with GRASS-user as recipient...
> >
> > On 05.03.20 16:21, Micha Silver wrote:
> > >
> > > On 3/5/20 10:47 AM, Johannes Radinger wrote:
> > >>
> > >> Hi Micha, hi all,
> > >>
> > >> sorry for my late response...however, just today I managed to try
> > >> your approach of building polylines to connect "touching stream
> > >> lines"...but...
> > >>
> > >> On 24.02.20 16:48, Micha Silver wrote:
> > >>>
> > >>> On 24/02/2020 10:45, Johannes Radinger wrote:
> >  Hi all,
> >  I have a large river network dataset (lines). Now I'd to assign
> >  unique categories to each group of connected lines that have an
> >  attribute in common.
> > 
> >  For example, my rivers are categorized based on some kind of stream
> >  order. I want to group all rivers that belong to stream order 2 and
> >  are spatially connected; each group should get a unique category
> >  value. I thought that I could first extract all rivers with a
> >  particular attribute (e.g. stream order = 2) which will provide me
> >  some scattered pattern of lines. Then I need a spatial join tool to
> >  make subgroups of lines that are connected. How can I achieve the
> >  latter? Any idea?
> > >>>
> > >
> > >
> > >>>
> > >>> Here's a procedure that might work for you. Somewhat clunky, but I
> > >>> think it gets what you want.
> > >>>
> > >>> It's based on the v.build.polylines module to connect all touching
> > >>> stream reaches. First extract each order from the stream vector into
> > >>> a new vector. Then build polylines. Patch them all together. Now you
> > >>> have a polyline vector with a single cat value for each set of
> > >>> original stream reaches that had the same order and that were
> touching.
> > >>
> > >> Unfortunately, the v.build.polylines tool does not work as it only
> > >> does not connect multiple (intersecting) lines like in a river
> > >> network. As an example I tried to build polylines from the stream
> > >> network of the NC dataset. Yous suggested approach should result that
> > >> each sub-network (i.e. river network that is not connected to another
> > >> one) should get its own ID/cat...however, v.build.polylines results
> > >> in a connected stream network that consists of multiple cats:
> > >>
> > > Maybe I misunderstood your question. The steps I tried use a
> > > stream_order column to group stream segments, then apply a new
> > > attribute "merged_id" to those stream orders that touch. i.e. that
> > > connect to the same confluence point.
> > >
> > >
> > > Here's what I get using the nc_basic_spm mapset:
> > >
> > >
> > > r.watershed elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas
> > > stream=nc_str thresh=1000
> > > r.stream.order stream_rast=nc_str direct=nc_fdir elev=elevation
> > > accum=nc_facc stream_vect=nc_streams
> > > ORDERS=`v.db.select -c nc_streams group=strahler column=strahler`
> > > echo $ORDERS
> > >
> > > # Create a new stream vector for each stream order
> > >
> > > for o in $ORDERS; do
> > >
> > > v.extract input=nc_streams output=streams_${o}
> where="strahler=${o}"
> > >
> > > # Give each polyline it's own cat value
> > >
> > > v.build.polylines input=streams_${o} output=streams_${o}_polyline
> > > type=line cat=first
> > >
> > > done
> > >
> > >
> > > # patch the stream orders back together
> > >
> > > POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`
> > >
> > > v.patch input=$POLYLINES output=streams_polylines
> > >
> > > v.db.addcolumn map=streams column="merged_id INTEGER"
> > >
> > >
> > > # And use v.distance to update that merged_id column from cat values
> > > in polylines vector
> > > v.distance from=streams to=streams_polylines upload=cat
> column=merged_id
> > > v.db.addcolumn map=nc_streams column="merged_id INTEGER"
> > > v.distance from=nc_streams to=streams_polylines upload=cat
> > > column=merged_id
> > >
> > > Now, all stream reaches that have the same order and are "touching"
> > > have the same merged_id. See the attached image.
> > >
> > >
> > > If that's not your 

Re: [GRASS-user] Merge spatially connected features

2020-03-11 Thread Markus Metz
Hi Johannes,

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.

Just a suggestion:
for each stream order:
  extract all lines with this stream order (v.extract)
  identify connected lines (v.net + v.net.components)
  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

HTH,

Markus M


On Tue, Mar 10, 2020 at 5:20 PM Johannes Radinger <
johannesradin...@gmail.com> wrote:
>
> So...no also with GRASS-user as recipient...
>
> On 05.03.20 16:21, Micha Silver wrote:
> >
> > On 3/5/20 10:47 AM, Johannes Radinger wrote:
> >>
> >> Hi Micha, hi all,
> >>
> >> sorry for my late response...however, just today I managed to try
> >> your approach of building polylines to connect "touching stream
> >> lines"...but...
> >>
> >> On 24.02.20 16:48, Micha Silver wrote:
> >>>
> >>> On 24/02/2020 10:45, Johannes Radinger wrote:
>  Hi all,
>  I have a large river network dataset (lines). Now I'd to assign
>  unique categories to each group of connected lines that have an
>  attribute in common.
> 
>  For example, my rivers are categorized based on some kind of stream
>  order. I want to group all rivers that belong to stream order 2 and
>  are spatially connected; each group should get a unique category
>  value. I thought that I could first extract all rivers with a
>  particular attribute (e.g. stream order = 2) which will provide me
>  some scattered pattern of lines. Then I need a spatial join tool to
>  make subgroups of lines that are connected. How can I achieve the
>  latter? Any idea?
> >>>
> >
> >
> >>>
> >>> Here's a procedure that might work for you. Somewhat clunky, but I
> >>> think it gets what you want.
> >>>
> >>> It's based on the v.build.polylines module to connect all touching
> >>> stream reaches. First extract each order from the stream vector into
> >>> a new vector. Then build polylines. Patch them all together. Now you
> >>> have a polyline vector with a single cat value for each set of
> >>> original stream reaches that had the same order and that were
touching.
> >>
> >> Unfortunately, the v.build.polylines tool does not work as it only
> >> does not connect multiple (intersecting) lines like in a river
> >> network. As an example I tried to build polylines from the stream
> >> network of the NC dataset. Yous suggested approach should result that
> >> each sub-network (i.e. river network that is not connected to another
> >> one) should get its own ID/cat...however, v.build.polylines results
> >> in a connected stream network that consists of multiple cats:
> >>
> > Maybe I misunderstood your question. The steps I tried use a
> > stream_order column to group stream segments, then apply a new
> > attribute "merged_id" to those stream orders that touch. i.e. that
> > connect to the same confluence point.
> >
> >
> > Here's what I get using the nc_basic_spm mapset:
> >
> >
> > r.watershed elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas
> > stream=nc_str thresh=1000
> > r.stream.order stream_rast=nc_str direct=nc_fdir elev=elevation
> > accum=nc_facc stream_vect=nc_streams
> > ORDERS=`v.db.select -c nc_streams group=strahler column=strahler`
> > echo $ORDERS
> >
> > # Create a new stream vector for each stream order
> >
> > for o in $ORDERS; do
> >
> > v.extract input=nc_streams output=streams_${o} where="strahler=${o}"
> >
> > # Give each polyline it's own cat value
> >
> > v.build.polylines input=streams_${o} output=streams_${o}_polyline
> > type=line cat=first
> >
> > done
> >
> >
> > # patch the stream orders back together
> >
> > POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`
> >
> > v.patch input=$POLYLINES output=streams_polylines
> >
> > v.db.addcolumn map=streams column="merged_id INTEGER"
> >
> >
> > # And use v.distance to update that merged_id column from cat values
> > in polylines vector
> > v.distance from=streams to=streams_polylines upload=cat column=merged_id
> > v.db.addcolumn map=nc_streams column="merged_id INTEGER"
> > v.distance from=nc_streams to=streams_polylines upload=cat
> > column=merged_id
> >
> > Now, all stream reaches that have the same order and are "touching"
> > have the same merged_id. See the attached image.
> >
> >
> > If that's not your purpose, then just ignore...
> >
> Micha thank you for your help and of course, you're fully correct!
> Merging lines that belong to the same stream order works in this case
> well...but this is because of the definition of the Strahler ordering
> system, where there is only one "touching node" (i.e. river junction) of
> two rivers of the same stream order (i.e. when two 2nd order streams
> meet, the become a 3rd order stream). Thus your solution works because
> of this specifics and might not work if streams 

Re: [GRASS-user] Merge spatially connected features

2020-03-10 Thread Johannes Radinger

So...no also with GRASS-user as recipient...

On 05.03.20 16:21, Micha Silver wrote:


On 3/5/20 10:47 AM, Johannes Radinger wrote:


Hi Micha, hi all,

sorry for my late response...however, just today I managed to try 
your approach of building polylines to connect "touching stream 
lines"...but...


On 24.02.20 16:48, Micha Silver wrote:


On 24/02/2020 10:45, Johannes Radinger wrote:

Hi all,
I have a large river network dataset (lines). Now I'd to assign 
unique categories to each group of connected lines that have an 
attribute in common.


For example, my rivers are categorized based on some kind of stream 
order. I want to group all rivers that belong to stream order 2 and 
are spatially connected; each group should get a unique category 
value. I thought that I could first extract all rivers with a 
particular attribute (e.g. stream order = 2) which will provide me 
some scattered pattern of lines. Then I need a spatial join tool to 
make subgroups of lines that are connected. How can I achieve the 
latter? Any idea?







Here's a procedure that might work for you. Somewhat clunky, but I 
think it gets what you want.


It's based on the v.build.polylines module to connect all touching 
stream reaches. First extract each order from the stream vector into 
a new vector. Then build polylines. Patch them all together. Now you 
have a polyline vector with a single cat value for each set of 
original stream reaches that had the same order and that were touching.


Unfortunately, the v.build.polylines tool does not work as it only 
does not connect multiple (intersecting) lines like in a river 
network. As an example I tried to build polylines from the stream 
network of the NC dataset. Yous suggested approach should result that 
each sub-network (i.e. river network that is not connected to another 
one) should get its own ID/cat...however, v.build.polylines results 
in a connected stream network that consists of multiple cats:


Maybe I misunderstood your question. The steps I tried use a 
stream_order column to group stream segments, then apply a new 
attribute "merged_id" to those stream orders that touch. i.e. that 
connect to the same confluence point.



Here's what I get using the nc_basic_spm mapset:


r.watershed elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas 
stream=nc_str thresh=1000
r.stream.order stream_rast=nc_str direct=nc_fdir elev=elevation 
accum=nc_facc stream_vect=nc_streams

ORDERS=`v.db.select -c nc_streams group=strahler column=strahler`
echo $ORDERS

# Create a new stream vector for each stream order

for o in $ORDERS; do

    v.extract input=nc_streams output=streams_${o} where="strahler=${o}"

    # Give each polyline it's own cat value

    v.build.polylines input=streams_${o} output=streams_${o}_polyline 
type=line cat=first


done


# patch the stream orders back together

POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`

v.patch input=$POLYLINES output=streams_polylines

v.db.addcolumn map=streams column="merged_id INTEGER"


# And use v.distance to update that merged_id column from cat values 
in polylines vector

v.distance from=streams to=streams_polylines upload=cat column=merged_id
v.db.addcolumn map=nc_streams column="merged_id INTEGER"
v.distance from=nc_streams to=streams_polylines upload=cat 
column=merged_id


Now, all stream reaches that have the same order and are "touching" 
have the same merged_id. See the attached image.



If that's not your purpose, then just ignore...

Micha thank you for your help and of course, you're fully correct! 
Merging lines that belong to the same stream order works in this case 
well...but this is because of the definition of the Strahler ordering 
system, where there is only one "touching node" (i.e. river junction) of 
two rivers of the same stream order (i.e. when two 2nd order streams 
meet, the become a 3rd order stream). Thus your solution works because 
of this specifics and might not work if streams are grouped based on a 
different (ordering) system.


I was already thinking of the next step (beyond simple Strahler): As 
mentioned in my initial post I am dealing with "some kind" of stream 
order. It is similar to grouped stream orders (e.g. stream order 1-2 = 
"headwater streams"). I tried to somehow reproduce my situation based on 
your example of the NC dataset. What I basically did was to reassign a 
new stream order "99" to all former 1st and 2nd order streams. Then I 
did exactly what you did in your example, and of course I don't unique 
merged_ids for the subnetworks of touching lines (see attached Figs) 
that all belong the the same "order" 99 (the original strahler order 3 
works of course, see Fig.)...So is there a more general way (as said 
something like v.dissolve but for lines/networks?):


#
g.region raster=elevation

r.watershed --o elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas 
stream=nc_str thresh=1000
r.stream.order stream_rast=nc_str 

Re: [GRASS-user] Merge spatially connected features

2020-03-05 Thread Micha Silver


On 3/5/20 10:47 AM, Johannes Radinger wrote:


Hi Micha, hi all,

sorry for my late response...however, just today I managed to try your 
approach of building polylines to connect "touching stream lines"...but...


On 24.02.20 16:48, Micha Silver wrote:


On 24/02/2020 10:45, Johannes Radinger wrote:

Hi all,
I have a large river network dataset (lines). Now I'd to assign 
unique categories to each group of connected lines that have an 
attribute in common.


For example, my rivers are categorized based on some kind of stream 
order. I want to group all rivers that belong to stream order 2 and 
are spatially connected; each group should get a unique category 
value. I thought that I could first extract all rivers with a 
particular attribute (e.g. stream order = 2) which will provide me 
some scattered pattern of lines. Then I need a spatial join tool to 
make subgroups of lines that are connected. How can I achieve the 
latter? Any idea?







Here's a procedure that might work for you. Somewhat clunky, but I 
think it gets what you want.


It's based on the v.build.polylines module to connect all touching 
stream reaches. First extract each order from the stream vector into 
a new vector. Then build polylines. Patch them all together. Now you 
have a polyline vector with a single cat value for each set of 
original stream reaches that had the same order and that were touching.


Unfortunately, the v.build.polylines tool does not work as it only 
does not connect multiple (intersecting) lines like in a river 
network. As an example I tried to build polylines from the stream 
network of the NC dataset. Yous suggested approach should result that 
each sub-network (i.e. river network that is not connected to another 
one) should get its own ID/cat...however, v.build.polylines results in 
a connected stream network that consists of multiple cats:


Maybe I misunderstood your question. The steps I tried use a 
stream_order column to group stream segments, then apply a new attribute 
"merged_id" to those stream orders that touch. i.e. that connect to the 
same confluence point.



Here's what I get using the nc_basic_spm mapset:


r.watershed elev=elevation accum=nc_facc drain=nc_fdir bas=nc_bas 
stream=nc_str thresh=1000
r.stream.order stream_rast=nc_str direct=nc_fdir elev=elevation 
accum=nc_facc stream_vect=nc_streams

ORDERS=`v.db.select -c nc_streams group=strahler column=strahler`
echo $ORDERS

# Create a new stream vector for each stream order

for o in $ORDERS; do

    v.extract input=nc_streams output=streams_${o} where="strahler=${o}"

    # Give each polyline it's own cat value

    v.build.polylines input=streams_${o} output=streams_${o}_polyline 
type=line cat=first


done


# patch the stream orders back together

POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`

v.patch input=$POLYLINES output=streams_polylines

v.db.addcolumn map=streams column="merged_id INTEGER"


# And use v.distance to update that merged_id column from cat values in 
polylines vector

v.distance from=streams to=streams_polylines upload=cat column=merged_id
v.db.addcolumn map=nc_streams column="merged_id INTEGER"
v.distance from=nc_streams to=streams_polylines upload=cat column=merged_id

Now, all stream reaches that have the same order and are "touching" have 
the same merged_id. See the attached image.



If that's not your purpose, then just ignore...


v.clean --overwrite input=streams@PERMANENT output=streams_break 
tool=break
v.build.polylines --overwrite input=streams_break@test 
output=streams_poly cats=first type=line

d.vect -c map=streams_poly

So what would be needed here is some kind of tool that connects all 
touching lines and assigns a common category value, similar to the 
v.dissolve tool for polygon features. I can imagine that such a task 
might be not that uncommon also in another context? Any suggestions 
how to achieve this in GRASS?


A workaround that came into my mind was to create buffers around lines 
in order to make areas out of lines. Subsequently these touching areas 
can be merged using v.dissolve and the information about the common 
category can be queried using v.distance. Nevertheless, a rather 
cumbersome way to just assign a common category value to all lines 
that are touching...


Any further ideas?

cheers,

Johannes




Cheers,
Johannes

___
grass-user mailing list
grass-user@lists.osgeo.org 
https://lists.osgeo.org/mailman/listinfo/grass-user



--
Micha Silver
Ben Gurion Univ.
Sde Boker, Remote Sensing Lab
cell: +972-523-665918

___
grass-user mailing list
grass-user@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-user

Re: [GRASS-user] Merge spatially connected features

2020-03-05 Thread Johannes Radinger
Hi Micha, hi all,

sorry for my late response...however, just today I managed to try your
approach of building polylines to connect "touching stream lines"...but...
On 24.02.20 16:48, Micha Silver wrote:


On 24/02/2020 10:45, Johannes Radinger wrote:

Hi all,
I have a large river network dataset (lines). Now I'd to assign unique
categories to each group of connected lines that have an attribute in
common.

For example, my rivers are categorized based on some kind of stream order.
I want to group all rivers that belong to stream order 2 and are spatially
connected; each group should get a unique category value. I thought that I
could first extract all rivers with a particular attribute (e.g. stream
order = 2) which will provide me some scattered pattern of lines. Then I
need a spatial join tool to make subgroups of lines that are connected. How
can I achieve the latter? Any idea?



Here's a procedure that might work for you. Somewhat clunky, but I think it
gets what you want.

It's based on the v.build.polylines module to connect all touching stream
reaches. First extract each order from the stream vector into a new vector.
Then build polylines. Patch them all together. Now you have a polyline
vector with a single cat value for each set of original stream reaches that
had the same order and that were touching.

Unfortunately, the v.build.polylines tool does not work as it only does not
connect multiple (intersecting) lines like in a river network. As an
example I tried to build polylines from the stream network of the NC
dataset. Yous suggested approach should result that each sub-network (i.e.
river network that is not connected to another one) should get its own
ID/cat...however, v.build.polylines results in a connected stream network
that consists of multiple cats:

v.clean --overwrite input=streams@PERMANENT output=streams_break tool=break
v.build.polylines --overwrite input=streams_break@test output=streams_poly
cats=first type=line
d.vect -c map=streams_poly

So what would be needed here is some kind of tool that connects all
touching lines and assigns a common category value, similar to the
v.dissolve tool for polygon features. I can imagine that such a task might
be not that uncommon also in another context? Any suggestions how to
achieve this in GRASS?

A workaround that came into my mind was to create buffers around lines in
order to make areas out of lines. Subsequently these touching areas can be
merged using v.dissolve and the information about the common category can
be queried using v.distance. Nevertheless, a rather cumbersome way to just
assign a common category value to all lines that are touching...

Any further ideas?

cheers,

Johannes


Finally, with v.distance you can upload that cat value to the original
streams.


# Get a list of stream orders
ORDERS=`v.db.select -c streams group=strahler column=strahler`
echo $ORDERS
#1 2 3 4 5 6
# How many stream segments in original
v.info -t streams | grep lines
# lines=1420

# Now loop thru list of stream orders and extract stream segments for each
order
for o in $ORDERS; do
v.extract input=streams output=streams_${o} where="strahler=${o}"
# Create polyline for each stream order
# Line "connects" all touching stream segments
v.build.polylines input=streams_${o} output=streams_${o}_polyline
type=line cat=first
done

# Patch stream order polylines together
POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`
echo $POLYLINES
v.patch input=$POLYLINES output=streams_polylines
v.info -t streams_polylines | grep lines
# lines=738

# Add a new column to the original streams for new ID value
v.db.addcolumn map=streams column="merged_id INTEGER"
# And use v.distance to update that column from cat values in polylines
vector
v.distance from=streams to=streams_polylines upload=cat column=merged_id

HTH


Cheers,
Johannes

___
grass-user mailing list
grass-user@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-user
___
grass-user mailing list
grass-user@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-user

Re: [GRASS-user] Merge spatially connected features

2020-03-02 Thread Johannes Radinger

Hi Micha, hi all,

sorry for my late response...however, just today I managed to try your 
approach of building polylines to connect "touching stream lines"...but...


On 24.02.20 16:48, Micha Silver wrote:


On 24/02/2020 10:45, Johannes Radinger wrote:

Hi all,
I have a large river network dataset (lines). Now I'd to assign 
unique categories to each group of connected lines that have an 
attribute in common.


For example, my rivers are categorized based on some kind of stream 
order. I want to group all rivers that belong to stream order 2 and 
are spatially connected; each group should get a unique category 
value. I thought that I could first extract all rivers with a 
particular attribute (e.g. stream order = 2) which will provide me 
some scattered pattern of lines. Then I need a spatial join tool to 
make subgroups of lines that are connected. How can I achieve the 
latter? Any idea?



Here's a procedure that might work for you. Somewhat clunky, but I 
think it gets what you want.


It's based on the v.build.polylines module to connect all touching 
stream reaches. First extract each order from the stream vector into a 
new vector. Then build polylines. Patch them all together. Now you 
have a polyline vector with a single cat value for each set of 
original stream reaches that had the same order and that were touching.


Unfortunately, the v.build.polylines tool does not work here as it does 
not connect multiple (intersecting) lines like in a river network. For 
example, I tried to build polylines from the stream network of the NC 
dataset. The suggested approach should result that each sub-network 
(i.e. river network that is not connected to another one) should get its 
own ID/cat...however, v.build.polylines results in a  stream sub-network 
that consists of multiple cats:


v.clean --overwrite input=streams@PERMANENT output=streams_break tool=break
v.build.polylines --overwrite input=streams_break@test 
output=streams_poly cats=first type=line

d.vect -c map=streams_poly

So is there any other way to join all lines that are touching...This 
would be something similar to v.dissolve but based on lines rather than 
on polygons.


Any ideas for a simple work around?

cheers,

Johannes




Finally, with v.distance you can upload that cat value to the original 
streams.



# Get a list of stream orders
ORDERS=`v.db.select -c streams group=strahler column=strahler`
echo $ORDERS
#1 2 3 4 5 6
# How many stream segments in original
v.info -t streams | grep lines
# lines=1420

# Now loop thru list of stream orders and extract stream segments for 
each order

for o in $ORDERS; do
    v.extract input=streams output=streams_${o} where="strahler=${o}"
    # Create polyline for each stream order
    # Line "connects" all touching stream segments
    v.build.polylines input=streams_${o} 
output=streams_${o}_polyline type=line cat=first

done

# Patch stream order polylines together
POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`
echo $POLYLINES
v.patch input=$POLYLINES output=streams_polylines
v.info -t streams_polylines | grep lines
# lines=738

# Add a new column to the original streams for new ID value
v.db.addcolumn map=streams column="merged_id INTEGER"
# And use v.distance to update that column from cat values in 
polylines vector

v.distance from=streams to=streams_polylines upload=cat column=merged_id

HTH


Cheers,
Johannes

___
grass-user mailing list
grass-user@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-user



___
grass-user mailing list
grass-user@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-user

Re: [GRASS-user] Merge spatially connected features

2020-02-24 Thread Micha Silver


On 24/02/2020 10:45, Johannes Radinger wrote:

Hi all,
I have a large river network dataset (lines). Now I'd to assign unique 
categories to each group of connected lines that have an attribute in 
common.


For example, my rivers are categorized based on some kind of stream 
order. I want to group all rivers that belong to stream order 2 and 
are spatially connected; each group should get a unique category 
value. I thought that I could first extract all rivers with a 
particular attribute (e.g. stream order = 2) which will provide me 
some scattered pattern of lines. Then I need a spatial join tool to 
make subgroups of lines that are connected. How can I achieve the 
latter? Any idea?



Here's a procedure that might work for you. Somewhat clunky, but I think 
it gets what you want.


It's based on the v.build.polylines module to connect all touching 
stream reaches. First extract each order from the stream vector into a 
new vector. Then build polylines. Patch them all together. Now you have 
a polyline vector with a single cat value for each set of original 
stream reaches that had the same order and that were touching.


Finally, with v.distance you can upload that cat value to the original 
streams.



# Get a list of stream orders
ORDERS=`v.db.select -c streams group=strahler column=strahler`
echo $ORDERS
#1 2 3 4 5 6
# How many stream segments in original
v.info -t streams | grep lines
# lines=1420

# Now loop thru list of stream orders and extract stream segments for 
each order

for o in $ORDERS; do
    v.extract input=streams output=streams_${o} where="strahler=${o}"
    # Create polyline for each stream order
    # Line "connects" all touching stream segments
    v.build.polylines input=streams_${o} 
output=streams_${o}_polyline type=line cat=first

done

# Patch stream order polylines together
POLYLINES=`g.list vect pattern="streams*polyline" separator=comma`
echo $POLYLINES
v.patch input=$POLYLINES output=streams_polylines
v.info -t streams_polylines | grep lines
# lines=738

# Add a new column to the original streams for new ID value
v.db.addcolumn map=streams column="merged_id INTEGER"
# And use v.distance to update that column from cat values in polylines 
vector

v.distance from=streams to=streams_polylines upload=cat column=merged_id

HTH


Cheers,
Johannes

___
grass-user mailing list
grass-user@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-user


--
Micha Silver
Ben Gurion Univ.
Sde Boker, Remote Sensing Lab
cell: +972-523-665918
https://orcid.org/-0002-1128-1325

___
grass-user mailing list
grass-user@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-user