GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
tilewrite.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 
6 #include <grass/gis.h>
7 #include <grass/raster.h>
8 #include "raster3d_intern.h"
9 
10 /*---------------------------------------------------------------------------*/
11 
12 static int Rast3d_tile2xdrTile(RASTER3D_Map *map, const void *tile, int rows,
13  int cols, int depths, int xRedundant,
14  int yRedundant, int zRedundant UNUSED,
15  int nofNum, int type)
16 {
17  int y, z;
18 
19  if (!Rast3d_init_copy_to_xdr(map, type)) {
20  Rast3d_error("Rast3d_tile2xdrTile: error in Rast3d_init_copy_to_xdr");
21  return 0;
22  }
23 
24  if (nofNum == map->tileSize) {
25  if (!Rast3d_copy_to_xdr(tile, map->tileSize)) {
26  Rast3d_error("Rast3d_tile2xdrTile: error in Rast3d_copy_to_xdr");
27  return 0;
28  }
29  return 1;
30  }
31 
32  if (xRedundant) {
33  for (z = 0; z < depths; z++) {
34  for (y = 0; y < rows; y++) {
35  if (!Rast3d_copy_to_xdr(tile, cols)) {
37  "Rast3d_tile2xdrTile: error in Rast3d_copy_to_xdr");
38  return 0;
39  }
40  tile = G_incr_void_ptr(tile, map->tileX * Rast3d_length(type));
41  }
42  if (yRedundant)
43  tile = G_incr_void_ptr(tile, map->tileX * yRedundant *
44  Rast3d_length(type));
45  }
46  return 1;
47  }
48 
49  if (yRedundant) {
50  for (z = 0; z < depths; z++) {
51  if (!Rast3d_copy_to_xdr(tile, map->tileX * rows)) {
53  "Rast3d_tile2xdrTile: error in Rast3d_copy_to_xdr");
54  return 0;
55  }
56  tile = G_incr_void_ptr(tile, map->tileXY * Rast3d_length(type));
57  }
58  return 1;
59  }
60 
61  if (!Rast3d_copy_to_xdr(tile, map->tileXY * depths)) {
62  Rast3d_error("Rast3d_tile2xdrTile: error in Rast3d_copy_to_xdr");
63  return 0;
64  }
65  return 1;
66 }
67 
68 /*---------------------------------------------------------------------------*/
69 
70 static int Rast3d_writeTileUncompressed(RASTER3D_Map *map, int nofNum)
71 {
72  if (write(map->data_fd, xdr, map->numLengthExtern * nofNum) !=
73  map->numLengthExtern * nofNum) {
74  Rast3d_error("Rast3d_writeTileUncompressed: can't write file.");
75  return 0;
76  }
77 
78  return 1;
79 }
80 
81 /*---------------------------------------------------------------------------*/
82 
83 static int Rast3d_writeTileCompressed(RASTER3D_Map *map, int nofNum)
84 {
85  if (!Rast3d_fpcompress_write_xdr_nums(map->data_fd, xdr, nofNum,
86  map->precision, tmpCompress,
87  map->type == FCELL_TYPE)) {
88  Rast3d_error("Rast3d_writeTileCompressed: error in "
89  "Rast3d_fpcompress_write_xdr_nums");
90  return 0;
91  }
92 
93  return 1;
94 }
95 
96 /*---------------------------------------------------------------------------*/
97 
98 /*---------------------------------------------------------------------------*/
99 
100 /* EXPORTED FUNCTIONS */
101 
102 /*---------------------------------------------------------------------------*/
103 
104 /*---------------------------------------------------------------------------*/
105 
106 /*!
107  * \brief
108  *
109  *
110  * Writes tile with index <em>tileIndex</em> to the file corresponding to
111  * <em>map</em>. It is assumed that the cells in <em>tile</em> are of
112  * <em>type</em> which must be one of FCELL_TYPE and DCELL_TYPE. The actual
113  * type used to write the tile depends on the type specified at the time when
114  * <em>map</em> is initialized. A tile can only be written once. Subsequent
115  * attempts to write the same tile are ignored.
116  *
117  * \param map
118  * \param tileIndex
119  * \param tile
120  * \param type
121  * \return 1 ... if successful,
122  * 2 ... if write request was ignored,
123  * 0 ... otherwise.
124  */
125 int Rast3d_write_tile(RASTER3D_Map *map, int tileIndex, const void *tile,
126  int type)
127 {
128  int rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum;
129 
130  /* valid tileIndex ? */
131  if ((tileIndex > map->nTiles) || (tileIndex < 0))
132  Rast3d_fatal_error("Rast3d_write_tile: tileIndex out of range");
133 
134  /* already written ? */
135  if (map->index[tileIndex] != -1)
136  return 2;
137 
138  /* save the file position */
139  map->index[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END);
140  if (map->index[tileIndex] == -1) {
141  Rast3d_error("Rast3d_write_tile: can't position file");
142  return 0;
143  }
144 
145  nofNum = Rast3d_compute_clipped_tile_dimensions(map, tileIndex, &rows,
146  &cols, &depths, &xRedundant,
147  &yRedundant, &zRedundant);
148 
149  Rast3d_range_update_from_tile(map, tile, rows, cols, depths, xRedundant,
150  yRedundant, zRedundant, nofNum, type);
151 
152  if (!Rast3d_tile2xdrTile(map, tile, rows, cols, depths, xRedundant,
153  yRedundant, zRedundant, nofNum, type)) {
154  Rast3d_error("Rast3d_write_tile: error in Rast3d_tile2xdrTile");
155  return 0;
156  }
157 
158  if (map->compression == RASTER3D_NO_COMPRESSION) {
159  if (!Rast3d_writeTileUncompressed(map, nofNum)) {
160  Rast3d_error(
161  "Rast3d_write_tile: error in Rast3d_writeTileUncompressed");
162  return 0;
163  }
164  }
165  else {
166  if (!Rast3d_writeTileCompressed(map, nofNum)) {
167  Rast3d_error(
168  "Rast3d_write_tile: error in Rast3d_writeTileCompressed");
169  return 0;
170  }
171  }
172 
173  /* compute the length */
174  map->tileLength[tileIndex] =
175  lseek(map->data_fd, (long)0, SEEK_END) - map->index[tileIndex];
176 
177  return 1;
178 }
179 
180 /*---------------------------------------------------------------------------*/
181 
182 /*!
183  * \brief
184  *
185  * Is equivalent to <tt>Rast3d_write_tile (map, tileIndex, tile,
186  * FCELL_TYPE).</tt>
187  *
188  * \param map
189  * \param tileIndex
190  * \param tile
191  * \return int
192  */
193 int Rast3d_write_tile_float(RASTER3D_Map *map, int tileIndex, const void *tile)
194 {
195  int status;
196 
197  if ((status = Rast3d_write_tile(map, tileIndex, tile, FCELL_TYPE)))
198  return status;
199 
200  Rast3d_error("Rast3d_write_tile_float: error in Rast3d_write_tile");
201  return 0;
202 }
203 
204 /*---------------------------------------------------------------------------*/
205 
206 /*!
207  * \brief
208  *
209  * Is equivalent to <tt>Rast3d_write_tile (map, tileIndex, tile,
210  * DCELL_TYPE).</tt>
211  *
212  * \param map
213  * \param tileIndex
214  * \param tile
215  * \return int
216  */
217 int Rast3d_write_tile_double(RASTER3D_Map *map, int tileIndex, const void *tile)
218 {
219  int status;
220 
221  if ((status = Rast3d_write_tile(map, tileIndex, tile, DCELL_TYPE)))
222  return status;
223 
224  Rast3d_error("Rast3d_write_tile_double: error in Rast3d_write_tile");
225  return 0;
226 }
227 
228 /*---------------------------------------------------------------------------*/
229 
230 /* CACHE-MODE-ONLY FUNCTIONS */
231 
232 /*---------------------------------------------------------------------------*/
233 
234 /*!
235  * \brief
236  *
237  * Writes the tile with
238  * <em>tileIndex</em> to the file corresponding to <em>map</em> and removes the
239  * tile from the cache (in non-cache mode the buffer provided by the
240  * map-structure is written). If this tile has already been written before the
241  * write request is ignored. If the tile was never referred to before the
242  * invocation of Rast3d_flush_tile, a tile filled with NULL-values is written.
243  *
244  * \param map
245  * \param tileIndex
246  * \return 1 ... if successful,
247  * 0 ... otherwise.
248  */
249 int Rast3d_flush_tile(RASTER3D_Map *map, int tileIndex)
250 {
251  const void *tile;
252 
253  tile = Rast3d_get_tile_ptr(map, tileIndex);
254  if (tile == NULL) {
255  Rast3d_error("Rast3d_flush_tile: error in Rast3d_get_tile_ptr");
256  return 0;
257  }
258 
259  if (!Rast3d_write_tile(map, tileIndex, tile, map->typeIntern)) {
260  Rast3d_error("Rast3d_flush_tile: error in Rast3d_write_tile");
261  return 0;
262  }
263 
264  if (!Rast3d__remove_tile(map, tileIndex)) {
265  Rast3d_error("Rast3d_flush_tile: error in Rast3d__remove_tile");
266  return 0;
267  }
268 
269  return 1;
270 }
271 
272 /*---------------------------------------------------------------------------*/
273 
274 /*!
275  * \brief
276  *
277  * Writes the tiles with tile-coordinates
278  * contained in the axis-parallel cube with vertices <em>(xMin, yMin, zMin)</em>
279  * and <em>(xMax, yMax, zMax</em>). Tiles which are not stored in the cache are
280  * written as NULL-tiles. Write attempts for tiles which have already been
281  * written earlier are ignored.
282  *
283  * \param map
284  * \param xMin
285  * \param yMin
286  * \param zMin
287  * \param xMax
288  * \param yMax
289  * \param zMax
290  * \return 1 ... if successful,
291  * 0 ... otherwise.
292  */
293 int Rast3d_flush_tile_cube(RASTER3D_Map *map, int xMin, int yMin, int zMin,
294  int xMax, int yMax, int zMax)
295 {
296  int x, y, z;
297 
298  if (!map->useCache)
300  "Rast3d_flush_tile_cube: function invalid in non-cache mode");
301 
302  for (x = xMin; x <= xMax; x++)
303  for (y = yMin; y <= yMax; y++)
304  for (z = zMin; z <= zMax; z++)
305  if (!Rast3d_flush_tile(map,
306  Rast3d_tile2tile_index(map, x, y, z))) {
307  Rast3d_error(
308  "Rast3d_flush_tile_cube: error in Rast3d_flush_tile");
309  return 0;
310  }
311 
312  return 1;
313 }
314 
315 /*---------------------------------------------------------------------------*/
316 
317 /*!
318  * \brief
319  *
320  * Writes those tiles for which
321  * <em>every</em> cell has coordinate contained in the axis-parallel cube
322  * defined by the vertices with cell-coordinates <em>(xMin, yMin, zMin)</em>
323  * and <em>(xMax, yMax, zMax)</em>.
324  * Tiles which are not stored in the cache are written as NULL-tiles.
325  * Write attempts for tiles which have already been written earlier are
326  * ignored.
327  *
328  * \param map
329  * \param xMin
330  * \param yMin
331  * \param zMin
332  * \param xMax
333  * \param yMax
334  * \param zMax
335  * \return 1 ... if successful,
336  * 0 ... otherwise.
337  */
338 int Rast3d_flush_tiles_in_cube(RASTER3D_Map *map, int xMin, int yMin, int zMin,
339  int xMax, int yMax, int zMax)
340 {
341  int xTileMin, yTileMin, zTileMin, xTileMax, yTileMax, zTileMax;
342  int xOffs, yOffs, zOffs;
343  int regionMaxX, regionMaxY, regionMaxZ;
344 
345  if (!map->useCache)
347  "Rast3d_flush_tiles_in_cube: function invalid in non-cache mode");
348  /*AV*/
349  /*BEGIN OF ORIGINAL CODE */
350  /*
351  * Rast3d_get_coords_map (map, &regionMaxX, &regionMaxY, &regionMaxZ);
352  */
353  /*AV*/
354  /* BEGIN OF MY CODE */
355  Rast3d_get_coords_map(map, &regionMaxY, &regionMaxX, &regionMaxZ);
356  /* END OF MY CODE */
357 
358  if ((xMin < 0) && (xMax < 0))
360  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
361  if ((xMin >= regionMaxX) && (xMax >= regionMaxX))
363  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
364 
365  xMin = MIN(MAX(0, xMin), regionMaxX - 1);
366 
367  if ((yMin < 0) && (yMax < 0))
369  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
370  if ((yMin >= regionMaxY) && (yMax >= regionMaxY))
372  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
373 
374  yMin = MIN(MAX(0, yMin), regionMaxY - 1);
375 
376  if ((zMin < 0) && (zMax < 0))
378  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
379  if ((zMin >= regionMaxZ) && (zMax >= regionMaxZ))
381  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
382 
383  zMin = MIN(MAX(0, zMin), regionMaxZ - 1);
384 
385  Rast3d_coord2tile_coord(map, xMin, yMin, zMin, &xTileMin, &yTileMin,
386  &zTileMin, &xOffs, &yOffs, &zOffs);
387 
388  if (xOffs != 0)
389  xTileMin++;
390  if (yOffs != 0)
391  yTileMin++;
392  if (zOffs != 0)
393  zTileMin++;
394 
395  Rast3d_coord2tile_coord(map, xMax + 1, yMax + 1, zMax + 1, &xTileMax,
396  &yTileMax, &zTileMax, &xOffs, &yOffs, &zOffs);
397 
398  xTileMax--;
399  yTileMax--;
400  zTileMax--;
401 
402  if (!Rast3d_flush_tile_cube(map, xTileMin, yTileMin, zTileMin, xTileMax,
403  yTileMax, zTileMax)) {
404  Rast3d_error(
405  "Rast3d_flush_tiles_in_cube: error in Rast3d_flush_tile_cube");
406  return 0;
407  }
408 
409  return 1;
410 }
411 
412 #undef MIN
413 #undef MAX
414 
415 /*---------------------------------------------------------------------------*/
#define NULL
Definition: ccmath.h:32
#define G_incr_void_ptr(ptr, size)
Definition: defs/gis.h:81
void Rast3d_get_coords_map(RASTER3D_Map *, int *, int *, int *)
Returns the size of the region of map in cells.
Definition: headerinfo.c:17
void * Rast3d_get_tile_ptr(RASTER3D_Map *, int)
This function returns a pointer to a tile which contains the data for the tile with index tileIndex....
Definition: tileio.c:78
int Rast3d_tile2tile_index(RASTER3D_Map *, int, int, int)
Returns tile-index corresponding to tile-coordinates (xTile, yTile, zTile).
Definition: tilemath.c:47
void Rast3d_range_update_from_tile(RASTER3D_Map *, const void *, int, int, int, int, int, int, int, int)
void Rast3d_coord2tile_coord(RASTER3D_Map *, int, int, int, int *, int *, int *, int *, int *, int *)
Converts cell-coordinates (x, y, z) into tile-coordinates (xTile, yTile, zTile) and the coordinate of...
Definition: tilemath.c:124
int Rast3d_length(int)
Definition: raster3d/misc.c:75
int Rast3d_copy_to_xdr(const void *, int)
Definition: fpxdr.c:141
int Rast3d_compute_clipped_tile_dimensions(RASTER3D_Map *, int, int *, int *, int *, int *, int *, int *)
Computes the dimensions of the tile when clipped to fit the region of map. The clipped dimensions are...
Definition: tilemath.c:243
void Rast3d_error(const char *,...) __attribute__((format(printf
int Rast3d__remove_tile(RASTER3D_Map *, int)
Definition: tileio.c:133
void Rast3d_fatal_error(const char *,...) __attribute__((format(printf
int Rast3d_init_copy_to_xdr(RASTER3D_Map *, int)
Definition: fpxdr.c:102
int Rast3d_fpcompress_write_xdr_nums(int, char *, int, int, char *, int)
Definition: fpcompress.c:685
#define MIN(a, b)
Definition: gis.h:153
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:46
#define MAX(a, b)
Definition: gis.h:148
void * xdr
void * tmpCompress
#define RASTER3D_NO_COMPRESSION
Definition: raster3d.h:13
#define FCELL_TYPE
Definition: raster.h:12
#define DCELL_TYPE
Definition: raster.h:13
long * index
Definition: raster3d.h:142
int numLengthExtern
Definition: raster3d.h:173
int precision
Definition: raster3d.h:109
int compression
Definition: raster3d.h:111
int tileSize
Definition: raster3d.h:180
int * tileLength
Definition: raster3d.h:145
int useCache
Definition: raster3d.h:160
int typeIntern
Definition: raster3d.h:150
int Rast3d_write_tile_double(RASTER3D_Map *map, int tileIndex, const void *tile)
Is equivalent to Rast3d_write_tile (map, tileIndex, tile, DCELL_TYPE).
Definition: tilewrite.c:217
int Rast3d_flush_tile_cube(RASTER3D_Map *map, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax)
Writes the tiles with tile-coordinates contained in the axis-parallel cube with vertices (xMin,...
Definition: tilewrite.c:293
int Rast3d_write_tile_float(RASTER3D_Map *map, int tileIndex, const void *tile)
Is equivalent to Rast3d_write_tile (map, tileIndex, tile, FCELL_TYPE).
Definition: tilewrite.c:193
int Rast3d_flush_tile(RASTER3D_Map *map, int tileIndex)
Writes the tile with tileIndex to the file corresponding to map and removes the tile from the cache (...
Definition: tilewrite.c:249
int Rast3d_write_tile(RASTER3D_Map *map, int tileIndex, const void *tile, int type)
Writes tile with index tileIndex to the file corresponding to map. It is assumed that the cells in ti...
Definition: tilewrite.c:125
int Rast3d_flush_tiles_in_cube(RASTER3D_Map *map, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax)
Writes those tiles for which every cell has coordinate contained in the axis-parallel cube defined by...
Definition: tilewrite.c:338
#define write
Definition: unistd.h:6
#define x