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