GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
Loading...
Searching...
No Matches
interp2d.c
Go to the documentation of this file.
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 * SPDX-FileCopyrightText: 1993-1999 Lubos Mitas
28 * SPDX-FileCopyrightText: GRASS Development Team
29 * SPDX-License-Identifier: GPL-2.0-or-later
30 */
31
32#include <stdio.h>
33#include <math.h>
34#include <unistd.h>
35
36#include <grass/gis.h>
37#include <grass/raster.h>
38#include <grass/glocale.h>
39#include <grass/bitmap.h>
40
41#include <grass/interpf.h>
42
43#define CEULER .57721566
44
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 */
57 struct interp_params *params, 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 G_UNUSED, /*!< 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 /*
71 * C C INTERPOLATION BY FUNCTIONAL METHOD : TPS + complete regul.
72 * c
73 */
74 double x_or = data->x_orig;
75 double y_or = data->y_orig;
76 int n_rows = data->n_rows;
77 int n_cols = data->n_cols;
78 int n_points = data->n_points;
79 struct triple *points;
80 static double *w2 = NULL;
81 static double *w = NULL;
82 int cond1, cond2;
83 double r;
84 double stepix, stepiy, xx, xg, yg, xx2;
85 double /* rfsta2, cons, cons1, */ wm, dx, dy, dxx, dyy, dxy, h, bmgd1,
86 bmgd2;
87 double r2, gd1, gd2; /* for interpder() */
88 int /* n1, */ k, l, m;
89 int ngstc, nszc, ngstr, nszr;
90 double zz;
91 int bmask = 1;
92 static int first_time_z = 1;
93 off_t offset, offset2;
94 double fstar2 = params->fi * params->fi / 4.;
95 double tfsta2, tfstad;
96 double ns_res, ew_res;
97 double rsin = 0, rcos = 0, teta,
98 scale = 0; /*anisotropy parameters - added by JH 2002 */
99 double xxr, yyr;
100
101 if (params->theta) {
102 teta = params->theta / M_R2D; /* deg to rad */
103 rsin = sin(teta);
104 rcos = cos(teta);
105 }
106 if (params->scalex)
107 scale = params->scalex;
108
109 ns_res = (((struct quaddata *)(data))->ymax -
110 ((struct quaddata *)(data))->y_orig) /
111 data->n_rows;
112 ew_res = (((struct quaddata *)(data))->xmax -
113 ((struct quaddata *)(data))->x_orig) /
114 data->n_cols;
115
116 /* tfsta2 = fstar2 * 2.; modified after removing normalization of z */
117 tfsta2 = (fstar2 * 2.) / dnorm;
118 tfstad = tfsta2 / dnorm;
119 points = data->points;
120
121 /*
122 * normalization
123 */
124 stepix = ew_res / dnorm;
125 stepiy = ns_res / dnorm;
126
127 cond2 = ((params->adxx != NULL) || (params->adyy != NULL) ||
128 (params->adxy != NULL));
129 cond1 = ((params->adx != NULL) || (params->ady != NULL) || cond2);
130
131 if (!w) {
132 if (!(w = (double *)G_malloc(sizeof(double) * (params->KMAX2 + 9)))) {
133 G_warning(_("Out of memory"));
134 return -1;
135 }
136 }
137 if (!w2) {
138 if (!(w2 = (double *)G_malloc(sizeof(double) * (params->KMAX2 + 9)))) {
139 G_warning(_("Out of memory"));
140 return -1;
141 }
142 }
143 /* n1 = n_points + 1; */
144 /*
145 * C C INTERPOLATION * MOST INNER LOOPS ! C
146 */
147 ngstc = (int)(x_or / ew_res + 0.5) + 1;
148 nszc = ngstc + n_cols - 1;
149 ngstr = (int)(y_or / ns_res + 0.5) + 1;
150 nszr = ngstr + n_rows - 1;
151
152 for (k = ngstr; k <= nszr; k++) {
153 offset = offset1 * (k - 1); /* rows offset */
154 yg = (k - ngstr) * stepiy + stepiy / 2.; /* fixed by J.H. in July 01 */
155 for (m = 1; m <= n_points; m++) {
156 wm = yg - points[m - 1].y;
157 w[m] = wm;
158 w2[m] = wm * wm;
159 }
160 for (l = ngstc; l <= nszc; l++) {
161 if (bitmask != NULL)
162 /* if(params->maskmap != NULL) PK Apr 03 MASK support */
163 bmask =
164 BM_get(bitmask, l - 1, k - 1); /*fixed by helena jan 97 */
165 /* if(bmask==0 || bmask==-1) fprintf(stderr, "bmask=%d, at
166 * (%d,%d)\n", bmask, l, k); */
167 xg = (l - ngstc) * stepix +
168 stepix / 2.; /*fixed by J.H. in July 01 */
169 dx = 0.;
170 dy = 0.;
171 dxx = 0.;
172 dyy = 0.;
173 dxy = 0.;
174 zz = 0.;
175 if (bmask == 1) { /* compute everything for area which is
176 * not masked out */
177 h = b[0];
178 for (m = 1; m <= n_points; m++) {
179 xx = xg - points[m - 1].x;
180 if ((params->theta) && (params->scalex)) {
181 /* we run anisotropy */
182 xxr = xx * rcos + w[m] * rsin;
183 yyr = w[m] * rcos - xx * rsin;
184 xx2 = xxr * xxr;
185 w2[m] = yyr * yyr;
186 r2 = scale * xx2 + w2[m];
187 r = r2;
188 /* rfsta2 = scale * xx2 + w2[m]; */
189 }
190 else {
191 xx2 = xx * xx;
192 r2 = xx2 + w2[m];
193 r = r2;
194 /* rfsta2 = xx2 + w2[m]; */
195 }
196
197 h = h + b[m] * params->interp(r, params->fi);
198 if (cond1) {
199 if (!params->interpder(r, params->fi, &gd1, &gd2))
200 return -1;
201 bmgd1 = b[m] * gd1;
202 dx = dx + bmgd1 * xx;
203 dy = dy + bmgd1 * w[m];
204 if (cond2) {
205 bmgd2 = b[m] * gd2;
206 dxx = dxx + bmgd2 * xx2 + bmgd1;
207 dyy = dyy + bmgd2 * w2[m] + bmgd1;
208 dxy = dxy + bmgd2 * xx * w[m];
209 }
210 }
211 }
212
213 /* zz = (h * dnorm) + zmin; replaced by helena jan. 97 due
214 to removing norma lization of z and zm in segmen2d.c */
215 zz = h + zmin;
216 if (first_time_z) {
217 first_time_z = 0;
218 *zmaxac = *zminac = zz;
219 }
220 *zmaxac = amax1(zz, *zmaxac);
221 *zminac = amin1(zz, *zminac);
222 if ((zz > zmax + 0.1 * (zmax - zmin)) ||
223 (zz < zmin - 0.1 * (zmax - zmin))) {
224 static int once = 0;
225
226 if (!once) {
227 once = 1;
228 G_warning(
229 _("Overshoot - increase in tension suggested. "
230 "Overshoot occurs at (%d,%d) cell. "
231 "Z-value %f, zmin %f, zmax %f."),
232 l, k, zz, zmin, zmax);
233 }
234 }
235
236 params->az[l] = (FCELL)zz;
237
238 if (cond1) {
239 params->adx[l] = (FCELL)(-dx * tfsta2);
240 params->ady[l] = (FCELL)(-dy * tfsta2);
241 if (cond2) {
242 params->adxx[l] = (FCELL)(-dxx * tfstad);
243 params->adyy[l] = (FCELL)(-dyy * tfstad);
244 params->adxy[l] = (FCELL)(-dxy * tfstad);
245 }
246 }
247 }
248 else {
249 Rast_set_d_null_value(params->az + l, 1);
250 /* fprintf (stderr, "zz=%f, az[l]=%f, c=%d\n", zz,
251 * params->az[l], l); */
252
253 if (cond1) {
254 Rast_set_d_null_value(params->adx + l, 1);
255 Rast_set_d_null_value(params->ady + l, 1);
256 if (cond2) {
257 Rast_set_d_null_value(params->adxx + l, 1);
258 Rast_set_d_null_value(params->adyy + l, 1);
259 Rast_set_d_null_value(params->adxy + l, 1);
260 }
261 }
262 }
263 }
264 if (cond1 && (params->deriv != 1)) {
265 if (params->secpar(params, ngstc, nszc, k, bitmask, gmin, gmax,
266 c1min, c1max, c2min, c2max, cond1, cond2) < 0)
267 return -1;
268 }
269
270 offset2 = (offset + ngstc - 1) * sizeof(FCELL);
271 if (params->wr_temp(params, ngstc, nszc, offset2) < 0)
272 return -1;
273 }
274 return 1;
275}
#define NULL
Definition ccmath.h:32
int BM_get(struct BM *, int, int)
Gets 'val' from the bitmap.
Definition bitmap.c:213
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition defs/gis.h:136
void Rast_set_d_null_value(DCELL *, int)
To set a number of DCELL raster values to NULL.
Definition null_val.c:151
float FCELL
Definition gis.h:633
#define M_R2D
Definition gis.h:169
#define G_UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:43
#define _(str)
Definition glocale.h:10
int IL_grid_calc_2d(struct interp_params *params, struct quaddata *data, struct BM *bitmask, double zmin, double zmax, double *zminac, double *zmaxac, double *gmin, double *gmax, double *c1min, double *c1max, double *c2min, double *c2max, double *ertot, double *b, off_t offset1, double dnorm)
Definition interp2d.c:56
double amin1(double, double)
Definition minmax.c:68
double amax1(double, double)
Definition minmax.c:55
double b
Definition r_raster.c:37
double l
Definition r_raster.c:37
double r
Definition r_raster.c:37
Definition bitmap.h:17
DCELL * az
Definition interpf.h:94
interp_fn * interp
Definition interpf.h:136
secpar_fn * secpar
Definition interpf.h:134
double fi
Definition interpf.h:97
double theta
Definition interpf.h:116
DCELL * adxy
Definition interpf.h:94
DCELL * adyy
Definition interpf.h:94
DCELL * adx
Definition interpf.h:94
DCELL * ady
Definition interpf.h:94
double scalex
Definition interpf.h:119
wr_temp_fn * wr_temp
Definition interpf.h:140
interpder_fn * interpder
Definition interpf.h:138
DCELL * adxx
Definition interpf.h:94
double ymax
Definition dataquad.h:45
double y_orig
Definition dataquad.h:43
double x_orig
Definition dataquad.h:42
struct triple * points
Definition dataquad.h:49
int n_points
Definition dataquad.h:48
double xmax
Definition dataquad.h:44
int n_cols
Definition dataquad.h:47
int n_rows
Definition dataquad.h:46