浏览代码

v.decimate: add attribute table to output (fixes https://trac.osgeo.org/grass/ticket/3541)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@72583 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 7 年之前
父节点
当前提交
72554f9f1c
共有 2 个文件被更改,包括 144 次插入1 次删除
  1. 135 0
      vector/v.decimate/copy_tab.c
  2. 9 1
      vector/v.decimate/main.c

+ 135 - 0
vector/v.decimate/copy_tab.c

@@ -0,0 +1,135 @@
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+void copy_tabs(const struct Map_info *In, struct Map_info *Out)
+{
+    int nlines, line, i;
+    int ttype, ntabs;
+    int **ocats, *nocats, nfields, *fields;
+    
+    struct field_info *IFi, *OFi;
+    struct line_cats *Cats;
+    dbDriver *driver;
+    
+    ntabs = 0;
+    
+    /* Collect list of output cats */
+    Cats = Vect_new_cats_struct();
+    nfields = Vect_cidx_get_num_fields(Out);
+    ocats = (int **)G_malloc(nfields * sizeof(int *));
+    nocats = (int *)G_malloc(nfields * sizeof(int));
+    fields = (int *)G_malloc(nfields * sizeof(int));
+    for (i = 0; i < nfields; i++) {
+	nocats[i] = 0;
+	ocats[i] =
+	    (int *)G_malloc(Vect_cidx_get_num_cats_by_index(Out, i) *
+			    sizeof(int));
+	fields[i] = Vect_cidx_get_field_number(Out, i);
+    }
+    
+    nlines = Vect_get_num_lines(Out);
+    for (line = 1; line <= nlines; line++) {
+	Vect_read_line(Out, NULL, Cats, line);
+	
+	for (i = 0; i < Cats->n_cats; i++) {
+	    int f, j;
+	    
+	    f = -1;
+	    for (j = 0; j < nfields; j++) {	/* find field */
+		if (fields[j] == Cats->field[i]) {
+		    f = j;
+		    break;
+		}
+	    }
+	    if (f >= 0) {
+		ocats[f][nocats[f]] = Cats->cat[i];
+		nocats[f]++;
+	    }
+	}
+    }
+    
+    /* Copy tables */
+    G_message(_("Writing attributes..."));
+    
+    /* Number of output tabs */
+    for (i = 0; i < Vect_get_num_dblinks(In); i++) {
+	int j, f = -1;
+	
+	IFi = Vect_get_dblink(In, i);
+	
+	for (j = 0; j < nfields; j++) {	/* find field */
+	    if (fields[j] == IFi->number) {
+		f = j;
+		break;
+	    }
+	}
+	if (f >= 0 && nocats[f] > 0)
+	    ntabs++;
+    }
+    
+    if (ntabs > 1)
+	ttype = GV_MTABLE;
+    else
+	ttype = GV_1TABLE;
+    
+    for (i = 0; i < nfields; i++) {
+	int ret;
+	
+	if (fields[i] == 0)
+	    continue;
+	if (nocats[i] == 0)
+	    continue;
+	
+	G_verbose_message(_("Writing attributes for layer %d"), fields[i]);
+	
+	/* Make a list of categories */
+	IFi = Vect_get_field(In, fields[i]);
+	if (!IFi) {		/* no table */
+	    G_message(_("No attribute table for layer %d"), fields[i]);
+	    continue;
+	}
+	
+	OFi = Vect_default_field_info(Out, IFi->number, NULL, ttype);
+	
+	ret = db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
+				    OFi->driver,
+				    Vect_subst_var(OFi->database, Out),
+				    OFi->table, IFi->key, ocats[i],
+				    nocats[i]);
+	
+	if (ret == DB_FAILED) {
+	    G_warning(_("Unable to copy table <%s>"), IFi->table);
+	}
+	else {
+
+	    driver = db_start_driver_open_database(OFi->driver,
+						   Vect_subst_var(OFi->database,
+								    Out));
+
+	    if (!driver) {
+		G_warning(_("Unable to open database <%s> with driver <%s>"),
+			      OFi->database, OFi->driver);
+	    }
+	    else {
+
+		/* do not allow duplicate keys */
+		if (db_create_index2(driver, OFi->table, IFi->key) != DB_OK) {
+		    G_warning(_("Unable to create index"));
+		}
+
+		if (db_grant_on_table(driver, OFi->table, DB_PRIV_SELECT,
+		     DB_GROUP | DB_PUBLIC) != DB_OK) {
+		    G_warning(_("Unable to grant privileges on table <%s>"),
+				  OFi->table);
+		}
+
+		db_close_database_shutdown_driver(driver);
+	    }
+
+	    Vect_map_add_dblink(Out, OFi->number, OFi->name, OFi->table,
+				IFi->key, OFi->database, OFi->driver);
+	}
+    }
+}

+ 9 - 1
vector/v.decimate/main.c

@@ -24,6 +24,7 @@
 
 #include <stdlib.h>
 
+void copy_tabs(const struct Map_info *In, struct Map_info *Out);
 
 struct DecimationContext
 {
@@ -114,7 +115,7 @@ int main(int argc, char **argv)
     struct Option *skip_opt, *preserve_opt, *offset_opt, *limit_opt;
     struct Option *zdiff_opt, *limit_per_cell_opt, *zrange_opt;
     struct Flag *grid_decimation_flg, *first_point_flg, *cat_in_grid_flg;
-    struct Flag *use_z_flg, *nocats_flag, *notopo_flag;
+    struct Flag *use_z_flg, *nocats_flag, *notopo_flag, *notab_flag;
     struct Map_info vinput, voutput;
 
     G_gisinit(argv[0]);
@@ -245,6 +246,9 @@ int main(int argc, char **argv)
     notopo_flag = G_define_standard_flag(G_FLG_V_TOPO);
     notopo_flag->guisection = _("Speed");
 
+    notab_flag = G_define_standard_flag(G_FLG_V_TABLE);
+    notab_flag->guisection = _("Speed");
+
     /* here we have different decimations but also selections/filters */
     G_option_required(skip_opt, preserve_opt, offset_opt, limit_opt,
                       grid_decimation_flg, zrange_opt, cats_opt, NULL);
@@ -455,6 +459,10 @@ int main(int argc, char **argv)
 
     Vect_hist_command(&voutput);
 
+    if (write_context.write_cats == TRUE && !notab_flag->answer) {
+	copy_tabs(&vinput, &voutput);
+    }
+
     Vect_close(&vinput);
     if (!notopo_flag->answer)
         Vect_build(&voutput);