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