[GRASS-SVN] r58216 - grass/branches/develbranch_6/vector/v.what.rast
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Nov 14 01:34:55 PST 2013
Author: hamish
Date: 2013-11-14 01:34:55 -0800 (Thu, 14 Nov 2013)
New Revision: 58216
Modified:
grass/branches/develbranch_6/vector/v.what.rast/description.html
grass/branches/develbranch_6/vector/v.what.rast/main.c
Log:
add flag to interpolate values from the nearest four cells instead of using nearest neighbor; add flag to allow printing to stdout (merge from trunk)
Modified: grass/branches/develbranch_6/vector/v.what.rast/description.html
===================================================================
--- grass/branches/develbranch_6/vector/v.what.rast/description.html 2013-11-14 06:52:25 UTC (rev 58215)
+++ grass/branches/develbranch_6/vector/v.what.rast/description.html 2013-11-14 09:34:55 UTC (rev 58216)
@@ -1,41 +1,69 @@
<h2>DESCRIPTION</h2>
-<em>v.what.rast</em> reads raster value for each point in the vector and updates <b>col</b>
-column in vector attribute table by this value. The column should be type
-number (integer, float, double, ... ).
-<br>
-If more points have the same category, attribute value is set to NULL.
-If raster values is NULL, attribute value is set to NULL.
+<em>v.what.rast</em> reads the raster value for each point in the vector map
+and updates <b>column</b> in the vector attribute table by this value. The
+column should be type number (integer, float, double, ... ).
+<p>
+If the <b>-p</b> flag is used, then the attribute table is not updated
+and the results are printed to <tt>stdout</tt>.
+<p>
+If the <b>-i</b> flag is used, then the value to be uploaded to the database
+is interpolated from the four nearest raster cells values using an inverse
+distance weighting method (IDW). This is useful for cases when the vector
+point density is much higher than the raster cell size.
+
<h2>NOTES</h2>
+If multiple points have the same category, the attribute value is set to NULL.
+If the raster value is NULL, then attribute value is set to NULL.
+<p>
<em>v.what.rast</em> operates on the attribute table. To modify the vector
geometry instead, use <em>v.drape</em>.
+<p>
+Categories and values are output unsorted with the print flag. To sort them
+pipe the output of this module into the UNIX <tt>sort</tt> tool
+(<tt>sort -n</tt>). If you need coordinates, after sorting use
+<em>v.out.ascii</em> and the UNIX <tt>paste</tt> tool
+(<tt>paste -d'|'</tt>). In the case of a NULL result, a "<tt>*</tt>"
+will be printed in lieu of the value.
+<p>
+The interpolation flag is only useful for continuous value raster maps,
+if a categorical raster is given as input the results will be nonsense.
+Since the search window is limited to four raster cells there may still
+be raster cell-edge artifacts visible in the results, this compromise
+has been made for processing speed. If one or more of the nearest four
+raster cells is NULL, then only the raster cells containing values will
+be used in the weighted average.
+
<h2>EXAMPLES</h2>
-A) Reading values from raster map at position of vector points, writing these values
- into a column of the attribute table connected to the vector map:
+A) Reading values from raster map at position of vector points,
+ writing these values into a column of the attribute table
+ connected to the vector map:
<br>
+
<div class="code"><pre>
-v.what.rast vect=pnts rast=elevation col=heights
+v.what.rast vector=pnts raster=elevation column=heights
</pre></div>
<p>
B) In case of a vector map without attached attribute table, first add
-a new attribute table. This table is then populated with values
-queried from the raster map:
+ a new attribute table. This table is then populated with values
+ queried from the raster map:
<br>
+
<div class="code"><pre>
# create new random vector points map
v.random pnts n=100
# add new table, link to map
-v.db.addtable pnts col="heights double precision"
+v.db.addtable pnts column="heights double precision"
# query raster map and upload values to vector table into specified column
g.region rast=elevation -p
-v.what.rast vect=pnts raster=elevation column=heights
+v.what.rast vector=pnts raster=elevation column=heights
# verify new attribute table:
v.db.select pnts
@@ -44,6 +72,7 @@
v.univar map=pnts column=heights type=point
</pre></div>
+
<h2>SEE ALSO</h2>
<em>
@@ -52,11 +81,14 @@
<a href="v.drape.html">v.drape</a>,
<a href="v.univar.html">v.univar</a>,
<a href="v.rast.stats.html">v.rast.stats</a>,
+v.what.rast.buffer (AddOn module),
<a href="v.what.vect.html">v.what.vect</a>
</em>
-<h2>AUTHOR</h2>
-Radim Blazek
+<h2>AUTHORS</h2>
+Radim Blazek<br>
+Hamish Bowman (interpolation)
+
<p>
<i>Last changed: $Date$</i>
Modified: grass/branches/develbranch_6/vector/v.what.rast/main.c
===================================================================
--- grass/branches/develbranch_6/vector/v.what.rast/main.c 2013-11-14 06:52:25 UTC (rev 58215)
+++ grass/branches/develbranch_6/vector/v.what.rast/main.c 2013-11-14 09:34:55 UTC (rev 58216)
@@ -1,21 +1,24 @@
-/* ***************************************************************
- * *
- * * MODULE: v.what.rast
- * *
- * * AUTHOR(S): Radim Blazek (using r.what)
- * * Michael Shapiro, U.S. Army Construction Engineering Research Laboratory (r.what)
- * *
- * * PURPOSE: Query raster map
- * *
- * * COPYRIGHT: (C) 2001 by the GRASS Development Team
- * *
- * * This program is free software under the
- * * GNU General Public License (>=v2).
- * * Read the file COPYING that comes with GRASS
- * * for details.
- * *
- * * TODO: fix user notification if where= is used
- * **************************************************************/
+
+/***************************************************************
+ *
+ * MODULE: v.what.rast
+ *
+ * AUTHOR(S): Radim Blazek (adapted from r.what)
+ * Michael Shapiro, U.S. Army Construction Engineering
+ * Research Laboratory (r.what)
+ * Hamish Bowman, University of Otago, NZ (interpolation)
+ *
+ * PURPOSE: Query raster map
+ *
+ * COPYRIGHT: (C) 2001-2013 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ * TODO: fix user notification if where= is used
+ **************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -30,6 +33,7 @@
int count; /* nuber of points with category 'cat' */
int row;
int col;
+ double x, y; /* used with interp flag */
CELL value;
DCELL dvalue; /* used for FCELL and DCELL */
};
@@ -45,15 +49,16 @@
int i, j, nlines, type, field, cat;
int fd;
- /* struct Categories RCats; *//* TODO */
+ /* struct Categories RCats; */ /* TODO */
struct Cell_head window;
RASTER_MAP_TYPE out_type;
- CELL *cell;
- DCELL *dcell;
+ CELL *cell_row, *prev_c_row, *next_c_row;
+ DCELL *dcell_row, *prev_d_row, *next_d_row;
int width;
double drow, dcol;
char buf[2000];
struct Option *vect_opt, *rast_opt, *field_opt, *col_opt, *where_opt;
+ struct Flag *interp_flag, *print_flag;
int Cache_size;
struct order *cache;
int cur_row;
@@ -78,7 +83,7 @@
G_gisinit(argv[0]);
module = G_define_module();
- module->keywords = _("vector, raster, attribute table");
+ module->keywords = _("vector, raster, attribute table, sampling");
module->description =
_("Uploads raster values at positions of vector points to the table.");
@@ -96,12 +101,22 @@
col_opt = G_define_option();
col_opt->key = "column";
col_opt->type = TYPE_STRING;
- col_opt->required = YES;
+ col_opt->required = NO;
col_opt->description =
_("Column name (will be updated by raster values)");
where_opt = G_define_standard_option(G_OPT_WHERE);
+ interp_flag = G_define_flag();
+ interp_flag->key = 'i';
+ interp_flag->description =
+ _("Interpolate values from the nearest four cells");
+
+ print_flag = G_define_flag();
+ print_flag->key = 'p';
+ print_flag->description =
+ _("Print categories and values instead of updating the database");
+
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
@@ -112,6 +127,9 @@
Points = Vect_new_line_struct();
Cats = Vect_new_cats_struct();
+ if (!print_flag->answer && !col_opt->answer)
+ G_fatal_error(_("Required parameter <%s> not set"), col_opt->key);
+
G_get_window(&window);
Vect_region_box(&window, &box); /* T and B set to +/- PORT_DOUBLE_MAX */
@@ -122,6 +140,7 @@
Vect_set_open_level(2);
Vect_open_old(&Map, vect_opt->answer, mapset);
+ /* FIXME: if print flag is used then a database doesn't need to exist */
Fi = Vect_get_field(&Map, field);
if (Fi == NULL)
G_fatal_error(_("Database connection not defined for layer %d"),
@@ -153,20 +172,22 @@
G_fatal_error ( "Cannot read category file");
*/
- /* Check column type */
- col_type = db_column_Ctype(driver, Fi->table, col_opt->answer);
+ if (!print_flag->answer) {
+ /* Check column type */
+ col_type = db_column_Ctype(driver, Fi->table, col_opt->answer);
- if (col_type == -1)
- G_fatal_error(_("Column <%s> not found"), col_opt->answer);
+ if (col_type == -1)
+ G_fatal_error(_("Column <%s> not found"), col_opt->answer);
- if (col_type != DB_C_TYPE_INT && col_type != DB_C_TYPE_DOUBLE)
- G_fatal_error(_("Column type not supported"));
+ if (col_type != DB_C_TYPE_INT && col_type != DB_C_TYPE_DOUBLE)
+ G_fatal_error(_("Column type not supported"));
- if (out_type == CELL_TYPE && col_type == DB_C_TYPE_DOUBLE)
- G_warning(_("Raster type is integer and column type is float"));
+ if (out_type == CELL_TYPE && col_type == DB_C_TYPE_DOUBLE)
+ G_warning(_("Raster type is integer and column type is float"));
- if (out_type != CELL_TYPE && col_type == DB_C_TYPE_INT)
- G_warning(_("Raster type is float and column type is integer, some data lost!!"));
+ if (out_type != CELL_TYPE && col_type == DB_C_TYPE_INT)
+ G_warning(_("Raster type is float and column type is integer, some data lost!!"));
+ }
/* Read vector points to cache */
Cache_size = Vect_get_num_primitives(&Map, GV_POINT);
@@ -218,6 +239,10 @@
cache[point_cnt].row = (int)drow;
cache[point_cnt].col = (int)dcol;
+ if (interp_flag->answer) {
+ cache[point_cnt].x = Points->x[0];
+ cache[point_cnt].y = Points->y[0];
+ }
cache[point_cnt].cat = cat;
cache[point_cnt].count = 1;
point_cnt++;
@@ -239,6 +264,7 @@
cache[++i] = cache[j];
else
cache[i].count++;
+
point_cnt = i + 1;
G_debug(1, "%d vector points left after removal of duplicates",
@@ -257,10 +283,22 @@
/* Allocate space for raster row */
if (out_type == CELL_TYPE)
- cell = G_allocate_c_raster_buf();
+ cell_row = G_allocate_c_raster_buf();
else
- dcell = G_allocate_d_raster_buf();
+ dcell_row = G_allocate_d_raster_buf();
+ if (interp_flag->answer) {
+ if (out_type == CELL_TYPE) {
+ prev_c_row = G_allocate_c_raster_buf();
+ next_c_row = G_allocate_c_raster_buf();
+ }
+ else {
+ prev_d_row = G_allocate_d_raster_buf();
+ next_d_row = G_allocate_d_raster_buf();
+ }
+ G_begin_distance_calculations();
+ }
+
/* Extract raster values from file and store in cache */
G_debug(1, "Extracting raster values");
@@ -272,111 +310,377 @@
if (cur_row != cache[point].row) {
if (out_type == CELL_TYPE) {
- if (G_get_c_raster_row(fd, cell, cache[point].row) < 0)
+ if (G_get_c_raster_row(fd, cell_row, cache[point].row) < 0)
G_fatal_error(_("Unable to read raster map <%s> row %d"),
rast_opt->answer, cache[point].row);
+
+ if (interp_flag->answer) {
+ if (cache[point].row <= 0)
+ G_set_null_value(prev_c_row, window.cols, out_type);
+ else {
+ if (G_get_c_raster_row
+ (fd, prev_c_row, cache[point].row - 1) < 0)
+ G_fatal_error(_("Unable to read raster map <%s> row %d"),
+ rast_opt->answer,
+ cache[point].row - 1);
+ }
+ if (cache[point].row + 1 > window.rows - 1)
+ G_set_null_value(next_c_row, window.cols, out_type);
+ else {
+
+ if (G_get_c_raster_row
+ (fd, next_c_row, cache[point].row + 1) < 0)
+ G_fatal_error(_("Unable to read raster map <%s> row %d"),
+ rast_opt->answer,
+ cache[point].row + 1);
+ }
+ }
}
else {
- if (G_get_d_raster_row(fd, dcell, cache[point].row) < 0)
+ if (G_get_d_raster_row(fd, dcell_row, cache[point].row) < 0)
G_fatal_error(_("Unable to read raster map <%s> row %d"),
rast_opt->answer, cache[point].row);
+
+ if (interp_flag->answer) {
+ if (cache[point].row <= 0)
+ G_set_null_value(prev_d_row, window.cols, out_type);
+ else {
+
+ if (G_get_d_raster_row
+ (fd, prev_d_row, cache[point].row - 1) < 0)
+ G_fatal_error(_("Unable to read raster map <%s> row %d"),
+ rast_opt->answer,
+ cache[point].row - 1);
+ }
+ if (cache[point].row + 1 > window.rows - 1)
+ G_set_null_value(next_d_row, window.cols, out_type);
+ else {
+ if (G_get_d_raster_row
+ (fd, next_d_row, cache[point].row + 1) < 0)
+ G_fatal_error(_("Unable to read raster map <%s> row %d"),
+ rast_opt->answer,
+ cache[point].row + 1);
+ }
+ }
}
}
cur_row = cache[point].row;
- if (out_type == CELL_TYPE) {
- cache[point].value = cell[cache[point].col];
+
+ if (!interp_flag->answer) {
+ if (out_type == CELL_TYPE)
+ cache[point].value = cell_row[cache[point].col];
+ else
+ cache[point].dvalue = dcell_row[cache[point].col];
}
else {
- cache[point].dvalue = dcell[cache[point].col];
- }
- } /* point loop */
+ /* do four-way IDW */
+ /* TODO: optimize, parallelize, and function-ize! */
+ double distance[4], weight[4];
+ double weightsum, valweight;
+ int col_offset, row_offset;
- /* Update table from cache */
- G_debug(1, "Updating db table");
+ weightsum = valweight = 0;
- /* select existing categories to array (array is sorted) */
- select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst);
- db_begin_transaction(driver);
+ if (cache[point].x <
+ G_col_to_easting(cache[point].col,
+ &window) + window.ew_res / 2)
+ col_offset = -1;
+ else
+ col_offset = +1;
- norec_cnt = update_cnt = upderr_cnt = dupl_cnt = 0;
+ if (cache[point].y >
+ G_row_to_northing(cache[point].row,
+ &window) - window.ns_res / 2)
+ row_offset = -1;
+ else
+ row_offset = +1;
- for (point = 0; point < point_cnt; point++) {
- if (cache[point].count > 1) {
- G_warning(_("More points (%d) of category %d, value set to 'NULL'"),
- cache[point].count, cache[point].cat);
- dupl_cnt++;
- }
- /* category exist in DB ? */
- cex =
- (int *)bsearch((void *)&(cache[point].cat), catexst, select,
- sizeof(int), srch_cat);
- if (cex == NULL) { /* cat does not exist in DB */
- norec_cnt++;
- G_warning(_("No record for category %d in table <%s>"),
- cache[point].cat, Fi->table);
- continue;
- }
+ distance[0] = G_distance(cache[point].x, cache[point].y,
+ G_col_to_easting(cache[point].col,
+ &window) +
+ window.ew_res / 2,
+ G_row_to_northing(cache[point].row,
+ &window) -
+ window.ns_res / 2);
- sprintf(buf, "update %s set %s = ", Fi->table, col_opt->answer);
+ distance[1] = G_distance(cache[point].x, cache[point].y,
+ G_col_to_easting(cache[point].col +
+ col_offset,
+ &window) +
+ window.ew_res / 2,
+ G_row_to_northing(cache[point].row,
+ &window) -
+ window.ns_res / 2);
- db_set_string(&stmt, buf);
+ if (row_offset == -1) {
+ distance[2] = G_distance(cache[point].x, cache[point].y,
+ G_col_to_easting(cache[point].col +
+ col_offset,
+ &window) +
+ window.ew_res / 2,
+ G_row_to_northing(cache[point].row -
+ 1,
+ &window) -
+ window.ns_res / 2);
+ distance[3] =
+ G_distance(cache[point].x, cache[point].y,
+ G_col_to_easting(cache[point].col,
+ &window) + window.ew_res / 2,
+ G_row_to_northing(cache[point].row - 1,
+ &window) -
+ window.ns_res / 2);
+ }
+ else {
+ distance[2] = G_distance(cache[point].x, cache[point].y,
+ G_col_to_easting(cache[point].col +
+ col_offset,
+ &window) +
+ window.ew_res / 2,
+ G_row_to_northing(cache[point].row + 1,
+ &window) -
+ window.ns_res / 2);
+ distance[3] =
+ G_distance(cache[point].x, cache[point].y,
+ G_col_to_easting(cache[point].col,
+ &window) + window.ew_res / 2,
+ G_row_to_northing(cache[point].row + 1,
+ &window) -
+ window.ns_res / 2);
+ }
- if (out_type == CELL_TYPE) {
- if (cache[point].count > 1 ||
- G_is_c_null_value(&cache[point].value)) {
- sprintf(buf, "NULL");
+
+ if (out_type == CELL_TYPE) {
+
+ CELL nearby_c_val[4];
+
+ /* avoid infinite weights */
+ if (distance[0] < GRASS_EPSILON) {
+ cache[point].value = cell_row[cache[point].col];
+ continue;
+ }
+
+ nearby_c_val[0] = cell_row[cache[point].col];
+
+ if (cache[point].col + col_offset < 0 ||
+ cache[point].col + col_offset >= window.cols) /* UNTESTED */
+ G_set_null_value(&nearby_c_val[1], 1, out_type); /* UNTESTED */
+ else
+ nearby_c_val[1] = cell_row[cache[point].col + col_offset];
+
+ if (row_offset == -1) {
+ if (cache[point].col + col_offset < 0 ||
+ cache[point].col + col_offset >= window.cols)
+ G_set_null_value(&nearby_c_val[2], 1, out_type);
+ else
+ nearby_c_val[2] =
+ prev_c_row[cache[point].col + col_offset];
+
+ nearby_c_val[3] = prev_c_row[cache[point].col];
+ }
+ else {
+ if (cache[point].col + col_offset < 0 ||
+ cache[point].col + col_offset >= window.cols)
+ G_set_null_value(&nearby_c_val[2], 1, out_type);
+ else
+ nearby_c_val[2] =
+ next_c_row[cache[point].col + col_offset];
+
+ nearby_c_val[3] = next_c_row[cache[point].col];
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (!G_is_null_value(&nearby_c_val[i], out_type)) {
+ weight[i] = 1.0 / (distance[i] * distance[i]);
+ weightsum += weight[i];
+ valweight += weight[i] * nearby_c_val[i];
+ }
+ }
+
+ cache[point].value = valweight / weightsum;
}
else {
- sprintf(buf, "%d ", cache[point].value);
+ DCELL nearby_d_val[4];
+
+ /* avoid infinite weights */
+ if (distance[0] < GRASS_EPSILON) {
+ cache[point].dvalue = dcell_row[cache[point].col];
+ continue;
+ }
+
+ nearby_d_val[0] = dcell_row[cache[point].col];
+
+ if (cache[point].col + col_offset < 0 ||
+ cache[point].col + col_offset >= window.cols)
+ G_set_null_value(&nearby_d_val[1], 1, out_type);
+ else
+
+ nearby_d_val[1] =
+ dcell_row[cache[point].col + col_offset];
+
+ if (row_offset == -1) {
+ if (cache[point].col + col_offset < 0 ||
+ cache[point].col + col_offset >= window.cols)
+ G_set_null_value(&nearby_d_val[2], 1, out_type);
+ else
+ nearby_d_val[2] =
+ prev_d_row[cache[point].col + col_offset];
+
+ nearby_d_val[3] = prev_d_row[cache[point].col];
+ }
+ else {
+ if (cache[point].col + col_offset < 0 ||
+ cache[point].col + col_offset >= window.cols)
+ G_set_null_value(&nearby_d_val[2], 1, out_type);
+ else
+ nearby_d_val[2] =
+ next_d_row[cache[point].col + col_offset];
+
+ nearby_d_val[3] = next_d_row[cache[point].col];
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (!G_is_null_value(&nearby_d_val[i], out_type)) {
+ weight[i] = 1.0 / (distance[i] * distance[i]);
+ weightsum += weight[i];
+ valweight += weight[i] * nearby_d_val[i];
+ }
+ }
+
+ cache[point].dvalue = valweight / weightsum;
}
}
- else { /* FCELL or DCELL */
- if (cache[point].count > 1 ||
- G_is_d_null_value(&cache[point].dvalue)) {
- sprintf(buf, "NULL");
+ } /* point loop */
+ G_close_cell(fd);
+
+ if (print_flag->answer) {
+ dupl_cnt = 0;
+
+ G_message("%s|value", Fi->key);
+
+ for (point = 0; point < point_cnt; point++) {
+ if (cache[point].count > 1) {
+ G_warning(_("Multiple points (%d) of category %d, value set to 'NULL'"),
+ cache[point].count, cache[point].cat); /* TODO: improve message */
+ dupl_cnt++;
}
- else {
- sprintf(buf, "%.*g", width, cache[point].dvalue);
+
+ fprintf(stdout, "%d|", cache[point].cat);
+
+ if (out_type == CELL_TYPE) {
+ if (cache[point].count > 1 ||
+ G_is_c_null_value(&cache[point].value)) {
+ fprintf(stdout, "*");
+ }
+ else
+ fprintf(stdout, "%d", cache[point].value);
}
+ else { /* FCELL or DCELL */
+ if (cache[point].count > 1 ||
+ G_is_d_null_value(&cache[point].dvalue)) {
+ fprintf(stdout, "*");
+ }
+ else
+ fprintf(stdout, "%.*g", width, cache[point].dvalue);
+ }
+ fprintf(stdout, "\n");
}
- db_append_string(&stmt, buf);
+ }
+ else {
+ /* Update table from cache */
+ G_debug(1, "Updating db table");
- sprintf(buf, " where %s = %d", Fi->key, cache[point].cat);
- db_append_string(&stmt, buf);
- /* user provides where condition: */
- if (where_opt->answer) {
- sprintf(buf, " AND %s", where_opt->answer);
+ /* select existing categories to array (array is sorted) */
+ select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst);
+
+ db_begin_transaction(driver);
+
+ norec_cnt = update_cnt = upderr_cnt = dupl_cnt = 0;
+
+ for (point = 0; point < point_cnt; point++) {
+ if (cache[point].count > 1) {
+ G_warning(_("Multiple points (%d) of category %d, value set to 'NULL'"),
+ cache[point].count, cache[point].cat);
+ dupl_cnt++;
+ }
+
+ G_percent(point, point_cnt, 2);
+
+ /* category exist in DB ? */
+ cex =
+ (int *)bsearch((void *)&(cache[point].cat), catexst, select,
+ sizeof(int), srch_cat);
+ if (cex == NULL) { /* cat does not exist in DB */
+ norec_cnt++;
+ G_warning(_("No record for category %d in table <%s>"),
+ cache[point].cat, Fi->table);
+ continue;
+ }
+
+ sprintf(buf, "update %s set %s = ", Fi->table, col_opt->answer);
+
+ db_set_string(&stmt, buf);
+
+ if (out_type == CELL_TYPE) {
+ if (cache[point].count > 1 ||
+ G_is_c_null_value(&cache[point].value)) {
+ sprintf(buf, "NULL");
+ }
+ else
+ sprintf(buf, "%d ", cache[point].value);
+ }
+ else { /* FCELL or DCELL */
+ if (cache[point].count > 1 ||
+ G_is_d_null_value(&cache[point].dvalue)) {
+ sprintf(buf, "NULL");
+ }
+ else
+ sprintf(buf, "%.*g", width, cache[point].dvalue);
+ }
db_append_string(&stmt, buf);
+
+ sprintf(buf, " where %s = %d", Fi->key, cache[point].cat);
+ db_append_string(&stmt, buf);
+ /* user provides where condition: */
+ if (where_opt->answer) {
+ sprintf(buf, " AND %s", where_opt->answer);
+ db_append_string(&stmt, buf);
+ }
+ G_debug(3, db_get_string(&stmt));
+
+ /* Update table */
+ if (db_execute_immediate(driver, &stmt) == DB_OK) {
+ update_cnt++;
+ }
+ else {
+ upderr_cnt++;
+ }
}
- G_debug(3, db_get_string(&stmt));
+ G_percent(1, 1, 1);
- /* Update table */
- if (db_execute_immediate(driver, &stmt) == DB_OK) {
- update_cnt++;
- }
- else {
- upderr_cnt++;
- }
+ G_debug(1, "Committing DB transaction");
+ db_commit_transaction(driver);
+ G_free(catexst);
+ db_close_database_shutdown_driver(driver);
+ db_free_string(&stmt);
}
- G_debug(1, "Committing DB transaction");
- db_commit_transaction(driver);
- G_free(catexst);
- db_close_database_shutdown_driver(driver);
- db_free_string(&stmt);
-
/* Report */
G_message(_("%d categories loaded from table"), select);
G_message(_("%d categories loaded from vector"), point_cnt);
- G_message(_("%d categories from vector missing in table"), norec_cnt);
+
+ if (!print_flag->answer)
+ G_message(_("%d categories from vector missing in table"), norec_cnt);
+
G_message(_("%d duplicate categories in vector"), dupl_cnt);
- if (!where_opt->answer)
- G_message(_("%d records updated"), update_cnt);
- G_message(_("%d update errors"), upderr_cnt);
+ if (!print_flag->answer) {
+ if (!where_opt->answer)
+ G_message(_("%d records updated"), update_cnt);
+ G_message(_("%d update errors"), upderr_cnt);
+ }
exit(EXIT_SUCCESS);
}
More information about the grass-commit
mailing list