GRASS 8 Programmer's Manual 8.6.0dev(2026)-55de52a352
Loading...
Searching...
No Matches
n_arrays.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: 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 Allocate memory for a N_array_2d data structure.
25 *
26 * This function allocates memory for an array of type N_array_2d
27 * and returns the pointer to the new allocated memory.
28 * <br><br>
29 * The data type of this array is set by "type" and must be
30 * CELL_TYPE, FCELL_TYPE or DCELL_TYPE accordingly to the raster map data types.
31 * The offset sets the number of boundary cols and rows.
32 * This option is useful to generate homogeneous Neumann boundary conditions
33 around
34 * an array or to establish overlapping boundaries. The array is initialized
35 with 0 by default.
36 * <br><br>
37 * If the offset is greater then 0, negative indices are possible.
38 * <br><br>
39 *
40 * The data structure of a array with 3 rows and cols and an offset of 1
41 * will looks like this:
42 * <br><br>
43 *
44 \verbatim
45 0 0 0 0 0
46 0 0 1 2 0
47 0 3 4 5 0
48 0 6 7 8 0
49 0 0 0 0 0
50 \endverbatim
51 *
52 * 0 is the boundary.
53 * <br><br>
54 * Internal a one dimensional array is allocated to save memory and to speed up
55 the memory access.
56 * To access the one dimensional array with a two dimensional index use the
57 provided
58 * get and put functions. The internal representation of the above data will
59 look like this:
60 *
61 \verbatim
62 0 0 0 0 0 0 0 1 2 0 0 3 4 5 0 0 6 7 8 0 0 0 0 0 0
63 \endverbatim
64 *
65 * \param cols int
66 * \param rows int
67 * \param offset int
68 * \param type int
69 * \return N_array_2d *
70 *
71 * */
72N_array_2d *N_alloc_array_2d(int cols, int rows, int offset, int type)
73{
74 N_array_2d *data = NULL;
75
76 if (rows < 1 || cols < 1)
77 G_fatal_error("N_alloc_array_2d: cols and rows should be > 0");
78
79 if (type != CELL_TYPE && type != FCELL_TYPE && type != DCELL_TYPE)
80 G_fatal_error("N_alloc_array_2d: Wrong data type, should be CELL_TYPE, "
81 "FCELL_TYPE or DCELL_TYPE");
82
83 data = (N_array_2d *)G_calloc(1, sizeof(N_array_2d));
84
85 data->cols = cols;
86 data->rows = rows;
87 data->type = type;
88 data->offset = offset;
89 data->rows_intern = rows + 2 * offset; /*offset position at booth sides */
90 data->cols_intern = cols + 2 * offset; /*offset position at booth sides */
91 data->cell_array = NULL;
92 data->fcell_array = NULL;
93 data->dcell_array = NULL;
94
95 if (data->type == CELL_TYPE) {
96 data->cell_array = (CELL *)G_calloc(
97 (size_t)data->rows_intern * data->cols_intern, sizeof(CELL));
98 G_debug(3,
99 "N_alloc_array_2d: CELL array allocated rows_intern %i "
100 "cols_intern %i offset %i",
101 data->rows_intern, data->cols_intern, data->offset = offset);
102 }
103 else if (data->type == FCELL_TYPE) {
104 data->fcell_array = (FCELL *)G_calloc(
105 (size_t)data->rows_intern * data->cols_intern, sizeof(FCELL));
106 G_debug(3,
107 "N_alloc_array_2d: FCELL array allocated rows_intern %i "
108 "cols_intern %i offset %i",
109 data->rows_intern, data->cols_intern, data->offset = offset);
110 }
111 else if (data->type == DCELL_TYPE) {
112 data->dcell_array = (DCELL *)G_calloc(
113 (size_t)data->rows_intern * data->cols_intern, sizeof(DCELL));
114 G_debug(3,
115 "N_alloc_array_2d: DCELL array allocated rows_intern %i "
116 "cols_intern %i offset %i",
117 data->rows_intern, data->cols_intern, data->offset = offset);
118 }
119
120 return data;
121}
122
123/*!
124 * \brief Release the memory of a N_array_2d structure
125 *
126 * \param data N_array_2d *
127 * \return void
128 * */
130{
131
132 if (data != NULL) {
133 G_debug(3, "N_free_array_2d: free N_array_2d");
134
135 if (data->type == CELL_TYPE && data->cell_array != NULL) {
136 G_free(data->cell_array);
137 }
138 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
139 G_free(data->fcell_array);
140 }
141 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
142 G_free(data->dcell_array);
143 }
144
145 G_free(data);
146 data = NULL;
147 }
148
149 return;
150}
151
152/*!
153 * \brief Return the data type of the N_array_2d struct
154 *
155 * The data type can be CELL_TYPE, FCELL_TYPE or DCELL_TYPE accordingly to the
156 * raster map data types.
157 *
158 * \param array N_array_2d *
159 * \return type int
160 * */
162{
163 return array->type;
164}
165
166/*!
167 * \brief Write the value of the N_array_2d struct at position col, row to value
168 *
169 * The value must be of the same type as the array. Otherwise you will risk data
170 * losses.
171 *
172 * \param data N_array_2d *
173 * \param col int
174 * \param row int
175 * \param value void * - this variable contains the array value at col, row
176 * position \return void
177 * */
178
179void N_get_array_2d_value(N_array_2d *data, int col, int row, void *value)
180{
181
182 if (data->offset == 0) {
183 if (data->type == CELL_TYPE && data->cell_array != NULL) {
184 *((CELL *)value) = data->cell_array[row * data->cols_intern + col];
185 }
186 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
187 *((FCELL *)value) =
188 data->fcell_array[row * data->cols_intern + col];
189 }
190 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
191 *((DCELL *)value) =
192 data->dcell_array[row * data->cols_intern + col];
193 }
194 }
195 else {
196 if (data->type == CELL_TYPE && data->cell_array != NULL) {
197 *((CELL *)value) =
198 data->cell_array[(row + data->offset) * data->cols_intern +
199 col + data->offset];
200 }
201 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
202 *((FCELL *)value) =
203 data->fcell_array[(row + data->offset) * data->cols_intern +
204 col + data->offset];
205 }
206 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
207 *((DCELL *)value) =
208 data->dcell_array[(row + data->offset) * data->cols_intern +
209 col + data->offset];
210 }
211 }
212
213 return;
214}
215
216/*!
217 * \brief Returns 1 if the value of N_array_2d struct at position col, row
218 * is of type null, otherwise 0
219 *
220 * This function checks automatically the type of the array and checks for the
221 * data type null value.
222 *
223 * \param data N_array_2d *
224 * \param col int
225 * \param row int
226 * \return int - 1 = is null, 0 otherwise
227 * */
229{
230
231 if (data->offset == 0) {
232 if (data->type == CELL_TYPE && data->cell_array != NULL) {
233 G_debug(6,
234 "N_is_array_2d_value_null: null value is of type CELL at "
235 "pos [%i][%i]",
236 col, row);
237 return Rast_is_null_value(
238 (void *)&(data->cell_array[row * data->cols_intern + col]),
239 CELL_TYPE);
240 }
241 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
242 G_debug(6,
243 "N_is_array_2d_value_null: null value is of type FCELL at "
244 "pos [%i][%i]",
245 col, row);
246 return Rast_is_null_value(
247 (void *)&(data->fcell_array[row * data->cols_intern + col]),
248 FCELL_TYPE);
249 }
250 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
251 G_debug(6,
252 "N_is_array_2d_value_null: null value is of type DCELL at "
253 "pos [%i][%i]",
254 col, row);
255 return Rast_is_null_value(
256 (void *)&(data->dcell_array[row * data->cols_intern + col]),
257 DCELL_TYPE);
258 }
259 }
260 else {
261 if (data->type == CELL_TYPE && data->cell_array != NULL) {
262 G_debug(6,
263 "N_is_array_2d_value_null: null value is of type CELL at "
264 "pos [%i][%i]",
265 col, row);
266 return Rast_is_null_value(
267 (void *)&(
268 data->cell_array[(row + data->offset) * data->cols_intern +
269 col + data->offset]),
270 CELL_TYPE);
271 }
272 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
273 G_debug(6,
274 "N_is_array_2d_value_null: null value is of type FCELL at "
275 "pos [%i][%i]",
276 col, row);
277 return Rast_is_null_value(
278 (void *)&(
279 data->fcell_array[(row + data->offset) * data->cols_intern +
280 col + data->offset]),
281 FCELL_TYPE);
282 }
283 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
284 G_debug(6,
285 "N_is_array_2d_value_null: null value is of type DCELL at "
286 "pos [%i][%i]",
287 col, row);
288 return Rast_is_null_value(
289 (void *)&(
290 data->dcell_array[(row + data->offset) * data->cols_intern +
291 col + data->offset]),
292 DCELL_TYPE);
293 }
294 }
295
296 return 0;
297}
298
299/*!
300 * \brief Returns the value of type CELL at position col, row
301 *
302 * The data array can be of type CELL, FCELL or DCELL, the value will be casted
303 * to the CELL type.
304 *
305 * \param data N_array_2d *
306 * \param col int
307 * \param row int
308 * \return CELL
309 *
310 * */
312{
313 CELL value = 0;
314 FCELL fvalue = 0.0;
315 DCELL dvalue = 0.0;
316
317 switch (data->type) {
318 case CELL_TYPE:
319 N_get_array_2d_value(data, col, row, (void *)&value);
320 return (CELL)value;
321 case FCELL_TYPE:
322 N_get_array_2d_value(data, col, row, (void *)&fvalue);
323 return (CELL)fvalue;
324 case DCELL_TYPE:
325 N_get_array_2d_value(data, col, row, (void *)&dvalue);
326 return (CELL)dvalue;
327 }
328
329 return value;
330}
331
332/*!
333 * \brief Returns the value of type FCELL at position col, row
334 *
335 * The data array can be of type CELL, FCELL or DCELL, the value will be casted
336 to the FCELL type.
337 *
338 * \param data N_array_2d *
339 * \param col int
340 * \param row int
341 * \return FCELL
342
343 * */
345{
346 CELL value = 0;
347 FCELL fvalue = 0.0;
348 DCELL dvalue = 0.0;
349
350 switch (data->type) {
351 case CELL_TYPE:
352 N_get_array_2d_value(data, col, row, (void *)&value);
353 return (FCELL)value;
354 case FCELL_TYPE:
355 N_get_array_2d_value(data, col, row, (void *)&fvalue);
356 return (FCELL)fvalue;
357 case DCELL_TYPE:
358 N_get_array_2d_value(data, col, row, (void *)&dvalue);
359 return (FCELL)dvalue;
360 }
361
362 return fvalue;
363}
364
365/*!
366 * \brief Returns the value of type DCELL at position col, row
367 *
368 * The data array can be of type CELL, FCELL or DCELL, the value will be casted
369 * to the DCELL type.
370 *
371 * \param data N_array_2d *
372 * \param col int
373 * \param row int
374 * \return DCELL
375 *
376 * */
378{
379 CELL value = 0;
380 FCELL fvalue = 0.0;
381 DCELL dvalue = 0.0;
382
383 switch (data->type) {
384 case CELL_TYPE:
385 N_get_array_2d_value(data, col, row, (void *)&value);
386 return (DCELL)value;
387 case FCELL_TYPE:
388 N_get_array_2d_value(data, col, row, (void *)&fvalue);
389 return (DCELL)fvalue;
390 case DCELL_TYPE:
391 N_get_array_2d_value(data, col, row, (void *)&dvalue);
392 return (DCELL)dvalue;
393 }
394
395 return dvalue;
396}
397
398/*!
399 * \brief Writes a value to the N_array_2d struct at position col, row
400 *
401 * The value will be automatically cast to the array type.
402 *
403 * \param data N_array_2d *
404 * \param col int
405 * \param row int
406 * \param value char *
407 * \return void
408 * */
409void N_put_array_2d_value(N_array_2d *data, int col, int row, char *value)
410{
411
412 G_debug(6, "N_put_array_2d_value: put value to array");
413
414 if (data->offset == 0) {
415 if (data->type == CELL_TYPE && data->cell_array != NULL) {
416 data->cell_array[row * data->cols_intern + col] = *((CELL *)value);
417 }
418 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
419 data->fcell_array[row * data->cols_intern + col] =
420 *((FCELL *)value);
421 }
422 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
423 data->dcell_array[row * data->cols_intern + col] =
424 *((DCELL *)value);
425 }
426 }
427 else {
428 if (data->type == CELL_TYPE && data->cell_array != NULL) {
429 data->cell_array[(row + data->offset) * data->cols_intern + col +
430 data->offset] = *((CELL *)value);
431 }
432 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
433 data->fcell_array[(row + data->offset) * data->cols_intern + col +
434 data->offset] = *((FCELL *)value);
435 }
436 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
437 data->dcell_array[(row + data->offset) * data->cols_intern + col +
438 data->offset] = *((DCELL *)value);
439 }
440 }
441
442 return;
443}
444
445/*!
446 * \brief Writes the null value to the N_array_2d struct at position col, row
447 *
448 * The null value will be automatically set to the array data type (CELL, FCELL
449 * or DCELL).
450 *
451 * \param data N_array_2d *
452 * \param col int
453 * \param row int
454 * \return void
455 * */
456void N_put_array_2d_value_null(N_array_2d *data, int col, int row)
457{
458
459 G_debug(6,
460 "N_put_array_2d_value_null: put null value to array pos [%i][%i]",
461 col, row);
462
463 if (data->offset == 0) {
464 if (data->type == CELL_TYPE && data->cell_array != NULL) {
466 (void *)&(data->cell_array[row * data->cols_intern + col]), 1);
467 }
468 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
470 (void *)&(data->fcell_array[row * data->cols_intern + col]), 1);
471 }
472 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
474 (void *)&(data->dcell_array[row * data->cols_intern + col]), 1);
475 }
476 }
477 else {
478 if (data->type == CELL_TYPE && data->cell_array != NULL) {
480 (void *)&(
481 data->cell_array[(row + data->offset) * data->cols_intern +
482 col + data->offset]),
483 1);
484 }
485 else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
487 (void *)&(
488 data->fcell_array[(row + data->offset) * data->cols_intern +
489 col + data->offset]),
490 1);
491 }
492 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
494 (void *)&(
495 data->dcell_array[(row + data->offset) * data->cols_intern +
496 col + data->offset]),
497 1);
498 }
499 }
500
501 return;
502}
503
504/*!
505 * \brief Writes a CELL value to the N_array_2d struct at position col, row
506 *
507 * \param data N_array_2d *
508 * \param col int
509 * \param row int
510 * \param value CELL
511 * \return void
512 * */
513void N_put_array_2d_c_value(N_array_2d *data, int col, int row, CELL value)
514{
517
518 switch (data->type) {
519 case FCELL_TYPE:
520 fvalue = (FCELL)value;
521 N_put_array_2d_value(data, col, row, (char *)&fvalue);
522 return;
523 case DCELL_TYPE:
524 dvalue = (DCELL)value;
525 N_put_array_2d_value(data, col, row, (char *)&dvalue);
526 return;
527 }
528
529 N_put_array_2d_value(data, col, row, (char *)&value);
530
531 return;
532}
533
534/*!
535 * \brief Writes a FCELL value to the N_array_2d struct at position col, row
536 *
537 * \param data N_array_2d *
538 * \param col int
539 * \param row int
540 * \param value FCELL
541 * \return void
542 * */
543void N_put_array_2d_f_value(N_array_2d *data, int col, int row, FCELL value)
544{
545 CELL cvalue;
547
548 switch (data->type) {
549 case CELL_TYPE:
550 cvalue = (CELL)value;
551 N_put_array_2d_value(data, col, row, (char *)&cvalue);
552 return;
553 case DCELL_TYPE:
554 dvalue = (DCELL)value;
555 N_put_array_2d_value(data, col, row, (char *)&dvalue);
556 return;
557 }
558
559 N_put_array_2d_value(data, col, row, (char *)&value);
560
561 return;
562}
563
564/*!
565 * \brief Writes a DCELL value to the N_array_2d struct at position col, row
566 *
567 * \param data N_array_2d *
568 * \param col int
569 * \param row int
570 * \param value DCELL
571 * \return void
572 * */
573void N_put_array_2d_d_value(N_array_2d *data, int col, int row, DCELL value)
574{
575 CELL cvalue;
577
578 switch (data->type) {
579 case CELL_TYPE:
580 cvalue = (CELL)value;
581 N_put_array_2d_value(data, col, row, (char *)&cvalue);
582 return;
583 case FCELL_TYPE:
584 fvalue = (FCELL)value;
585 N_put_array_2d_value(data, col, row, (char *)&fvalue);
586 return;
587 }
588
589 N_put_array_2d_value(data, col, row, (char *)&value);
590
591 return;
592}
593
594/*!
595 * \brief This function writes the data info of the array data to stdout
596 *
597 * \param data N_array_2d *
598 * \return void
599 * */
601{
602
603 fprintf(stdout, "N_array_2d \n");
604 fprintf(stdout, "Cols %i\n", data->cols);
605 fprintf(stdout, "Rows: %i\n", data->rows);
606 fprintf(stdout, "Array type: %i\n", data->type);
607 fprintf(stdout, "Offset: %i\n", data->offset);
608 fprintf(stdout, "Internal cols: %i\n", data->cols_intern);
609 fprintf(stdout, "Internal rows: %i\n", data->rows_intern);
610 fprintf(stdout, "CELL array pointer: %p\n", (void *)data->cell_array);
611 fprintf(stdout, "FCELL array pointer: %p\n", (void *)data->fcell_array);
612 fprintf(stdout, "DCELL array pointer: %p\n", (void *)data->dcell_array);
613
614 return;
615}
616
617/*!
618 * \brief Write info and content of the N_array_2d struct to stdout
619 *
620 * Offsets are ignored
621 *
622 * \param data N_array_2d *
623 * \return void
624 * */
626{
627 int i, j;
628
630
631 for (j = 0 - data->offset; j < data->rows + data->offset; j++) {
632 for (i = 0 - data->offset; i < data->cols + data->offset; i++) {
633 if (data->type == CELL_TYPE)
634 fprintf(stdout, "%6d ", N_get_array_2d_c_value(data, i, j));
635 else if (data->type == FCELL_TYPE)
636 fprintf(stdout, "%6.6f ", N_get_array_2d_f_value(data, i, j));
637 else if (data->type == DCELL_TYPE)
638 printf("%6.6f ", N_get_array_2d_d_value(data, i, j));
639 }
640 fprintf(stdout, "\n");
641 }
642 fprintf(stdout, "\n");
643
644 return;
645}
646
647/* ******************** 3D ARRAY FUNCTIONS *********************** */
648
649/*!
650 * \brief Allocate memory for a N_array_3d data structure.
651 *
652 * This functions allocates an array of type N_array_3d and returns a pointer
653 * to the new allocated memory.
654 * <br><br>
655 * The data type of this array set by "type" must be
656 * FCELL_TYPE or DCELL_TYPE accordingly to the raster3d map data types.
657 * The offsets sets the number of boundary cols, rows and depths.
658 * This option is useful to generate homogeneous Neumann boundary conditions
659 around
660 * an array or to establish overlapping boundaries. The arrays are initialized
661 with 0 by default.
662 * <br><br>
663 * If the offset is greater then 0, negative indices are possible.
664 * The data structure of a array with 3 depths, rows and cols and an offset of 1
665 * will looks like this:
666 *
667 \verbatim
668 0 0 0 0 0
669 0 0 0 0 0
670 0 0 0 0 0
671 0 0 0 0 0
672 0 0 0 0 0
673
674 0 0 0 0 0
675 0 0 1 2 0
676 0 3 4 5 0
677 0 6 7 8 0
678 0 0 0 0 0
679
680 0 0 0 0 0
681 0 9 10 11 0
682 0 12 13 14 0
683 0 15 16 17 0
684 0 0 0 0 0
685
686 0 0 0 0 0
687 0 18 19 20 0
688 0 21 22 23 0
689 0 24 25 26 0
690 0 0 0 0 0
691
692 0 0 0 0 0
693 0 0 0 0 0
694 0 0 0 0 0
695 0 0 0 0 0
696 0 0 0 0 0
697
698 \endverbatim
699
700 The depth counts from the bottom to the top.
701
702 * <br><br>
703 * Internal a one dimensional array is allocated to speed up the memory access.
704 * To access the dimensional array with a three dimensional indexing use the
705 provided
706 * get and put functions.
707 *
708 * \param cols int
709 * \param rows int
710 * \param depths int
711 * \param offset int
712 * \param type int
713 * \return N_array_3d *
714 *
715 * */
716N_array_3d *N_alloc_array_3d(int cols, int rows, int depths, int offset,
717 int type)
718{
719 N_array_3d *data = NULL;
720
721 if (rows < 1 || cols < 1 || depths < 1)
722 G_fatal_error("N_alloc_array_3d: depths, cols and rows should be > 0");
723
724 if (type != DCELL_TYPE && type != FCELL_TYPE)
725 G_fatal_error("N_alloc_array_3d: Wrong data type, should be FCELL_TYPE "
726 "or DCELL_TYPE");
727
728 data = (N_array_3d *)G_calloc(1, sizeof(N_array_3d));
729
730 data->cols = cols;
731 data->rows = rows;
732 data->depths = depths;
733 data->type = type;
734 data->offset = offset;
735 data->rows_intern = rows + 2 * offset;
736 data->cols_intern = cols + 2 * offset;
737 data->depths_intern = depths + 2 * offset;
738 data->fcell_array = NULL;
739 data->dcell_array = NULL;
740
741 if (data->type == FCELL_TYPE) {
742 data->fcell_array = (float *)G_calloc(
743 (size_t)data->depths_intern * data->rows_intern * data->cols_intern,
744 sizeof(float));
745 G_debug(3,
746 "N_alloc_array_3d: float array allocated rows_intern %i "
747 "cols_intern %i depths_intern %i offset %i",
748 data->rows_intern, data->cols_intern, data->depths_intern,
749 data->offset = offset);
750 }
751 else if (data->type == DCELL_TYPE) {
752 data->dcell_array = (double *)G_calloc(
753 (size_t)data->depths_intern * data->rows_intern * data->cols_intern,
754 sizeof(double));
755 G_debug(3,
756 "N_alloc_array_3d: double array allocated rows_intern %i "
757 "cols_intern %i depths_intern %i offset %i",
758 data->rows_intern, data->cols_intern, data->depths_intern,
759 data->offset = offset);
760 }
761
762 return data;
763}
764
765/*!
766 * \brief Release the memory of a N_array_3d
767 *
768 * \param data N_array_3d *
769 * \return void
770 * */
772{
773
774 if (data != NULL) {
775 G_debug(3, "N_free_array_3d: free N_array_3d");
776
777 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
778 G_free(data->fcell_array);
779 }
780 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
781 G_free(data->dcell_array);
782 }
783
784 G_free(data);
785 data = NULL;
786 }
787
788 return;
789}
790
791/*!
792 * \brief Return the data type of the N_array_3d
793 *
794 * The data type can be FCELL_TYPE and DCELL_TYPE accordingly to the raster map
795 * data types.
796 *
797 * \param array N_array_3d *
798 * \return type int -- FCELL_TYPE or DCELL_TYPE
799 * */
801{
802 return array->type;
803}
804
805/*!
806 * \brief This function writes the value of N_array_3d data at position col,
807 * row, depth to the variable value
808 *
809 * The value must be from the same type as the array. Otherwise you will risk
810 * data losses.
811 *
812 * \param data N_array_3d *
813 * \param col int
814 * \param row int
815 * \param depth int
816 * \param value void *
817 * \return void
818 * */
819void N_get_array_3d_value(N_array_3d *data, int col, int row, int depth,
820 void *value)
821{
822
823 if (data->offset == 0) {
824 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
825 *((float *)value) =
826 data->fcell_array[depth *
827 (data->rows_intern * data->cols_intern) +
828 row * data->cols_intern + col];
829 }
830 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
831 *((double *)value) =
832 data->dcell_array[depth *
833 (data->rows_intern * data->cols_intern) +
834 row * data->cols_intern + col];
835 }
836 }
837 else {
838 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
839 *((float *)value) =
840 data->fcell_array[(depth + data->offset) *
841 (data->rows_intern * data->cols_intern) +
842 (row + data->offset) * data->cols_intern +
843 (col + data->offset)];
844 }
845 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
846 *((double *)value) =
847 data->dcell_array[(depth + data->offset) *
848 (data->rows_intern * data->cols_intern) +
849 (row + data->offset) * data->cols_intern +
850 (col + data->offset)];
851 }
852 }
853
854 return;
855}
856
857/*!
858 * \brief This function returns 1 if value of N_array_3d data at position col,
859 * row, depth is of type null, otherwise 0
860 *
861 * This function checks automatically the type of the array and checks for the
862 * data type null value.
863 *
864 * \param data N_array_3d *
865 * \param col int
866 * \param row int
867 * \param depth int
868 * \return void
869 * */
870int N_is_array_3d_value_null(N_array_3d *data, int col, int row, int depth)
871{
872
873 if (data->offset == 0) {
874 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
875 G_debug(6,
876 "N_is_array_3d_value_null: null value is of type "
877 "DCELL_TYPE at pos [%i][%i][%i]",
878 depth, row, col);
880 (void *)&(data->fcell_array[depth * (data->rows_intern *
881 data->cols_intern) +
882 row * data->cols_intern + col]),
883 FCELL_TYPE);
884 }
885 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
886 G_debug(6,
887 "N_is_array_3d_value_null: null value is of type "
888 "DCELL_TYPE at pos [%i][%i][%i]",
889 depth, row, col);
891 (void *)&(data->dcell_array[depth * (data->rows_intern *
892 data->cols_intern) +
893 row * data->cols_intern + col]),
894 DCELL_TYPE);
895 }
896 }
897 else {
898 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
899 G_debug(6,
900 "N_is_array_3d_value_null: null value is of type "
901 "DCELL_TYPE at pos [%i][%i][%i]",
902 depth, row, col);
904 (void *)&(
905 data->fcell_array[(depth + data->offset) *
906 (data->rows_intern *
907 data->cols_intern) +
908 (row + data->offset) * data->cols_intern +
909 (col + data->offset)]),
910 FCELL_TYPE);
911 }
912 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
913 G_debug(6,
914 "N_is_array_3d_value_null: null value is of type "
915 "DCELL_TYPE at pos [%i][%i][%i]",
916 depth, row, col);
918 (void *)&(
919 data->dcell_array[(depth + data->offset) *
920 (data->rows_intern *
921 data->cols_intern) +
922 (row + data->offset) * data->cols_intern +
923 (col + data->offset)]),
924 DCELL_TYPE);
925 }
926 }
927
928 return 0;
929}
930
931/*!
932 * \brief This function returns the value of type float at position col, row,
933 * depth
934 *
935 * The data type can be FCELL_TYPE or DCELL_TYPE accordingly to the raster map
936 * data types.
937 *
938 * \param data N_array_3d *
939 * \param col int
940 * \param row int
941 * \param depth int
942 * \return float
943 *
944 * */
945float N_get_array_3d_f_value(N_array_3d *data, int col, int row, int depth)
946{
947 float fvalue = 0.0;
948 double dvalue = 0.0;
949
950 switch (data->type) {
951 case FCELL_TYPE:
952 N_get_array_3d_value(data, col, row, depth, (void *)&fvalue);
953 return (float)fvalue;
954 case DCELL_TYPE:
955 N_get_array_3d_value(data, col, row, depth, (void *)&dvalue);
956 return (float)dvalue;
957 }
958
959 return fvalue;
960}
961
962/*!
963 * \brief This function returns the value of type float at position col, row,
964 * depth
965 *
966 * The data type can be FCELL_TYPE or DCELL_TYPE accordingly to the raster map
967 * data types.
968 *
969 * \param data N_array_3d *
970 * \param col int
971 * \param row int
972 * \param depth int
973 * \return double
974 *
975 * */
976double N_get_array_3d_d_value(N_array_3d *data, int col, int row, int depth)
977{
978 float fvalue = 0.0;
979 double dvalue = 0.0;
980
981 switch (data->type) {
982
983 case FCELL_TYPE:
984 N_get_array_3d_value(data, col, row, depth, (void *)&fvalue);
985 return (double)fvalue;
986 case DCELL_TYPE:
987 N_get_array_3d_value(data, col, row, depth, (void *)&dvalue);
988 return (double)dvalue;
989 }
990
991 return dvalue;
992}
993
994/*!
995 * \brief This function writes a value to the N_array_3d data at position col,
996 * row, depth
997 *
998 * The value will be automatically cast to the array type.
999 *
1000 * \param data N_array_3d *
1001 * \param col int
1002 * \param row int
1003 * \param depth int
1004 * \param value char *
1005 * \return void
1006 * */
1007void N_put_array_3d_value(N_array_3d *data, int col, int row, int depth,
1008 char *value)
1009{
1010
1011 G_debug(6, "N_put_array_3d_value: put value to array at pos [%i][%i][%i]",
1012 depth, row, col);
1013
1014 if (data->offset == 0) {
1015 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
1016 data->fcell_array[depth * (data->rows_intern * data->cols_intern) +
1017 row * data->cols_intern + col] =
1018 *((float *)value);
1019 }
1020 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
1021
1022 data->dcell_array[depth * (data->rows_intern * data->cols_intern) +
1023 row * data->cols_intern + col] =
1024 *((double *)value);
1025 }
1026 }
1027 else {
1028 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
1029 data->fcell_array[(depth + data->offset) *
1030 (data->rows_intern * data->cols_intern) +
1031 (row + data->offset) * data->cols_intern +
1032 (col + data->offset)] = *((float *)value);
1033 }
1034 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
1035 data->dcell_array[(depth + data->offset) *
1036 (data->rows_intern * data->cols_intern) +
1037 (row + data->offset) * data->cols_intern +
1038 (col + data->offset)] = *((double *)value);
1039 }
1040 }
1041
1042 return;
1043}
1044
1045/*!
1046 * \brief This function writes a null value to the N_array_3d data at position
1047 * col, row, depth
1048 *
1049 * The null value will be automatically set to the array type.
1050 *
1051 * \param data N_array_3d *
1052 * \param col int
1053 * \param row int
1054 * \param depth int
1055 * \return void
1056 * */
1057void N_put_array_3d_value_null(N_array_3d *data, int col, int row, int depth)
1058{
1059
1060 G_debug(6,
1061 "N_put_array_3d_value_null: put null value to array at pos "
1062 "[%i][%i][%i]",
1063 depth, row, col);
1064
1065 if (data->offset == 0) {
1066 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
1068 (void *)&(data->fcell_array[depth * (data->rows_intern *
1069 data->cols_intern) +
1070 row * data->cols_intern + col]),
1071 1, FCELL_TYPE);
1072 }
1073 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
1075 (void *)&(data->dcell_array[depth * (data->rows_intern *
1076 data->cols_intern) +
1077 row * data->cols_intern + col]),
1078 1, DCELL_TYPE);
1079 }
1080 }
1081 else {
1082 if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
1084 (void *)&(
1085 data->fcell_array[(depth + data->offset) *
1086 (data->rows_intern *
1087 data->cols_intern) +
1088 (row + data->offset) * data->cols_intern +
1089 (col + data->offset)]),
1090 1, FCELL_TYPE);
1091 }
1092 else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
1094 (void *)&(
1095 data->dcell_array[(depth + data->offset) *
1096 (data->rows_intern *
1097 data->cols_intern) +
1098 (row + data->offset) * data->cols_intern +
1099 (col + data->offset)]),
1100 1, DCELL_TYPE);
1101 }
1102 }
1103
1104 return;
1105}
1106
1107/*!
1108 * \brief This function writes a float value to the N_array_3d data at position
1109 * col, row, depth
1110 *
1111 * \param data N_array_3d *
1112 * \param col int
1113 * \param row int
1114 * \param depth int
1115 * \param value float
1116 * \return void
1117 * */
1118void N_put_array_3d_f_value(N_array_3d *data, int col, int row, int depth,
1119 float value)
1120{
1121 double dval;
1122
1123 if (data->type == DCELL_TYPE) {
1124 dval = (double)value;
1125 N_put_array_3d_value(data, col, row, depth, (void *)&dval);
1126 }
1127 else {
1128 N_put_array_3d_value(data, col, row, depth, (void *)&value);
1129 }
1130
1131 return;
1132}
1133
1134/*!
1135 * \brief Writes a double value to the N_array_3d struct at position col, row,
1136 * depth
1137 *
1138 * \param data N_array_3d *
1139 * \param col int
1140 * \param row int
1141 * \param depth int
1142 * \param value double
1143 * \return void
1144 * */
1145void N_put_array_3d_d_value(N_array_3d *data, int col, int row, int depth,
1146 double value)
1147{
1148 float fval;
1149
1150 if (data->type == FCELL_TYPE) {
1151 fval = (double)value;
1152 N_put_array_3d_value(data, col, row, depth, (void *)&fval);
1153 }
1154 else {
1155 N_put_array_3d_value(data, col, row, depth, (void *)&value);
1156 }
1157
1158 return;
1159}
1160
1161/*!
1162 * \brief Write the info of the array to stdout
1163 *
1164 * \param data N_array_3d *
1165 * \return void
1166 * */
1168{
1169
1170 fprintf(stdout, "N_array_3d \n");
1171 fprintf(stdout, "Cols %i\n", data->cols);
1172 fprintf(stdout, "Rows: %i\n", data->rows);
1173 fprintf(stdout, "Depths: %i\n", data->depths);
1174 fprintf(stdout, "Array type: %i\n", data->type);
1175 fprintf(stdout, "Offset: %i\n", data->offset);
1176 fprintf(stdout, "Internal cols: %i\n", data->cols_intern);
1177 fprintf(stdout, "Internal rows: %i\n", data->rows_intern);
1178 fprintf(stdout, "Internal depths: %i\n", data->depths_intern);
1179 fprintf(stdout, "FCELL array pointer: %p\n", (void *)data->fcell_array);
1180 fprintf(stdout, "DCELL array pointer: %p\n", (void *)data->dcell_array);
1181
1182 return;
1183}
1184
1185/*!
1186 * \brief Write info and content of the array data to stdout
1187 *
1188 * Offsets are ignored
1189 *
1190 * \param data N_array_2d *
1191 * \return void
1192 * */
1194{
1195 int i, j, k;
1196
1198
1199 for (k = 0; k < data->depths; k++) {
1200 for (j = 0; j < data->rows; j++) {
1201 for (i = 0; i < data->cols; i++) {
1202 if (data->type == FCELL_TYPE)
1203 printf("%6.6f ", N_get_array_3d_f_value(data, i, j, k));
1204 else if (data->type == DCELL_TYPE)
1205 printf("%6.6f ", N_get_array_3d_d_value(data, i, j, k));
1206 }
1207 printf("\n");
1208 }
1209 printf("\n");
1210 }
1211 printf("\n");
1212
1213 return;
1214}
#define NULL
Definition ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_calloc(m, n)
Definition defs/gis.h:137
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
void Rast3d_set_null_value(void *, int, int)
Fills the vector pointed to by c with nofElts NULL-values of type.
Definition null.c:33
int Rast3d_is_null_value_num(const void *, int)
Definition null.c:12
int Rast_is_null_value(const void *, RASTER_MAP_TYPE)
To check if a raster value is set to NULL.
Definition null_val.c:174
void Rast_set_d_null_value(DCELL *, int)
To set a number of DCELL raster values to NULL.
Definition null_val.c:151
void Rast_set_f_null_value(FCELL *, int)
To set a number of FCELL raster values to NULL.
Definition null_val.c:136
void Rast_set_c_null_value(CELL *, int)
To set a number of CELL raster values to NULL.
Definition null_val.c:122
float FCELL
Definition gis.h:633
double DCELL
Definition gis.h:632
int CELL
Definition gis.h:631
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
void N_print_array_3d_info(N_array_3d *data)
Write the info of the array to stdout.
Definition n_arrays.c:1167
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_free_array_3d(N_array_3d *data)
Release the memory of a N_array_3d.
Definition n_arrays.c:771
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
int N_get_array_2d_type(N_array_2d *array)
Return the data type of the N_array_2d struct.
Definition n_arrays.c:161
void N_put_array_3d_value(N_array_3d *data, int col, int row, int depth, char *value)
This function writes a value to the N_array_3d data at position col, row, depth.
Definition n_arrays.c:1007
void N_print_array_2d(N_array_2d *data)
Write info and content of the N_array_2d struct to stdout.
Definition n_arrays.c:625
int N_is_array_3d_value_null(N_array_3d *data, int col, int row, int depth)
This function returns 1 if value of N_array_3d data at position col, row, depth is of type null,...
Definition n_arrays.c:870
void N_get_array_2d_value(N_array_2d *data, int col, int row, void *value)
Write the value of the N_array_2d struct at position col, row to value.
Definition n_arrays.c:179
void N_put_array_2d_value(N_array_2d *data, int col, int row, char *value)
Writes a value to the N_array_2d struct at position col, row.
Definition n_arrays.c:409
void N_print_array_2d_info(N_array_2d *data)
This function writes the data info of the array data to stdout.
Definition n_arrays.c:600
int N_is_array_2d_value_null(N_array_2d *data, int col, int row)
Returns 1 if the value of N_array_2d struct at position col, row is of type null, otherwise 0.
Definition n_arrays.c:228
void N_free_array_2d(N_array_2d *data)
Release the memory of a N_array_2d structure.
Definition n_arrays.c:129
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_get_array_3d_value(N_array_3d *data, int col, int row, int depth, void *value)
This function writes the value of N_array_3d data at position col, row, depth to the variable value.
Definition n_arrays.c:819
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
int N_get_array_3d_type(N_array_3d *array)
Return the data type of the N_array_3d.
Definition n_arrays.c:800
void N_print_array_3d(N_array_3d *data)
Write info and content of the array data to stdout.
Definition n_arrays.c:1193
#define FCELL_TYPE
Definition raster.h:12
#define DCELL_TYPE
Definition raster.h:13
#define CELL_TYPE
Definition raster.h:11
int type
Definition N_pde.h:130
DCELL * dcell_array
Definition N_pde.h:138
FCELL * fcell_array
Definition N_pde.h:136
CELL * cell_array
Definition N_pde.h:134
int cols
Definition N_pde.h:131
int rows_intern
Definition N_pde.h:132
int rows
Definition N_pde.h:131
int offset
Definition N_pde.h:133
int cols_intern
Definition N_pde.h:132
int cols_intern
Definition N_pde.h:175
int type
Definition N_pde.h:173
int offset
Definition N_pde.h:176
int rows
Definition N_pde.h:174
double * dcell_array
Definition N_pde.h:179
float * fcell_array
Definition N_pde.h:177
int depths_intern
Definition N_pde.h:175
int rows_intern
Definition N_pde.h:175
int depths
Definition N_pde.h:174
int cols
Definition N_pde.h:174