GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
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 * SPDX-FileCopyrightText: 2000 GRASS Development Team
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 *
13 *****************************************************************************/
14
15#include <math.h>
16
17#include <grass/N_pde.h>
18#include <grass/raster.h>
19#include <grass/glocale.h>
20
21/* ******************** 2D ARRAY FUNCTIONS *********************** */
22
23/*!
24 * \brief Read a raster map into a N_array_2d structure
25 *
26 * The raster map will be opened in the current region settings.
27 * If no N_array_2d structure is provided (NULL pointer), a new structure will
28 * be allocated with the same data type as the raster map and the size of the
29 * current region. The array offset will be set to 0. <br><br> If a N_array_2d
30 * structure is provided, the values from the raster map are casted to the
31 * N_array_2d type. The array must have the same size as the current region.
32 * <br><br>
33 * The new created or the provided array are returned.
34 * If the reading of the raster map fails, G_fatal_error() will
35 * be invoked.
36 *
37 * \param name * char - the name of an existing raster map
38 * \param array * N_array_2d - an existing array or NULL
39 * \return N_array_2d * - the existing or new allocated array
40 * */
42{
43 int map; /*The rastermap */
44 int x, y, cols, rows, type;
45 void *rast;
46 void *ptr;
47 struct Cell_head region;
48 N_array_2d *data = array;
49
50 /* Get the active region */
51 G_get_set_window(&region);
52
53 /*set the rows and cols */
54 rows = region.rows;
55 cols = region.cols;
56
57 /*open the raster map */
58 map = Rast_open_old(name, "");
59
60 type = Rast_get_map_type(map);
61
62 /*if the array is NULL create a new one with the data type of the raster map
63 */
64 /*the offset is 0 by default */
65 if (data == NULL) {
66 if (type == DCELL_TYPE) {
68 }
69 if (type == FCELL_TYPE) {
71 }
72 if (type == CELL_TYPE) {
74 }
75 }
76 else {
77 /*Check the array sizes */
78 if (data->cols != cols)
79 G_fatal_error("N_read_rast_to_array_2d: the data array size is "
80 "different from the current region settings");
81 if (data->rows != rows)
82 G_fatal_error("N_read_rast_to_array_2d: the data array size is "
83 "different from the current region settings");
84 }
85
86 rast = Rast_allocate_buf(type);
87
88 G_message(_("Reading raster map <%s> into memory"), name);
89
90 for (y = 0; y < rows; y++) {
91 G_percent(y, rows - 1, 10);
92
93 Rast_get_row(map, rast, y, type);
94
95 for (x = 0, ptr = rast; x < cols;
96 x++, ptr = G_incr_void_ptr(ptr, Rast_cell_size(type))) {
97 if (type == CELL_TYPE) {
98 if (Rast_is_c_null_value(ptr)) {
100 }
101 else {
102 if (data->type == CELL_TYPE)
103 N_put_array_2d_c_value(data, x, y,
104 (CELL) * (CELL *)ptr);
105 if (data->type == FCELL_TYPE)
106 N_put_array_2d_f_value(data, x, y,
107 (FCELL) * (CELL *)ptr);
108 if (data->type == DCELL_TYPE)
109 N_put_array_2d_d_value(data, x, y,
110 (DCELL) * (CELL *)ptr);
111 }
112 }
113 if (type == FCELL_TYPE) {
114 if (Rast_is_f_null_value(ptr)) {
116 }
117 else {
118 if (data->type == CELL_TYPE)
119 N_put_array_2d_c_value(data, x, y,
120 (CELL) * (FCELL *)ptr);
121 if (data->type == FCELL_TYPE)
122 N_put_array_2d_f_value(data, x, y,
123 (FCELL) * (FCELL *)ptr);
124 if (data->type == DCELL_TYPE)
125 N_put_array_2d_d_value(data, x, y,
126 (DCELL) * (FCELL *)ptr);
127 }
128 }
129 if (type == DCELL_TYPE) {
130 if (Rast_is_d_null_value(ptr)) {
132 }
133 else {
134 if (data->type == CELL_TYPE)
135 N_put_array_2d_c_value(data, x, y,
136 (CELL) * (DCELL *)ptr);
137 if (data->type == FCELL_TYPE)
138 N_put_array_2d_f_value(data, x, y,
139 (FCELL) * (DCELL *)ptr);
140 if (data->type == DCELL_TYPE)
141 N_put_array_2d_d_value(data, x, y,
142 (DCELL) * (DCELL *)ptr);
143 }
144 }
145 }
146 }
147
148 /* Close file */
149 Rast_close(map);
150 G_free(rast);
151
152 return data;
153}
154
155/*!
156 * \brief Write a N_array_2d struct to a raster map
157 *
158 * A new raster map is created with the same type as the N_array_2d.
159 * The current region is used to open the raster map.
160 * The N_array_2d must have the same size as the current region.
161 If the writing of the raster map fails, G_fatal_error() will
162 * be invoked.
163
164 * \param array N_array_2d *
165 * \param name char * - the name of the raster map
166 * \return void
167 *
168 * */
170{
171 int map; /*The rastermap */
172 int x, y, cols, rows, type;
173 CELL *rast = NULL;
174 FCELL *frast = NULL;
175 DCELL *drast = NULL;
176 struct Cell_head region;
177
178 if (!array)
179 G_fatal_error(_("N_array_2d * array is empty"));
180
181 /* Get the current region */
182 G_get_set_window(&region);
183
184 rows = region.rows;
185 cols = region.cols;
186 type = array->type;
187
188 /*Open the new map */
189 map = Rast_open_new(name, type);
190
191 if (type == CELL_TYPE)
192 rast = Rast_allocate_buf(type);
193 if (type == FCELL_TYPE)
194 frast = Rast_allocate_buf(type);
195 if (type == DCELL_TYPE)
196 drast = Rast_allocate_buf(type);
197
198 G_message(_("Write 2d array to raster map <%s>"), name);
199
200 for (y = 0; y < rows; y++) {
201 G_percent(y, rows - 1, 10);
202 for (x = 0; x < cols; x++) {
203 if (type == CELL_TYPE)
204 rast[x] = N_get_array_2d_c_value(array, x, y);
205 if (type == FCELL_TYPE)
206 frast[x] = N_get_array_2d_f_value(array, x, y);
207 if (type == DCELL_TYPE)
208 drast[x] = N_get_array_2d_d_value(array, x, y);
209 }
210 if (type == CELL_TYPE)
211 Rast_put_c_row(map, rast);
212 if (type == FCELL_TYPE)
213 Rast_put_f_row(map, frast);
214 if (type == DCELL_TYPE)
215 Rast_put_d_row(map, drast);
216 }
217
218 /* Close file */
219 Rast_close(map);
220 G_free(rast);
221 G_free(frast);
222 G_free(drast);
223}
224
225/* ******************** 3D ARRAY FUNCTIONS *********************** */
226
227/*!
228 * \brief Read a volume map into a N_array_3d structure
229 *
230 * The volume map is opened in the current region settings.
231 * If no N_array_3d structure is provided (NULL pointer), a new structure will
232 * be allocated with the same data type as the volume map and the size of the
233 * current region. The array offset will be set to 0. <br><br>
234 *
235 * If a N_array_3d structure is provided, the values from the volume map are
236 * casted to the N_array_3d type. The array must have the same size
237 * as the current region.
238 * <br><br>
239 *
240 * The new created or the provided array is returned.
241 * If the reading of the volume map fails, Rast3d_fatal_error() will
242 * be invoked.
243 *
244 * \param name * char - the name of an existing volume map
245 * \param array * N_array_3d - an existing array or NULL
246 * \param mask int - 0 = false, 1 = true : if a mask is presenent, use it with
247 * the input volume map \return N_array_3d * - the existing or new allocated
248 * array
249 * */
251{
252 void *map = NULL; /*The 3D Rastermap */
253 int changemask = 0;
254 int x, y, z, cols, rows, depths, type;
255 double d1 = 0, f1 = 0;
256 N_array_3d *data = array;
257 RASTER3D_Region region;
258
259 /*get the current region */
260 Rast3d_get_window(&region);
261
262 cols = region.cols;
263 rows = region.rows;
264 depths = region.depths;
265
266 if (NULL == G_find_raster3d(name, ""))
267 Rast3d_fatal_error(_("3D raster map <%s> not found"), name);
268
269 /*Open all maps with default region */
273
274 if (map == NULL)
275 Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), name);
276
277 type = Rast3d_tile_type_map(map);
278
279 /*if the array is NULL create a new one with the data type of the volume map
280 */
281 /*the offset is 0 by default */
282 if (data == NULL) {
283 if (type == FCELL_TYPE) {
285 }
286 if (type == DCELL_TYPE) {
288 }
289 }
290 else {
291 /*Check the array sizes */
292 if (data->cols != cols)
293 G_fatal_error("N_read_rast_to_array_3d: the data array size is "
294 "different from the current region settings");
295 if (data->rows != rows)
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->depths != depths)
299 G_fatal_error("N_read_rast_to_array_3d: the data array size is "
300 "different from the current region settings");
301 }
302
303 G_message(_("Read g3d map <%s> into the memory"), name);
304
305 /*if requested set the Mask on */
306 if (mask) {
308 changemask = 0;
309 if (Rast3d_mask_is_off(map)) {
310 Rast3d_mask_on(map);
311 changemask = 1;
312 }
313 }
314 }
315
316 for (z = 0; z < depths; z++) { /*From the bottom to the top */
317 G_percent(z, depths - 1, 10);
318 for (y = 0; y < rows; y++) {
319 for (x = 0; x < cols; x++) {
320 if (type == FCELL_TYPE) {
321 Rast3d_get_value(map, x, y, z, &f1, type);
322 if (Rast_is_f_null_value((void *)&f1)) {
323 N_put_array_3d_value_null(data, x, y, z);
324 }
325 else {
326 if (data->type == FCELL_TYPE)
327 N_put_array_3d_f_value(data, x, y, z, f1);
328 if (data->type == DCELL_TYPE)
329 N_put_array_3d_d_value(data, x, y, z, (double)f1);
330 }
331 }
332 else {
333 Rast3d_get_value(map, x, y, z, &d1, type);
334 if (Rast_is_d_null_value((void *)&d1)) {
335 N_put_array_3d_value_null(data, x, y, z);
336 }
337 else {
338 if (data->type == FCELL_TYPE)
339 N_put_array_3d_f_value(data, x, y, z, (float)d1);
340 if (data->type == DCELL_TYPE)
341 N_put_array_3d_d_value(data, x, y, z, d1);
342 }
343 }
344 }
345 }
346 }
347
348 /*We set the Mask off, if it was off before */
349 if (mask) {
351 if (Rast3d_mask_is_on(map) && changemask)
352 Rast3d_mask_off(map);
353 }
354
355 /* Close files and exit */
356 if (!Rast3d_close(map))
357 Rast3d_fatal_error(_("Error closing g3d file <%s>"), name);
358
359 return data;
360}
361
362/*!
363 * \brief Write a N_array_3d struct to a volume map
364 *
365 * A new volume map is created with the same type as the N_array_3d.
366 * The current region is used to open the volume map.
367 * The N_array_3d must have the same size as the current region.
368 * If the writing of the volume map fails, Rast3d_fatal_error() will
369 * be invoked.
370 *
371 *
372 * \param array N_array_3d *
373 * \param name char * - the name of the volume map
374 * \param mask int - 1 = use a 3d mask, 0 do not use a 3d mask
375 * \return void
376 *
377 * */
379{
380 void *map = NULL; /*The 3D Rastermap */
381 int changemask = 0;
382 int x, y, z, cols, rows, depths, type;
383 double d1 = 0.0, f1 = 0.0;
384 N_array_3d *data = array;
385 RASTER3D_Region region;
386
387 /*get the current region */
388 Rast3d_get_window(&region);
389
390 cols = region.cols;
391 rows = region.rows;
392 depths = region.depths;
393 type = data->type;
394
395 /*Check the array sizes */
396 if (data->cols != cols)
397 G_fatal_error("N_write_array_3d_to_rast3d: the data array size is "
398 "different from the current region settings");
399 if (data->rows != rows)
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->depths != depths)
403 G_fatal_error("N_write_array_3d_to_rast3d: the data array size is "
404 "different from the current region settings");
405
406 /*Open the new map */
407 if (type == DCELL_TYPE)
409 &region, DCELL_TYPE, 32);
410 else if (type == FCELL_TYPE)
412 &region, FCELL_TYPE, 32);
413
414 if (map == NULL)
415 Rast3d_fatal_error(_("Error opening g3d map <%s>"), name);
416
417 G_message(_("Write 3d array to g3d map <%s>"), name);
418
419 /*if requested set the Mask on */
420 if (mask) {
422 changemask = 0;
423 if (Rast3d_mask_is_off(map)) {
424 Rast3d_mask_on(map);
425 changemask = 1;
426 }
427 }
428 }
429
430 for (z = 0; z < depths; z++) { /*From the bottom to the top */
431 G_percent(z, depths - 1, 10);
432 for (y = 0; y < rows; y++) {
433 for (x = 0; x < cols; x++) {
434 if (type == FCELL_TYPE) {
435 f1 = N_get_array_3d_f_value(data, x, y, z);
436 Rast3d_put_float(map, x, y, z, f1);
437 }
438 else if (type == DCELL_TYPE) {
439 d1 = N_get_array_3d_d_value(data, x, y, z);
440 Rast3d_put_double(map, x, y, z, d1);
441 }
442 }
443 }
444 }
445
446 /*We set the Mask off, if it was off before */
447 if (mask) {
449 if (Rast3d_mask_is_on(map) && changemask)
450 Rast3d_mask_off(map);
451 }
452
453 /* Flush all tile */
454 if (!Rast3d_flush_all_tiles(map))
455 Rast3d_fatal_error("Error flushing tiles with Rast3d_flush_all_tiles");
456 /* Close files and exit */
457 if (!Rast3d_close(map))
458 Rast3d_fatal_error(_("Error closing g3d file <%s>"), name);
459
460 return;
461}
#define NULL
Definition ccmath.h:32
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
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:26
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:78
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:35
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:51
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:633
double DCELL
Definition gis.h:632
int CELL
Definition gis.h:631
#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:344
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:1057
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:716
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:311
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:543
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:945
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:1118
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:377
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:1145
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:72
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:976
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:456
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:513
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:573
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:41
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:443
int depths
number of depths for 3D data
Definition gis.h:466
int rows
Number of rows for 2D data.
Definition gis.h:458
int cols
Number of columns for 2D data.
Definition gis.h:462
int type
Definition N_pde.h:130
int type
Definition N_pde.h:173
int rows
Definition N_pde.h:174
int depths
Definition N_pde.h:174
int cols
Definition N_pde.h:174
#define x