GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-87d2d42d3b
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 
126 int Rast3d_write_tile(RASTER3D_Map *map, int tileIndex, const void *tile,
127  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, &rows,
147  &cols, &depths, &xRedundant,
148  &yRedundant, &zRedundant);
149 
150  Rast3d_range_update_from_tile(map, tile, rows, cols, depths, xRedundant,
151  yRedundant, zRedundant, nofNum, type);
152 
153  if (!Rast3d_tile2xdrTile(map, tile, rows, cols, depths, xRedundant,
154  yRedundant, zRedundant, nofNum, type)) {
155  Rast3d_error("Rast3d_write_tile: error in Rast3d_tile2xdrTile");
156  return 0;
157  }
158 
159  if (map->compression == RASTER3D_NO_COMPRESSION) {
160  if (!Rast3d_writeTileUncompressed(map, nofNum)) {
161  Rast3d_error(
162  "Rast3d_write_tile: error in Rast3d_writeTileUncompressed");
163  return 0;
164  }
165  }
166  else {
167  if (!Rast3d_writeTileCompressed(map, nofNum)) {
168  Rast3d_error(
169  "Rast3d_write_tile: error in Rast3d_writeTileCompressed");
170  return 0;
171  }
172  }
173 
174  /* compute the length */
175  map->tileLength[tileIndex] =
176  lseek(map->data_fd, (long)0, SEEK_END) - map->index[tileIndex];
177 
178  return 1;
179 }
180 
181 /*---------------------------------------------------------------------------*/
182 
183 /*!
184  * \brief
185  *
186  * Is equivalent to <tt>Rast3d_write_tile (map, tileIndex, tile,
187  * 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  * \brief
210  *
211  * Is equivalent to <tt>Rast3d_write_tile (map, tileIndex, tile,
212  * 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  * \brief
239  *
240  * Writes the tile with
241  * <em>tileIndex</em> to the file corresponding to <em>map</em> and removes the
242  * tile from the cache (in non-cache mode the buffer provided by the
243  * map-structure is written). If this tile has already been written before the
244  * write request is ignored. If the tile was never referred to before the
245  * invocation of Rast3d_flush_tile, a tile filled with NULL-values is written.
246  *
247  * \param map
248  * \param tileIndex
249  * \return 1 ... if successful,
250  * 0 ... otherwise.
251  */
252 
253 int Rast3d_flush_tile(RASTER3D_Map *map, int tileIndex)
254 {
255  const void *tile;
256 
257  tile = Rast3d_get_tile_ptr(map, tileIndex);
258  if (tile == NULL) {
259  Rast3d_error("Rast3d_flush_tile: error in Rast3d_get_tile_ptr");
260  return 0;
261  }
262 
263  if (!Rast3d_write_tile(map, tileIndex, tile, map->typeIntern)) {
264  Rast3d_error("Rast3d_flush_tile: error in Rast3d_write_tile");
265  return 0;
266  }
267 
268  if (!Rast3d__remove_tile(map, tileIndex)) {
269  Rast3d_error("Rast3d_flush_tile: error in Rast3d__remove_tile");
270  return 0;
271  }
272 
273  return 1;
274 }
275 
276 /*---------------------------------------------------------------------------*/
277 
278 /*!
279  * \brief
280  *
281  * Writes the tiles with tile-coordinates
282  * contained in the axis-parallel cube with vertices <em>(xMin, yMin, zMin)</em>
283  * and <em>(xMax, yMax, zMax</em>). Tiles which are not stored in the cache are
284  * written as NULL-tiles. Write attempts for tiles which have already been
285  * written earlier are ignored.
286  *
287  * \param map
288  * \param xMin
289  * \param yMin
290  * \param zMin
291  * \param xMax
292  * \param yMax
293  * \param zMax
294  * \return 1 ... if successful,
295  * 0 ... otherwise.
296  */
297 
298 int Rast3d_flush_tile_cube(RASTER3D_Map *map, int xMin, int yMin, int zMin,
299  int xMax, int yMax, int zMax)
300 {
301  int x, y, z;
302 
303  if (!map->useCache)
305  "Rast3d_flush_tile_cube: function invalid in non-cache mode");
306 
307  for (x = xMin; x <= xMax; x++)
308  for (y = yMin; y <= yMax; y++)
309  for (z = zMin; z <= zMax; z++)
310  if (!Rast3d_flush_tile(map,
311  Rast3d_tile2tile_index(map, x, y, z))) {
312  Rast3d_error(
313  "Rast3d_flush_tile_cube: error in Rast3d_flush_tile");
314  return 0;
315  }
316 
317  return 1;
318 }
319 
320 /*---------------------------------------------------------------------------*/
321 
322 /*!
323  * \brief
324  *
325  * Writes those tiles for which
326  * <em>every</em> cell has coordinate contained in the axis-parallel cube
327  * defined by the vertices with cell-coordinates <em>(xMin, yMin, zMin)</em>
328  * and <em>(xMax, yMax, zMax)</em>.
329  * Tiles which are not stored in the cache are written as NULL-tiles.
330  * Write attempts for tiles which have already been written earlier are
331  * ignored.
332  *
333  * \param map
334  * \param xMin
335  * \param yMin
336  * \param zMin
337  * \param xMax
338  * \param yMax
339  * \param zMax
340  * \return 1 ... if successful,
341  * 0 ... otherwise.
342  */
343 
344 int Rast3d_flush_tiles_in_cube(RASTER3D_Map *map, int xMin, int yMin, int zMin,
345  int xMax, int yMax, int zMax)
346 {
347  int xTileMin, yTileMin, zTileMin, xTileMax, yTileMax, zTileMax;
348  int xOffs, yOffs, zOffs;
349  int regionMaxX, regionMaxY, regionMaxZ;
350 
351  if (!map->useCache)
353  "Rast3d_flush_tiles_in_cube: function invalid in non-cache mode");
354  /*AV*/
355  /*BEGIN OF ORIGINAL CODE */
356  /*
357  * Rast3d_get_coords_map (map, &regionMaxX, &regionMaxY, &regionMaxZ);
358  */
359  /*AV*/
360  /* BEGIN OF MY CODE */
361  Rast3d_get_coords_map(map, &regionMaxY, &regionMaxX, &regionMaxZ);
362  /* END OF MY CODE */
363 
364  if ((xMin < 0) && (xMax < 0))
366  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
367  if ((xMin >= regionMaxX) && (xMax >= regionMaxX))
369  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
370 
371  xMin = MIN(MAX(0, xMin), regionMaxX - 1);
372 
373  if ((yMin < 0) && (yMax < 0))
375  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
376  if ((yMin >= regionMaxY) && (yMax >= regionMaxY))
378  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
379 
380  yMin = MIN(MAX(0, yMin), regionMaxY - 1);
381 
382  if ((zMin < 0) && (zMax < 0))
384  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
385  if ((zMin >= regionMaxZ) && (zMax >= regionMaxZ))
387  "Rast3d_flush_tiles_in_cube: coordinate out of Range");
388 
389  zMin = MIN(MAX(0, zMin), regionMaxZ - 1);
390 
391  Rast3d_coord2tile_coord(map, xMin, yMin, zMin, &xTileMin, &yTileMin,
392  &zTileMin, &xOffs, &yOffs, &zOffs);
393 
394  if (xOffs != 0)
395  xTileMin++;
396  if (yOffs != 0)
397  yTileMin++;
398  if (zOffs != 0)
399  zTileMin++;
400 
401  Rast3d_coord2tile_coord(map, xMax + 1, yMax + 1, zMax + 1, &xTileMax,
402  &yTileMax, &zTileMax, &xOffs, &yOffs, &zOffs);
403 
404  xTileMax--;
405  yTileMax--;
406  zTileMax--;
407 
408  if (!Rast3d_flush_tile_cube(map, xTileMin, yTileMin, zTileMin, xTileMax,
409  yTileMax, zTileMax)) {
410  Rast3d_error(
411  "Rast3d_flush_tiles_in_cube: error in Rast3d_flush_tile_cube");
412  return 0;
413  }
414 
415  return 1;
416 }
417 
418 #undef MIN
419 #undef MAX
420 
421 /*---------------------------------------------------------------------------*/
#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:18
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:79
int Rast3d_tile2tile_index(RASTER3D_Map *, int, int, int)
Returns tile-index corresponding to tile-coordinates (xTile, yTile, zTile).
Definition: tilemath.c:49
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:129
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:253
void Rast3d_error(const char *,...) __attribute__((format(printf
int Rast3d__remove_tile(RASTER3D_Map *, int)
Definition: tileio.c:135
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:154
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:47
#define MAX(a, b)
Definition: gis.h:149
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:220
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:298
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 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:253
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:126
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:344
#define x