4
\brief GIS library - sampling methods (extract a cell value from
7
1/2006: moved to libgis from v.sample/v.drape for clone removal
9
(C) 2001-2008 by the GRASS Development Team
11
This program is free software under the
12
GNU General Public License (>=v2).
13
Read the file COPYING that comes with GRASS
16
\author James Darrell McCauley <darrell mccauley-usa.com>, http://mccauley-usa.com/
24
#include <grass/gis.h>
25
#include <grass/glocale.h>
28
static double scancatlabel(const char *);
29
static void raster_row_error(const struct Cell_head *window, double north,
34
* \brief Extract a cell value from raster map.
36
* Extract a cell value from raster map at given northing and easting
37
* with a sampled 3x3 window using a specified interpolation method.
39
* \param fd file descriptor
40
* \param window region settings
41
* \param cats categories
42
* \param north northing position
43
* \param east easting position
44
* \param usedesc flag to scan category label
45
* \param itype interpolation method
47
* \return cell value at given position
50
DCELL G_get_raster_sample(
52
const struct Cell_head *window,
53
struct Categories *cats,
54
double north, double east,
55
int usedesc, INTERP_TYPE itype)
61
retval = G_get_raster_sample_nearest(fd, window, cats, north, east, usedesc);
64
retval = G_get_raster_sample_bilinear(fd, window, cats, north, east, usedesc);
67
retval = G_get_raster_sample_cubic(fd, window, cats, north, east, usedesc);
70
G_fatal_error("G_get_raster_sample: %s",
71
_("Unknown interpolation type"));
78
DCELL G_get_raster_sample_nearest(
80
const struct Cell_head *window,
81
struct Categories *cats,
82
double north, double east, int usedesc)
86
DCELL *maprow = G_allocate_d_raster_buf();
88
/* convert northing and easting to row and col, resp */
89
row = (int)floor(G_northing_to_row(north, window));
90
col = (int)floor(G_easting_to_col(east, window));
92
if (row < 0 || row >= G_window_rows() ||
93
col < 0 || col >= G_window_cols()) {
94
G_set_d_null_value(&result, 1);
98
if (G_get_d_raster_row(fd, maprow, row) < 0)
99
raster_row_error(window, north, east);
101
if (G_is_d_null_value(&maprow[col])) {
102
G_set_d_null_value(&result, 1);
107
char *buf = G_get_cat(maprow[col], cats);
110
result = scancatlabel(buf);
113
result = maprow[col];
122
DCELL G_get_raster_sample_bilinear(
124
const struct Cell_head *window,
125
struct Categories *cats,
126
double north, double east, int usedesc)
130
DCELL *arow = G_allocate_d_raster_buf();
131
DCELL *brow = G_allocate_d_raster_buf();
132
double frow, fcol, trow, tcol;
135
frow = G_northing_to_row(north, window);
136
fcol = G_easting_to_col(east, window);
138
/* convert northing and easting to row and col, resp */
139
row = (int)floor(frow - 0.5);
140
col = (int)floor(fcol - 0.5);
142
trow = frow - row - 0.5;
143
tcol = fcol - col - 0.5;
145
if (row < 0 || row + 1 >= G_window_rows() ||
146
col < 0 || col + 1 >= G_window_cols()) {
147
G_set_d_null_value(&result, 1);
151
if (G_get_d_raster_row(fd, arow, row) < 0)
152
raster_row_error(window, north, east);
153
if (G_get_d_raster_row(fd, brow, row + 1) < 0)
154
raster_row_error(window, north, east);
156
if (G_is_d_null_value(&arow[col]) || G_is_d_null_value(&arow[col + 1]) ||
157
G_is_d_null_value(&brow[col]) || G_is_d_null_value(&brow[col + 1])) {
158
G_set_d_null_value(&result, 1);
163
* now were ready to do bilinear interpolation over
164
* arow[col], arow[col+1],
165
* brow[col], brow[col+1]
171
G_squeeze(buf = G_get_cat((int)arow[col], cats));
172
grid[0][0] = scancatlabel(buf);
173
G_squeeze(buf = G_get_cat((int)arow[col + 1], cats));
174
grid[0][1] = scancatlabel(buf);
175
G_squeeze(buf = G_get_cat((int)brow[col], cats));
176
grid[1][0] = scancatlabel(buf);
177
G_squeeze(buf = G_get_cat((int)brow[col + 1], cats));
178
grid[1][1] = scancatlabel(buf);
181
grid[0][0] = arow[col];
182
grid[0][1] = arow[col + 1];
183
grid[1][0] = brow[col];
184
grid[1][1] = brow[col + 1];
187
result = G_interp_bilinear(tcol, trow,
188
grid[0][0], grid[0][1], grid[1][0], grid[1][1]);
197
DCELL G_get_raster_sample_cubic(
199
const struct Cell_head *window,
200
struct Categories *cats,
201
double north, double east, int usedesc)
206
double frow, fcol, trow, tcol;
209
for (i = 0; i < 4; i++)
210
rows[i] = G_allocate_d_raster_buf();
212
frow = G_northing_to_row(north, window);
213
fcol = G_easting_to_col(east, window);
215
/* convert northing and easting to row and col, resp */
216
row = (int)floor(frow - 1.5);
217
col = (int)floor(fcol - 1.5);
219
trow = frow - row - 1.5;
220
tcol = fcol - col - 1.5;
222
if (row < 0 || row + 3 >= G_window_rows() ||
223
col < 0 || col + 3 >= G_window_cols()) {
224
G_set_d_null_value(&result, 1);
228
for (i = 0; i < 4; i++)
229
if (G_get_d_raster_row(fd, rows[i], row + i) < 0)
230
raster_row_error(window, north, east);
232
for (i = 0; i < 4; i++)
233
for (j = 0; j < 4; j++)
234
if (G_is_d_null_value(&rows[i][col + j])) {
235
G_set_d_null_value(&result, 1);
240
* now were ready to do cubic interpolation over
241
* arow[col], arow[col+1], arow[col+2], arow[col+3],
242
* brow[col], brow[col+1], brow[col+2], brow[col+3],
243
* crow[col], crow[col+1], crow[col+2], crow[col+3],
244
* drow[col], drow[col+1], drow[col+2], drow[col+3],
250
for (i = 0; i < 4; i++) {
251
for (j = 0; j < 4; j++) {
252
G_squeeze(buf = G_get_cat(rows[i][col + j], cats));
253
grid[i][j] = scancatlabel(buf);
258
for (i = 0; i < 4; i++)
259
for (j = 0; j < 4; j++)
260
grid[i][j] = rows[i][col + j];
263
result = G_interp_bicubic(tcol, trow,
264
grid[0][0], grid[0][1], grid[0][2], grid[0][3],
265
grid[1][0], grid[1][1], grid[1][2], grid[1][3],
266
grid[2][0], grid[2][1], grid[2][2], grid[2][3],
267
grid[3][0], grid[3][1], grid[3][2], grid[3][3]);
270
for (i = 0; i < 4; i++)
277
static double scancatlabel(const char *str)
281
if (strcmp(str, "no data") != 0)
282
sscanf(str, "%lf", &val);
284
G_warning(_("\"no data\" label found; setting to zero"));
292
static void raster_row_error(const struct Cell_head *window, double north,
295
G_debug(3, "DIAG: \tRegion is: n=%g s=%g e=%g w=%g",
296
window->north, window->south, window->east, window->west);
297
G_debug(3, " \tData point is north=%g east=%g", north, east);
299
G_fatal_error(_("Problem reading raster map"));