[GRASS-user] vector segment lengths

Hi GRASS list,

How do I find out the length of each segment after running v.split?

I have this code:

v.split -f input=v output=v_split units=meters length=100 --o

I'd like to know the length. Presumably they are 100 m, but the last segment of each line in 'v' must be less than or equal to that.

I tried this:

v.db.addcolumn map=v_split column="length double precision"
v.to.db map=v_split type=line option=length columns=length units=meters

When I display with 'd.vect' and click, I see both 'v' and 'v_split'. When I click on a segment I see the total length of 'v' and the 100 m (or 42.214 for the end segment) of 'v_split'. But I don't see it when I query it at the command line with:

db.select sql='select * from v_split'

In this case, it only reports the original few segments from 'v', not the many 100s of segments from 'v_split'. It appears both vectors are linked to the same table.

Still (sometimes) trying to figure out the GRASS DB and layers connected to tables...

Thanks,

  -k.

On 29/11/18 08:55, Ken Mankoff wrote:

Hi GRASS list,

How do I find out the length of each segment after running v.split?

I have this code:

v.split -f input=v output=v_split units=meters length=100 --o

I'd like to know the length. Presumably they are 100 m, but the last segment of each line in 'v' must be less than or equal to that.

I tried this:

v.db.addcolumn map=v_split column="length double precision"
v.to.db map=v_split type=line option=length columns=length units=meters

When I display with 'd.vect' and click, I see both 'v' and 'v_split'. When I click on a segment I see the total length of 'v' and the 100 m (or 42.214 for the end segment) of 'v_split'. But I don't see it when I query it at the command line with:

db.select sql='select * from v_split'

In this case, it only reports the original few segments from 'v', not the many 100s of segments from 'v_split'. It appears both vectors are linked to the same table.

Still (sometimes) trying to figure out the GRASS DB and layers connected to tables...

v.split does not change the layer, nor the category information, nor the attribute table links of the original file. It just splits each line in segments and attributes the same category to all segments of the same original line. As the attribute table is linked to the features with their category as key, all segments originating from the same original line are linked to the same line in the original attribute table which is just copied to the new map.

When you run v.to.db on this, it will add length information for each segment in its respective attribute line, but since all the segments of the same original line share the same attribute table line, it only gets updated once.

If you want the length of each segment, you will have to attribute different category values to all of them. The best is to this on a separate layer, using v.category

v.category v_split op=add layer=2 output=v_split_2

then you can run your above commands on that layer:

v.db.addcolumn map=v_split_2 column="length double precision layer=2
v.to.db map=v_split_2 type=line option=length columns=length units=meters layer=2

This info should probably somehow go into the man page of v.split.

Moritz

Hi Moritz,

On 2018-11-29 at 04:38 -0800, Moritz Lennert <mlennert@club.worldonline.be> wrote:

If you want the length of each segment, you will have to attribute
different category values to all of them. The best is to this on a
separate layer, using v.category

v.category v_split op=add layer=2 output=v_split_2

then you can run your above commands on that layer:

v.db.addcolumn map=v_split_2 column="length double precision layer=2

v.to.db map=v_split_2 type=line option=length columns=length
units=meters layer=2

The code you provided does not work for me, but does if I change you 'v.db.addcolumn' command to

v.db.addtable map=v_split_2 layer=2 columns="length double precision"

This info should probably somehow go into the man page of v.split.

I would edit the man page and upload a patch to Trac but am not confident enough I understand what you've suggested (yet) to document it for others.

Anyway, afterwards, I have the following tables (from db.tables):

v
v_split
v_split_2
v_split_2_2

Now I need to select the split segments in v_split_2_2 but aggregate them based on the larger segments they came from (in v_split_2). I don't see how these tables are connected at this point, nor how to join them. The categories are unique:

v.db.select map=v_split_2 layer=1 | head -n3
cat|id|label
1|1|
2|1|

v.db.select map=v_split_2 layer=2 | head -n3
cat|length
1|100
2|100

  -k.

Am 5. Dezember 2018 22:14:27 MEZ schrieb Ken Mankoff <mankoff@gmail.com>:

Hi Moritz,

On 2018-11-29 at 04:38 -0800, Moritz Lennert
<mlennert@club.worldonline.be> wrote:

If you want the length of each segment, you will have to attribute
different category values to all of them. The best is to this on a
separate layer, using v.category

v.category v_split op=add layer=2 output=v_split_2

then you can run your above commands on that layer:

v.db.addcolumn map=v_split_2 column="length double precision layer=2

v.to.db map=v_split_2 type=line option=length columns=length
units=meters layer=2

The code you provided does not work for me, but does if I change you
'v.db.addcolumn' command to

v.db.addtable map=v_split_2 layer=2 columns="length double precision"

Your absolutely right, you obviously need to add an attribute table to layer 2 first. Sorry for that.

This info should probably somehow go into the man page of v.split.

I would edit the man page and upload a patch to Trac but am not
confident enough I understand what you've suggested (yet) to document
it for others.

Just give it a try. We can always suggest amendments if necessary.

Anyway, afterwards, I have the following tables (from db.tables):

v
v_split
v_split_2
v_split_2_2

Now I need to select the split segments in v_split_2_2 but aggregate
them based on the larger segments they came from (in v_split_2). I
don't see how these tables are connected at this point, nor how to join
them. The categories are unique:

v.db.select map=v_split_2 layer=1 | head -n3
cat|id|label
1|1|
2|1|

v.db.select map=v_split_2 layer=2 | head -n3
cat|length
1|100
2|100

You can use v.to.db with layer=2 option=query query_layer=1 query_column=cat to load the original cat value to the table of layer 2.

Moritz

On Thu, Nov 29, 2018 at 1:38 PM Moritz Lennert
<mlennert@club.worldonline.be> wrote:

On 29/11/18 08:55, Ken Mankoff wrote:
> Hi GRASS list,
>
> How do I find out the length of each segment after running v.split?
>
> I have this code:
>
> v.split -f input=v output=v_split units=meters length=100 --o
>
> I'd like to know the length. Presumably they are 100 m, but the last segment of each line in 'v' must be less than or equal to that.
>
> I tried this:
>
> v.db.addcolumn map=v_split column="length double precision"
> v.to.db map=v_split type=line option=length columns=length units=meters
>
> When I display with 'd.vect' and click, I see both 'v' and 'v_split'. When I click on a segment I see the total length of 'v' and the 100 m (or 42.214 for the end segment) of 'v_split'. But I don't see it when I query it at the command line with:
>
> db.select sql='select * from v_split'
>
> In this case, it only reports the original few segments from 'v', not the many 100s of segments from 'v_split'. It appears both vectors are linked to the same table.
>
> Still (sometimes) trying to figure out the GRASS DB and layers connected to tables...

v.split does not change the layer, nor the category information, nor the
attribute table links of the original file. It just splits each line in
segments and attributes the same category to all segments of the same
original line. As the attribute table is linked to the features with
their category as key, all segments originating from the same original
line are linked to the same line in the original attribute table which
is just copied to the new map.

When you run v.to.db on this, it will add length information for each
segment in its respective attribute line, but since all the segments of
the same original line share the same attribute table line, it only gets
updated once.

If you want the length of each segment, you will have to attribute
different category values to all of them. The best is to this on a
separate layer, using v.category

v.category v_split op=add layer=2 output=v_split_2

then you can run your above commands on that layer:

v.db.addcolumn map=v_split_2 column="length double precision layer=2
v.to.db map=v_split_2 type=line option=length columns=length
units=meters layer=2

This info should probably somehow go into the man page of v.split.

I have made an attempt to add that (r73781):

https://grass.osgeo.org/grass77/manuals/v.split.html#notes-on-segment-length-information

Pls fix as needed, then I'll backport it.

Markus

On 2018-12-09 at 03:49 -0800, Markus Neteler <neteler@osgeo.org> wrote:

I have made an attempt to add that (r73781):
https://grass.osgeo.org/grass77/manuals/v.split.html#notes-on-segment-length-information

Pls fix as needed, then I'll backport it.

How do you prefer small documentation change suggestions. I have grass_trunk via svn. Post an email here? Patch here? Patch to grass-dev? Issue on Trac?

  -k.

On Sun, Dec 9, 2018 at 3:41 PM Ken Mankoff <mankoff@gmail.com> wrote:

On 2018-12-09 at 03:49 -0800, Markus Neteler <neteler@osgeo.org> wrote:
> I have made an attempt to add that (r73781):
> https://grass.osgeo.org/grass77/manuals/v.split.html#notes-on-segment-length-information
>
> Pls fix as needed, then I'll backport it.

How do you prefer small documentation change suggestions. I have grass_trunk via svn.

Good, thanks

Post an email here? Patch here? Patch to grass-dev? Issue on Trac?

A diff to me or here is fine.

One (soon!) day we'll have git :slight_smile:

Markus