GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
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 typeIntern
76  * \param cache
77  * \return void *
78  */
79 void *Rast3d_open_cell_old(const char *name, const char *mapset,
80  RASTER3D_Region *window, int typeIntern, int cache)
81 {
82  RASTER3D_Map *map;
83  int proj, zone;
84  int compression, useRle, useLzw, type, tileX, tileY, tileZ;
85  int rows, cols, depths, precision;
86  double ew_res, ns_res, tb_res;
87  int nofHeaderBytes, dataOffset, useXdr, hasIndex;
88  char *unit;
89  unsigned char *ltmp;
90  int vertical_unit;
91  int version;
92  double north, south, east, west, top, bottom;
93 
94  map = Rast3d_open_cell_old_no_header(name, mapset);
95  if (map == NULL) {
97  _("Rast3d_open_cell_old: error in Rast3d_open_cell_old_no_header"));
98  return (void *)NULL;
99  }
100 
101  if (lseek(map->data_fd, (long)0, SEEK_SET) == -1) {
102  Rast3d_error(_("Rast3d_open_cell_old: can't rewind file"));
103  return (void *)NULL;
104  }
105 
106  if (!Rast3d_read_header(
107  map, &proj, &zone, &north, &south, &east, &west, &top, &bottom,
108  &rows, &cols, &depths, &ew_res, &ns_res, &tb_res, &tileX, &tileY,
109  &tileZ, &type, &compression, &useRle, &useLzw, &precision,
110  &dataOffset, &useXdr, &hasIndex, &unit, &vertical_unit, &version)) {
111  Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_read_header"));
112  return 0;
113  }
114 
115  if (window == RASTER3D_DEFAULT_WINDOW)
116  window = Rast3d_window_ptr();
117 
118  if (proj != window->proj) {
119  Rast3d_error(_("Rast3d_open_cell_old: projection does not match window "
120  "projection"));
121  return (void *)NULL;
122  }
123  if (zone != window->zone) {
124  Rast3d_error(
125  _("Rast3d_open_cell_old: zone does not match window zone"));
126  return (void *)NULL;
127  }
128 
129  map->useXdr = useXdr;
130 
131  if (hasIndex) {
132  /* see RASTER3D_openCell_new () for format of header */
133  if ((!Rast3d_read_ints(map->data_fd, map->useXdr,
134  &(map->indexLongNbytes), 1)) ||
135  (!Rast3d_read_ints(map->data_fd, map->useXdr,
136  &(map->indexNbytesUsed), 1))) {
137  Rast3d_error(_("Rast3d_open_cell_old: can't read header"));
138  return (void *)NULL;
139  }
140 
141  /* if our long is to short to store offsets we can't read the file */
142  if (map->indexNbytesUsed > (int)sizeof(long))
144  _("Rast3d_open_cell_old: index does not fit into long"));
145 
146  ltmp = Rast3d_malloc(map->indexLongNbytes);
147  if (ltmp == NULL) {
148  Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_malloc"));
149  return (void *)NULL;
150  }
151 
152  /* convert file long to long */
153  if (read(map->data_fd, ltmp, map->indexLongNbytes) !=
154  map->indexLongNbytes) {
155  Rast3d_error(_("Rast3d_open_cell_old: can't read header"));
156  return (void *)NULL;
157  }
158  Rast3d_long_decode(ltmp, &(map->indexOffset), 1, map->indexLongNbytes);
159  Rast3d_free(ltmp);
160  }
161 
162  nofHeaderBytes = dataOffset;
163 
164  if (typeIntern == RASTER3D_TILE_SAME_AS_FILE)
165  typeIntern = type;
166 
168  useLzw, type, precision, cache, hasIndex,
169  map->useXdr, typeIntern, nofHeaderBytes, tileX,
170  tileY, tileZ, proj, zone, north, south, east, west,
171  top, bottom, rows, cols, depths, ew_res, ns_res,
172  tb_res, unit, vertical_unit, 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  * \brief
188  *
189  * Opens new g3d-file with <em>name</em> in the current mapset. Tiles
190  * are stored in memory with <em>type</em> which must be one of FCELL_TYPE,
191  * DCELL_TYPE, or RASTER3D_TILE_SAME_AS_FILE. <em>cache</em> specifies the
192  * cache-mode used and must be either RASTER3D_NO_CACHE,
193  * RASTER3D_USE_CACHE_DEFAULT, RASTER3D_USE_CACHE_X, RASTER3D_USE_CACHE_Y,
194  * RASTER3D_USE_CACHE_Z, RASTER3D_USE_CACHE_XY, RASTER3D_USE_CACHE_XZ,
195  * RASTER3D_USE_CACHE_YZ, RASTER3D_USE_CACHE_XYZ, the result of
196  * <tt>Rast3d_cache_size_encode ()</tt> (cf.{g3d:G3d.cacheSizeEncode}), or any
197  * positive integer which specifies the number of tiles buffered in the cache.
198  * <em>region</em> specifies the 3d region. Returns a pointer to the cell
199  * structure ... if successful, NULL ... otherwise.
200  *
201  * \param name
202  * \param typeIntern
203  * \param cache
204  * \param region
205  * \return void *
206  */
207 void *Rast3d_open_cell_new(const char *name, int typeIntern, int cache,
208  RASTER3D_Region *region)
209 {
210  RASTER3D_Map *map;
211  int nofHeaderBytes, dummy = 0, compression, precision;
212  long ldummy = 0;
213  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
214 
216  if (!Rast3d_mask_open_old()) {
217  Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_mask_open_old"));
218  return (void *)NULL;
219  }
220 
222  precision = g3d_precision;
223 
224  map = Rast3d_malloc(sizeof(RASTER3D_Map));
225  if (map == NULL) {
226  Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_malloc"));
227  return (void *)NULL;
228  }
229 
230  if (G_unqualified_name(name, G_mapset(), xname, xmapset) < 0) {
231  G_warning(_("map <%s> is not in the current mapset"), name);
232  return (void *)NULL;
233  }
234 
235  map->fileName = G_store(xname);
236  map->mapset = G_store(xmapset);
237 
238  map->tempName = G_tempfile();
239  map->data_fd = open(map->tempName, O_RDWR | O_CREAT | O_TRUNC, 0666);
240  if (map->data_fd < 0) {
241  Rast3d_error(_("Rast3d_open_cell_new: could not open file"));
242  return (void *)NULL;
243  }
244 
246 
247  /* XDR support has been removed */
248  map->useXdr = RASTER3D_NO_XDR;
249 
250  if (g3d_file_type == FCELL_TYPE) {
251  if (precision > 23)
252  precision = 23; /* 32 - 8 - 1 */
253  else if (precision < -1)
254  precision = 0;
255  }
256  else if (precision > 52)
257  precision = 52; /* 64 - 11 - 1 */
258  else if (precision < -1)
259  precision = 0;
260 
261  /* no need to write trailing zeros */
262  if ((typeIntern == FCELL_TYPE) && (g3d_file_type == DCELL_TYPE)) {
263  if (precision == -1)
264  precision = 23;
265  else
266  precision = RASTER3D_MIN(precision, 23);
267  }
268 
270  precision = RASTER3D_MAX_PRECISION;
271 
272  if (RASTER3D_HAS_INDEX) {
273  map->indexLongNbytes = sizeof(long);
274 
275  /* at the beginning of the file write */
276  /* nof bytes of "long" */
277  /* max nof bytes used for index */
278  /* position of index in file */
279  /* the index is appended at the end of the file at closing time. since
280  */
281  /* we do not know this position yet we write dummy values */
282 
283  if ((!Rast3d_write_ints(map->data_fd, map->useXdr,
284  &(map->indexLongNbytes), 1)) ||
285  (!Rast3d_write_ints(map->data_fd, map->useXdr, &dummy, 1))) {
286  Rast3d_error(_("Rast3d_open_cell_new: can't write header"));
287  return (void *)NULL;
288  }
289  if (write(map->data_fd, &ldummy, map->indexLongNbytes) !=
290  map->indexLongNbytes) {
291  Rast3d_error(_("Rast3d_open_cell_new: can't write header"));
292  return (void *)NULL;
293  }
294  }
295 
296  /* can't use a constant since this depends on sizeof (long) */
297  nofHeaderBytes = lseek(map->data_fd, (long)0, SEEK_CUR);
298 
299  Rast3d_range_init(map);
300  Rast3d_adjust_region(region);
301 
302  if (!Rast3d_fill_header(
304  precision, cache, RASTER3D_HAS_INDEX, map->useXdr, typeIntern,
305  nofHeaderBytes, g3d_tile_dimension[0], g3d_tile_dimension[1],
306  g3d_tile_dimension[2], region->proj, region->zone, region->north,
307  region->south, region->east, region->west, region->top,
308  region->bottom, region->rows, region->cols, region->depths,
309  region->ew_res, region->ns_res, region->tb_res, g3d_unit_default,
311  Rast3d_error(_("Rast3d_open_cell_new: error in Rast3d_fill_header"));
312  return (void *)NULL;
313  }
314 
315  /*Set the map window to the map region */
316  Rast3d_region_copy(&(map->window), region);
317  /*Set the resampling function to nearest neighbor for data access */
319 
320  Rast3d_mask_off(map);
321 
322  return (void *)map;
323 }
#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:73
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:339
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:144
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:88
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:196
void Rast3d_init_defaults(void)
Initializes the default values described in RASTER3D Defaults. Applications have to use this function...
Definition: defaults.c:282
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.
Header file for msvc/fcntl.c.
#define open
Definition: fcntl.h:33
#define GMAPSET_MAX
Definition: gis.h:197
#define GNAME_MAX
Definition: gis.h:196
#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:79
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
#define read
Definition: unistd.h:5
#define write
Definition: unistd.h:6