GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-a1cfe415e
raster3d/open.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <sys/types.h>
5 #include <unistd.h>
6 #include <grass/raster3d.h>
7 #include <grass/glocale.h>
8 #include "raster3d_intern.h"
9 
10 /*---------------------------------------------------------------------------*/
11 
12 void *Rast3d_open_cell_old_no_header(const char *name, const char *mapset)
13 {
14  RASTER3D_Map *map;
15  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
16 
18 
19  if (!Rast3d_mask_open_old()) {
20  Rast3d_error(_("Rast3d_open_cell_old_no_header: error in Rast3d_mask_open_old"));
21  return (void *)NULL;
22  }
23 
24  map = Rast3d_malloc(sizeof(RASTER3D_Map));
25  if (map == NULL) {
26  Rast3d_error(_("Rast3d_open_cell_old_no_header: error in Rast3d_malloc"));
27  return (void *)NULL;
28  }
29 
30  G_unqualified_name(name, mapset, xname, xmapset);
31 
32  map->fileName = G_store(xname);
33  map->mapset = G_store(xmapset);
34 
36  if (map->data_fd < 0) {
37  Rast3d_error(_("Rast3d_open_cell_old_no_header: error in G_open_old"));
38  return (void *)NULL;
39  }
40 
41  Rast3d_range_init(map);
42  Rast3d_mask_off(map);
43 
44  return map;
45 }
46 
47 /*---------------------------------------------------------------------------*/
48 
49 
50 /*!
51  * \brief
52  *
53  * Opens existing g3d-file <em>name</em> in <em>mapset</em>.
54  * Tiles are stored in memory with <em>type</em> which must be any of FCELL_TYPE,
55  * DCELL_TYPE, or RASTER3D_TILE_SAME_AS_FILE. <em>cache</em> specifies the
56  * cache-mode used and must be either RASTER3D_NO_CACHE, RASTER3D_USE_CACHE_DEFAULT,
57  * RASTER3D_USE_CACHE_X, RASTER3D_USE_CACHE_Y, RASTER3D_USE_CACHE_Z,
58  * RASTER3D_USE_CACHE_XY, RASTER3D_USE_CACHE_XZ, RASTER3D_USE_CACHE_YZ,
59  * RASTER3D_USE_CACHE_XYZ, the result of <tt>Rast3d_cache_size_encode ()</tt> (cf.{g3d:G3d.cacheSizeEncode}), or any positive integer which
60  * specifies the number of tiles buffered in the cache. <em>window</em> sets the
61  * window-region for the map. It is either a pointer to a window structure or
62  * RASTER3D_DEFAULT_WINDOW, which uses the window stored at initialization time or
63  * set via <tt>Rast3d_set_window ()</tt> (cf.{g3d:G3d.setWindow}).
64  * To modify the window for the map after it has already been opened use
65  * <tt>Rast3d_set_window_map ()</tt> (cf.{g3d:G3d.setWindowMap}).
66  * Returns a pointer to the cell structure ... if successful, NULL ...
67  * otherwise.
68  *
69  * \param name
70  * \param mapset
71  * \param window
72  * \param type
73  * \param cache
74  * \return void *
75  */
76 
77 void *Rast3d_open_cell_old(const char *name, const char *mapset,
78  RASTER3D_Region * window, int typeIntern, int cache)
79 {
80  RASTER3D_Map *map;
81  int proj, zone;
82  int compression, useRle, useLzw, type, tileX, tileY, tileZ;
83  int rows, cols, depths, precision;
84  double ew_res, ns_res, tb_res;
85  int nofHeaderBytes, dataOffset, useXdr, hasIndex;
86  char *unit;
87  unsigned char *ltmp;
88  int vertical_unit;
89  int version;
90  double north, south, east, west, top, bottom;
91 
92  map = Rast3d_open_cell_old_no_header(name, mapset);
93  if (map == NULL) {
94  Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_open_cell_old_no_header"));
95  return (void *)NULL;
96  }
97 
98  if (lseek(map->data_fd, (long)0, SEEK_SET) == -1) {
99  Rast3d_error(_("Rast3d_open_cell_old: can't rewind file"));
100  return (void *)NULL;
101  }
102 
103  if (!Rast3d_read_header(map,
104  &proj, &zone,
105  &north, &south, &east, &west, &top, &bottom,
106  &rows, &cols, &depths,
107  &ew_res, &ns_res, &tb_res,
108  &tileX, &tileY, &tileZ,
109  &type, &compression, &useRle, &useLzw,
110  &precision, &dataOffset, &useXdr, &hasIndex, &unit, &vertical_unit,
111  &version)) {
112  Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_read_header"));
113  return 0;
114  }
115 
116  if (window == RASTER3D_DEFAULT_WINDOW)
117  window = Rast3d_window_ptr();
118 
119  if (proj != window->proj) {
120  Rast3d_error(_("Rast3d_open_cell_old: projection does not match window projection"));
121  return (void *)NULL;
122  }
123  if (zone != window->zone) {
124  Rast3d_error(_("Rast3d_open_cell_old: zone does not match window zone"));
125  return (void *)NULL;
126  }
127 
128  map->useXdr = useXdr;
129 
130  if (hasIndex) {
131  /* see RASTER3D_openCell_new () for format of header */
132  if ((!Rast3d_read_ints(map->data_fd, map->useXdr,
133  &(map->indexLongNbytes), 1)) ||
134  (!Rast3d_read_ints(map->data_fd, map->useXdr,
135  &(map->indexNbytesUsed), 1))) {
136  Rast3d_error(_("Rast3d_open_cell_old: can't read header"));
137  return (void *)NULL;
138  }
139 
140  /* if our long is to short to store offsets we can't read the file */
141  if (map->indexNbytesUsed > sizeof(long))
142  Rast3d_fatal_error(_("Rast3d_open_cell_old: index does not fit into long"));
143 
144  ltmp = Rast3d_malloc(map->indexLongNbytes);
145  if (ltmp == NULL) {
146  Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_malloc"));
147  return (void *)NULL;
148  }
149 
150  /* convert file long to long */
151  if (read(map->data_fd, ltmp, map->indexLongNbytes) !=
152  map->indexLongNbytes) {
153  Rast3d_error(_("Rast3d_open_cell_old: can't read header"));
154  return (void *)NULL;
155  }
156  Rast3d_long_decode(ltmp, &(map->indexOffset), 1, map->indexLongNbytes);
157  Rast3d_free(ltmp);
158  }
159 
160  nofHeaderBytes = dataOffset;
161 
162  if (typeIntern == RASTER3D_TILE_SAME_AS_FILE)
163  typeIntern = type;
164 
165  if (!Rast3d_fill_header(map, RASTER3D_READ_DATA, compression, useRle, useLzw,
166  type, precision, cache,
167  hasIndex, map->useXdr, typeIntern,
168  nofHeaderBytes, tileX, tileY, tileZ,
169  proj, zone,
170  north, south, east, west, top, bottom,
171  rows, cols, depths, ew_res, ns_res, tb_res, unit, vertical_unit,
172  version)) {
173  Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_fill_header"));
174  return (void *)NULL;
175  }
176 
177  Rast3d_region_copy(&(map->window), window);
178  Rast3d_adjust_region(&(map->window));
180 
181  return map;
182 }
183 
184 /*---------------------------------------------------------------------------*/
185 
186 
187 /*!
188  * \brief
189  *
190  * Opens new g3d-file with <em>name</em> in the current mapset. Tiles
191  * are stored in memory with <em>type</em> which must be one of FCELL_TYPE,
192  * DCELL_TYPE, or RASTER3D_TILE_SAME_AS_FILE. <em>cache</em> specifies the
193  * cache-mode used and must be either RASTER3D_NO_CACHE, RASTER3D_USE_CACHE_DEFAULT,
194  * RASTER3D_USE_CACHE_X, RASTER3D_USE_CACHE_Y, RASTER3D_USE_CACHE_Z,
195  * RASTER3D_USE_CACHE_XY, RASTER3D_USE_CACHE_XZ, RASTER3D_USE_CACHE_YZ,
196  * RASTER3D_USE_CACHE_XYZ, the result of <tt>Rast3d_cache_size_encode ()</tt>
197  * (cf.{g3d:G3d.cacheSizeEncode}), or any positive integer which
198  * specifies the number of tiles buffered in the cache. <em>region</em> specifies
199  * the 3d region.
200  * Returns a pointer to the cell structure ... if successful,
201  * NULL ... otherwise.
202  *
203  * \param name
204  * \param type
205  * \param cache
206  * \param region
207  * \return void *
208  */
209 
210 void *Rast3d_open_cell_new(const char *name, int typeIntern, int cache,
211  RASTER3D_Region * region)
212 {
213  RASTER3D_Map *map;
214  int nofHeaderBytes, dummy = 0, compression, precision;
215  long ldummy = 0;
216  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
217 
219  if (!Rast3d_mask_open_old()) {
220  Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_mask_open_old"));
221  return (void *)NULL;
222  }
223 
225  precision = g3d_precision;
226 
227  map = Rast3d_malloc(sizeof(RASTER3D_Map));
228  if (map == NULL) {
229  Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_malloc"));
230  return (void *)NULL;
231  }
232 
233  if (G_unqualified_name(name, G_mapset(), xname, xmapset) < 0) {
234  G_warning(_("map <%s> is not in the current mapset"), name);
235  return (void *)NULL;
236  }
237 
238  map->fileName = G_store(xname);
239  map->mapset = G_store(xmapset);
240 
241  map->tempName = G_tempfile();
242  map->data_fd = open(map->tempName, O_RDWR | O_CREAT | O_TRUNC, 0666);
243  if (map->data_fd < 0) {
244  Rast3d_error(_("Rast3d_open_cell_new: could not open file"));
245  return (void *)NULL;
246  }
247 
249 
250  /* XDR support has been removed */
251  map->useXdr = RASTER3D_NO_XDR;
252 
253  if (g3d_file_type == FCELL_TYPE) {
254  if (precision > 23)
255  precision = 23; /* 32 - 8 - 1 */
256  else if (precision < -1)
257  precision = 0;
258  }
259  else if (precision > 52)
260  precision = 52; /* 64 - 11 - 1 */
261  else if (precision < -1)
262  precision = 0;
263 
264  /* no need to write trailing zeros */
265  if ((typeIntern == FCELL_TYPE) && (g3d_file_type == DCELL_TYPE)) {
266  if (precision == -1)
267  precision = 23;
268  else
269  precision = RASTER3D_MIN(precision, 23);
270  }
271 
273  precision = RASTER3D_MAX_PRECISION;
274 
275  if (RASTER3D_HAS_INDEX) {
276  map->indexLongNbytes = sizeof(long);
277 
278  /* at the beginning of the file write */
279  /* nof bytes of "long" */
280  /* max nof bytes used for index */
281  /* position of index in file */
282  /* the index is appended at the end of the file at closing time. since */
283  /* we do not know this position yet we write dummy values */
284 
285  if ((!Rast3d_write_ints(map->data_fd, map->useXdr,
286  &(map->indexLongNbytes), 1)) ||
287  (!Rast3d_write_ints(map->data_fd, map->useXdr, &dummy, 1))) {
288  Rast3d_error(_("Rast3d_open_cell_new: can't write header"));
289  return (void *)NULL;
290  }
291  if (write(map->data_fd, &ldummy, map->indexLongNbytes) !=
292  map->indexLongNbytes) {
293  Rast3d_error(_("Rast3d_open_cell_new: can't write header"));
294  return (void *)NULL;
295  }
296  }
297 
298  /* can't use a constant since this depends on sizeof (long) */
299  nofHeaderBytes = lseek(map->data_fd, (long)0, SEEK_CUR);
300 
301  Rast3d_range_init(map);
302  Rast3d_adjust_region(region);
303 
305  g3d_file_type, precision, cache, RASTER3D_HAS_INDEX,
306  map->useXdr, typeIntern, nofHeaderBytes,
309  region->proj, region->zone,
310  region->north, region->south, region->east,
311  region->west, region->top, region->bottom,
312  region->rows, region->cols, region->depths,
313  region->ew_res, region->ns_res, region->tb_res,
315  Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_fill_header"));
316  return (void *)NULL;
317  }
318 
319  /*Set the map window to the map region */
320  Rast3d_region_copy(&(map->window), region);
321  /*Set the resampling function to nearest neighbor for data access */
323 
324  Rast3d_mask_off(map);
325 
326  return (void *)map;
327 }
double east
Definition: raster3d.h:51
unsigned short compression
Definition: gsd_img_tif.c:42
void Rast3d_adjust_region(RASTER3D_Region *region)
Computes an adjusts the resolutions in the region structure from the region boundaries and number of ...
Definition: region.c:151
#define GMAPSET_MAX
Definition: gis.h:165
#define RASTER3D_MAX_PRECISION
Definition: raster3d.h:17
double top
Definition: raster3d.h:52
long indexOffset
Definition: raster3d.h:122
double tb_res
Definition: raster3d.h:57
char * fileName
Definition: raster3d.h:76
int g3d_precision
Definition: defaults.c:66
double bottom
Definition: raster3d.h:52
#define RASTER3D_WRITE_DATA
void Rast3d_fatal_error(const char *msg,...)
Prints fatal error message.
double ns_res
Definition: raster3d.h:57
#define RASTER3D_DEFAULT_WINDOW
Definition: raster3d.h:29
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:87
int g3d_do_compression
Definition: defaults.c:65
int Rast3d_fill_header(RASTER3D_Map *map, int operation, int compression, int useRle, int useLzw, int type, int precision, int cache, int hasIndex, int useXdr, int typeIntern, int nofHeaderBytes, int tileX, int tileY, int tileZ, int proj, int zone, double north, double south, double east, double west, double top, double bottom, int rows, int cols, int depths, double ew_res, double ns_res, double tb_res, char *unit, int vertical_unit, int version)
void Rast3d_get_nearest_neighbor_fun_ptr(void(**nnFunPtr)())
Returns in nnFunPtr a pointer to Rast3d_nearest_neighbor () (cf.{g3d:G3d.nearestNeighbor}).
Definition: resample.c:90
int G_unqualified_name(const char *name, const char *mapset, char *xname, char *xmapset)
Returns unqualified map name (without @ mapset)
Definition: nme_in_mps.c:134
char * G_tempfile(void)
Returns a temporary file name.
Definition: tempfile.c:62
#define NULL
Definition: ccmath.h:32
char * g3d_unit_default
Definition: defaults.c:73
int G_open_old_misc(const char *dir, const char *element, const char *name, const char *mapset)
open a database file for reading
Definition: open_misc.c:134
double north
Definition: raster3d.h:50
char * tempName
Definition: raster3d.h:77
void * Rast3d_open_cell_old_no_header(const char *name, const char *mapset)
Definition: raster3d/open.c:12
#define RASTER3D_CELL_ELEMENT
Definition: raster3d.h:32
#define DCELL_TYPE
Definition: raster.h:13
int Rast3d_mask_open_old(void)
Definition: mask.c:73
double west
Definition: raster3d.h:51
#define RASTER3D_NO_XDR
int indexLongNbytes
Definition: raster3d.h:125
void Rast3d_error(const char *msg,...)
void Rast3d_long_decode(unsigned char *source, long *dst, int nofNums, int longNbytes)
Definition: long.c:36
double ew_res
Definition: raster3d.h:57
#define RASTER3D_HAS_INDEX
int Rast3d_write_ints(int fd, int useXdr, const int *i, int nofNum)
Definition: intio.c:9
int Rast3d_read_header(RASTER3D_Map *map, int *proj, int *zone, double *north, double *south, double *east, double *west, double *top, double *bottom, int *rows, int *cols, int *depths, double *ew_res, double *ns_res, double *tb_res, int *tileX, int *tileY, int *tileZ, int *type, int *compression, int *useRle, int *useLzw, int *precision, int *dataOffset, int *useXdr, int *hasIndex, char **unit, int *vertical_unit, int *version)
RASTER3D_Region * Rast3d_window_ptr()
#define RASTER3D_MIN(a, b)
#define RASTER3D_NO_COMPRESSION
Definition: raster3d.h:14
#define RASTER3D_READ_DATA
void Rast3d_free(void *buf)
Same as free (ptr).
int indexNbytesUsed
Definition: raster3d.h:129
void * Rast3d_malloc(int nBytes)
Same as malloc (nBytes), except that in case of error Rast3d_error() is invoked.
void Rast3d_init_defaults(void)
Initializes the default values described in RASTER3D Defaults. Applications have to use this function...
Definition: defaults.c:305
#define RASTER3D_DIRECTORY
Definition: raster3d.h:31
int g3d_tile_dimension[3]
Definition: defaults.c:70
#define RASTER3D_TILE_SAME_AS_FILE
Definition: raster3d.h:12
#define GNAME_MAX
Definition: gis.h:164
int Rast3d_range_init(RASTER3D_Map *map)
Definition: d/range.c:206
int g3d_file_type
Definition: defaults.c:69
#define _(str)
Definition: glocale.h:13
int g3d_vertical_unit_default
Definition: defaults.c:74
#define FCELL_TYPE
Definition: raster.h:12
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
void * Rast3d_open_cell_new(const char *name, int typeIntern, int cache, RASTER3D_Region *region)
Opens new g3d-file with name in the current mapset. Tiles are stored in memory with type which must b...
const char * name
Definition: named_colr.c:7
int Rast3d_read_ints(int fd, int useXdr, int *i, int nofNum)
Definition: intio.c:51
char * mapset
Definition: raster3d.h:78
resample_fn * resampleFun
Definition: raster3d.h:90
#define RASTER3D_MAP_VERSION
Definition: raster3d.h:7
double south
Definition: raster3d.h:50
RASTER3D_Region window
Definition: raster3d.h:87
void * Rast3d_open_cell_old(const char *name, const char *mapset, RASTER3D_Region *window, int typeIntern, int cache)
Opens existing g3d-file name in mapset. Tiles are stored in memory with type which must be any of FCE...
Definition: raster3d/open.c:77
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
void Rast3d_mask_off(RASTER3D_Map *map)
Turns off the mask for map. This is the default. Do not invoke this function after the first tile has...
Definition: mask.c:349
void Rast3d_make_mapset_map_directory(const char *mapName)
void Rast3d_region_copy(RASTER3D_Region *regionDest, RASTER3D_Region *regionSrc)
Copies the values of regionSrc into regionDst.
Definition: region.c:207