2
/***********************************************************************
4
* MODULE: r.resamp.bspline
6
* AUTHOR(S): Markus Metz
8
* PURPOSE: Spline Interpolation and cross correlation
10
* COPYRIGHT: (C) 2010 GRASS development team
12
* This program is free software under the
13
* GNU General Public License (>=v2).
14
* Read the file COPYING that comes with GRASS
17
**************************************************************************/
19
#include <grass/config.h>
25
struct Point *P_Read_Raster_Region_masked(SEGMENT *mask_seg,
26
struct Cell_head *Original,
27
struct bound_box output_box,
28
struct bound_box General,
29
int *num_points, int dim_vect,
32
int col, row, startcol, endcol, startrow, endrow, nrows, ncols;
39
obs = (struct Point *)G_calloc(pippo, sizeof(struct Point));
41
/* Reading points inside output box and inside General box */
44
nrows = Original->rows;
45
ncols = Original->cols;
47
/* original region = output region
48
* -> General box is somewhere inside output region */
49
if (Original->north > General.N) {
50
startrow = (double)((Original->north - General.N) / Original->ns_res - 1);
56
if (Original->south < General.S) {
57
endrow = (double)((Original->north - General.S) / Original->ns_res + 1);
63
if (General.W > Original->west) {
64
startcol = (double)((General.W - Original->west) / Original->ew_res - 1);
70
if (General.E < Original->east) {
71
endcol = (double)((General.E - Original->west) / Original->ew_res + 1);
78
for (row = startrow; row < endrow; row++) {
79
for (col = startcol; col < endcol; col++) {
81
Segment_get(mask_seg, &mask_val, row, col);
85
X = Rast_col_to_easting((double)(col) + 0.5, Original);
86
Y = Rast_row_to_northing((double)(row) + 0.5, Original);
88
/* Here, mean is just for asking if obs point is in box */
89
if (Vect_point_in_box(X, Y, mean, &General)) { /* General */
90
if (npoints >= pippo) {
93
(struct Point *)G_realloc((void *)obs,
95
sizeof(struct Point));
98
/* Storing observation vector */
99
obs[npoints].coordX = X;
100
obs[npoints].coordY = Y;
101
obs[npoints].coordZ = 0;
107
*num_points = npoints;
111
int P_Sparse_Raster_Points(SEGMENT *out_seg, struct Cell_head *Elaboration,
112
struct Cell_head *Original, struct bound_box General, struct bound_box Overlap,
113
struct Point *obs, double *param, double pe, double pn,
114
double overlap, int nsplx, int nsply, int num_points,
115
int bilin, double mean)
118
double X, Y, interpolation, csi, eta, weight, dval;
119
int points_in_box = 0;
121
/* Reading points inside output region and inside general box */
122
/* all points available here are inside the output box,
123
* selected by P_Read_Raster_Region_Nulls(), no check needed */
125
for (i = 0; i < num_points; i++) {
130
/* X,Y are cell center cordinates, MUST be inside General box */
131
row = (int) (floor(Rast_northing_to_row(Y, Original)) + 0.1);
132
col = (int) (floor((X - Original->west) / Original->ew_res) + 0.1);
134
if (row < 0 || row >= Original->rows) {
135
G_fatal_error("row index out of range");
139
if (col < 0 || col >= Original->cols) {
140
G_fatal_error("col index out of range");
145
G_debug(3, "P_Sparse_Raster_Points: interpolate point %d...", i);
148
dataInterpolateBilin(X, Y, pe, pn, nsplx,
149
nsply, Elaboration->west,
150
Elaboration->south, param);
153
dataInterpolateBicubic(X, Y, pe, pn, nsplx,
154
nsply, Elaboration->west,
155
Elaboration->south, param);
157
interpolation += mean;
159
if (Vect_point_in_box(X, Y, interpolation, &Overlap)) { /* (5) */
160
dval = interpolation;
163
Segment_get(out_seg, &dval, row, col);
164
if ((X > Overlap.E) && (X < General.E)) {
165
if ((Y > Overlap.N) && (Y < General.N)) { /* (3) */
166
csi = (General.E - X) / overlap;
167
eta = (General.N - Y) / overlap;
169
interpolation *= weight;
170
dval += interpolation;
172
else if ((Y < Overlap.S) && (Y > General.S)) { /* (1) */
173
csi = (General.E - X) / overlap;
174
eta = (Y - General.S) / overlap;
176
interpolation *= weight;
177
dval = interpolation;
179
else if ((Y >= Overlap.S) && (Y <= Overlap.N)) { /* (1) */
180
weight = (General.E - X ) / overlap;
181
interpolation *= weight;
182
dval = interpolation;
185
else if ((X < Overlap.W) && (X > General.W)) {
186
if ((Y > Overlap.N) && (Y < General.N)) { /* (4) */
187
csi = (X - General.W) / overlap;
188
eta = (General.N - Y) / overlap;
190
interpolation *= weight;
191
dval += interpolation;
193
else if ((Y < Overlap.S) && (Y > General.S)) { /* (2) */
194
csi = (X - General.W) / overlap;
195
eta = (Y - General.S) / overlap;
197
interpolation *= weight;
198
dval += interpolation;
200
else if ((Y >= Overlap.S) && (Y <= Overlap.N)) { /* (2) */
201
weight = (X - General.W) / overlap;
202
interpolation *= weight;
203
dval += interpolation;
206
else if ((X >= Overlap.W) && (X <= Overlap.E)) {
207
if ((Y > Overlap.N) && (Y < General.N)) { /* (3) */
208
weight = (General.N - Y) / overlap;
209
interpolation *= weight;
210
dval += interpolation;
212
else if ((Y < Overlap.S) && (Y > General.S)) { /* (1) */
213
weight = (Y - General.S) / overlap;
214
interpolation *= weight;
215
dval = interpolation;
218
} /* end not in overlap */
219
Segment_put(out_seg, &dval, row, col);
220
} /* for num_points */
225
/* align elaboration box to source region
227
int align_elaboration_box(struct Cell_head *elaboration, struct Cell_head *original, int type)
232
case GENERAL_ROW: /* General case N-S direction */
234
row = (int)((original->north - elaboration->north) / original->ns_res);
239
elaboration->north = original->north - original->ns_res * row;
242
row = (int)((original->north - elaboration->south) / original->ns_res) + 1;
244
if (row > original->rows + 1)
245
row = original->rows + 1;
247
elaboration->south = original->north - original->ns_res * row;
251
case GENERAL_COLUMN: /* General case E-W direction */
254
col = (int)((elaboration->east - original->west) / original->ew_res) + 1;
256
if (col > original->cols + 1)
257
col = original->cols + 1;
259
elaboration->east = original->west + original->ew_res * col;
262
col = (int)((elaboration->west - original->west) / original->ew_res);
267
elaboration->west = original->west + original->ew_res * col;
275
/* align interpolation boxes to destination region
276
* return 1 on success, 0 on failure */
278
int align_interp_boxes(struct bound_box *general, struct bound_box *overlap,
279
struct Cell_head *original, struct bound_box last_general,
280
struct bound_box last_overlap, int type)
285
case GENERAL_ROW: /* General case N-S direction */
289
general->N = last_overlap.S;
292
row = (int)((original->north - general->S) / original->ns_res);
294
if (row > original->rows + 1)
295
row = original->rows + 1;
297
general->S = original->north - original->ns_res * row;
301
overlap->N = last_general.S;
304
row = (int)((original->north - overlap->S) / original->ns_res);
306
if (row > original->rows + 1)
307
row = original->rows + 1;
309
overlap->S = original->north - original->ns_res * row;
313
case GENERAL_COLUMN: /* General case E-W direction */
317
general->W = last_overlap.E;
320
col = (int)((general->E - original->west) / original->ew_res);
322
if (col > original->cols + 1)
323
col = original->cols + 1;
325
general->E = original->west + original->ew_res * col;
329
overlap->W = last_general.E;
332
col = (int)((overlap->E - original->west) / original->ew_res);
334
if (col > original->cols + 1)
335
col = original->cols + 1;
337
overlap->E = original->west + original->ew_res * col;
341
case FIRST_ROW: /* Just started with first row */
342
general->N = original->north;
343
overlap->N = original->north;
346
row = (int)((original->north - general->S) / original->ns_res);
348
if (row > original->rows)
349
row = original->rows;
351
general->S = original->north - original->ns_res * row;
353
row = (int)((original->north - overlap->S) / original->ns_res);
355
if (row > original->rows + 1)
356
row = original->rows + 1;
358
overlap->S = original->north - original->ns_res * row;
362
case LAST_ROW: /* Reached last row */
363
general->S = original->south;
364
overlap->S = original->south;
368
case FIRST_COLUMN: /* Just started with first column */
369
general->W = original->west;
370
overlap->W = original->west;
373
col = (int)((general->E - original->west) / original->ew_res);
375
if (col > original->cols + 1)
376
col = original->cols + 1;
378
general->E = original->west + original->ew_res * col;
380
col = (int)((overlap->E - original->west) / original->ew_res);
382
if (col > original->cols + 1)
383
col = original->cols + 1;
385
overlap->E = original->west + original->ew_res * col;
389
case LAST_COLUMN: /* Reached last column */
390
general->E = original->east;
391
overlap->E = original->east;