[GRASS-user] populating dbtable with value sequence

This question is also posted on stackexchange.com

I have a vector map that includes 100 points. These points were created using v.extract to randomly sample a larger map of 10k points. As such, the ‘cat’ values range from 1 to more than 10k. What I would like to do is to update the attribute table by rescaling these values to 1 to 100.

Here’s what I’ve experienced. If I use

v.category input=pts100 output=foo option=del
v.category input=foo output=pts100 option=add --o

Then when the ‘cat’ values appear rescaled when I print them with

v.category input=pts100 option=print

However, if I look at the dbtable with

db.select pts100

the ‘cat’ values have not changed (presumably because it is the key column).

So I’m thinking I will need to add a new column using v.db.addcol, but I don’t know how to specify the range of value to populate the new column. From what I can tell, I have to specify a single value.

Ideas?

On 18/04/13 15:52, Shaun Langley wrote:

**This question is also posted on stackexchange.com
<http://stackexchange.com>**

I have a vector map that includes 100 points. These points were created
using |v.extract| to randomly sample a larger map of 10k points. As
such, the 'cat' values range from 1 to more than 10k. What I would like
to do is to update the attribute table by rescaling these values to 1 to
100.

Here's what I've experienced. If I use

|v.category input=pts100 output=foo option=del
v.category input=foo output=pts100 option=add --o|

Then when the 'cat' values /appear/ rescaled when I print them with

|v.category input=pts100 option=print|

However, if I look at the dbtable with

|db.select pts100|

the 'cat' values have not changed (presumably because it is the key column).

So I'm thinking I will need to add a new column using |v.db.addcol|, but
I don't know how to specify the range of value to populate the new
column. From what I can tell, I have to specify a single value.

Ideas?

Either

- v.distance (possibly with dmax=0) to get the cat values from the new points into the old map and then v.reclass to use the new values as cat values.

or

- v.db.addcol YourOldMap col='newcat int'
- populate that column with values from 1 to 100
- v.reclass as above

It might be an idea to add to v.category the possibility to propagate cat value changes to the attribute table. You could file a wish on the bugtracker.

Moritz

On Apr 18, 2013, at 9:48 AM, Moritz Lennert <mlennert@club.worldonline.be> wrote:

On 18/04/13 15:52, Shaun Langley wrote:

**This question is also posted on stackexchange.com
<http://stackexchange.com>**

I have a vector map that includes 100 points. These points were created
using |v.extract| to randomly sample a larger map of 10k points. As
such, the 'cat' values range from 1 to more than 10k. What I would like
to do is to update the attribute table by rescaling these values to 1 to
100.

Here's what I've experienced. If I use

|v.category input=pts100 output=foo option=del
v.category input=foo output=pts100 option=add --o|

Then when the 'cat' values /appear/ rescaled when I print them with

|v.category input=pts100 option=print|

However, if I look at the dbtable with

|db.select pts100|

the 'cat' values have not changed (presumably because it is the key column).

So I'm thinking I will need to add a new column using |v.db.addcol|, but
I don't know how to specify the range of value to populate the new
column. From what I can tell, I have to specify a single value.

Ideas?

Either

- v.distance (possibly with dmax=0) to get the cat values from the new points into the old map and then v.reclass to use the new values as cat values.

It isn't clear to me how this can be used to rescale the cat values. Points map has cat values that are (for example)

120
343
444
521
1334

I don't necessarily have to rescale the cat values if I can create a new column in which the values are scaled 1-100 (it's not feasible to do this by hand given the quantity of values I'd have to change. I need to script it.)

or

- v.db.addcol YourOldMap col='newcat int'
- populate that column with values from 1 to 100
- v.reclass as above

This is the kind of solution I was thinking I'd need to employ, but I need to automate the propagation of new values.

It might be an idea to add to v.category the possibility to propagate cat value changes to the attribute table. You could file a wish on the bugtracker.

Moritz

I have a possible solution!

1. add column to new table "newcol"
2. initialize first value

val=1

3. update values incrementally

for i in `v.category foo option=print`; do
  v.db.update foo column=newcol value=$val where="cat=$i"
  val=val+1
done

On Apr 18, 2013, at 11:16 AM, Shaun Langley <shaunlangley@gmail.com> wrote:

On Apr 18, 2013, at 9:48 AM, Moritz Lennert <mlennert@club.worldonline.be> wrote:

On 18/04/13 15:52, Shaun Langley wrote:

**This question is also posted on stackexchange.com
<http://stackexchange.com>**

I have a vector map that includes 100 points. These points were created
using |v.extract| to randomly sample a larger map of 10k points. As
such, the 'cat' values range from 1 to more than 10k. What I would like
to do is to update the attribute table by rescaling these values to 1 to
100.

Here's what I've experienced. If I use

|v.category input=pts100 output=foo option=del
v.category input=foo output=pts100 option=add --o|

Then when the 'cat' values /appear/ rescaled when I print them with

|v.category input=pts100 option=print|

However, if I look at the dbtable with

|db.select pts100|

the 'cat' values have not changed (presumably because it is the key column).

So I'm thinking I will need to add a new column using |v.db.addcol|, but
I don't know how to specify the range of value to populate the new
column. From what I can tell, I have to specify a single value.

Ideas?

Either

- v.distance (possibly with dmax=0) to get the cat values from the new points into the old map and then v.reclass to use the new values as cat values.

It isn't clear to me how this can be used to rescale the cat values. Points map has cat values that are (for example)

120
343
444
521
1334

I don't necessarily have to rescale the cat values if I can create a new column in which the values are scaled 1-100 (it's not feasible to do this by hand given the quantity of values I'd have to change. I need to script it.)

or

- v.db.addcol YourOldMap col='newcat int'
- populate that column with values from 1 to 100
- v.reclass as above

This is the kind of solution I was thinking I'd need to employ, but I need to automate the propagation of new values.

It might be an idea to add to v.category the possibility to propagate cat value changes to the attribute table. You could file a wish on the bugtracker.

Moritz

On 18/04/13 18:16, Shaun Langley wrote:

On Apr 18, 2013, at 9:48 AM, Moritz
Lennert<mlennert@club.worldonline.be> wrote:

On 18/04/13 15:52, Shaun Langley wrote:

**This question is also posted on stackexchange.com
<http://stackexchange.com>**

I have a vector map that includes 100 points. These points were
created using |v.extract| to randomly sample a larger map of 10k
points. As such, the 'cat' values range from 1 to more than 10k.
What I would like to do is to update the attribute table by
rescaling these values to 1 to 100.

Here's what I've experienced. If I use

|v.category input=pts100 output=foo option=del v.category
input=foo output=pts100 option=add --o|

Then when the 'cat' values /appear/ rescaled when I print them
with

|v.category input=pts100 option=print|

However, if I look at the dbtable with

|db.select pts100|

the 'cat' values have not changed (presumably because it is the
key column).

So I'm thinking I will need to add a new column using
|v.db.addcol|, but I don't know how to specify the range of value
to populate the new column. From what I can tell, I have to
specify a single value.

Ideas?

Either

- v.distance (possibly with dmax=0) to get the cat values from the
new points into the old map and then v.reclass to use the new
values as cat values.

It isn't clear to me how this can be used to rescale the cat values.

I meant using the new vector map pts100 as 'to_map' and your original map as 'from_map' and filling in a new column in the original map with the cat values of pts100. dmax=0 should work as the points are identical.

Points map has cat values that are (for example)

120 343 444 521 1334

I don't necessarily have to rescale the cat values if I can create a
new column in which the values are scaled 1-100 (it's not feasible to
do this by hand given the quantity of values I'd have to change. I
need to script it.)

If you use PostgreSQL as a data backend, you can simply create a sequence and fill up the table with calls to nextval().

I don't think SQLite has sequences as such (only autoincrement for rowid's).

Otherwise, I agree that you will probably have to script, so maybe the v.category + v.distance is actually the easiest.

Or, just thought of another possible solution (untested): use v.category to add a new layer with your ordered cat values to your original map, v.db.addtable to add a table to that layer, v.db.addcol to add a new column to the original attribute table in layer 1 cand v.db.update with qlayer and either option=cat (if this works, you actually don't have to create an attribute table for layer 2) or option=query and qcolumn.

Moritz