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