GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
n_arrays_io.c
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * MODULE: Grass PDE Numerical Library
4 * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
5 * soerengebbert <at> gmx <dot> de
6 *
7 * PURPOSE: IO array management functions
8 * part of the gpde library
9 *
10 * COPYRIGHT: (C) 2000 by the GRASS Development Team
11 *
12 * This program is free software under the GNU General Public
13 * License (>=v2). Read the file COPYING that comes with GRASS
14 * for details.
15 *
16 *****************************************************************************/
17
18#include <math.h>
19
20#include <grass/N_pde.h>
21#include <grass/raster.h>
22#include <grass/glocale.h>
23
24/* ******************** 2D ARRAY FUNCTIONS *********************** */
25
26/*!
27 * \brief Read a raster map into a N_array_2d structure
28 *
29 * The raster map will be opened in the current region settings.
30 * If no N_array_2d structure is provided (NULL pointer), a new structure will
31 * be allocated with the same data type as the raster map and the size of the
32 * current region. The array offset will be set to 0. <br><br> If a N_array_2d
33 * structure is provided, the values from the raster map are casted to the
34 * N_array_2d type. The array must have the same size as the current region.
35 * <br><br>
36 * The new created or the provided array are returned.
37 * If the reading of the raster map fails, G_fatal_error() will
38 * be invoked.
39 *
40 * \param name * char - the name of an existing raster map
41 * \param array * N_array_2d - an existing array or NULL
42 * \return N_array_2d * - the existing or new allocated array
43 * */
45{
46 int map; /*The rastermap */
47 int x, y, cols, rows, type;
48 void *rast;
49 void *ptr;
50 struct Cell_head region;
51 N_array_2d *data = array;
52
53 /* Get the active region */
54 G_get_set_window(&region);
55
56 /*set the rows and cols */
57 rows = region.rows;
58 cols = region.cols;
59
60 /*open the raster map */
61 map = Rast_open_old(name, "");
62
63 type = Rast_get_map_type(map);
64
65 /*if the array is NULL create a new one with the data type of the raster map
66 */
67 /*the offset is 0 by default */
68 if (data == NULL) {
69 if (type == DCELL_TYPE) {
71 }
72 if (type == FCELL_TYPE) {
74 }
75 if (type == CELL_TYPE) {
77 }
78 }
79 else {
80 /*Check the array sizes */
81 if (data->cols != cols)
82 G_fatal_error("N_read_rast_to_array_2d: the data array size is "
83 "different from the current region settings");
84 if (data->rows != rows)
85 G_fatal_error("N_read_rast_to_array_2d: the data array size is "
86 "different from the current region settings");
87 }
88
89 rast = Rast_allocate_buf(type);
90
91 G_message(_("Reading raster map <%s> into memory"), name);
92
93 for (y = 0; y < rows; y++) {
94 G_percent(y, rows - 1, 10);
95
96 Rast_get_row(map, rast, y, type);
97
98 for (x = 0, ptr = rast; x < cols;
99 x++, ptr = G_incr_void_ptr(ptr, Rast_cell_size(type))) {
100 if (type == CELL_TYPE) {
101 if (Rast_is_c_null_value(ptr)) {
103 }
104 else {
105 if (data->type == CELL_TYPE)
106 N_put_array_2d_c_value(data, x, y,
107 (CELL) * (CELL *)ptr);
108 if (data->type == FCELL_TYPE)
109 N_put_array_2d_f_value(data, x, y,
110 (FCELL) * (CELL *)ptr);
111 if (data->type == DCELL_TYPE)
112 N_put_array_2d_d_value(data, x, y,
113 (DCELL) * (CELL *)ptr);
114 }
115 }
116 if (type == FCELL_TYPE) {
117 if (Rast_is_f_null_value(ptr)) {
119 }
120 else {
121 if (data->type == CELL_TYPE)
122 N_put_array_2d_c_value(data, x, y,
123 (CELL) * (FCELL *)ptr);
124 if (data->type == FCELL_TYPE)
125 N_put_array_2d_f_value(data, x, y,
126 (FCELL) * (FCELL *)ptr);
127 if (data->type == DCELL_TYPE)
128 N_put_array_2d_d_value(data, x, y,
129 (DCELL) * (FCELL *)ptr);
130 }
131 }
132 if (type == DCELL_TYPE) {
133 if (Rast_is_d_null_value(ptr)) {
135 }
136 else {
137 if (data->type == CELL_TYPE)
138 N_put_array_2d_c_value(data, x, y,
139 (CELL) * (DCELL *)ptr);
140 if (data->type == FCELL_TYPE)
141 N_put_array_2d_f_value(data, x, y,
142 (FCELL) * (DCELL *)ptr);
143 if (data->type == DCELL_TYPE)
144 N_put_array_2d_d_value(data, x, y,
145 (DCELL) * (DCELL *)ptr);
146 }
147 }
148 }
149 }
150
151 /* Close file */
152 Rast_close(map);
153 G_free(rast);
154
155 return data;
156}
157
158/*!
159 * \brief Write a N_array_2d struct to a raster map
160 *
161 * A new raster map is created with the same type as the N_array_2d.
162 * The current region is used to open the raster map.
163 * The N_array_2d must have the same size as the current region.
164 If the writing of the raster map fails, G_fatal_error() will
165 * be invoked.
166
167 * \param array N_array_2d *
168 * \param name char * - the name of the raster map
169 * \return void
170 *
171 * */
173{
174 int map; /*The rastermap */
175 int x, y, cols, rows, type;
176 CELL *rast = NULL;
177 FCELL *frast = NULL;
178 DCELL *drast = NULL;
179 struct Cell_head region;
180
181 if (!array)
182 G_fatal_error(_("N_array_2d * array is empty"));
183
184 /* Get the current region */
185 G_get_set_window(&region);
186
187 rows = region.rows;
188 cols = region.cols;
189 type = array->type;
190
191 /*Open the new map */
192 map = Rast_open_new(name, type);
193
194 if (type == CELL_TYPE)
195 rast = Rast_allocate_buf(type);
196 if (type == FCELL_TYPE)
197 frast = Rast_allocate_buf(type);
198 if (type == DCELL_TYPE)
199 drast = Rast_allocate_buf(type);
200
201 G_message(_("Write 2d array to raster map <%s>"), name);
202
203 for (y = 0; y < rows; y++) {
204 G_percent(y, rows - 1, 10);
205 for (x = 0; x < cols; x++) {
206 if (type == CELL_TYPE)
207 rast[x] = N_get_array_2d_c_value(array, x, y);
208 if (type == FCELL_TYPE)
209 frast[x] = N_get_array_2d_f_value(array, x, y);
210 if (type == DCELL_TYPE)
211 drast[x] = N_get_array_2d_d_value(array, x, y);
212 }
213 if (type == CELL_TYPE)
214 Rast_put_c_row(map, rast);
215 if (type == FCELL_TYPE)
216 Rast_put_f_row(map, frast);
217 if (type == DCELL_TYPE)
218 Rast_put_d_row(map, drast);
219 }
220
221 /* Close file */
222 Rast_close(map);
223 G_free(rast);
224 G_free(frast);
225 G_free(drast);
226}
227
228/* ******************** 3D ARRAY FUNCTIONS *********************** */
229
230/*!
231 * \brief Read a volume map into a N_array_3d structure
232 *
233 * The volume map is opened in the current region settings.
234 * If no N_array_3d structure is provided (NULL pointer), a new structure will
235 * be allocated with the same data type as the volume map and the size of the
236 * current region. The array offset will be set to 0. <br><br>
237 *
238 * If a N_array_3d structure is provided, the values from the volume map are
239 * casted to the N_array_3d type. The array must have the same size
240 * as the current region.
241 * <br><br>
242 *
243 * The new created or the provided array is returned.
244 * If the reading of the volume map fails, Rast3d_fatal_error() will
245 * be invoked.
246 *
247 * \param name * char - the name of an existing volume map
248 * \param array * N_array_3d - an existing array or NULL
249 * \param mask int - 0 = false, 1 = true : if a mask is presenent, use it with
250 * the input volume map \return N_array_3d * - the existing or new allocated
251 * array
252 * */
254{
255 void *map = NULL; /*The 3D Rastermap */
256 int changemask = 0;
257 int x, y, z, cols, rows, depths, type;
258 double d1 = 0, f1 = 0;
259 N_array_3d *data = array;
260 RASTER3D_Region region;
261
262 /*get the current region */
263 Rast3d_get_window(&region);
264
265 cols = region.cols;
266 rows = region.rows;
267 depths = region.depths;
268
269 if (NULL == G_find_raster3d(name, ""))
270 Rast3d_fatal_error(_("3D raster map <%s> not found"), name);
271
272 /*Open all maps with default region */
276
277 if (map == NULL)
278 Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), name);
279
280 type = Rast3d_tile_type_map(map);
281
282 /*if the array is NULL create a new one with the data type of the volume map
283 */
284 /*the offset is 0 by default */
285 if (data == NULL) {
286 if (type == FCELL_TYPE) {
288 }
289 if (type == DCELL_TYPE) {
291 }
292 }
293 else {
294 /*Check the array sizes */
295 if (data->cols != cols)
296 G_fatal_error("N_read_rast_to_array_3d: the data array size is "
297 "different from the current region settings");
298 if (data->rows != rows)
299 G_fatal_error("N_read_rast_to_array_3d: the data array size is "
300 "different from the current region settings");
301 if (data->depths != depths)
302 G_fatal_error("N_read_rast_to_array_3d: the data array size is "
303 "different from the current region settings");
304 }
305
306 G_message(_("Read g3d map <%s> into the memory"), name);
307
308 /*if requested set the Mask on */
309 if (mask) {
311 changemask = 0;
312 if (Rast3d_mask_is_off(map)) {
313 Rast3d_mask_on(map);
314 changemask = 1;
315 }
316 }
317 }
318
319 for (z = 0; z < depths; z++) { /*From the bottom to the top */
320 G_percent(z, depths - 1, 10);
321 for (y = 0; y < rows; y++) {
322 for (x = 0; x < cols; x++) {
323 if (type == FCELL_TYPE) {
324 Rast3d_get_value(map, x, y, z, &f1, type);
325 if (Rast_is_f_null_value((void *)&f1)) {
326 N_put_array_3d_value_null(data, x, y, z);
327 }
328 else {
329 if (data->type == FCELL_TYPE)
330 N_put_array_3d_f_value(data, x, y, z, f1);
331 if (data->type == DCELL_TYPE)
332 N_put_array_3d_d_value(data, x, y, z, (double)f1);
333 }
334 }
335 else {
336 Rast3d_get_value(map, x, y, z, &d1, type);
337 if (Rast_is_d_null_value((void *)&d1)) {
338 N_put_array_3d_value_null(data, x, y, z);
339 }
340 else {
341 if (data->type == FCELL_TYPE)
342 N_put_array_3d_f_value(data, x, y, z, (float)d1);
343 if (data->type == DCELL_TYPE)
344 N_put_array_3d_d_value(data, x, y, z, d1);
345 }
346 }
347 }
348 }
349 }
350
351 /*We set the Mask off, if it was off before */
352 if (mask) {
354 if (Rast3d_mask_is_on(map) && changemask)
355 Rast3d_mask_off(map);
356 }
357
358 /* Close files and exit */
359 if (!Rast3d_close(map))
360 Rast3d_fatal_error(_("Error closing g3d file <%s>"), name);
361
362 return data;
363}
364
365/*!
366 * \brief Write a N_array_3d struct to a volume map
367 *
368 * A new volume map is created with the same type as the N_array_3d.
369 * The current region is used to open the volume map.
370 * The N_array_3d must have the same size as the current region.
371 * If the writing of the volume map fails, Rast3d_fatal_error() will
372 * be invoked.
373 *
374 *
375 * \param array N_array_3d *
376 * \param name char * - the name of the volume map
377 * \param mask int - 1 = use a 3d mask, 0 do not use a 3d mask
378 * \return void
379 *
380 * */
382{
383 void *map = NULL; /*The 3D Rastermap */
384 int changemask = 0;
385 int x, y, z, cols, rows, depths, type;
386 double d1 = 0.0, f1 = 0.0;
387 N_array_3d *data = array;
388 RASTER3D_Region region;
389
390 /*get the current region */
391 Rast3d_get_window(&region);
392
393 cols = region.cols;
394 rows = region.rows;
395 depths = region.depths;
396 type = data->type;
397
398 /*Check the array sizes */
399 if (data->cols != cols)
400 G_fatal_error("N_write_array_3d_to_rast3d: the data array size is "
401 "different from the current region settings");
402 if (data->rows != rows)
403 G_fatal_error("N_write_array_3d_to_rast3d: the data array size is "
404 "different from the current region settings");
405 if (data->depths != depths)
406 G_fatal_error("N_write_array_3d_to_rast3d: the data array size is "
407 "different from the current region settings");
408
409 /*Open the new map */
410 if (type == DCELL_TYPE)
412 &region, DCELL_TYPE, 32);
413 else if (type == FCELL_TYPE)
415 &region, FCELL_TYPE, 32);
416
417 if (map == NULL)
418 Rast3d_fatal_error(_("Error opening g3d map <%s>"), name);
419
420 G_message(_("Write 3d array to g3d map <%s>"), name);
421
422 /*if requested set the Mask on */
423 if (mask) {
425 changemask = 0;
426 if (Rast3d_mask_is_off(map)) {
427 Rast3d_mask_on(map);
428 changemask = 1;
429 }
430 }
431 }
432
433 for (z = 0; z < depths; z++) { /*From the bottom to the top */
434 G_percent(z, depths - 1, 10);
435 for (y = 0; y < rows; y++) {
436 for (x = 0; x < cols; x++) {
437 if (type == FCELL_TYPE) {
438 f1 = N_get_array_3d_f_value(data, x, y, z);
439 Rast3d_put_float(map, x, y, z, f1);
440 }
441 else if (type == DCELL_TYPE) {
442 d1 = N_get_array_3d_d_value(data, x, y, z);
443 Rast3d_put_double(map, x, y, z, d1);
444 }
445 }
446 }
447 }
448
449 /*We set the Mask off, if it was off before */
450 if (mask) {
452 if (Rast3d_mask_is_on(map) && changemask)
453 Rast3d_mask_off(map);
454 }
455
456 /* Flush all tile */
457 if (!Rast3d_flush_all_tiles(map))
458 Rast3d_fatal_error("Error flushing tiles with Rast3d_flush_all_tiles");
459 /* Close files and exit */
460 if (!Rast3d_close(map))
461 Rast3d_fatal_error(_("Error closing g3d file <%s>"), name);
462
463 return;
464}
#define NULL
Definition ccmath.h:32
void G_percent(long, long, int)
Print percent complete messages.
Definition percent.c:61
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
const char * G_find_raster3d(const char *, const char *)
Search for a 3D raster map in current search path or in a specified mapset.
Definition find_rast3d.c:28
void G_get_set_window(struct Cell_head *)
Get the current working window (region)
#define G_incr_void_ptr(ptr, size)
Definition defs/gis.h:81
void G_message(const char *,...) __attribute__((format(printf
void * Rast3d_open_new_opt_tile_size(const char *, int, RASTER3D_Region *, int, int)
Opens new g3d-file with name in the current mapset. This method tries to compute optimal tile size ba...
Definition open2.c:95
void Rast3d_get_value(RASTER3D_Map *, int, int, int, void *, int)
Returns in *value the resampled cell-value of the cell with window-coordinate (x, y,...
Definition getvalue.c:21
int Rast3d_flush_all_tiles(RASTER3D_Map *)
Definition cache.c:283
int Rast3d_mask_is_off(RASTER3D_Map *)
Returns 1 if the mask for map is turned off. Returns 0 otherwise.
Definition mask.c:366
int Rast3d_put_float(RASTER3D_Map *, int, int, int, float)
Is equivalent to Rast3d_put_value (map, x, y, z, &value, FCELL_TYPE).
Definition putvalue.c:17
int Rast3d_tile_type_map(RASTER3D_Map *)
Returns the type in which tiles of map are stored in memory.
Definition headerinfo.c:150
void Rast3d_mask_off(RASTER3D_Map *)
Turns off the mask for map. This is the default. Do not invoke this function after the first tile has...
Definition mask.c:339
int Rast3d_mask_file_exists(void)
Returns 1 if the 3d mask file exists.
Definition mask.c:63
void * Rast3d_open_cell_old(const char *, const char *, RASTER3D_Region *, int, int)
Opens existing g3d-file name in mapset. Tiles are stored in memory with type which must be any of FCE...
void Rast3d_mask_on(RASTER3D_Map *)
Turns on the mask for map. Do not invoke this function after the first tile has been read since the r...
Definition mask.c:324
int Rast3d_put_double(RASTER3D_Map *, int, int, int, double)
Is equivalent to Rast3d_put_value (map, x, y, z, &value, DCELL_TYPE).
Definition putvalue.c:51
void Rast3d_get_window(RASTER3D_Region *)
Stores the current default window in window.
void Rast3d_fatal_error(const char *,...) __attribute__((format(printf
int Rast3d_close(RASTER3D_Map *)
Close 3D raster map files.
int Rast3d_mask_is_on(RASTER3D_Map *)
Returns 1 if the mask for map is turned on. Returns 0 otherwise.
Definition mask.c:353
#define Rast_is_f_null_value(fcellVal)
void Rast_close(int)
Close a raster map.
int Rast_open_old(const char *, const char *)
Open an existing integer raster map (cell)
void Rast_put_f_row(int, const FCELL *)
Writes the next row for fcell file (FCELL version)
int Rast_open_new(const char *, RASTER_MAP_TYPE)
Opens a new raster map.
size_t Rast_cell_size(RASTER_MAP_TYPE)
Returns size of a raster cell in bytes.
Definition alloc_cell.c:37
void Rast_put_d_row(int, const DCELL *)
Writes the next row for dcell file (DCELL version)
void * Rast_allocate_buf(RASTER_MAP_TYPE)
Allocate memory for a raster map of given type.
Definition alloc_cell.c:53
void Rast_put_c_row(int, const CELL *)
Writes the next row for cell file (CELL version)
#define Rast_is_d_null_value(dcellVal)
#define Rast_is_c_null_value(cellVal)
RASTER_MAP_TYPE Rast_get_map_type(int)
Determine raster type from descriptor.
void Rast_get_row(int, void *, int, RASTER_MAP_TYPE)
Get raster row.
float FCELL
Definition gis.h:636
double DCELL
Definition gis.h:635
int CELL
Definition gis.h:634
#define _(str)
Definition glocale.h:10
FCELL N_get_array_2d_f_value(N_array_2d *data, int col, int row)
Returns the value of type FCELL at position col, row.
Definition n_arrays.c:347
void N_put_array_3d_value_null(N_array_3d *data, int col, int row, int depth)
This function writes a null value to the N_array_3d data at position col, row, depth.
Definition n_arrays.c:1060
N_array_3d * N_alloc_array_3d(int cols, int rows, int depths, int offset, int type)
Allocate memory for a N_array_3d data structure.
Definition n_arrays.c:719
CELL N_get_array_2d_c_value(N_array_2d *data, int col, int row)
Returns the value of type CELL at position col, row.
Definition n_arrays.c:314
void N_put_array_2d_f_value(N_array_2d *data, int col, int row, FCELL value)
Writes a FCELL value to the N_array_2d struct at position col, row.
Definition n_arrays.c:546
float N_get_array_3d_f_value(N_array_3d *data, int col, int row, int depth)
This function returns the value of type float at position col, row, depth.
Definition n_arrays.c:948
void N_put_array_3d_f_value(N_array_3d *data, int col, int row, int depth, float value)
This function writes a float value to the N_array_3d data at position col, row, depth.
Definition n_arrays.c:1121
DCELL N_get_array_2d_d_value(N_array_2d *data, int col, int row)
Returns the value of type DCELL at position col, row.
Definition n_arrays.c:380
void N_put_array_3d_d_value(N_array_3d *data, int col, int row, int depth, double value)
Writes a double value to the N_array_3d struct at position col, row, depth.
Definition n_arrays.c:1148
N_array_2d * N_alloc_array_2d(int cols, int rows, int offset, int type)
Allocate memory for a N_array_2d data structure.
Definition n_arrays.c:75
double N_get_array_3d_d_value(N_array_3d *data, int col, int row, int depth)
This function returns the value of type float at position col, row, depth.
Definition n_arrays.c:979
void N_put_array_2d_value_null(N_array_2d *data, int col, int row)
Writes the null value to the N_array_2d struct at position col, row.
Definition n_arrays.c:459
void N_put_array_2d_c_value(N_array_2d *data, int col, int row, CELL value)
Writes a CELL value to the N_array_2d struct at position col, row.
Definition n_arrays.c:516
void N_put_array_2d_d_value(N_array_2d *data, int col, int row, DCELL value)
Writes a DCELL value to the N_array_2d struct at position col, row.
Definition n_arrays.c:576
void N_write_array_3d_to_rast3d(N_array_3d *array, char *name, int mask)
Write a N_array_3d struct to a volume map.
N_array_2d * N_read_rast_to_array_2d(char *name, N_array_2d *array)
Read a raster map into a N_array_2d structure.
Definition n_arrays_io.c:44
N_array_3d * N_read_rast3d_to_array_3d(char *name, N_array_3d *array, int mask)
Read a volume map into a N_array_3d structure.
void N_write_array_2d_to_rast(N_array_2d *array, char *name)
Write a N_array_2d struct to a raster map.
const char * name
Definition named_colr.c:6
#define RASTER3D_DEFAULT_WINDOW
Definition raster3d.h:29
#define RASTER3D_USE_CACHE_DEFAULT
Definition raster3d.h:19
#define RASTER3D_TILE_SAME_AS_FILE
Definition raster3d.h:11
#define RASTER3D_USE_CACHE_XY
Definition raster3d.h:23
#define FCELL_TYPE
Definition raster.h:12
#define DCELL_TYPE
Definition raster.h:13
#define CELL_TYPE
Definition raster.h:11
2D/3D raster map header (used also for region)
Definition gis.h:446
int depths
number of depths for 3D data
Definition gis.h:469
int rows
Number of rows for 2D data.
Definition gis.h:461
int cols
Number of columns for 2D data.
Definition gis.h:465
int type
Definition N_pde.h:133
int type
Definition N_pde.h:176
int rows
Definition N_pde.h:177
int depths
Definition N_pde.h:177
int cols
Definition N_pde.h:177
#define x