2
/*****************************************************************************
4
* MODULE: Grass PDE Numerical Library
5
* AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
6
* soerengebbert <at> gmx <dot> de
8
* PURPOSE: IO array managment functions
9
* part of the gpde library
11
* COPYRIGHT: (C) 2000 by the GRASS Development Team
13
* This program is free software under the GNU General Public
14
* License (>=v2). Read the file COPYING that comes with GRASS
17
*****************************************************************************/
20
#include <grass/N_pde.h>
21
#include <grass/raster.h>
22
#include <grass/glocale.h>
25
/* ******************** 2D ARRAY FUNCTIONS *********************** */
28
* \brief Read a raster map into a N_array_2d structure
30
* The raster map will be opened in the current region settings.
31
* If no N_array_2d structure is provided (NULL pointer), a new structure will be
32
* allocated with the same data type as the raster map and the size of the current region.
33
* The array offset will be set to 0.
35
* If a N_array_2d structure is provided, the values from the raster map are
36
* casted to the N_array_2d type. The array must have the same size
37
* as the current region.
39
* The new created or the provided array are returned.
40
* If the reading of the raster map fails, G_fatal_error() will
43
* \param name * char - the name of an existing raster map
44
* \param array * N_array_2d - an existing array or NULL
45
* \return N_array_2d * - the existing or new allocated array
47
N_array_2d *N_read_rast_to_array_2d(char *name, N_array_2d * array)
49
int map; /*The rastermap */
50
int x, y, cols, rows, type;
53
struct Cell_head region;
54
N_array_2d *data = array;
56
/* Get the active region */
57
G_get_set_window(®ion);
59
/*set the rows and cols */
63
/*open the raster map */
64
map = Rast_open_old(name, "");
66
type = Rast_get_map_type(map);
68
/*if the array is NULL create a new one with the data type of the raster map */
69
/*the offset is 0 by default */
71
if (type == DCELL_TYPE) {
72
data = N_alloc_array_2d(cols, rows, 0, DCELL_TYPE);
74
if (type == FCELL_TYPE) {
75
data = N_alloc_array_2d(cols, rows, 0, FCELL_TYPE);
77
if (type == CELL_TYPE) {
78
data = N_alloc_array_2d(cols, rows, 0, CELL_TYPE);
82
/*Check the array sizes */
83
if (data->cols != cols)
85
("N_read_rast_to_array_2d: the data array size is different from the current region settings");
86
if (data->rows != rows)
88
("N_read_rast_to_array_2d: the data array size is different from the current region settings");
91
rast = Rast_allocate_buf(type);
93
G_message(_("Reading raster map <%s> into memory"), name);
95
for (y = 0; y < rows; y++) {
96
G_percent(y, rows - 1, 10);
98
Rast_get_row(map, rast, y, type);
100
for (x = 0, ptr = rast; x < cols;
101
x++, ptr = G_incr_void_ptr(ptr, Rast_cell_size(type))) {
102
if (type == CELL_TYPE) {
103
if (Rast_is_c_null_value(ptr)) {
104
N_put_array_2d_value_null(data, x, y);
107
if (data->type == CELL_TYPE)
108
N_put_array_2d_c_value(data, x, y,
109
(CELL) * (CELL *) ptr);
110
if (data->type == FCELL_TYPE)
111
N_put_array_2d_f_value(data, x, y,
112
(FCELL) * (CELL *) ptr);
113
if (data->type == DCELL_TYPE)
114
N_put_array_2d_d_value(data, x, y,
115
(DCELL) * (CELL *) ptr);
118
if (type == FCELL_TYPE) {
119
if (Rast_is_f_null_value(ptr)) {
120
N_put_array_2d_value_null(data, x, y);
123
if (data->type == CELL_TYPE)
124
N_put_array_2d_c_value(data, x, y,
125
(CELL) * (FCELL *) ptr);
126
if (data->type == FCELL_TYPE)
127
N_put_array_2d_f_value(data, x, y,
128
(FCELL) * (FCELL *) ptr);
129
if (data->type == DCELL_TYPE)
130
N_put_array_2d_d_value(data, x, y,
131
(DCELL) * (FCELL *) ptr);
134
if (type == DCELL_TYPE) {
135
if (Rast_is_d_null_value(ptr)) {
136
N_put_array_2d_value_null(data, x, y);
139
if (data->type == CELL_TYPE)
140
N_put_array_2d_c_value(data, x, y,
141
(CELL) * (DCELL *) ptr);
142
if (data->type == FCELL_TYPE)
143
N_put_array_2d_f_value(data, x, y,
144
(FCELL) * (DCELL *) ptr);
145
if (data->type == DCELL_TYPE)
146
N_put_array_2d_d_value(data, x, y,
147
(DCELL) * (DCELL *) ptr);
160
* \brief Write a N_array_2d struct to a raster map
162
* A new raster map is created with the same type as the N_array_2d.
163
* The current region is used to open the raster map.
164
* The N_array_2d must have the same size as the current region.
165
If the writing of the raster map fails, G_fatal_error() will
168
* \param array N_array_2d *
169
* \param name char * - the name of the raster map
173
void N_write_array_2d_to_rast(N_array_2d * array, char *name)
175
int map; /*The rastermap */
176
int x, y, cols, rows, count, type;
180
struct Cell_head region;
183
G_fatal_error(_("N_array_2d * array is empty"));
185
/* Get the current region */
186
G_get_set_window(®ion);
192
/*Open the new map */
193
map = Rast_open_new(name, type);
195
if (type == CELL_TYPE)
196
rast = Rast_allocate_buf(type);
197
if (type == FCELL_TYPE)
198
frast = Rast_allocate_buf(type);
199
if (type == DCELL_TYPE)
200
drast = Rast_allocate_buf(type);
202
G_message(_("Write 2d array to raster map <%s>"), name);
205
for (y = 0; y < rows; y++) {
206
G_percent(y, rows - 1, 10);
207
for (x = 0; x < cols; x++) {
208
if (type == CELL_TYPE)
209
rast[x] = N_get_array_2d_c_value(array, x, y);
210
if (type == FCELL_TYPE)
211
frast[x] = N_get_array_2d_f_value(array, x, y);
212
if (type == DCELL_TYPE)
213
drast[x] = N_get_array_2d_d_value(array, x, y);
215
if (type == CELL_TYPE)
216
Rast_put_c_row(map, rast);
217
if (type == FCELL_TYPE)
218
Rast_put_f_row(map, frast);
219
if (type == DCELL_TYPE)
220
Rast_put_d_row(map, drast);
228
/* ******************** 3D ARRAY FUNCTIONS *********************** */
231
* \brief Read a volume map into a N_array_3d structure
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 be
235
* allocated with the same data type as the volume map and the size of the current region.
236
* The array offset will be set to 0.
239
* If a N_array_3d structure is provided, the values from the volume map are
240
* casted to the N_array_3d type. The array must have the same size
241
* as the current region.
244
* The new created or the provided array is returned.
245
* If the reading of the volume map fails, Rast3d_fatal_error() will
248
* \param name * char - the name of an existing volume map
249
* \param array * N_array_3d - an existing array or NULL
250
* \param mask int - 0 = false, 1 = ture : if a mask is presenent, use it with the input volume map
251
* \return N_array_3d * - the existing or new allocated array
253
N_array_3d *N_read_rast3d_to_array_3d(char *name, N_array_3d * array,
256
void *map = NULL; /*The 3D Rastermap */
258
int x, y, z, cols, rows, depths, type;
259
double d1 = 0, f1 = 0;
260
N_array_3d *data = array;
261
RASTER3D_Region region;
264
/*get the current region */
265
Rast3d_get_window(®ion);
269
depths = region.depths;
272
if (NULL == G_find_raster3d(name, ""))
273
Rast3d_fatal_error(_("3D raster map <%s> not found"), name);
275
/*Open all maps with default region */
277
Rast3d_open_cell_old(name, G_find_raster3d(name, ""), RASTER3D_DEFAULT_WINDOW,
278
RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT);
281
Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), name);
283
type = Rast3d_tile_type_map(map);
285
/*if the array is NULL create a new one with the data type of the volume map */
286
/*the offset is 0 by default */
288
if (type == FCELL_TYPE) {
289
data = N_alloc_array_3d(cols, rows, depths, 0, FCELL_TYPE);
291
if (type == DCELL_TYPE) {
292
data = N_alloc_array_3d(cols, rows, depths, 0, DCELL_TYPE);
296
/*Check the array sizes */
297
if (data->cols != cols)
299
("N_read_rast_to_array_3d: the data array size is different from the current region settings");
300
if (data->rows != rows)
302
("N_read_rast_to_array_3d: the data array size is different from the current region settings");
303
if (data->depths != depths)
305
("N_read_rast_to_array_3d: the data array size is different from the current region settings");
309
G_message(_("Read g3d map <%s> into the memory"), name);
311
/*if requested set the Mask on */
313
if (Rast3d_mask_file_exists()) {
315
if (Rast3d_mask_is_off(map)) {
322
for (z = 0; z < depths; z++) { /*From the bottom to the top */
323
G_percent(z, depths - 1, 10);
324
for (y = 0; y < rows; y++) {
325
for (x = 0; x < cols; x++) {
326
if (type == FCELL_TYPE) {
327
Rast3d_get_value(map, x, y, z, &f1, type);
328
if (Rast_is_f_null_value((void *)&f1)) {
329
N_put_array_3d_value_null(data, x, y, z);
332
if (data->type == FCELL_TYPE)
333
N_put_array_3d_f_value(data, x, y, z, f1);
334
if (data->type == DCELL_TYPE)
335
N_put_array_3d_d_value(data, x, y, z, (double)f1);
339
Rast3d_get_value(map, x, y, z, &d1, type);
340
if (Rast_is_d_null_value((void *)&d1)) {
341
N_put_array_3d_value_null(data, x, y, z);
344
if (data->type == FCELL_TYPE)
345
N_put_array_3d_f_value(data, x, y, z, (float)d1);
346
if (data->type == DCELL_TYPE)
347
N_put_array_3d_d_value(data, x, y, z, d1);
355
/*We set the Mask off, if it was off before */
357
if (Rast3d_mask_file_exists())
358
if (Rast3d_mask_is_on(map) && changemask)
359
Rast3d_mask_off(map);
362
/* Close files and exit */
363
if (!Rast3d_close(map))
364
Rast3d_fatal_error(map, NULL, 0, _("Error closing g3d file"));
370
* \brief Write a N_array_3d struct to a volume map
372
* A new volume map is created with the same type as the N_array_3d.
373
* The current region is used to open the volume map.
374
* The N_array_3d must have the same size as the current region.
375
* If the writing of the volume map fails, Rast3d_fatal_error() will
379
* \param array N_array_3d *
380
* \param name char * - the name of the volume map
381
* \param mask int - 1 = use a 3d mask, 0 do not use a 3d mask
385
void N_write_array_3d_to_rast3d(N_array_3d * array, char *name, int mask)
387
void *map = NULL; /*The 3D Rastermap */
389
int x, y, z, cols, rows, depths, count, type;
390
double d1 = 0.0, f1 = 0.0;
391
N_array_3d *data = array;
392
RASTER3D_Region region;
394
/*get the current region */
395
Rast3d_get_window(®ion);
399
depths = region.depths;
402
/*Check the array sizes */
403
if (data->cols != cols)
405
("N_write_array_3d_to_rast3d: the data array size is different from the current region settings");
406
if (data->rows != rows)
408
("N_write_array_3d_to_rast3d: the data array size is different from the current region settings");
409
if (data->depths != depths)
411
("N_write_array_3d_to_rast3d: the data array size is different from the current region settings");
413
/*Open the new map */
414
if (type == DCELL_TYPE)
415
map = Rast3d_open_new_opt_tile_size(name, RASTER3D_USE_CACHE_XY, ®ion, DCELL_TYPE, 32);
416
else if (type == FCELL_TYPE)
417
map = Rast3d_open_new_opt_tile_size(name, RASTER3D_USE_CACHE_XY, ®ion, FCELL_TYPE, 32);
420
Rast3d_fatal_error(_("Error opening g3d map <%s>"), name);
422
G_message(_("Write 3d array to g3d map <%s>"), name);
424
/*if requested set the Mask on */
426
if (Rast3d_mask_file_exists()) {
428
if (Rast3d_mask_is_off(map)) {
436
for (z = 0; z < depths; z++) { /*From the bottom to the top */
437
G_percent(z, depths - 1, 10);
438
for (y = 0; y < rows; y++) {
439
for (x = 0; x < cols; x++) {
440
if (type == FCELL_TYPE) {
441
f1 = N_get_array_3d_f_value(data, x, y, z);
442
Rast3d_put_float(map, x, y, z, f1);
444
else if (type == DCELL_TYPE) {
445
d1 = N_get_array_3d_d_value(data, x, y, z);
446
Rast3d_put_double(map, x, y, z, d1);
452
/*We set the Mask off, if it was off before */
454
if (Rast3d_mask_file_exists())
455
if (Rast3d_mask_is_on(map) && changemask)
456
Rast3d_mask_off(map);
460
if (!Rast3d_flush_all_tiles(map))
461
Rast3d_fatal_error("Error flushing tiles with Rast3d_flush_all_tiles");
462
/* Close files and exit */
463
if (!Rast3d_close(map))
464
Rast3d_fatal_error(map, NULL, 0, _("Error closing g3d file"));