[GRASS-SVN] r49413 - grass/trunk/vector/v.category
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Nov 28 15:18:26 EST 2011
Author: mmetz
Date: 2011-11-28 12:18:26 -0800 (Mon, 28 Nov 2011)
New Revision: 49413
Modified:
grass/trunk/vector/v.category/main.c
grass/trunk/vector/v.category/v.category.html
Log:
v.category: add option to copy categories (#1498)
Modified: grass/trunk/vector/v.category/main.c
===================================================================
--- grass/trunk/vector/v.category/main.c 2011-11-28 20:09:35 UTC (rev 49412)
+++ grass/trunk/vector/v.category/main.c 2011-11-28 20:18:26 UTC (rev 49413)
@@ -28,6 +28,7 @@
#define O_SUM 5
#define O_CHFIELD 6
#define O_TYPE_REP 7 /* report number of features for each type */
+#define O_TRANS 8
#define FRTYPES 9 /* number of field report types */
@@ -59,7 +60,7 @@
int i, j, ret, option, otype, type, with_z, step, id;
int n_areas, centr, new_centr, nmodified;
double x, y;
- int cat, ocat, *fields, nfields, field;
+ int cat, ocat, scat, *fields, nfields, field;
struct GModule *module;
struct Option *in_opt, *out_opt, *option_opt, *type_opt;
struct Option *cat_opt, *field_opt, *step_opt, *id_opt;
@@ -94,12 +95,13 @@
option_opt->type = TYPE_STRING;
option_opt->required = YES;
option_opt->multiple = NO;
- option_opt->options = "add,del,chlayer,sum,report,print";
+ option_opt->options = "add,del,chlayer,sum,report,print,transfer";
option_opt->description = _("Action to be done");
option_opt->descriptions = _("add;add a new category;"
"del;delete category (-1 to delete all categories of given layer);"
"chlayer;change layer number (e.g. layer=3,1 changes layer 3 to layer 1);"
"sum;add the value specified by cat option to the current category value;"
+ "transfer;copy values from one layer to another (e.g. layer=1,2 copies values from layer 1 to layer 2);"
"report;print report (statistics), in shell style: layer type count min max;"
"print;print category values, more cats in the same layer are separated by '/'");
@@ -140,6 +142,9 @@
case ('s'):
option = O_SUM;
break;
+ case ('t'):
+ option = O_TRANS;
+ break;
case ('r'):
option = O_REP;
break;
@@ -195,16 +200,41 @@
fields[i] = Vect_get_field_number(&In, field_opt->answers[i]);
i++;
}
- if (nfields > 1 && option != O_PRN && option != O_CHFIELD)
+ if (nfields > 1 && option != O_PRN && option != O_CHFIELD && option != O_TRANS)
G_fatal_error(_("Too many layers for this operation"));
if (nfields != 2 && option == O_CHFIELD)
G_fatal_error(_("2 layers must be specified"));
+ if (option == O_TRANS) {
+ /* check if field[1] already exists */
+ if (nfields > 1) {
+ if (Vect_cidx_get_field_index(&In, fields[1]) != -1)
+ G_warning(_("Categories already exist in layer %d"), fields[1]);
+ }
+ /* find next free layer number */
+ else if (nfields == 1) {
+ int max = -1;
+
+ for (i = 0; i < Vect_cidx_get_num_fields(&In); i++) {
+ if (max < Vect_cidx_get_field_number(&In, i))
+ max = Vect_cidx_get_field_number(&In, i);
+ }
+ max++;
+
+ nfields++;
+ fields = (int *)G_realloc(fields, nfields * sizeof(int));
+ fields[nfields - 1] = max;
+ }
+ }
+
+ if (otype & GV_AREA && option == O_TRANS && !(otype & GV_CENTROID))
+ otype |= GV_CENTROID;
+
/* open output vector if needed */
if (option == O_ADD || option == O_DEL || option == O_CHFIELD ||
- option == O_SUM) {
- with_z = In.head.with_z;
+ option == O_SUM || option == O_TRANS) {
+ with_z = Vect_is_3d(&In);
if (0 > Vect_open_new(&Out, out_opt->answer, with_z)) {
Vect_close(&In);
@@ -221,7 +251,7 @@
nmodified = 0;
if (option == O_ADD || option == O_DEL || option == O_CHFIELD ||
- option == O_SUM) {
+ option == O_SUM || option == O_TRANS) {
G_message(_("Processing features..."));
}
@@ -271,6 +301,32 @@
}
break;
+ case (O_TRANS):
+ /* Lines */
+ while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
+ id++;
+ if (type & otype && (!Clist ||
+ (Clist &&
+ Vect_cat_in_cat_list(id, Clist) == TRUE))) {
+ if ((Vect_cat_get(Cats, fields[1], &ocat)) == 0) {
+ if (ocat < 0) {
+ int n = Cats->n_cats;
+
+ for (i = 0; i < n; i++) {
+ if (Cats->field[i] == fields[0]) {
+ scat = Cats->cat[i];
+ if (Vect_cat_set(Cats, fields[1], scat) > 0) {
+ nmodified++;
+ }
+ }
+ }
+ }
+ }
+ }
+ Vect_write_line(&Out, type, Points, Cats);
+ }
+ break;
+
case (O_DEL):
while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
id++;
@@ -292,12 +348,30 @@
if (type & otype && (!Clist ||
(Clist &&
Vect_cat_in_cat_list(id, Clist) == TRUE))) {
- for (i = 0; i < Cats->n_cats; i++) {
+ i = 0;
+ while (i < Cats->n_cats) {
if (Cats->field[i] == fields[0]) {
- Cats->field[i] = fields[1];
+ int found = -1;
+
+ /* check if cat already exists in layer fields[1] */
+ for (j = 0; j < Cats->n_cats; j++) {
+ if (Cats->field[j] == fields[1] &&
+ Cats->cat[j] == Cats->cat[i]) {
+ found = j;
+ break;
+ }
+ }
+ /* does not exist, change layer */
+ if (found < 0) {
+ Cats->field[i] = fields[1];
+ i++;
+ }
+ /* exists already in fields[1], delete from fields[0] */
+ else
+ Vect_field_cat_del(Cats, fields[0], Cats->cat[found]);
+ nmodified++;
}
}
- nmodified++;
}
Vect_write_line(&Out, type, Points, Cats);
}
@@ -543,13 +617,16 @@
}
if (option == O_ADD || option == O_DEL || option == O_CHFIELD ||
- option == O_SUM) {
+ option == O_SUM || option == O_TRANS) {
G_message(_("Copying attribute table(s)..."));
if (Vect_copy_tables(&In, &Out, 0))
G_warning(_("Failed to copy attribute table to output map"));
Vect_build(&Out);
Vect_close(&Out);
+ if (option == O_TRANS && nmodified > 0)
+ G_important_message(_("Categories copied from layer %d to layer %d"),
+ fields[0], fields[1]);
G_done_msg(_("%d features modified."), nmodified);
}
Vect_close(&In);
Modified: grass/trunk/vector/v.category/v.category.html
===================================================================
--- grass/trunk/vector/v.category/v.category.html 2011-11-28 20:09:35 UTC (rev 49412)
+++ grass/trunk/vector/v.category/v.category.html 2011-11-28 20:18:26 UTC (rev 49413)
@@ -1,8 +1,12 @@
<h2>DESCRIPTION</h2>
-<em>v.category</em> attaches, deletes or reports vector categories to
-map geometry. These categories (IDs) are used to link geometry
-object(s) to attribute records (from attribute table linked to vector map).
+<em>v.category</em> attaches, copies, deletes or reports categories of
+vector geometry objects. Further on, <em>v.category</em> adds a number
+given by the <em>cat</em> option to categories of the selected layer.
+These categories (IDs) are used to assign IDs or to group geometry objects
+into categories (several different geometry objects share the same
+category). These categories are also used to link geometry
+object(s) to attribute records (from an attribute table linked to vector map).
<h2>NOTES</h2>
@@ -13,6 +17,7 @@
<p>The <b>type</b> parameter specifies the type of geometry objects to which
the category is added; it is similar to an input filter - only the
geometry specified in 'type' is processed.
+
<p>If the <b>type</b> parameter is set to <b>centroid</b> and
the <b>option</b> parameter set to <b>add</b>, new categories will be
added to existing centroids. Note however, that new centroids cannot
@@ -20,6 +25,16 @@
using <em><a href="wxGUI.Vector_Digitizing_Tool.html">wxGUI vector
digitizer</a></em> or by running <em>v.category</em> with the type
parameter set to area.
+
+<p>If categories are copied with <em>option=transfer</em>, a warning is
+issued if categories already exit in the layer they are copied to. In
+this case the user must make sure beforehand that copying categories
+from one layer to another layer does not cause undesired grouping of
+different geometry objects into the same categories. This can be avoided
+by specifying only one <em>layer</em>. The module will then find the
+next free layer number and copy categories to there. The new layer number
+is reported at the end.
+
<p>Areas are a special case because it is impossible to attach a cat to
an area without a centroid; in this case, the module places new
centroids in areas automatically.
More information about the grass-commit
mailing list