[GRASS-SVN] r72583 - grass/trunk/vector/v.decimate
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Mar 28 13:16:45 PDT 2018
Author: mmetz
Date: 2018-03-28 13:16:45 -0700 (Wed, 28 Mar 2018)
New Revision: 72583
Added:
grass/trunk/vector/v.decimate/copy_tab.c
Modified:
grass/trunk/vector/v.decimate/main.c
Log:
v.decimate: add attribute table to output (fixes #3541)
Copied: grass/trunk/vector/v.decimate/copy_tab.c (from rev 72559, grass/trunk/vector/v.extract/copy_tab.c)
===================================================================
--- grass/trunk/vector/v.decimate/copy_tab.c (rev 0)
+++ grass/trunk/vector/v.decimate/copy_tab.c 2018-03-28 20:16:45 UTC (rev 72583)
@@ -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);
+ }
+ }
+}
Modified: grass/trunk/vector/v.decimate/main.c
===================================================================
--- grass/trunk/vector/v.decimate/main.c 2018-03-28 11:27:34 UTC (rev 72582)
+++ grass/trunk/vector/v.decimate/main.c 2018-03-28 20:16:45 UTC (rev 72583)
@@ -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 @@
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 @@
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 @@
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);
More information about the grass-commit
mailing list