vinput2d.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /*!
  2. * \file vinput2d.c
  3. *
  4. * \author
  5. * Written by H. Mitasova, I. Kosinovsky, D. Gerdes Fall 1993
  6. * University of Illinois
  7. * US Army Construction Engineering Research Lab
  8. *
  9. * \author
  10. * Mitasova (University of Illinois),
  11. * I. Kosinovsky, (USA-CERL), and D.Gerdes (USA-CERL)
  12. *
  13. * \author modified by McCauley in August 1995
  14. * \author modified by Mitasova in August 1995
  15. * \author modofied by Mitasova in Nov 1999 (dmax fix)
  16. *
  17. * \copyright
  18. * (C) 1993-1999 by Helena Mitasova and the GRASS Development Team
  19. *
  20. * \copyright
  21. * This program is free software under the
  22. * GNU General Public License (>=v2).
  23. * Read the file COPYING that comes with GRASS
  24. * for details.
  25. */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include <grass/bitmap.h>
  30. #include <grass/linkm.h>
  31. #include <grass/gis.h>
  32. #include <grass/dbmi.h>
  33. #include <grass/vector.h>
  34. #include <grass/glocale.h>
  35. #include <grass/interpf.h>
  36. /*!
  37. * Insert into a quad tree
  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. * As z values may be used (in *Map*):
  43. * - z coordinates in 3D file -> field = 0
  44. * - categories -> field > 0, zcol = NULL
  45. * - attributes -> field > 0, zcol != NULL
  46. */
  47. int IL_vector_input_data_2d(struct interp_params *params, /*!< interpolation parameters */
  48. struct Map_info *Map, /*!< input vector map */
  49. int field, /*!< category field number */
  50. char *zcol, /*!< name of the column containing z values */
  51. char *scol, /*!< name of the column containing smooth values */
  52. struct tree_info *info, /*!< quadtree info */
  53. double *xmin, double *xmax,
  54. double *ymin, double *ymax,
  55. double *zmin, double *zmax,
  56. int *n_points, /*!< number of points used for interpolation */
  57. double *dmax /*!< max distance between points */
  58. )
  59. {
  60. double dmax2; /* max distance between points squared */
  61. double c1, c2, c3, c4;
  62. int i, line, k = 0;
  63. double ns_res, ew_res;
  64. int npoint, OUTRANGE;
  65. int totsegm;
  66. struct quaddata *data = (struct quaddata *)info->root->data;
  67. double xprev, yprev, zprev, x1, y1, z1, d1, xt, yt, z, sm;
  68. struct line_pnts *Points;
  69. struct line_cats *Cats;
  70. int times, j1, ltype, cat, zctype = 0, sctype = 0;
  71. struct field_info *Fi;
  72. dbDriver *driver;
  73. dbHandle handle;
  74. dbString stmt;
  75. dbCatValArray zarray, sarray;
  76. OUTRANGE = 0;
  77. npoint = 0;
  78. G_debug(2, "IL_vector_input_data_2d(): field = %d, zcol = %s, scol = %s",
  79. field, zcol, scol);
  80. ns_res = (data->ymax - data->y_orig) / data->n_rows;
  81. ew_res = (data->xmax - data->x_orig) / data->n_cols;
  82. dmax2 = *dmax * *dmax;
  83. Points = Vect_new_line_struct(); /* init line_pnts struct */
  84. Cats = Vect_new_cats_struct();
  85. if (field == 0 && !Vect_is_3d(Map))
  86. G_fatal_error(_("Vector map <%s> is not 3D"), Vect_get_full_name(Map));
  87. if (field > 0 && zcol != NULL) { /* open db driver */
  88. G_verbose_message(_("Loading data from attribute table ..."));
  89. Fi = Vect_get_field(Map, field);
  90. if (Fi == NULL)
  91. G_fatal_error(_("Database connection not defined for layer %d"),
  92. field);
  93. G_debug(3, " driver = %s database = %s table = %s", Fi->driver,
  94. Fi->database, Fi->table);
  95. db_init_handle(&handle);
  96. db_init_string(&stmt);
  97. driver = db_start_driver(Fi->driver);
  98. db_set_handle(&handle, Fi->database, NULL);
  99. if (db_open_database(driver, &handle) != DB_OK)
  100. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  101. Fi->database, Fi->driver);
  102. zctype = db_column_Ctype(driver, Fi->table, zcol);
  103. G_debug(3, " zcol C type = %d", zctype);
  104. if (zctype == -1)
  105. G_fatal_error(_("Column <%s> not found"),
  106. zcol);
  107. if (zctype != DB_C_TYPE_INT && zctype != DB_C_TYPE_DOUBLE)
  108. G_fatal_error(_("Data type of column <%s> must be numeric"), zcol);
  109. db_CatValArray_init(&zarray);
  110. G_debug(3, "RST SQL WHERE: %s", params->wheresql);
  111. db_select_CatValArray(driver, Fi->table, Fi->key, zcol,
  112. params->wheresql, &zarray);
  113. if (scol != NULL) {
  114. sctype = db_column_Ctype(driver, Fi->table, scol);
  115. G_debug(3, " scol C type = %d", sctype);
  116. if (sctype == -1)
  117. G_fatal_error(_("Column <%s> not found"), scol);
  118. if (sctype != DB_C_TYPE_INT && sctype != DB_C_TYPE_DOUBLE)
  119. G_fatal_error(_("Data type of column <%s> must be numeric"), scol);
  120. db_CatValArray_init(&sarray);
  121. db_select_CatValArray(driver, Fi->table, Fi->key, scol,
  122. params->wheresql, &sarray);
  123. }
  124. db_close_database_shutdown_driver(driver);
  125. }
  126. /* Lines without nodes */
  127. G_message(_("Reading features from vector map ..."));
  128. sm = 0;
  129. line = 1;
  130. while ((ltype = Vect_read_next_line(Map, Points, Cats)) != -2) {
  131. if (!(ltype & (GV_POINT | GV_LINE | GV_BOUNDARY)))
  132. continue;
  133. if (field > 0) { /* use cat or attribute */
  134. Vect_cat_get(Cats, field, &cat);
  135. /* line++; */
  136. if (zcol == NULL) { /* use categories */
  137. z = (double)cat;
  138. }
  139. else { /* read att from db */
  140. int ret, intval;
  141. if (zctype == DB_C_TYPE_INT) {
  142. ret = db_CatValArray_get_value_int(&zarray, cat, &intval);
  143. z = intval;
  144. }
  145. else { /* DB_C_TYPE_DOUBLE */
  146. ret = db_CatValArray_get_value_double(&zarray, cat, &z);
  147. }
  148. if (ret != DB_OK) {
  149. if (params->wheresql != NULL)
  150. /* G_message(_("Database record for cat %d not used due to SQL statement")); */
  151. /* do nothing in this case to not confuse user. Or implement second cat list */
  152. ;
  153. else
  154. G_warning(_("Database record for cat %d not found"),
  155. cat);
  156. continue;
  157. }
  158. if (scol != NULL) {
  159. if (sctype == DB_C_TYPE_INT) {
  160. ret =
  161. db_CatValArray_get_value_int(&sarray, cat,
  162. &intval);
  163. sm = intval;
  164. }
  165. else { /* DB_C_TYPE_DOUBLE */
  166. ret =
  167. db_CatValArray_get_value_double(&sarray, cat,
  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. /* Insert all points including nodes (end points) */
  177. for (i = 0; i < Points->n_points; i++) {
  178. if (field == 0)
  179. z = Points->z[i];
  180. process_point(Points->x[i], Points->y[i], z, sm, info,
  181. params->zmult, xmin, xmax, ymin, ymax, zmin,
  182. zmax, &npoint, &OUTRANGE, &k);
  183. }
  184. /* Check all segments */
  185. xprev = Points->x[0];
  186. yprev = Points->y[0];
  187. zprev = Points->z[0];
  188. for (i = 1; i < Points->n_points; i++) {
  189. /* compare the distance between current and previous */
  190. x1 = Points->x[i];
  191. y1 = Points->y[i];
  192. z1 = Points->z[i];
  193. xt = x1 - xprev;
  194. yt = y1 - yprev;
  195. d1 = (xt * xt + yt * yt);
  196. if ((d1 > dmax2) && (dmax2 != 0.)) {
  197. times = (int)(d1 / dmax2 + 0.5);
  198. for (j1 = 0; j1 < times; j1++) {
  199. xt = x1 - j1 * ((x1 - xprev) / times);
  200. yt = y1 - j1 * ((y1 - yprev) / times);
  201. if (field == 0)
  202. z = z1 - j1 * ((z1 - zprev) / times);
  203. process_point(xt, yt, z, sm, info, params->zmult,
  204. xmin, xmax, ymin, ymax, zmin, zmax, &npoint,
  205. &OUTRANGE, &k);
  206. }
  207. }
  208. xprev = x1;
  209. yprev = y1;
  210. zprev = z1;
  211. }
  212. }
  213. if (field > 0 && zcol != NULL)
  214. db_CatValArray_free(&zarray);
  215. if (scol != NULL) {
  216. db_CatValArray_free(&sarray);
  217. }
  218. c1 = *xmin - data->x_orig;
  219. c2 = data->xmax - *xmax;
  220. c3 = *ymin - data->y_orig;
  221. c4 = data->ymax - *ymax;
  222. if ((c1 > 5 * ew_res) || (c2 > 5 * ew_res) || (c3 > 5 * ns_res) ||
  223. (c4 > 5 * ns_res)) {
  224. static int once = 0;
  225. if (!once) {
  226. once = 1;
  227. G_warning(_("Strip exists with insufficient data"));
  228. }
  229. }
  230. totsegm =
  231. translate_quad(info->root, data->x_orig, data->y_orig, *zmin, 4);
  232. if (!totsegm)
  233. return 0;
  234. data->x_orig = 0;
  235. data->y_orig = 0;
  236. /* G_read_vector_timestamp(name,mapset,ts); */
  237. if (OUTRANGE > 0)
  238. G_warning(_("There are points outside specified 2D/3D region - %d points ignored"),
  239. OUTRANGE);
  240. if (npoint > 0)
  241. G_important_message(_("Ignoring %d points (too dense)"), npoint);
  242. npoint = k - npoint - OUTRANGE;
  243. if (npoint < params->kmin) {
  244. if (npoint != 0) {
  245. G_warning(_("%d points given for interpolation (after thinning) is less than given NPMIN=%d"),
  246. npoint, params->kmin);
  247. params->kmin = npoint;
  248. }
  249. else {
  250. G_warning(_("Zero points in the given region"));
  251. return -1;
  252. }
  253. }
  254. if (npoint > params->KMAX2 && params->kmin <= params->kmax) {
  255. G_warning(_("Segmentation parameters set to invalid values: npmin= %d, segmax= %d "
  256. "for smooth connection of segments, npmin > segmax (see manual)"),
  257. params->kmin, params->kmax);
  258. return -1;
  259. }
  260. if (npoint < params->KMAX2 && params->kmax != params->KMAX2)
  261. G_warning(_("There are less than %d points for interpolation. No "
  262. "segmentation is necessary, to run the program faster set "
  263. "segmax=%d (see manual)"), params->KMAX2, params->KMAX2);
  264. G_verbose_message(_("Number of points from vector map %d"), k);
  265. G_verbose_message(_("Number of points outside of 2D/3D region %d"),
  266. OUTRANGE);
  267. G_verbose_message(_("Number of points being used %d"), npoint);
  268. *n_points = npoint;
  269. return (totsegm);
  270. }
  271. int process_point(double x, double y, double z, double sm, struct tree_info *info, /* quadtree info */
  272. double zmult, /* multiplier for z-values */
  273. double *xmin,
  274. double *xmax,
  275. double *ymin,
  276. double *ymax,
  277. double *zmin,
  278. double *zmax, int *npoint, int *OUTRANGE, int *total)
  279. {
  280. struct triple *point;
  281. double c1, c2, c3, c4;
  282. int a;
  283. static int first_time = 1;
  284. struct quaddata *data = (struct quaddata *)info->root->data;
  285. (*total)++;
  286. z = z * zmult;
  287. c1 = x - data->x_orig;
  288. c2 = data->xmax - x;
  289. c3 = y - data->y_orig;
  290. c4 = data->ymax - y;
  291. if (!((c1 >= 0) && (c2 >= 0) && (c3 >= 0) && (c4 >= 0))) {
  292. if (!(*OUTRANGE)) {
  293. G_warning(_("Some points outside of region (ignored)"));
  294. }
  295. (*OUTRANGE)++;
  296. }
  297. else {
  298. if (!(point = quad_point_new(x, y, z, sm))) {
  299. G_warning(_("Unable to allocate memory"));
  300. return -1;
  301. }
  302. a = MT_insert(point, info, info->root, 4);
  303. if (a == 0) {
  304. (*npoint)++;
  305. }
  306. if (a < 0) {
  307. G_warning(_("Unable to insert %f,%f,%f a = %d"), x, y, z, a);
  308. return -1;
  309. }
  310. free(point);
  311. if (first_time) {
  312. first_time = 0;
  313. *xmin = x;
  314. *ymin = y;
  315. *zmin = z;
  316. *xmax = x;
  317. *ymax = y;
  318. *zmax = z;
  319. }
  320. *xmin = amin1(*xmin, x);
  321. *ymin = amin1(*ymin, y);
  322. *zmin = amin1(*zmin, z);
  323. *xmax = amax1(*xmax, x);
  324. *ymax = amax1(*ymax, y);
  325. *zmax = amax1(*zmax, z);
  326. }
  327. return 1;
  328. }