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