GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
sample.c
Go to the documentation of this file.
1/*!
2 \file lib/raster/sample.c
3
4 \brief Raster library - Sampling methods (extract a cell value from
5 raster map)
6
7 1/2006: moved to libgis from v.sample/v.drape for clone removal
8
9 SPDX-FileCopyrightText: 2001-2009 GRASS Development Team
10 SPDX-License-Identifier: GPL-2.0-or-later
11
12 \author James Darrell McCauley <darrell mccauley-usa.com>,
13 http://mccauley-usa.com/
14 */
15
16#include <string.h>
17#include <unistd.h>
18#include <math.h>
19
20#include <grass/gis.h>
21#include <grass/raster.h>
22#include <grass/glocale.h>
23
24/* prototypes */
25static double scancatlabel(const char *);
26
27/*!
28 * \brief Extract a cell value from raster map.
29 *
30 * Extract a cell value from raster map at given northing and easting
31 * with a sampled 3x3 window using a specified interpolation method.
32 *
33 * - NEAREST neighbor interpolation
34 * - BILINEAR bilinear interpolation
35 * - CUBIC cubic interpolation
36 *
37 * \param fd file descriptor
38 * \param window region settings
39 * \param cats categories
40 * \param north northing position
41 * \param east easting position
42 * \param usedesc flag to scan category label
43 * \param itype interpolation method
44 *
45 * \return cell value at given position
46 */
47DCELL Rast_get_sample(int fd, const struct Cell_head *window,
48 struct Categories *cats, double north, double east,
50{
51 double retval;
52
53 switch (itype) {
54 case INTERP_NEAREST:
55 retval =
56 Rast_get_sample_nearest(fd, window, cats, north, east, usedesc);
57 break;
58 case INTERP_BILINEAR:
59 retval =
60 Rast_get_sample_bilinear(fd, window, cats, north, east, usedesc);
61 break;
62 case INTERP_BICUBIC:
63 retval = Rast_get_sample_cubic(fd, window, cats, north, east, usedesc);
64 break;
65 default:
66 G_fatal_error("Rast_get_sample: %s", _("Unknown interpolation type"));
67 }
68
69 return retval;
70}
71
72/*!
73 * \brief Extract a cell value from raster map (neighbor interpolation)
74 *
75 * Extract a cell value from raster map at given northing and easting
76 * with a sampled 3x3 window using a neighbor interpolation.
77 *
78 * \param fd file descriptor
79 * \param window region settings
80 * \param cats categories
81 * \param north northing position
82 * \param east easting position
83 * \param usedesc flag to scan category label
84 *
85 * \return cell value at given position
86 */
87DCELL Rast_get_sample_nearest(int fd, const struct Cell_head *window,
88 struct Categories *cats, double north,
89 double east, int usedesc)
90{
91 int row, col;
92 DCELL result;
94
95 /* convert northing and easting to row and col, resp */
96 row = (int)floor(Rast_northing_to_row(north, window));
97 col = (int)floor(Rast_easting_to_col(east, window));
98
100 col >= Rast_window_cols()) {
101 Rast_set_d_null_value(&result, 1);
102 goto done;
103 }
104
105 Rast_get_d_row(fd, maprow, row);
106
108 Rast_set_d_null_value(&result, 1);
109 goto done;
110 }
111
112 if (usedesc) {
113 char *buf = Rast_get_c_cat((CELL *)&(maprow[col]), cats);
114
115 G_squeeze(buf);
116 result = scancatlabel(buf);
117 }
118 else
119 result = maprow[col];
120
121done:
122 G_free(maprow);
123
124 return result;
125}
126
127/*!
128 * \brief Extract a cell value from raster map (bilinear interpolation).
129 *
130 * Extract a cell value from raster map at given northing and easting
131 * with a sampled 3x3 window using a bilinear interpolation.
132 *
133 * \param fd file descriptor
134 * \param window region settings
135 * \param cats categories
136 * \param north northing position
137 * \param east easting position
138 * \param usedesc flag to scan category label
139 *
140 * \return cell value at given position
141 */
142DCELL Rast_get_sample_bilinear(int fd, const struct Cell_head *window,
143 struct Categories *cats, double north,
144 double east, int usedesc)
145{
146 int row, col;
147 double grid[2][2];
150 double frow, fcol, trow, tcol;
151 DCELL result;
152
153 frow = Rast_northing_to_row(north, window);
154 fcol = Rast_easting_to_col(east, window);
155
156 /* convert northing and easting to row and col, resp */
157 row = (int)floor(frow - 0.5);
158 col = (int)floor(fcol - 0.5);
159
160 trow = frow - row - 0.5;
161 tcol = fcol - col - 0.5;
162
164 col + 1 >= Rast_window_cols()) {
165 Rast_set_d_null_value(&result, 1);
166 goto done;
167 }
168
169 Rast_get_d_row(fd, arow, row);
170 Rast_get_d_row(fd, brow, row + 1);
171
176 Rast_set_d_null_value(&result, 1);
177 goto done;
178 }
179
180 /*-
181 * now were ready to do bilinear interpolation over
182 * arow[col], arow[col+1],
183 * brow[col], brow[col+1]
184 */
185
186 if (usedesc) {
187 char *buf;
188
189 G_squeeze(buf = Rast_get_c_cat((int *)&(arow[col]), cats));
190 grid[0][0] = scancatlabel(buf);
191 G_squeeze(buf = Rast_get_c_cat((CELL *)&(arow[col + 1]), cats));
192 grid[0][1] = scancatlabel(buf);
193 G_squeeze(buf = Rast_get_c_cat((CELL *)&(brow[col]), cats));
194 grid[1][0] = scancatlabel(buf);
195 G_squeeze(buf = Rast_get_c_cat((CELL *)&(brow[col + 1]), cats));
196 grid[1][1] = scancatlabel(buf);
197 }
198 else {
199 grid[0][0] = arow[col];
200 grid[0][1] = arow[col + 1];
201 grid[1][0] = brow[col];
202 grid[1][1] = brow[col + 1];
203 }
204
205 result = Rast_interp_bilinear(tcol, trow, grid[0][0], grid[0][1],
206 grid[1][0], grid[1][1]);
207
208done:
209 G_free(arow);
210 G_free(brow);
211
212 return result;
213}
214
215/*!
216 * \brief Extract a cell value from raster map (cubic interpolation).
217 *
218 * Extract a cell value from raster map at given northing and easting
219 * with a sampled 3x3 window using a cubic interpolation.
220 *
221 * \param fd file descriptor
222 * \param window region settings
223 * \param cats categories
224 * \param north northing position
225 * \param east easting position
226 * \param usedesc flag to scan category label
227 *
228 * \return cell value at given position
229 */
230DCELL Rast_get_sample_cubic(int fd, const struct Cell_head *window,
231 struct Categories *cats, double north, double east,
232 int usedesc)
233{
234 int i, j, row, col;
235 double grid[4][4];
236 DCELL *rows[4];
237 double frow, fcol, trow, tcol;
238 DCELL result;
239
240 for (i = 0; i < 4; i++)
241 rows[i] = Rast_allocate_d_buf();
242
243 frow = Rast_northing_to_row(north, window);
244 fcol = Rast_easting_to_col(east, window);
245
246 /* convert northing and easting to row and col, resp */
247 row = (int)floor(frow - 1.5);
248 col = (int)floor(fcol - 1.5);
249
250 trow = frow - row - 1.5;
251 tcol = fcol - col - 1.5;
252
254 col + 3 >= Rast_window_cols()) {
255 Rast_set_d_null_value(&result, 1);
256 goto done;
257 }
258
259 for (i = 0; i < 4; i++)
260 Rast_get_d_row(fd, rows[i], row + i);
261
262 for (i = 0; i < 4; i++)
263 for (j = 0; j < 4; j++)
264 if (Rast_is_d_null_value(&rows[i][col + j])) {
265 Rast_set_d_null_value(&result, 1);
266 goto done;
267 }
268
269 /*
270 * now were ready to do cubic interpolation over
271 * arow[col], arow[col+1], arow[col+2], arow[col+3],
272 * brow[col], brow[col+1], brow[col+2], brow[col+3],
273 * crow[col], crow[col+1], crow[col+2], crow[col+3],
274 * drow[col], drow[col+1], drow[col+2], drow[col+3],
275 */
276
277 if (usedesc) {
278 char *buf;
279
280 for (i = 0; i < 4; i++) {
281 for (j = 0; j < 4; j++) {
282 G_squeeze(
283 buf = Rast_get_c_cat((CELL *)&(rows[i][col + j]), cats));
284 grid[i][j] = scancatlabel(buf);
285 }
286 }
287 }
288 else {
289 for (i = 0; i < 4; i++)
290 for (j = 0; j < 4; j++)
291 grid[i][j] = rows[i][col + j];
292 }
293
294 result = Rast_interp_bicubic(
295 tcol, trow, grid[0][0], grid[0][1], grid[0][2], grid[0][3], grid[1][0],
296 grid[1][1], grid[1][2], grid[1][3], grid[2][0], grid[2][1], grid[2][2],
297 grid[2][3], grid[3][0], grid[3][1], grid[3][2], grid[3][3]);
298
299done:
300 for (i = 0; i < 4; i++)
301 G_free(rows[i]);
302
303 return result;
304}
305
306static double scancatlabel(const char *str)
307{
308 double val;
309
310 if (strcmp(str, "no data") != 0)
311 sscanf(str, "%lf", &val);
312 else {
313 G_warning(_("\"no data\" label found; setting to zero"));
314 val = 0.0;
315 }
316
317 return val;
318}
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
void G_squeeze(char *)
Remove superfluous white space.
Definition strings.c:444
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
DCELL Rast_interp_bilinear(double, double, DCELL, DCELL, DCELL, DCELL)
Definition interp.c:24
DCELL * Rast_allocate_d_buf(void)
Allocates memory for a raster map of type DCELL.
Definition alloc_cell.c:104
double Rast_easting_to_col(double, const struct Cell_head *)
Easting to column.
DCELL Rast_interp_bicubic(double, double, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL, DCELL)
Definition interp.c:42
void Rast_set_d_null_value(DCELL *, int)
To set a number of DCELL raster values to NULL.
Definition null_val.c:151
char * Rast_get_c_cat(CELL *, struct Categories *)
Get a raster category label (CELL)
void Rast_get_d_row(int, DCELL *, int)
Get raster row (DCELL type)
int Rast_window_cols(void)
Number of columns in active window.
int Rast_window_rows(void)
Number of rows in active window.
double Rast_northing_to_row(double, const struct Cell_head *)
Northing to row.
#define Rast_is_d_null_value(dcellVal)
double DCELL
Definition gis.h:632
int CELL
Definition gis.h:631
#define _(str)
Definition glocale.h:10
#define INTERP_BILINEAR
Definition raster.h:21
#define INTERP_NEAREST
Definition raster.h:20
#define INTERP_BICUBIC
Definition raster.h:22
int INTERP_TYPE
Definition raster.h:28
DCELL Rast_get_sample_cubic(int fd, const struct Cell_head *window, struct Categories *cats, double north, double east, int usedesc)
Extract a cell value from raster map (cubic interpolation).
Definition sample.c:230
DCELL Rast_get_sample_nearest(int fd, const struct Cell_head *window, struct Categories *cats, double north, double east, int usedesc)
Extract a cell value from raster map (neighbor interpolation)
Definition sample.c:87
DCELL Rast_get_sample_bilinear(int fd, const struct Cell_head *window, struct Categories *cats, double north, double east, int usedesc)
Extract a cell value from raster map (bilinear interpolation).
Definition sample.c:142
DCELL Rast_get_sample(int fd, const struct Cell_head *window, struct Categories *cats, double north, double east, int usedesc, INTERP_TYPE itype)
Extract a cell value from raster map.
Definition sample.c:47
2D/3D raster map header (used also for region)
Definition gis.h:443