GRASS 8 Programmer's Manual  8.5.0dev(2025)-d272f2f102
tilemath.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <unistd.h>
5 #include "raster3d_intern.h"
6 
7 /*---------------------------------------------------------------------------*/
8 
9 /*!
10  * \brief
11  *
12  * Converts index <em>tileIndex</em> into tile-coordinates
13  * <em>(xTile, yTile, zTile)</em>.
14  *
15  * \param map
16  * \param tileIndex
17  * \param xTile
18  * \param yTile
19  * \param zTile
20  * \return void
21  */
22 void Rast3d_tile_index2tile(RASTER3D_Map *map, int tileIndex, int *xTile,
23  int *yTile, int *zTile)
24 {
25  int tileIndex2d;
26 
27  *zTile = tileIndex / map->nxy;
28  tileIndex2d = tileIndex % map->nxy;
29  *yTile = tileIndex2d / map->nx;
30  *xTile = tileIndex2d % map->nx;
31 }
32 
33 /*---------------------------------------------------------------------------*/
34 
35 /*!
36  * \brief
37  *
38  * Returns tile-index corresponding to tile-coordinates <em>(xTile,
39  * yTile, zTile)</em>.
40  *
41  * \param map
42  * \param xTile
43  * \param yTile
44  * \param zTile
45  * \return int
46  */
47 int Rast3d_tile2tile_index(RASTER3D_Map *map, int xTile, int yTile, int zTile)
48 {
49  return map->nxy * zTile + map->nx * yTile + xTile;
50 }
51 
52 /*---------------------------------------------------------------------------*/
53 
54 /*!
55  * \brief
56  *
57  * Computes the cell-coordinates <em>(x, y, z)</em>
58  * which correspond to the origin of the tile with tile-coordinates <em>(xTile,
59  * yTile, zTile)</em>.
60  *
61  * \param map
62  * \param xTile
63  * \param yTile
64  * \param zTile
65  * \param x
66  * \param y
67  * \param z
68  * \return void
69  */
70 void Rast3d_tile_coord_origin(RASTER3D_Map *map, int xTile, int yTile,
71  int zTile, int *x, int *y, int *z)
72 {
73  *x = map->tileX * xTile;
74  *y = map->tileY * yTile;
75  *z = map->tileZ * zTile;
76 }
77 
78 /*---------------------------------------------------------------------------*/
79 
80 /*!
81  * \brief
82  *
83  * Computes the cell-coordinates <em>(x, y, z)</em> which correspond to
84  * the origin of the tile with <em>tileIndex</em>.
85  *
86  * \param map
87  * \param tileIndex
88  * \param x
89  * \param y
90  * \param z
91  * \return void
92  */
93 void Rast3d_tile_index_origin(RASTER3D_Map *map, int tileIndex, int *x, int *y,
94  int *z)
95 {
96  int xTile, yTile, zTile;
97 
98  Rast3d_tile_index2tile(map, tileIndex, &xTile, &yTile, &zTile);
99  Rast3d_tile_coord_origin(map, xTile, yTile, zTile, x, y, z);
100 }
101 
102 /*---------------------------------------------------------------------------*/
103 
104 /*!
105  * \brief
106  *
107  * Converts
108  * cell-coordinates <em>(x, y, z)</em> into tile-coordinates <em>(xTile, yTile,
109  * zTile)</em> and the coordinate of the cell <em>(xOffs, yOffs, zOffs)</em>
110  * within the tile.
111  *
112  * \param map
113  * \param x
114  * \param y
115  * \param z
116  * \param xTile
117  * \param yTile
118  * \param zTile
119  * \param xOffs
120  * \param yOffs
121  * \param zOffs
122  * \return void
123  */
124 void Rast3d_coord2tile_coord(RASTER3D_Map *map, int x, int y, int z, int *xTile,
125  int *yTile, int *zTile, int *xOffs, int *yOffs,
126  int *zOffs)
127 {
128  *xTile = x / map->tileX;
129  *xOffs = x % map->tileX;
130  *yTile = y / map->tileY;
131  *yOffs = y % map->tileY;
132  *zTile = z / map->tileZ;
133  *zOffs = z % map->tileZ;
134 }
135 
136 /*---------------------------------------------------------------------------*/
137 
138 /*!
139  * \brief
140  *
141  * Converts cell-coordinates <em>(x, y, z)</em> into
142  * <em>tileIndex</em> and the <em>offset</em> of the cell within the tile.
143  *
144  * \param map
145  * \param x
146  * \param y
147  * \param z
148  * \param tileIndex
149  * \param offset
150  * \return void
151  */
152 void Rast3d_coord2tile_index(RASTER3D_Map *map, int x, int y, int z,
153  int *tileIndex, int *offset)
154 {
155  int xTile, yTile, zTile, xOffs, yOffs, zOffs;
156 
157  Rast3d_coord2tile_coord(map, x, y, z, &xTile, &yTile, &zTile, &xOffs,
158  &yOffs, &zOffs);
159  *tileIndex = Rast3d_tile2tile_index(map, xTile, yTile, zTile);
160  *offset = zOffs * map->tileXY + yOffs * map->tileX + xOffs;
161 }
162 
163 /*---------------------------------------------------------------------------*/
164 
165 /*!
166  * \brief
167  *
168  * Returns 1 if
169  * cell-coordinate <em>(x, y, z)</em> is a coordinate inside the region. Returns
170  * 0 otherwise.
171  *
172  * \param map
173  * \param x
174  * \param y
175  * \param z
176  * \return int
177  */
178 int Rast3d_coord_in_range(RASTER3D_Map *map, int x, int y, int z)
179 {
180  return (x >= 0) && (x < map->region.cols) && (y >= 0) &&
181  (y < map->region.rows) && (z >= 0) && (z < map->region.depths);
182 }
183 
184 /*---------------------------------------------------------------------------*/
185 
186 /*!
187  * \brief
188  *
189  * Returns 1 if <em>tileIndex</em> is a valid index for <em>map</em>.
190  * Returns 0 otherwise.
191  *
192  * \param map
193  * \param tileIndex
194  * \return int
195  */
196 int Rast3d_tile_index_in_range(RASTER3D_Map *map, int tileIndex)
197 {
198  return (tileIndex < map->nTiles) && (tileIndex >= 0);
199 }
200 
201 /*---------------------------------------------------------------------------*/
202 
203 /*!
204  * \brief
205  *
206  * Returns 1 if
207  * tile-coordinate <em>(x, y, z)</em> is a coordinate inside tile cube. Returns
208  * 0 otherwise.
209  *
210  * \param map
211  * \param x
212  * \param y
213  * \param z
214  * \return int
215  */
216 int Rast3d_tile_in_range(RASTER3D_Map *map, int x, int y, int z)
217 {
218  return (x >= 0) && (x < map->nx) && (y >= 0) && (y < map->ny) && (z >= 0) &&
219  (z < map->nz);
220 }
221 
222 /*---------------------------------------------------------------------------*/
223 
224 /*!
225  * \brief
226  *
227  * Computes the dimensions of the tile when clipped to fit the
228  * region of <em>map</em>. The clipped dimensions are returned in <em>rows</em>,
229  * <em>cols</em>, <em>depths</em>. The complement is returned in
230  * <em>xRedundant</em>, <em>yRedundant</em>, and <em>zRedundant</em>. This
231  * function returns the number of cells in the clipped tile.
232  *
233  * \param map
234  * \param tileIndex
235  * \param rows
236  * \param cols
237  * \param depths
238  * \param xRedundant
239  * \param yRedundant
240  * \param zRedundant
241  * \return int
242  */
244  int *rows, int *cols, int *depths,
245  int *xRedundant, int *yRedundant,
246  int *zRedundant)
247 {
248  int x, y, z;
249 
250  Rast3d_tile_index2tile(map, tileIndex, &x, &y, &z);
251 
252  if ((x != map->clipX) && (y != map->clipY) && (z != map->clipZ)) {
253  return map->tileSize;
254  }
255 
256  if (x != map->clipX) {
257  *cols = map->tileX;
258  *xRedundant = 0;
259  }
260  else {
261  *cols = (map->region.cols - 1) % map->tileX + 1;
262  *xRedundant = map->tileX - *cols;
263  }
264  if (y != map->clipY) {
265  *rows = map->tileY;
266  *yRedundant = 0;
267  }
268  else {
269  *rows = (map->region.rows - 1) % map->tileY + 1;
270  *yRedundant = map->tileY - *rows;
271  }
272  if (z != map->clipZ) {
273  *depths = map->tileZ;
274  *zRedundant = 0;
275  }
276  else {
277  *depths = (map->region.depths - 1) % map->tileZ + 1;
278  *zRedundant = map->tileZ - *depths;
279  }
280 
281  /* printf ("%d (%d %d %d): (%d %d) (%d %d) (%d %d), %d\n", */
282  /* tileIndex, x, y, z, *rows, *xRedundant, *cols, *yRedundant, */
283  /* *depths, *zRedundant, *depths * *cols * *rows); */
284 
285  return *depths * *cols * *rows;
286 }
287 
288 /*---------------------------------------------------------------------------*/
289 
290 /*!
291  * \brief Compute the optimal tile size.
292  *
293  * This function computes tile sizes with an optimal ratio between tile
294  * dimensions and minimized border tile overlapping. Large dimensions (in most
295  * cases x and y) will be reduced more often than small dimensions to fit the
296  * maxSize criteria.
297  *
298  * \param region The region of the map
299  * \param type The type of the map (FCELL_TYPE or DCELL_TYPE)
300  * \param tileX Pointer of the tile size in x direction for result storage
301  * \param tileY Pointer of the tile size in y direction for result storage
302  * \param tileZ Pointer of the tile size in z direction for result storage
303  * \param maxSize The max size of the tile in kilo bytes
304  * \return void
305  */
307  int *tileX, int *tileY, int *tileZ,
308  int maxSize)
309 {
310  unsigned long size = 0;
311  unsigned long x, y, z;
312  unsigned long i = 0;
313  unsigned long tileSize;
314  unsigned long divx = 2;
315  unsigned long divy = 2;
316  unsigned long divz = 2;
317 
318  if (type == FCELL_TYPE)
319  size = sizeof(FCELL);
320 
321  if (type == DCELL_TYPE)
322  size = sizeof(DCELL);
323 
324  x = region->cols;
325  y = region->rows;
326  z = region->depths;
327 
328  while (1) {
329  tileSize = size * x * y * z;
330 
331  G_debug(2,
332  "Rast3d_compute_optimal_tile_dimension: tilesize %li x %li y "
333  "%li z %li\n",
334  tileSize, x, y, z);
335 
336  if (maxSize < 0 || tileSize <= (unsigned int)maxSize * 1024)
337  break;
338 
339  /* Compute weighted tile sizes. Take care that the tile size is computed
340  based on the dimension ratio and reduce the border tile overlapping.
341  In case one dimension is much larger than the other, reduce
342  the large dimension by a factor till the maxSize is reached or till
343  the the other dimensions are only by factor 2 smaller. */
344  if ((y / x) <= 2 && (z / x) <= 2) {
345  if (region->cols % divx != 0)
346  x = region->cols / divx + 1;
347  else
348  x = region->cols / divx;
349  divx += 1;
350  }
351  if ((x / y) <= 2 && (z / y) <= 2) {
352  if (region->rows % divy != 0)
353  y = region->rows / divy + 1;
354  else
355  y = region->rows / divy;
356  divy += 1;
357  }
358  if ((x / z) <= 2 && (y / z) <= 2) {
359  if (region->depths % divz != 0)
360  z = region->depths / divz + 1;
361  else
362  z = region->depths / divz;
363  divz += 1;
364  }
365 
366  /* Avoid infinite loop */
367  i++;
368  if (i > 10000)
369  break;
370  }
371 
372  *tileX = (int)x;
373  *tileY = (int)y;
374  *tileZ = (int)z;
375 }
int G_debug(int, const char *,...) __attribute__((format(printf
float FCELL
Definition: gis.h:636
double DCELL
Definition: gis.h:635
#define FCELL_TYPE
Definition: raster.h:12
#define DCELL_TYPE
Definition: raster.h:13
RASTER3D_Region region
Definition: raster3d.h:82
int tileSize
Definition: raster3d.h:180
int Rast3d_tile_in_range(RASTER3D_Map *map, int x, int y, int z)
Returns 1 if tile-coordinate (x, y, z) is a coordinate inside tile cube. Returns 0 otherwise.
Definition: tilemath.c:216
void Rast3d_tile_coord_origin(RASTER3D_Map *map, int xTile, int yTile, int zTile, int *x, int *y, int *z)
Computes the cell-coordinates (x, y, z) which correspond to the origin of the tile with tile-coordina...
Definition: tilemath.c:70
int Rast3d_tile2tile_index(RASTER3D_Map *map, int xTile, int yTile, int zTile)
Returns tile-index corresponding to tile-coordinates (xTile, yTile, zTile).
Definition: tilemath.c:47
void Rast3d_tile_index_origin(RASTER3D_Map *map, int tileIndex, int *x, int *y, int *z)
Computes the cell-coordinates (x, y, z) which correspond to the origin of the tile with tileIndex.
Definition: tilemath.c:93
void Rast3d_tile_index2tile(RASTER3D_Map *map, int tileIndex, int *xTile, int *yTile, int *zTile)
Converts index tileIndex into tile-coordinates (xTile, yTile, zTile).
Definition: tilemath.c:22
void Rast3d_coord2tile_index(RASTER3D_Map *map, int x, int y, int z, int *tileIndex, int *offset)
Converts cell-coordinates (x, y, z) into tileIndex and the offset of the cell within the tile.
Definition: tilemath.c:152
int Rast3d_tile_index_in_range(RASTER3D_Map *map, int tileIndex)
Returns 1 if tileIndex is a valid index for map. Returns 0 otherwise.
Definition: tilemath.c:196
int Rast3d_compute_clipped_tile_dimensions(RASTER3D_Map *map, int tileIndex, int *rows, int *cols, int *depths, int *xRedundant, int *yRedundant, int *zRedundant)
Computes the dimensions of the tile when clipped to fit the region of map. The clipped dimensions are...
Definition: tilemath.c:243
void Rast3d_compute_optimal_tile_dimension(RASTER3D_Region *region, int type, int *tileX, int *tileY, int *tileZ, int maxSize)
Compute the optimal tile size.
Definition: tilemath.c:306
void Rast3d_coord2tile_coord(RASTER3D_Map *map, int x, int y, int z, int *xTile, int *yTile, int *zTile, int *xOffs, int *yOffs, int *zOffs)
Converts cell-coordinates (x, y, z) into tile-coordinates (xTile, yTile, zTile) and the coordinate of...
Definition: tilemath.c:124
int Rast3d_coord_in_range(RASTER3D_Map *map, int x, int y, int z)
Returns 1 if cell-coordinate (x, y, z) is a coordinate inside the region. Returns 0 otherwise.
Definition: tilemath.c:178
#define x