GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-55b2a2bccc
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  * */
75 N_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 
182 void 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  * */
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 "
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  * */
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
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  * */
347 FCELL 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  * */
380 DCELL 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  * */
412 void 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  * */
459 void 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) {
469  (void *)&(data->cell_array[row * data->cols_intern + col]), 1);
470  }
471  else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
473  (void *)&(data->fcell_array[row * data->cols_intern + col]), 1);
474  }
475  else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
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) {
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) {
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) {
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  * */
516 void 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  * */
546 void 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  * */
576 void 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 
632  N_print_array_2d_info(data);
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  * */
719 N_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  * */
822 void 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  * */
873 int 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);
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);
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);
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);
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  * */
948 float 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  * */
979 double 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  * */
1010 void 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  * */
1060 void 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) {
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) {
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) {
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) {
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  * */
1121 void 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  * */
1148 void 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 
1200  N_print_array_3d_info(data);
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 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_calloc(m, n)
Definition: defs/gis.h:95
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:34
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:176
void Rast_set_d_null_value(DCELL *, int)
To set a number of DCELL raster values to NULL.
Definition: null_val.c:153
void Rast_set_f_null_value(FCELL *, int)
To set a number of FCELL raster values to NULL.
Definition: null_val.c:138
void Rast_set_c_null_value(CELL *, int)
To set a number of CELL raster values to NULL.
Definition: null_val.c:124
float FCELL
Definition: gis.h:629
double DCELL
Definition: gis.h:628
int CELL
Definition: gis.h:627
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
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
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
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
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
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
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
#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:133
DCELL * dcell_array
Definition: N_pde.h:141
FCELL * fcell_array
Definition: N_pde.h:139
CELL * cell_array
Definition: N_pde.h:137
int cols
Definition: N_pde.h:134
int rows_intern
Definition: N_pde.h:135
int rows
Definition: N_pde.h:134
int offset
Definition: N_pde.h:136
int cols_intern
Definition: N_pde.h:135
int cols_intern
Definition: N_pde.h:178
int type
Definition: N_pde.h:176
int offset
Definition: N_pde.h:179
int rows
Definition: N_pde.h:177
double * dcell_array
Definition: N_pde.h:182
float * fcell_array
Definition: N_pde.h:180
int depths_intern
Definition: N_pde.h:178
int rows_intern
Definition: N_pde.h:178
int depths
Definition: N_pde.h:177
int cols
Definition: N_pde.h:177