vinput2d.c 10.0 KB

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