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