GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
ressegm2d.c
Go to the documentation of this file.
1/*-
2 * Written by H. Mitasova, I. Kosinovsky, D. Gerdes Summer 1993
3 * University of Illinois
4 * US Army Construction Engineering Research Lab
5 * SPDX-FileCopyrightText: 1993 H. Mitasova (University of Illinois)
6 * SPDX-FileCopyrightText: 1993 I. Kosinovsky (USA-CERL)
7 * SPDX-FileCopyrightText: 1993 D.Gerdes (USA-CERL)
8 * SPDX-FileCopyrightText: GRASS Development Team
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 *
11 * modified by McCauley in August 1995
12 * modified by Mitasova in August 1995
13 *
14 * bug fixes by Jaro Hofierka in February 1999:
15 * line: 175,348 (*dnorm)
16 * 177,350 (points[m1].sm)
17 * 457,461 (})
18 *
19 * modified by Mitasova November 1999 (option for dnorm ind. tension)
20 *
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <math.h>
26
27#include <grass/gis.h>
28#include <grass/raster.h>
29#include <grass/interpf.h>
30#include <grass/gmath.h>
31
32static int input_data(struct interp_params *, int, int, struct fcell_triple *,
33 int, int, int, int, double, double, double);
34static int write_zeros(struct interp_params *, struct quaddata *, off_t);
35
37 struct interp_params *params, struct BM *bitmask, /* bitmask */
38 double zmin, double zmax, /* min and max input z-values */
39 double *zminac, double *zmaxac, /* min and max interp. z-values */
40 double *gmin, double *gmax, /* min and max inperp. slope val. */
41 double *c1min, double *c1max, double *c2min,
42 double *c2max, /* min and max interp. curv. val. */
43 double *ertot, /* total interplating func. error */
44 off_t offset1, /* offset for temp file writing */
45 double *dnorm, int overlap, int inp_rows, int inp_cols, int fdsmooth,
46 int fdinp, double ns_res, double ew_res, double inp_ns_res,
47 double inp_ew_res, int dtens)
48{
49
50 int i, j, k, l, m, m1, i1; /* loop coounters */
51 int cursegm = 0;
52 int new_comp = 0;
53 int n_rows, n_cols /*, inp_r, inp_c */;
54 double x_or, y_or, xm, ym;
55 static int first = 1, new_first = 1;
56 double **matrix = NULL, **new_matrix = NULL, *b = NULL;
57 int *indx = NULL, *new_indx = NULL;
58 static struct fcell_triple *in_points = NULL; /* input points */
59 int out_check_rows, out_check_cols; /* total output rows/cols */
60 int first_row, last_row; /* first and last input row of segment */
61 int first_col, last_col; /* first and last input col of segment */
62 int num, prev;
63 int div; /* number of divides */
64 int rem_out_row, rem_out_col; /* output rows/cols remainders */
65 int inp_seg_r, inp_seg_c, /* # of input rows/cols in segment */
66 out_seg_r, out_seg_c; /* # of output rows/cols in segment */
67 int ngstc, nszc /* first and last output col of the
68 * segment */
69 ,
70 ngstr, nszr; /* first and last output row of the
71 * segment */
72 int index; /* index for input data */
73 int c, r;
74 int overlap1;
75 int p_size;
76 struct quaddata *data;
77 double xmax, xmin, ymax, ymin;
78 int totsegm; /* total number of segments */
79 int total_points = 0;
80 struct triple triple = {0.0, 0.0, 0.0, 0.0}; /* contains garbage */
81
82 xmin = params->x_orig;
83 ymin = params->y_orig;
84 xmax = xmin + ew_res * params->nsizc;
85 ymax = ymin + ns_res * params->nsizr;
86 prev = inp_rows * inp_cols;
87 if (prev <= params->kmax)
88 div = 1; /* no segmentation */
89
90 else { /* find the number of divides */
91 for (i = 2;; i++) {
92 c = inp_cols / i;
93 r = inp_rows / i;
94 num = c * r;
95 if (num < params->kmin) {
96 if (((params->kmin - num) > (prev + 1 - params->kmax)) &&
97 (prev + 1 < params->KMAX2)) {
98 div = i - 1;
99 break;
100 }
101 else {
102 div = i;
103 break;
104 }
105 }
106 if ((num > params->kmin) && (num + 1 < params->kmax)) {
107 div = i;
108 break;
109 }
110 prev = num;
111 }
112 }
113 out_seg_r = params->nsizr / div; /* output rows per segment */
114 out_seg_c = params->nsizc / div; /* output cols per segment */
115 inp_seg_r = inp_rows / div; /* input rows per segment */
116 inp_seg_c = inp_cols / div; /* input rows per segment */
117 rem_out_col = params->nsizc % div;
118 rem_out_row = params->nsizr % div;
119 overlap1 = min1(overlap, inp_seg_c - 1);
121 out_check_rows = 0;
122 out_check_cols = 0;
123
124 if (div == 1) {
126 }
127 else {
128 p_size = (overlap1 * 2 + inp_seg_c) * (overlap1 * 2 + inp_seg_r);
129 }
130 if (!in_points) {
131 if (!(in_points = (struct fcell_triple *)G_malloc(
132 sizeof(struct fcell_triple) * p_size * div))) {
133 fprintf(stderr, "Cannot allocate memory for in_points\n");
134 return -1;
135 }
136 }
137
138 *dnorm =
139 sqrt(((xmax - xmin) * (ymax - ymin) * p_size) / (inp_rows * inp_cols));
140
141 if (dtens) {
142 params->fi = params->fi * (*dnorm) / 1000.;
143 fprintf(stderr, "dnorm = %f, rescaled tension = %f\n", *dnorm,
144 params->fi);
145 }
146
147 if (div == 1) { /* no segmentation */
148 totsegm = 1;
149 cursegm = 1;
150
151 input_data(params, 1, inp_rows, in_points, fdsmooth, fdinp, inp_rows,
153
154 x_or = 0.;
155 y_or = 0.;
156 xm = params->nsizc * ew_res;
157 ym = params->nsizr * ns_res;
158
159 data = (struct quaddata *)quad_data_new(
160 x_or, y_or, xm, ym, params->nsizr, params->nsizc, 0, params->KMAX2);
161 m1 = 0;
162 for (k = 1; k <= p_size; k++) {
163 if (!Rast_is_f_null_value(&(in_points[k - 1].z))) {
164 data->points[m1].x = in_points[k - 1].x / (*dnorm);
165 data->points[m1].y = in_points[k - 1].y / (*dnorm);
166 /* data->points[m1].z = (double) (in_points[k - 1].z) /
167 * (*dnorm); */
168 data->points[m1].z = (double)(in_points[k - 1].z);
169 data->points[m1].sm = in_points[k - 1].smooth;
170 m1++;
171 }
172 }
173 data->n_points = m1;
174 total_points = m1;
175 if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) {
176 fprintf(stderr, "Cannot allocate memory for indx\n");
177 return -1;
178 }
179 if (!(matrix = G_alloc_matrix(params->KMAX2 + 1, params->KMAX2 + 1))) {
180 fprintf(stderr, "Cannot allocate memory for matrix\n");
181 return -1;
182 }
183 if (!(b = G_alloc_vector(params->KMAX2 + 2))) {
184 fprintf(stderr, "Cannot allocate memory for b\n");
185 return -1;
186 }
187
188 if (params->matrix_create(params, data->points, m1, matrix, indx) < 0)
189 return -1;
190 for (i = 0; i < m1; i++) {
191 b[i + 1] = data->points[i].z;
192 }
193 b[0] = 0.;
194 G_lubksb(matrix, m1 + 1, indx, b);
195
196 params->check_points(params, data, b, ertot, zmin, *dnorm, &triple);
197
198 if (params->grid_calc(params, data, bitmask, zmin, zmax, zminac, zmaxac,
200 offset1, *dnorm) < 0) {
201 fprintf(stderr, "interpolation failed\n");
202 return -1;
203 }
204 else {
205 if (totsegm != 0) {
207 }
208 /*
209 * if (b) G_free_vector(b); if (matrix) G_free_matrix(matrix); if
210 * (indx) G_free_ivector(indx);
211 */
212 fprintf(stderr, "dnorm in ressegm after grid before out= %f \n",
213 *dnorm);
214 return total_points;
215 }
216 }
217
218 out_seg_r = params->nsizr / div; /* output rows per segment */
219 out_seg_c = params->nsizc / div; /* output cols per segment */
220 inp_seg_r = inp_rows / div; /* input rows per segment */
221 inp_seg_c = inp_cols / div; /* input rows per segment */
222 rem_out_col = params->nsizc % div;
223 rem_out_row = params->nsizr % div;
224 overlap1 = min1(overlap, inp_seg_c - 1);
226 out_check_rows = 0;
227 out_check_cols = 0;
228
229 totsegm = div * div;
230
231 /* set up a segment */
232 for (i = 1; i <= div; i++) { /* input and output rows */
233 if (i <= div - rem_out_row)
235 else
236 n_rows = out_seg_r + 1;
237 /* inp_r = inp_seg_r; */
238 out_check_cols = 0;
239 ngstr = out_check_rows + 1; /* first output row of the segment */
240 nszr = ngstr + n_rows - 1; /* last output row of the segment */
241 y_or = (ngstr - 1) * ns_res; /* y origin of the segment */
242 /*
243 * Calculating input starting and ending rows and columns of this
244 * segment
245 */
246 first_row = (int)(y_or / inp_ns_res) + 1;
247 if (first_row > overlap1) {
248 first_row -= overlap1; /* middle */
249 last_row = first_row + inp_seg_r + overlap1 * 2 - 1;
250 if (last_row > inp_rows) {
251 first_row -= (last_row - inp_rows); /* bottom */
253 }
254 }
255 else {
256 first_row = 1; /* top */
257 last_row = first_row + inp_seg_r + overlap1 * 2 - 1;
258 }
259 if ((last_row > inp_rows) || (first_row < 1)) {
260 fprintf(stderr, "Row overlap too large!\n");
261 return -1;
262 }
263 input_data(params, first_row, last_row, in_points, fdsmooth, fdinp,
265
266 for (j = 1; j <= div; j++) { /* input and output cols */
267 if (j <= div - rem_out_col)
269 else
270 n_cols = out_seg_c + 1;
271 /* inp_c = inp_seg_c; */
272
273 ngstc = out_check_cols + 1; /* first output col of the segment */
274 nszc = ngstc + n_cols - 1; /* last output col of the segment */
275 x_or = (ngstc - 1) * ew_res; /* x origin of the segment */
276
277 first_col = (int)(x_or / inp_ew_res) + 1;
278 if (first_col > overlap1) {
279 first_col -= overlap1; /* middle */
280 last_col = first_col + inp_seg_c + overlap1 * 2 - 1;
281 if (last_col > inp_cols) {
282 first_col -= (last_col - inp_cols); /* right */
284 }
285 }
286 else {
287 first_col = 1; /* left */
288 last_col = first_col + inp_seg_c + overlap1 * 2 - 1;
289 }
290 if ((last_col > inp_cols) || (first_col < 1)) {
291 fprintf(stderr, "Column overlap too large!\n");
292 return -1;
293 }
294 m = 0;
295 /* Getting points for interpolation (translated) */
296
297 xm = nszc * ew_res;
298 ym = nszr * ns_res;
299 data = (struct quaddata *)quad_data_new(
300 x_or, y_or, xm, ym, nszr - ngstr + 1, nszc - ngstc + 1, 0,
301 params->KMAX2);
302 new_comp = 0;
303
304 for (k = 0; k <= last_row - first_row; k++) {
305 for (l = first_col - 1; l < last_col; l++) {
306 index = k * inp_cols + l;
307 if (!Rast_is_f_null_value(&(in_points[index].z))) {
308 /* if the point is inside the segment (not overlapping)
309 */
310 if ((in_points[index].x - x_or >= 0) &&
311 (in_points[index].y - y_or >= 0) &&
312 ((nszc - 1) * ew_res - in_points[index].x >= 0) &&
313 ((nszr - 1) * ns_res - in_points[index].y >= 0))
314 total_points += 1;
315 data->points[m].x =
316 (in_points[index].x - x_or) / (*dnorm);
317 data->points[m].y =
318 (in_points[index].y - y_or) / (*dnorm);
319 /* data->points[m].z = (double)
320 * (in_points[index].z) / (*dnorm); */
321 data->points[m].z = (double)(in_points[index].z);
322 data->points[m].sm = in_points[index].smooth;
323 m++;
324 }
325 else
326 new_comp = 1;
327
328 /* fprintf(stderr,"%f,%f,%f
329 zmin=%f\n",in_points[index].x,in_points[index].y,in_points[index].z,zmin);
330 */
331 }
332 }
333 /* fprintf (stdout,"m,index:%di,%d\n",m,index); */
334 if (m <= params->KMAX2)
335 data->n_points = m;
336 else
337 data->n_points = params->KMAX2;
339 cursegm = (i - 1) * div + j - 1;
340
341 /* show before to catch 0% */
342 if (totsegm != 0) {
344 }
345 if (m == 0) {
346 /*
347 * fprintf(stderr,"Warning: segment with zero points
348 * encountered, insrease overlap\n");
349 */
350 write_zeros(params, data, offset1);
351 }
352 else {
353 if (new_comp) {
354 if (new_first) {
355 new_first = 0;
356 if (!b) {
357 if (!(b = G_alloc_vector(params->KMAX2 + 2))) {
359 "Cannot allocate memory for b\n");
360 return -1;
361 }
362 }
363 if (!(new_indx = G_alloc_ivector(params->KMAX2 + 1))) {
365 "Cannot allocate memory for new_indx\n");
366 return -1;
367 }
368 if (!(new_matrix = G_alloc_matrix(params->KMAX2 + 1,
369 params->KMAX2 + 1))) {
371 "Cannot allocate memory for new_matrix\n");
372 return -1;
373 }
374 } /*new_first */
375 if (params->matrix_create(params, data->points,
376 data->n_points, new_matrix,
377 new_indx) < 0)
378 return -1;
379
380 for (i1 = 0; i1 < m; i1++) {
381 b[i1 + 1] = data->points[i1].z;
382 }
383 b[0] = 0.;
384 G_lubksb(new_matrix, data->n_points + 1, new_indx, b);
385
386 params->check_points(params, data, b, ertot, zmin, *dnorm,
387 &triple);
388
389 if (params->grid_calc(params, data, bitmask, zmin, zmax,
391 c1max, c2min, c2max, ertot, b,
392 offset1, *dnorm) < 0) {
393
394 fprintf(stderr, "interpolate() failed\n");
395 return -1;
396 }
397 } /*new_comp */
398 else {
399 if (first) {
400 first = 0;
401 if (!b) {
402 if (!(b = G_alloc_vector(params->KMAX2 + 2))) {
404 "Cannot allocate memory for b\n");
405 return -1;
406 }
407 }
408 if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) {
410 "Cannot allocate memory for indx\n");
411 return -1;
412 }
413 if (!(matrix = G_alloc_matrix(params->KMAX2 + 1,
414 params->KMAX2 + 1))) {
416 "Cannot allocate memory for matrix\n");
417 return -1;
418 }
419 } /* first */
420 if (params->matrix_create(params, data->points,
421 data->n_points, matrix, indx) < 0)
422 return -1;
423 /* } here it was bug */
424 for (i1 = 0; i1 < m; i1++)
425 b[i1 + 1] = data->points[i1].z;
426 b[0] = 0.;
427 G_lubksb(matrix, data->n_points + 1, indx, b);
428
429 params->check_points(params, data, b, ertot, zmin, *dnorm,
430 &triple);
431
432 if (params->grid_calc(params, data, bitmask, zmin, zmax,
434 c1max, c2min, c2max, ertot, b,
435 offset1, *dnorm) < 0) {
436
437 fprintf(stderr, "interpolate() failed\n");
438 return -1;
439 }
440 }
441 }
442 if (data) {
443 G_free(data->points);
444 G_free(data);
445 }
446 /*
447 * cursegm++;
448 */
449 }
451 }
452
453 /* run one last time after the loop is done to catch 100% */
454 if (totsegm != 0)
455 G_percent(1, 1,
456 1); /* cursegm doesn't get to totsegm so we force 100% */
457
458 /*
459 * if (b) G_free_vector(b); if (indx) G_free_ivector(indx); if (matrix)
460 * G_free_matrix(matrix);
461 */
462 fprintf(stderr, "dnorm in ressegm after grid before out2= %f \n", *dnorm);
463 return total_points;
464}
465
466/* input of data for interpolation and smoothing parameters */
467
468static int input_data(struct interp_params *params, int first_row, int last_row,
469 struct fcell_triple *points, int fdsmooth, int fdinp,
470 int inp_rows, int inp_cols, double zmin,
471 double inp_ns_res, double inp_ew_res)
472{
473 double x, y, sm; /* input data and smoothing */
474 int m1, m2; /* loop counters */
475 static FCELL *cellinp = NULL; /* cell buffer for input data */
476 static FCELL *cellsmooth = NULL; /* cell buffer for smoothing */
477
478 if (!cellinp)
480 if (!cellsmooth)
482
483 for (m1 = 0; m1 <= last_row - first_row; m1++) {
485 if (fdsmooth >= 0)
487
488 y = params->y_orig + (m1 + first_row - 1 + 0.5) * inp_ns_res;
489 for (m2 = 0; m2 < inp_cols; m2++) {
490 x = params->x_orig + (m2 + 0.5) * inp_ew_res;
491 /*
492 * z = cellinp[m2]*params->zmult;
493 */
494 if (fdsmooth >= 0)
495 sm = (double)cellsmooth[m2];
496 else
497 sm = 0.01;
498
499 points[m1 * inp_cols + m2].x = x - params->x_orig;
500 points[m1 * inp_cols + m2].y = y - params->y_orig;
501 if (!Rast_is_f_null_value(cellinp + m2)) {
502 points[m1 * inp_cols + m2].z =
503 cellinp[m2] * params->zmult - zmin;
504 }
505 else {
506 Rast_set_f_null_value(&(points[m1 * inp_cols + m2].z), 1);
507 }
508
509 /* fprintf (stdout,"sm: %f\n",sm); */
510
511 points[m1 * inp_cols + m2].smooth = sm;
512 }
513 }
514 return 1;
515}
516
517static int write_zeros(struct interp_params *params,
518 struct quaddata *data, /* given segment */
519 off_t offset1 /* offset for temp file writing */
520)
521{
522
523 /*
524 * C C INTERPOLATION BY FUNCTIONAL METHOD : TPS + complete regul.
525 * c
526 */
527 double x_or = data->x_orig;
528 double y_or = data->y_orig;
529 int n_rows = data->n_rows;
530 int n_cols = data->n_cols;
531 int cond1, cond2;
532 int k, l;
533 int ngstc, nszc, ngstr, nszr;
534 off_t offset, offset2;
535 double ns_res, ew_res;
536
537 ns_res = (((struct quaddata *)(data))->ymax -
538 ((struct quaddata *)(data))->y_orig) /
539 data->n_rows;
540 ew_res = (((struct quaddata *)(data))->xmax -
541 ((struct quaddata *)(data))->x_orig) /
542 data->n_cols;
543
544 cond2 = ((params->adxx != NULL) || (params->adyy != NULL) ||
545 (params->adxy != NULL));
546 cond1 = ((params->adx != NULL) || (params->ady != NULL) || cond2);
547
548 ngstc = (int)(x_or / ew_res + 0.5) + 1;
549 nszc = ngstc + n_cols - 1;
550 ngstr = (int)(y_or / ns_res + 0.5) + 1;
551 nszr = ngstr + n_rows - 1;
552
553 for (k = ngstr; k <= nszr; k++) {
554 offset = offset1 * (k - 1); /* rows offset */
555 for (l = ngstc; l <= nszc; l++) {
556 /*
557 * params->az[l] = 0.;
558 */
559 Rast_set_d_null_value(params->az + l, 1);
560 if (cond1) {
561 /*
562 * params->adx[l] = (FCELL)0.; params->ady[l] = (FCELL)0.;
563 */
564 Rast_set_d_null_value(params->adx + l, 1);
565 Rast_set_d_null_value(params->ady + l, 1);
566 if (cond2) {
567 Rast_set_d_null_value(params->adxx + l, 1);
568 Rast_set_d_null_value(params->adyy + l, 1);
569 Rast_set_d_null_value(params->adxy + l, 1);
570 /*
571 * params->adxx[l] = (FCELL)0.; params->adyy[l] = (FCELL)0.;
572 * params->adxy[l] = (FCELL)0.;
573 */
574 }
575 }
576 }
577 offset2 = (offset + ngstc - 1) * sizeof(FCELL);
578 if (params->wr_temp(params, ngstc, nszc, offset2) < 0)
579 return -1;
580 }
581 return 1;
582}
#define NULL
Definition ccmath.h:32
struct quaddata * quad_data_new(double x_or, double y_or, double xmax, double ymax, int rows, int cols, int n_points, int kmax)
Definition dataquad.c:55
void G_percent(long, long, int)
Print percent complete messages.
Definition percent.c:59
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_malloc(n)
Definition defs/gis.h:136
int * G_alloc_ivector(size_t)
Vector matrix memory allocation.
Definition ialloc.c:38
void G_lubksb(double **a, int n, int *indx, double b[])
LU backward substitution.
Definition lu.c:98
double * G_alloc_vector(size_t)
Vector matrix memory allocation.
Definition dalloc.c:38
double ** G_alloc_matrix(int, int)
Matrix memory allocation.
Definition dalloc.c:55
#define Rast_is_f_null_value(fcellVal)
void Rast_set_d_null_value(DCELL *, int)
To set a number of DCELL raster values to NULL.
Definition null_val.c:151
void Rast_set_f_null_value(FCELL *, int)
To set a number of FCELL raster values to NULL.
Definition null_val.c:136
FCELL * Rast_allocate_f_buf(void)
Allocates memory for a raster map of type FCELL.
Definition alloc_cell.c:91
void Rast_get_f_row(int, FCELL *, int)
Get raster row (FCELL type)
float FCELL
Definition gis.h:633
int min1(int, int)
Definition minmax.c:20
double b
Definition r_raster.c:37
double l
Definition r_raster.c:37
double r
Definition r_raster.c:37
int IL_resample_interp_segments_2d(struct interp_params *params, 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, off_t offset1, double *dnorm, int overlap, int inp_rows, int inp_cols, int fdsmooth, int fdinp, double ns_res, double ew_res, double inp_ns_res, double inp_ew_res, int dtens)
Definition ressegm2d.c:36
Definition bitmap.h:17
check_points_fn * check_points
Definition interpf.h:132
double zmult
Definition interpf.h:72
DCELL * az
Definition interpf.h:94
grid_calc_fn * grid_calc
Definition interpf.h:128
double fi
Definition interpf.h:97
double x_orig
Definition interpf.h:112
DCELL * adxy
Definition interpf.h:94
DCELL * adyy
Definition interpf.h:94
DCELL * adx
Definition interpf.h:94
double y_orig
Definition interpf.h:112
DCELL * ady
Definition interpf.h:94
wr_temp_fn * wr_temp
Definition interpf.h:140
DCELL * adxx
Definition interpf.h:94
matrix_create_fn * matrix_create
Definition interpf.h:130
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
#define x