interp2d.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*!
  2. * \file interp2d.c
  3. *
  4. * \author
  5. * Lubos Mitas (original program and various modifications)
  6. *
  7. * \author
  8. * H. Mitasova,
  9. * I. Kosinovsky, D. Gerdes,
  10. * D. McCauley
  11. * (GRASS4.1 version of the program and GRASS4.2 modifications)
  12. *
  13. * \author
  14. * L. Mitas,
  15. * H. Mitasova,
  16. * I. Kosinovsky,
  17. * D.Gerdes,
  18. * D. McCauley
  19. * (1993, 1995)
  20. *
  21. * \author modified by McCauley in August 1995
  22. * \author modified by Mitasova in August 1995, Nov. 1996
  23. * \author
  24. * bug fixes(mask) and modification for variable smoothing
  25. * Mitasova (Jan 1997)
  26. *
  27. * \copyright
  28. * (C) 1993-1999 by Lubos Mitas and the GRASS Development Team
  29. *
  30. * \copyright
  31. * This program is free software under the
  32. * GNU General Public License (>=v2).
  33. * Read the file COPYING that comes with GRASS
  34. * for details.
  35. */
  36. #include <stdio.h>
  37. #include <math.h>
  38. #include <unistd.h>
  39. #include <grass/gis.h>
  40. #include <grass/raster.h>
  41. #include <grass/glocale.h>
  42. #include <grass/bitmap.h>
  43. #include <grass/interpf.h>
  44. #define CEULER .57721566
  45. /*!
  46. * Calculates grid values for a given segment
  47. *
  48. * Calculates grid for the given segment represented by data (contains
  49. * n_rows, n_cols, ew_res,ns_res, and all points inside + overlap) using
  50. * solutions of system of linear equations and interpolating functions
  51. * interp() and interpder(). Also calls secpar() to compute slope, aspect
  52. * and curvatures if required.
  53. *
  54. * *ertot* can be also called *RMS deviation of the interpolated surface*
  55. */
  56. int IL_grid_calc_2d(struct interp_params *params,
  57. struct quaddata *data, /*!< given segment */
  58. struct BM *bitmask, /*!< bitmask */
  59. double zmin, double zmax, /*!< min and max input z-values */
  60. double *zminac, double *zmaxac, /*!< min and max interp. z-values */
  61. double *gmin, double *gmax, /*!< min and max interp. slope val. */
  62. double *c1min, double *c1max, /*!< min and max interp. curv. val. */
  63. double *c2min, double *c2max, /*!< min and max interp. curv. val. */
  64. double *ertot, /*!< total interpolating func. error */
  65. double *b, /*!< solutions of linear equations */
  66. off_t offset1, /*!< offset for temp file writing */
  67. double dnorm)
  68. {
  69. /*
  70. * C C INTERPOLATION BY FUNCTIONAL METHOD : TPS + complete regul.
  71. * c
  72. */
  73. double x_or = data->x_orig;
  74. double y_or = data->y_orig;
  75. int n_rows = data->n_rows;
  76. int n_cols = data->n_cols;
  77. int n_points = data->n_points;
  78. struct triple *points;
  79. static double *w2 = NULL;
  80. static double *w = NULL;
  81. int cond1, cond2;
  82. double r;
  83. double stepix, stepiy, xx, xg, yg, xx2;
  84. double rfsta2, /* cons, cons1, */ wm, dx, dy, dxx, dyy, dxy, h, bmgd1,
  85. bmgd2;
  86. double r2, gd1, gd2; /* for interpder() */
  87. int n1, k, l, m;
  88. int ngstc, nszc, ngstr, nszr;
  89. double zz;
  90. int bmask = 1;
  91. static int first_time_z = 1;
  92. off_t offset, offset2;
  93. double fstar2 = params->fi * params->fi / 4.;
  94. double tfsta2, tfstad;
  95. double ns_res, ew_res;
  96. double rsin = 0, rcos = 0, teta, scale = 0; /*anisotropy parameters - added by JH 2002 */
  97. double xxr, yyr;
  98. if (params->theta) {
  99. teta = params->theta / M_R2D; /* deg to rad */
  100. rsin = sin(teta);
  101. rcos = cos(teta);
  102. }
  103. if (params->scalex)
  104. scale = params->scalex;
  105. ns_res = (((struct quaddata *)(data))->ymax -
  106. ((struct quaddata *)(data))->y_orig) / data->n_rows;
  107. ew_res = (((struct quaddata *)(data))->xmax -
  108. ((struct quaddata *)(data))->x_orig) / data->n_cols;
  109. /* tfsta2 = fstar2 * 2.; modified after removing normalization of z */
  110. tfsta2 = (fstar2 * 2.) / dnorm;
  111. tfstad = tfsta2 / dnorm;
  112. points = data->points;
  113. /*
  114. * normalization
  115. */
  116. stepix = ew_res / dnorm;
  117. stepiy = ns_res / dnorm;
  118. cond2 = ((params->adxx != NULL) || (params->adyy != NULL) ||
  119. (params->adxy != NULL));
  120. cond1 = ((params->adx != NULL) || (params->ady != NULL) || cond2);
  121. if (!w) {
  122. if (!(w = (double *)G_malloc(sizeof(double) * (params->KMAX2 + 9)))) {
  123. G_warning(_("Out of memory"));
  124. return -1;
  125. }
  126. }
  127. if (!w2) {
  128. if (!(w2 = (double *)G_malloc(sizeof(double) * (params->KMAX2 + 9)))) {
  129. G_warning(_("Out of memory"));
  130. return -1;
  131. }
  132. }
  133. n1 = n_points + 1;
  134. /*
  135. * C C INTERPOLATION * MOST INNER LOOPS ! C
  136. */
  137. ngstc = (int)(x_or / ew_res + 0.5) + 1;
  138. nszc = ngstc + n_cols - 1;
  139. ngstr = (int)(y_or / ns_res + 0.5) + 1;
  140. nszr = ngstr + n_rows - 1;
  141. for (k = ngstr; k <= nszr; k++) {
  142. offset = offset1 * (k - 1); /* rows offset */
  143. yg = (k - ngstr) * stepiy + stepiy / 2.; /* fixed by J.H. in July 01 */
  144. for (m = 1; m <= n_points; m++) {
  145. wm = yg - points[m - 1].y;
  146. w[m] = wm;
  147. w2[m] = wm * wm;
  148. }
  149. for (l = ngstc; l <= nszc; l++) {
  150. if (bitmask != NULL)
  151. /* if(params->maskmap != NULL) PK Apr 03 MASK support */
  152. bmask = BM_get(bitmask, l - 1, k - 1); /*fixed by helena jan 97 */
  153. /* if(bmask==0 || bmask==-1) fprintf(stderr, "bmask=%d, at (%d,%d)\n", bmask, l, k); */
  154. xg = (l - ngstc) * stepix + stepix / 2.; /*fixed by J.H. in July 01 */
  155. dx = 0.;
  156. dy = 0.;
  157. dxx = 0.;
  158. dyy = 0.;
  159. dxy = 0.;
  160. zz = 0.;
  161. if (bmask == 1) { /* compute everything for area which is
  162. * not masked out */
  163. h = b[0];
  164. for (m = 1; m <= n_points; m++) {
  165. xx = xg - points[m - 1].x;
  166. if ((params->theta) && (params->scalex)) {
  167. /* we run anisotropy */
  168. xxr = xx * rcos + w[m] * rsin;
  169. yyr = w[m] * rcos - xx * rsin;
  170. xx2 = xxr * xxr;
  171. w2[m] = yyr * yyr;
  172. r2 = scale * xx2 + w2[m];
  173. r = r2;
  174. rfsta2 = scale * xx2 + w2[m];
  175. }
  176. else {
  177. xx2 = xx * xx;
  178. r2 = xx2 + w2[m];
  179. r = r2;
  180. rfsta2 = xx2 + w2[m];
  181. }
  182. h = h + b[m] * params->interp(r, params->fi);
  183. if (cond1) {
  184. if (!params->interpder(r, params->fi, &gd1, &gd2))
  185. return -1;
  186. bmgd1 = b[m] * gd1;
  187. dx = dx + bmgd1 * xx;
  188. dy = dy + bmgd1 * w[m];
  189. if (cond2) {
  190. bmgd2 = b[m] * gd2;
  191. dxx = dxx + bmgd2 * xx2 + bmgd1;
  192. dyy = dyy + bmgd2 * w2[m] + bmgd1;
  193. dxy = dxy + bmgd2 * xx * w[m];
  194. }
  195. }
  196. }
  197. /* zz = (h * dnorm) + zmin; replaced by helena jan. 97 due to removing norma
  198. lization of z and zm in segmen2d.c */
  199. zz = h + zmin;
  200. if (first_time_z) {
  201. first_time_z = 0;
  202. *zmaxac = *zminac = zz;
  203. }
  204. *zmaxac = amax1(zz, *zmaxac);
  205. *zminac = amin1(zz, *zminac);
  206. if ((zz > zmax + 0.1 * (zmax - zmin))
  207. || (zz < zmin - 0.1 * (zmax - zmin))) {
  208. static int once = 0;
  209. if (!once) {
  210. once = 1;
  211. G_warning(_("Overshoot - increase in tension suggested. "
  212. "Overshoot occurs at (%d,%d) cell. "
  213. "Z-value %f, zmin %f, zmax %f."),
  214. l, k, zz, zmin, zmax);
  215. }
  216. }
  217. params->az[l] = (FCELL) zz;
  218. if (cond1) {
  219. params->adx[l] = (FCELL) (-dx * tfsta2);
  220. params->ady[l] = (FCELL) (-dy * tfsta2);
  221. if (cond2) {
  222. params->adxx[l] = (FCELL) (-dxx * tfstad);
  223. params->adyy[l] = (FCELL) (-dyy * tfstad);
  224. params->adxy[l] = (FCELL) (-dxy * tfstad);
  225. }
  226. }
  227. }
  228. else {
  229. Rast_set_d_null_value(params->az + l, 1);
  230. /* fprintf (stderr, "zz=%f, az[l]=%f, c=%d\n", zz, params->az[l], l); */
  231. if (cond1) {
  232. Rast_set_d_null_value(params->adx + l, 1);
  233. Rast_set_d_null_value(params->ady + l, 1);
  234. if (cond2) {
  235. Rast_set_d_null_value(params->adxx + l, 1);
  236. Rast_set_d_null_value(params->adyy + l, 1);
  237. Rast_set_d_null_value(params->adxy + l, 1);
  238. }
  239. }
  240. }
  241. }
  242. if (cond1 && (params->deriv != 1)) {
  243. if (params->secpar(params, ngstc, nszc, k, bitmask,
  244. gmin, gmax, c1min, c1max, c2min, c2max, cond1,
  245. cond2) < 0)
  246. return -1;
  247. }
  248. offset2 = (offset + ngstc - 1) * sizeof(FCELL);
  249. if (params->wr_temp(params, ngstc, nszc, offset2) < 0)
  250. return -1;
  251. }
  252. return 1;
  253. }