GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vinput2d.c
Go to the documentation of this file.
1 
2 /*-
3  * Written by H. Mitasova, I. Kosinovsky, D. Gerdes Fall 1993
4  * University of Illinois
5  * US Army Construction Engineering Research Lab
6  * Copyright 1993, H. Mitasova (University of Illinois),
7  * I. Kosinovsky, (USA-CERL), and D.Gerdes (USA-CERL)
8  *
9  * modified by McCauley in August 1995
10  * modified by Mitasova in August 1995
11  * modofied by Mitasova in Nov 1999 (dmax fix)
12  *
13  */
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <math.h>
18 #include <grass/bitmap.h>
19 #include <grass/linkm.h>
20 #include <grass/gis.h>
21 #include <grass/dbmi.h>
22 #include <grass/Vect.h>
23 #include <grass/glocale.h>
24 
25 #include <grass/interpf.h>
26 
27 int IL_vector_input_data_2d(struct interp_params *params, struct Map_info *Map, /* input vector map */
28  /* as z values may be used: 1) z coordinates in 3D file -> field = 0
29  * 2) categories -> field > 0, zcol = NULL
30  * 3) attributes -> field > 0, zcol != NULL */
31  int field, /* category field number */
32  char *zcol, /* name of the column containing z values */
33  char *scol, /* name of the column containing smooth values */
34  struct tree_info *info, /* quadtree info */
35  double *xmin, double *xmax, double *ymin, double *ymax, double *zmin, double *zmax, int *n_points, /* number of points used for interpolation */
36  double *dmax)
37 
38 /*
39  * Inserts input data inside the region into a quad tree. Also translates
40  * data. Returns number of segments in the quad tree.
41  */
42 {
43  double dmax2; /* max distance between points squared */
44  double c1, c2, c3, c4;
45  int i, line, k = 0, nnodes;
46  double ns_res, ew_res;
47  int npoint, OUTRANGE;
48  int totsegm;
49  struct quaddata *data = (struct quaddata *)info->root->data;
50  double xprev, yprev, zprev, x1, y1, z1, d1, xt, yt, z, sm;
51  struct line_pnts *Points;
52  struct line_cats *Cats;
53  int times, j1, k1, ltype, cat, zctype = 0, sctype = 0;
54  struct field_info *Fi;
55  dbDriver *driver;
56  dbHandle handle;
57  dbString stmt;
58  dbCatValArray zarray, sarray;
59 
60  OUTRANGE = 0;
61  npoint = 0;
62 
63  G_debug(2, "IL_vector_input_data_2d(): field = %d, zcol = %s, scol = %s",
64  field, zcol, scol);
65  ns_res = (data->ymax - data->y_orig) / data->n_rows;
66  ew_res = (data->xmax - data->x_orig) / data->n_cols;
67  dmax2 = *dmax * *dmax;
68 
69  Points = Vect_new_line_struct(); /* init line_pnts struct */
70  Cats = Vect_new_cats_struct();
71 
72  if (field == 0 && !Vect_is_3d(Map))
73  G_fatal_error(_("Vector map <%s> is not 3D"), Vect_get_full_name(Map));
74 
75  if (field > 0 && zcol != NULL) { /* open db driver */
76  G_verbose_message(_("Loading data from attribute table ..."));
77  Fi = Vect_get_field(Map, field);
78  if (Fi == NULL)
79  G_fatal_error(_("Database connection not defined for layer %d"),
80  field);
81  G_debug(3, " driver = %s database = %s table = %s", Fi->driver,
82  Fi->database, Fi->table);
83  db_init_handle(&handle);
84  db_init_string(&stmt);
85  driver = db_start_driver(Fi->driver);
86  db_set_handle(&handle, Fi->database, NULL);
87  if (db_open_database(driver, &handle) != DB_OK)
88  G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
89  Fi->database, Fi->driver);
90 
91  zctype = db_column_Ctype(driver, Fi->table, zcol);
92  G_debug(3, " zcol C type = %d", zctype);
93  if (zctype == -1)
94  G_fatal_error(_("Column <%s> not found"),
95  zcol);
96  if (zctype != DB_C_TYPE_INT && zctype != DB_C_TYPE_DOUBLE)
97  G_fatal_error(_("Data type of column <%s> must be numeric"), zcol);
98 
99  db_CatValArray_init(&zarray);
100  G_debug(3, "RST SQL WHERE: %s", params->wheresql);
101  db_select_CatValArray(driver, Fi->table, Fi->key, zcol,
102  params->wheresql, &zarray);
103 
104  if (scol != NULL) {
105  sctype = db_column_Ctype(driver, Fi->table, scol);
106  G_debug(3, " scol C type = %d", sctype);
107  if (sctype == -1)
108  G_fatal_error(_("Column <%s> not found"), scol);
109  if (sctype != DB_C_TYPE_INT && sctype != DB_C_TYPE_DOUBLE)
110  G_fatal_error(_("Data type of column <%s> must be numeric"), scol);
111 
112  db_CatValArray_init(&sarray);
113  db_select_CatValArray(driver, Fi->table, Fi->key, scol,
114  params->wheresql, &sarray);
115  }
116 
118  }
119 
120  /* Lines without nodes */
121  G_message(_("Reading features from vector map ..."));
122  sm = 0;
123  line = 1;
124  while ((ltype = Vect_read_next_line(Map, Points, Cats)) != -2) {
125 
126  if (!(ltype & (GV_POINT | GV_LINE | GV_BOUNDARY)))
127  continue;
128 
129  if (field > 0) { /* use cat or attribute */
130  Vect_cat_get(Cats, field, &cat);
131 
132  /* line++; */
133  if (zcol == NULL) { /* use categories */
134  z = (double)cat;
135  }
136  else { /* read att from db */
137  int ret, intval;
138 
139  if (zctype == DB_C_TYPE_INT) {
140  ret = db_CatValArray_get_value_int(&zarray, cat, &intval);
141  z = intval;
142  }
143  else { /* DB_C_TYPE_DOUBLE */
144  ret = db_CatValArray_get_value_double(&zarray, cat, &z);
145  }
146 
147  if (ret != DB_OK) {
148  if (params->wheresql != NULL)
149  /* G_message(_("Database record for cat %d not used due to SQL statement")); */
150  /* do nothing in this case to not confuse user. Or implement second cat list */
151  ;
152  else
153  G_warning(_("Database record for cat %d not found"),
154  cat);
155  continue;
156  }
157 
158  if (scol != NULL) {
159  if (sctype == DB_C_TYPE_INT) {
160  ret =
162  &intval);
163  sm = intval;
164  }
165  else { /* DB_C_TYPE_DOUBLE */
166  ret =
168  &sm);
169  }
170  if (sm < 0.0)
171  G_fatal_error(_("Negative value of smoothing detected: sm must be >= 0"));
172  }
173  G_debug(5, " z = %f sm = %f", z, sm);
174  }
175  }
176 
177  if (Vect_level(Map) == 1) {
178  /* Insert all points including nodes (end points) */
179  for (i = 0; i < Points->n_points; i++) {
180  if (field == 0)
181  z = Points->z[i];
182  process_point(Points->x[i], Points->y[i], z, sm, info,
183  params->zmult, xmin, xmax, ymin, ymax, zmin,
184  zmax, &npoint, &OUTRANGE, &k);
185 
186  }
187  }
188  else {
189  /* Insert all points except nodes (end points) */
190  for (i = 1; i < Points->n_points - 1; i++) {
191  if (field == 0)
192  z = Points->z[i];
193  process_point(Points->x[i], Points->y[i], z, sm, info,
194  params->zmult, xmin, xmax, ymin, ymax, zmin,
195  zmax, &npoint, &OUTRANGE, &k);
196 
197  }
198  }
199 
200  /* Check all segments */
201  xprev = Points->x[0];
202  yprev = Points->y[0];
203  zprev = Points->z[0];
204  for (i = 1; i < Points->n_points; i++) {
205  /* compare the distance between current and previous */
206  x1 = Points->x[i];
207  y1 = Points->y[i];
208  z1 = Points->z[i];
209 
210  xt = x1 - xprev;
211  yt = y1 - yprev;
212  d1 = (xt * xt + yt * yt);
213  if ((d1 > dmax2) && (dmax2 != 0.)) {
214  times = (int)(d1 / dmax2 + 0.5);
215  for (j1 = 0; j1 < times; j1++) {
216  xt = x1 - j1 * ((x1 - xprev) / times);
217  yt = y1 - j1 * ((y1 - yprev) / times);
218  if (field == 0)
219  z = z1 - j1 * ((z1 - zprev) / times);
220 
221  process_point(xt, yt, z, sm, info, params->zmult,
222  xmin, xmax, ymin, ymax, zmin, zmax, &npoint,
223  &OUTRANGE, &k);
224  }
225  }
226  xprev = x1;
227  yprev = y1;
228  zprev = z1;
229  }
230  }
231 
232  /* Process all nodes */
233  G_message(_("Reading nodes from vector map ..."));
234  nnodes = Vect_get_num_nodes(Map);
235  for (k1 = 1; k1 <= nnodes; k1++) {
236  G_debug(5, " node %d", k1);
237  G_percent(k1, nnodes, 1);
238  Vect_get_node_coor(Map, k1, &x1, &y1, &z);
239 
240  /* TODO: check more lines ? */
241  if (field > 0) {
242  line = abs(Vect_get_node_line(Map, k1, 0));
243  ltype = Vect_read_line(Map, NULL, Cats, line);
244  Vect_cat_get(Cats, field, &cat);
245  if (zcol == NULL) { /* use categories */
246  if (cat < 0)
247  continue;
248  z = (double)cat;
249  }
250  else { /* read att from db */
251  int ret, intval;
252 
253  if (cat == 0)
254  continue;
255 
256  if (zctype == DB_C_TYPE_INT) {
257  ret = db_CatValArray_get_value_int(&zarray, cat, &intval);
258  z = intval;
259  }
260  else { /* DB_C_TYPE_DOUBLE */
261  ret = db_CatValArray_get_value_double(&zarray, cat, &z);
262  }
263 
264  if (ret != DB_OK) {
265  if (params->wheresql != NULL)
266  /* G_message(_("Database record for cat %d not used due to SQL statement")); */
267  /* do nothing in this case to not confuse user. Or implement second cat list */
268  ;
269  else
270  G_warning(_("Database record for cat %d not found"),
271  cat);
272  continue;
273  }
274 
275  if (scol != NULL) {
276  if (sctype == DB_C_TYPE_INT) {
277  ret =
279  &intval);
280  sm = intval;
281  }
282  else { /* DB_C_TYPE_DOUBLE */
283  ret =
285  &sm);
286  }
287  if (sm < 0.0)
288  G_fatal_error(_("Negative value of smoothing detected: sm must be >= 0"));
289  }
290  G_debug(5, " z = %f sm = %f", z, sm);
291  }
292  }
293 
294  process_point(x1, y1, z, sm, info, params->zmult, xmin, xmax, ymin,
295  ymax, zmin, zmax, &npoint, &OUTRANGE, &k);
296  }
297 
298  if (field > 0 && zcol != NULL)
299  db_CatValArray_free(&zarray);
300  if (scol != NULL) {
301  db_CatValArray_free(&sarray);
302  }
303 
304  c1 = *xmin - data->x_orig;
305  c2 = data->xmax - *xmax;
306  c3 = *ymin - data->y_orig;
307  c4 = data->ymax - *ymax;
308  if ((c1 > 5 * ew_res) || (c2 > 5 * ew_res) || (c3 > 5 * ns_res) ||
309  (c4 > 5 * ns_res)) {
310  static int once = 0;
311 
312  if (!once) {
313  once = 1;
314  G_warning(_("Strip exists with insufficient data"));
315  }
316  }
317 
318  totsegm =
319  translate_quad(info->root, data->x_orig, data->y_orig, *zmin, 4);
320  if (!totsegm)
321  return 0;
322  data->x_orig = 0;
323  data->y_orig = 0;
324 
325  /* G_read_vector_timestamp(name,mapset,ts); */
326 
327  if (OUTRANGE > 0)
328  G_warning(_("There are points outside specified 2D/3D region - %d points ignored"),
329  OUTRANGE);
330  if (npoint > 0)
331  G_important_message(_("Ignoring %d points (too dense)"), npoint);
332  npoint = k - npoint - OUTRANGE;
333  if (npoint < params->kmin) {
334  if (npoint != 0) {
335  G_warning(_("%d points given for interpolation (after thinning) is less than given NPMIN=%d"),
336  npoint, params->kmin);
337  params->kmin = npoint;
338  }
339  else {
340  G_warning(_("Zero points in the given region"));
341  return -1;
342  }
343  }
344  if (npoint > params->KMAX2 && params->kmin <= params->kmax) {
345  G_warning(_("Segmentation parameters set to invalid values: npmin= %d, segmax= %d "
346  "for smooth connection of segments, npmin > segmax (see manual)"),
347  params->kmin, params->kmax);
348  return -1;
349  }
350  if (npoint < params->KMAX2 && params->kmax != params->KMAX2)
351  G_warning(_("There are less than %d points for interpolation. No "
352  "segmentation is necessary, to run the program faster set "
353  "segmax=%d (see manual)"), params->KMAX2, params->KMAX2);
354 
355  G_message(_("Number of points from vector map %d"), k);
356  G_verbose_message(_("Number of points outside of 2D/3D region %d"),
357  OUTRANGE);
358  G_message(_("Number of points being used %d"), npoint);
359 
360  *n_points = npoint;
361  return (totsegm);
362 }
363 
364 int process_point(double x, double y, double z, double sm, struct tree_info *info, /* quadtree info */
365  double zmult, /* multiplier for z-values */
366  double *xmin,
367  double *xmax,
368  double *ymin,
369  double *ymax,
370  double *zmin,
371  double *zmax, int *npoint, int *OUTRANGE, int *total)
372 {
373  struct triple *point;
374  double c1, c2, c3, c4;
375  int a;
376  static int first_time = 1;
377  struct quaddata *data = (struct quaddata *)info->root->data;
378 
379 
380  (*total)++;
381 
382 
383  z = z * zmult;
384  c1 = x - data->x_orig;
385  c2 = data->xmax - x;
386  c3 = y - data->y_orig;
387  c4 = data->ymax - y;
388 
389  if (!((c1 >= 0) && (c2 >= 0) && (c3 >= 0) && (c4 >= 0))) {
390  if (!(*OUTRANGE)) {
391  G_warning(_("Some points outside of region (ignored)"));
392  }
393  (*OUTRANGE)++;
394  }
395  else {
396  if (!(point = quad_point_new(x, y, z, sm))) {
397  G_warning(_("Unable to allocate memory"));
398  return -1;
399  }
400  a = MT_insert(point, info, info->root, 4);
401  if (a == 0) {
402  (*npoint)++;
403  }
404  if (a < 0) {
405  G_warning(_("Unable to insert %f,%f,%f a = %d"), x, y, z, a);
406  return -1;
407  }
408  free(point);
409  if (first_time) {
410  first_time = 0;
411  *xmin = x;
412  *ymin = y;
413  *zmin = z;
414  *xmax = x;
415  *ymax = y;
416  *zmax = z;
417  }
418  *xmin = amin1(*xmin, x);
419  *ymin = amin1(*ymin, y);
420  *zmin = amin1(*zmin, z);
421  *xmax = amax1(*xmax, x);
422  *ymax = amax1(*ymax, y);
423  *zmax = amax1(*zmax, z);
424  }
425  return 1;
426 }
def info
Display an informational message using g.message -i
Definition: core.py:339
int db_select_CatValArray(dbDriver *driver, const char *tab, const char *key, const char *col, const char *where, dbCatValArray *cvarr)
Select pairs key/value to array, values are sorted by key (must be integer)
int db_column_Ctype(dbDriver *driver, const char *tab, const char *col)
Get column ctype.
int db_CatValArray_get_value_int(dbCatValArray *arr, int key, int *val)
Find value (integer) by key.
struct field_info * Vect_get_field(struct Map_info *Map, int field)
Get information about link to database.
Definition: field.c:404
int Vect_get_node_line(struct Map_info *Map, int node, int line)
Get line id for node line index.
Definition: level_two.c:316
double xmax
Definition: dataquad.c:293
double y_orig
Definition: dataquad.h:33
struct triple * point
Definition: dataquad.c:294
int Vect_read_next_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c)
Read next vector feature (level 1 and 2)
int db_close_database_shutdown_driver(dbDriver *driver)
Close driver/database connection.
Definition: db.c:62
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
Definition: line.c:57
void G_important_message(const char *msg,...)
Print a message to stderr even in brief mode (verbosity=1)
double xmin
Definition: dataquad.c:293
int Vect_level(struct Map_info *Map)
Returns level that Map is opened at.
Definition: level.c:33
void db_CatValArray_free(dbCatValArray *arr)
Definition: value.c:348
double amax1(double, double)
Definition: minmax.c:54
int process_point(double, double, double, double, struct tree_info *, double, double *, double *, double *, double *, double *, double *, int *, int *, int *)
Definition: vinput2d.c:364
double ymin
Definition: dataquad.c:293
int y
Definition: plot.c:34
double x_orig
Definition: dataquad.h:32
int translate_quad(struct multtree *tree, double numberx, double numbery, double numberz, int n_leafs)
Definition: input2d.c:77
struct triple * quad_point_new(double x, double y, double z, double sm)
Definition: dataquad.c:18
const char * Vect_get_full_name(struct Map_info *Map)
Get full map name.
int db_CatValArray_get_value_double(dbCatValArray *arr, int key, double *val)
Find value (double) by key.
struct quaddata * data
Definition: qtree.h:40
int G_percent(long n, long d, int s)
Print percent complete messages.
Definition: percent.c:63
int Vect_is_3d(struct Map_info *Map)
Check if vector map is 3D (with z)
tuple data
void G_verbose_message(const char *msg,...)
Print a message to stderr but only if module is in verbose mode.
Definition: lib/gis/error.c:95
void G_message(const char *msg,...)
Print a message to stderr.
Definition: lib/gis/error.c:74
int
Definition: g3dcolor.c:48
int db_set_handle(dbHandle *handle, const char *dbName, const char *dbSchema)
Definition: handle.c:22
double ymax
Definition: dataquad.c:293
double ymax
Definition: dataquad.h:35
double amin1(double, double)
Definition: minmax.c:67
void db_CatValArray_init(dbCatValArray *arr)
Definition: value.c:335
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
return NULL
Definition: dbfopen.c:1394
Definition: driver.h:25
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
tuple Map
Definition: render.py:1310
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
void db_init_handle(dbHandle *handle)
Definition: handle.c:10
void free(void *)
double zmult
Definition: interpf.h:40
int MT_insert(struct triple *point, struct tree_info *info, struct multtree *tree, int n_leafs)
Definition: qtree.c:78
CELL cat
Definition: g3dcats.c:90
double xmax
Definition: dataquad.h:34
int Vect_get_node_coor(struct Map_info *map, int num, double *x, double *y, double *z)
Get node coordinates.
Definition: level_two.c:223
int n_rows
Definition: dataquad.h:36
int db_open_database(dbDriver *driver, dbHandle *handle)
Open database connection.
Definition: c_opendb.c:27
int Vect_get_num_nodes(struct Map_info *map)
Get number of nodes in vector map.
Definition: level_two.c:29
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
struct multtree * root
Definition: qtree.h:35
DCELL dmax
Definition: g3dcolor.c:53
int IL_vector_input_data_2d(struct interp_params *, struct Map_info *, int, char *, char *, struct tree_info *, double *, double *, double *, double *, double *, double *, int *, double *)
Definition: vinput2d.c:27
int n_cols
Definition: dataquad.h:37
dbDriver * db_start_driver(const char *name)
Initialize a new dbDriver for db transaction.
Definition: start.c:43
char * wheresql
Definition: interpf.h:71
void db_init_string(dbString *x)
Definition: string.c:11
int Vect_read_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature.
int Vect_cat_get(struct line_cats *Cats, int field, int *cat)
Get first found category of given field.