[GRASS-dev] modifying the dblink it require to re-build the topology

Hi all,

I want to add a new layer to an existing vector map. I've noticed that
if I try to open a vector map with topology in read mode, I got the
following warning:

WARNING: Unable to add attribute link, vector map is not opened in WRITE mode

If I open the vector map, with and without the topology, in read and
write mode it works, but after I need to re-build the topology... that
it is quite annoying because I did not touch the geometry features...
What it is the best way If I have only to modify the dblinks [0] of an
existing vector map?

And what happens to the categories? should I rewrite the categories to
link the new layer with the geometry features? Or if not define the
geometry features inherit the categories from the previous layer?

Best regards

Pietro

[0] http://grass.osgeo.org/programming7/structdblinks.html

Pietro,

On 05/11/13 18:03, Pietro wrote:

Hi all,

I want to add a new layer to an existing vector map. I've noticed that
if I try to open a vector map with topology in read mode, I got the
following warning:

WARNING: Unable to add attribute link, vector map is not opened in WRITE mode

If I open the vector map, with and without the topology, in read and
write mode it works, but after I need to re-build the topology... that
it is quite annoying because I did not touch the geometry features...
What it is the best way If I have only to modify the dblinks [0] of an
existing vector map?

If all you want to do is to connect a specific table to a layer then v.db.connect does that.

And what happens to the categories? should I rewrite the categories to
link the new layer with the geometry features? Or if not define the
geometry features inherit the categories from the previous layer?

Even though you can link a table to a layer, this only makes sense if there are category values in that layer for at least some of the features in the map. GRASS does not automatically add category values to a layer just because you add a link from that layer to a table. Nor do you actually need to add a link to a table to add layers.

If you want to use the same category values in each layer, than you have the "transfer" option in v.category (only grass7) to copy category values from one layer to another.

You can then create the new table and the link to it with v.db.addtable. Or create the table yourself and use v.db.connect to link to it.

Moritz

[Please keep discussions on the list]

On 07/11/13 08:35, Pietro wrote:

Hi Moritz,

On Tue, Nov 5, 2013 at 5:20 PM, Moritz Lennert
<mlennert@club.worldonline.be> wrote:

And what happens to the categories? should I rewrite the categories to
link the new layer with the geometry features? Or if not define the
geometry features inherit the categories from the previous layer?

If you want to use the same category values in each layer, than you have the
"transfer" option in v.category (only grass7) to copy category values from
one layer to another.

Ok, I transformed the i.segment results into a vector map, add a table
with the shape and raster statistics for each segment (segment_data),
and then I have another table with the class for each segment that I
want to use for the training (segment_training),

$ v.db.connect -p map=segments@final table=segments_data_training
Vector map<segments@final> is connected by:
layer<1/segments_data> table<segments_data> in database
</data/gis/edi/final/sqlite/sqlite.db> through driver<sqlite> with
key<cat>
layer<2/segments_data_training> table<segments_data_training> in
database</data/gis/edi/final/sqlite/sqlite.db> through driver
<sqlite> with key<cat>

After the classification I will ad a Table with a classification
results for each column, or maybe better a new table for each
classification method. What do you think?
The problem is when I try to use the v.category module.

$ v.category input=segments option=report
Layer: 1
type count min max
point 0 0 0
line 0 0 0
boundary 0 0 0
centroid 2726635 1 2726635
area 2726635 1 2726635
face 0 0 0
kernel 0 0 0
all 2726635 1 2726635
Layer: 2
type count min max
point 0 0 0
line 0 0 0
boundary 261842 0 0
centroid 0 0 0
area 0 0 0
face 0 0 0
kernel 0 0 0
all 261842 0 0

Now I would like to copy the categories, from the layer 1 to layer 2.
I tried with:

v.category input=segments output=segm option=transfer layer=1,2

Is it not possible to work on the input map without generating a new
one, isn't it?
Perhaps we can modify the v.category module, that if output is not
set, then open the input vector map in read-write mode and update all
the categories of the input map.

Any way lets check the output:

$ v.category input=segm option=report
v.category input=segm option=report
Layer/table: 1/segm_segments_data
type count min max
point 0 0 0
line 0 0 0
boundary 0 0 0
centroid 2726635 1 2726635
area 0 0 0
face 0 0 0
kernel 0 0 0
all 2726635 1 2726635
Layer/table: 2/segm_segments_data_training
type count min max
point 0 0 0
line 0 0 0
boundary 0 0 0
centroid 2726635 1 2726635
area 0 0 0
face 0 0 0
kernel 0 0 0
all 2726635 1 2726635

All the area are missing... but are missing non only on the categories
level, they are missing from the output map!

$ v.info segments -t
nodes=4779720
points=0
lines=0
boundaries=7250355
centroids=2726635
areas=2726635
islands=256000
primitives=9976990
map3d=0
$ v.info segm -t
nodes=0
points=0
lines=0
boundaries=0
centroids=2726635
areas=0
islands=0
primitives=2726635
map3d=0

I'm doing something wrong or is it a bug?

I thought that maybe you forgot to use the type parameter, but I just tried in the NC dataset and can confirm your issue:

v.category boundary_county op=report
Layer/table: 1/boundary_county
type count min max
point 0 0 0
line 0 0 0
boundary 0 0 0
centroid 926 1 926
area 926 1 926
face 0 0 0
kernel 0 0 0
all 926 1 926

And then, whatever the combination of types I chose, I get

v.category boundary_county op=transfer out=bc2 layer=1,2

v.category bc2 op=reportLayer/table: 1/bc2
type count min max
point 0 0 0
line 0 0 0
boundary 0 0 0
centroid 926 1 926
area 0 0 0
face 0 0 0
kernel 0 0 0
all 926 1 926
Layer: 2
type count min max
point 0 0 0
line 0 0 0
boundary 0 0 0
centroid 926 1 926
area 0 0 0
face 0 0 0
kernel 0 0 0
all 926 1 926

So I would guess that it's a bug. In the source code, when you look at the part for the 'add' option, you see that there is specific code for areas. I would guess that the same or similar needs to be added to the 'transfer' option to make sure that boundaries are also copied into the output map.

Is it not possible to work on the input map without generating a new
one, isn't it?
Perhaps we can modify the v.category module, that if output is not
set, then open the input vector map in read-write mode and update all
the categories of the input map.

I know that it can be annoying to have to create new maps, but at the same time it is a failsafe that makes sure that even if you make a mistake in the call to v.category, you still keep your original data.

I think that the overhead of a g.rename --o is a price worth paying for that security.

Moritz

On Thursday 07 Nov 2013 09:25:21 you wrote:

> I'm doing something wrong or is it a bug?

I thought that maybe you forgot to use the type parameter, but I
just tried in the NC dataset and can confirm your issue.

ok, the bug should be fixed in r58179, at the end it was much easier
than I thought.

Please test the v.category module, to be sure that I've not introduced
new bugs. :slight_smile:

I know that it can be annoying to have to create new maps, but at
the same time it is a failsafe that makes sure that even if you
make a mistake in the call to v.category, you still keep your
original data.

yes, it is particularly annoying, because the GRASS db driver is
pretty slow copying data from one table to another. Maybe we should
add a flag that skip to copy the attribute tables.

On the other hand, the tables are already there, we need only to link
the geometry features to the existing table.

Anyone against this new flag/option?

Best regards

Pietro

On 09/11/13 17:23, Pietro Zambelli wrote:

On Thursday 07 Nov 2013 09:25:21 you wrote:

I'm doing something wrong or is it a bug?

I thought that maybe you forgot to use the type parameter, but I
just tried in the NC dataset and can confirm your issue.

ok, the bug should be fixed in r58179, at the end it was much easier
than I thought.

Please test the v.category module, to be sure that I've not introduced
new bugs. :slight_smile:

I know that it can be annoying to have to create new maps, but at
the same time it is a failsafe that makes sure that even if you
make a mistake in the call to v.category, you still keep your
original data.

yes, it is particularly annoying, because the GRASS db driver is
pretty slow copying data from one table to another. Maybe we should
add a flag that skip to copy the attribute tables.

That could be an option, yes.

On the other hand, the tables are already there, we need only to link
the geometry features to the existing table.

No, if we have a new map it should use a different attribute table than the old map.

Anyone against this new flag/option?

I'm not against the flag as it seems a reasonable option to me, but I think that the performance issue should be solved as well. From what I see in the code, I have the feeling that v.category might be bitten by the same "bug"/problem as the one Hamish just reported for v.what.rast [1], so possibly it is feasible to improve the performance.

Moritz

[1] https://trac.osgeo.org/grass/ticket/2131

On 12/11/13 20:37, Moritz Lennert wrote:

On 09/11/13 17:23, Pietro Zambelli wrote:

On Thursday 07 Nov 2013 09:25:21 you wrote:

I'm doing something wrong or is it a bug?

I thought that maybe you forgot to use the type parameter, but I
just tried in the NC dataset and can confirm your issue.

ok, the bug should be fixed in r58179, at the end it was much easier
than I thought.

Please test the v.category module, to be sure that I've not introduced
new bugs. :slight_smile:

Sorry, forgot to mention. Haven't tested much but I haven't detected any new problems.

Moritz

On Tuesday 12 Nov 2013 20:37:24 you wrote:

>> I know that it can be annoying to have to create new maps, but at
>> the same time it is a failsafe that makes sure that even if you
>> make a mistake in the call to v.category, you still keep your
>> original data.
>
> yes, it is particularly annoying, because the GRASS db driver is
> pretty slow copying data from one table to another. Maybe we
> should
> add a flag that skip to copy the attribute tables.

That could be an option, yes.

Ok, done in r58202

> On the other hand, the tables are already there, we need only to
> link the geometry features to the existing table.

No, if we have a new map it should use a different attribute table
than the old map.

I don't agree I prefer to avoid to have several copy of the same thing
on my hard-disk, but I can understand your logic. :slight_smile:

> Anyone against this new flag/option?

I'm not against the flag as it seems a reasonable option to me, but
I think that the performance issue should be solved as well. From
what I see in the code, I have the feeling that v.category might be
bitten by the same "bug"/problem as the one Hamish just reported
for v.what.rast [1], so possibly it is feasible to improve the
performance.

Yes, I think that we have a huge problem in the DB drivers, but I
don't have time right now to understand where the problem is.

In general I try to avoid to use the C API of the DB as much as
possible, using directly the python API.

I think that the Attribute table, could gain in usability too if avoid
to use v.db.select, and start to use directly the python API...
and I think should avoid to load the whole table and load only the
first 250 rows [0].

Best regards

Pietro

[0] http://trac.osgeo.org/grass/ticket/2124

On 12/11/13 23:24, Pietro Zambelli wrote:

On Tuesday 12 Nov 2013 20:37:24 you wrote:

On the other hand, the tables are already there, we need only to
link the geometry features to the existing table.

No, if we have a new map it should use a different attribute table
than the old map.

I don't agree I prefer to avoid to have several copy of the same thing
on my hard-disk, but I can understand your logic. :slight_smile:

It's not about redundancy, but about the fact that when you have two maps (the old and the new) linked to the same table you will have conflicts to resolve. Normally GRASS erases the table linked to a map when that map is erased. So, if you link the new map to the old table and then erase the old map, you might lose all your attribute data...

Moritz