GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
g3dopen.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/G3d.h>
7 #include <grass/glocale.h>
8 #include "G3d_intern.h"
9 
10 /*---------------------------------------------------------------------------*/
11 
12 void *G3d_openCellOldNoHeader(const char *name, const char *mapset)
13 {
14  G3D_Map *map;
15  char buf[200], buf2[200], xname[512], xmapset[512];
16 
18 
19  if (!G3d_maskOpenOld()) {
20  G3d_error(_("G3d_openCellOldNoHeader: error in G3d_maskOpenOld"));
21  return (void *)NULL;
22  }
23 
24  map = G3d_malloc(sizeof(G3D_Map));
25  if (map == NULL) {
26  G3d_error(_("G3d_openCellOldNoHeader: error in G3d_malloc"));
27  return (void *)NULL;
28  }
29 
30  if (G__name_is_fully_qualified(name, xname, xmapset)) {
31  sprintf(buf, "%s/%s", G3D_DIRECTORY, xname);
32  sprintf(buf2, "%s@%s", G3D_CELL_ELEMENT, xmapset); /* == cell@mapset */
33  map->fileName = G_store(xname);
34  }
35  else {
36  sprintf(buf, "%s/%s", G3D_DIRECTORY, name);
37  sprintf(buf2, "%s", G3D_CELL_ELEMENT);
38  map->fileName = G_store(name);
39  }
40 
41  map->mapset = G_store(mapset);
42 
43  map->data_fd = G_open_old(buf, buf2, mapset);
44  if (map->data_fd < 0) {
45  G3d_error(_("G3d_openCellOldNoHeader: error in G_open_old"));
46  return (void *)NULL;
47  }
48 
49  G3d_range_init(map);
50  G3d_maskOff(map);
51 
52  return map;
53 }
54 
55 /*---------------------------------------------------------------------------*/
56 
57 
85 void *G3d_openCellOld(const char *name, const char *mapset,
86  G3D_Region * window, int typeIntern, int cache)
87 {
88  G3D_Map *map;
89  int proj, zone;
90  int compression, useRle, useLzw, type, tileX, tileY, tileZ;
91  int rows, cols, depths, precision;
92  double ew_res, ns_res, tb_res;
93  int nofHeaderBytes, dataOffset, useXdr, hasIndex;
94  char *ltmp, *unit;
95  double north, south, east, west, top, bottom;
96 
97  map = G3d_openCellOldNoHeader(name, mapset);
98  if (map == NULL) {
99  G3d_error(_("G3d_openCellOld: error in G3d_openCellOldNoHeader"));
100  return (void *)NULL;
101  }
102 
103  if (lseek(map->data_fd, (long)0, SEEK_SET) == -1) {
104  G3d_error(_("G3d_openCellOld: can't rewind file"));
105  return (void *)NULL;
106  }
107 
108  if (!G3d_readHeader(map,
109  &proj, &zone,
110  &north, &south, &east, &west, &top, &bottom,
111  &rows, &cols, &depths,
112  &ew_res, &ns_res, &tb_res,
113  &tileX, &tileY, &tileZ,
114  &type, &compression, &useRle, &useLzw,
115  &precision, &dataOffset, &useXdr, &hasIndex, &unit)) {
116  G3d_error(_("G3d_openCellOld: error in G3d_readHeader"));
117  return 0;
118  }
119 
120  if (window == G3D_DEFAULT_WINDOW)
121  window = G3d_windowPtr();
122 
123  if (proj != window->proj) {
124  G3d_error(_("G3d_openCellOld: projection does not match window projection"));
125  return (void *)NULL;
126  }
127  if (zone != window->zone) {
128  G3d_error(_("G3d_openCellOld: zone does not match window zone"));
129  return (void *)NULL;
130  }
131 
132  map->useXdr = useXdr;
133 
134  if (hasIndex) {
135  /* see G3D_openCell_new () for format of header */
136  if ((!G3d_readInts(map->data_fd, map->useXdr,
137  &(map->indexLongNbytes), 1)) ||
138  (!G3d_readInts(map->data_fd, map->useXdr,
139  &(map->indexNbytesUsed), 1))) {
140  G3d_error(_("G3d_openCellOld: can't read header"));
141  return (void *)NULL;
142  }
143 
144  /* if our long is to short to store offsets we can't read the file */
145  if (map->indexNbytesUsed > sizeof(long))
146  G3d_fatalError(_("G3d_openCellOld: index does not fit into long"));
147 
148  ltmp = G3d_malloc(map->indexLongNbytes);
149  if (ltmp == NULL) {
150  G3d_error(_("G3d_openCellOld: error in G3d_malloc"));
151  return (void *)NULL;
152  }
153 
154  /* convert file long to long */
155  if (read(map->data_fd, ltmp, map->indexLongNbytes) !=
156  map->indexLongNbytes) {
157  G3d_error(_("G3d_openCellOld: can't read header"));
158  return (void *)NULL;
159  }
160  G3d_longDecode(ltmp, &(map->indexOffset), 1, map->indexLongNbytes);
161  G3d_free(ltmp);
162  }
163 
164  nofHeaderBytes = dataOffset;
165 
166  if (typeIntern == G3D_TILE_SAME_AS_FILE)
167  typeIntern = type;
168 
169  if (!G3d_fillHeader(map, G3D_READ_DATA, compression, useRle, useLzw,
170  type, precision, cache,
171  hasIndex, map->useXdr, typeIntern,
172  nofHeaderBytes, tileX, tileY, tileZ,
173  proj, zone,
174  north, south, east, west, top, bottom,
175  rows, cols, depths, ew_res, ns_res, tb_res, unit)) {
176  G3d_error(_("G3d_openCellOld: error in G3d_fillHeader"));
177  return (void *)NULL;
178  }
179 
180  G3d_regionCopy(&(map->window), window);
181  G3d_adjustRegion(&(map->window));
182  G3d_getNearestNeighborFunPtr(&(map->resampleFun));
183 
184  return map;
185 }
186 
187 /*---------------------------------------------------------------------------*/
188 
189 
213 void *G3d_openCellNew(const char *name, int typeIntern, int cache,
214  G3D_Region * region)
215 {
216  G3D_Map *map;
217  int nofHeaderBytes, dummy = 0, compression, precision;
218  long ldummy = 0;
219  char xname[512], xmapset[512];
220 
222  if (!G3d_maskOpenOld()) {
223  G3d_error(_("G3d_openCellNew: error in G3d_maskOpenOld"));
224  return (void *)NULL;
225  }
226 
228  precision = g3d_precision;
229 
230  map = G3d_malloc(sizeof(G3D_Map));
231  if (map == NULL) {
232  G3d_error(_("G3d_openCellNew: error in G3d_malloc"));
233  return (void *)NULL;
234  }
235 
236  if (G__name_is_fully_qualified(name, xname, xmapset))
237  map->fileName = G_store(xname);
238  else
239  map->fileName = G_store(name);
240  map->mapset = G_store(G_mapset());
241 
242  map->tempName = G_tempfile();
243  map->data_fd = open(map->tempName, O_RDWR | O_CREAT | O_TRUNC, 0666);
244  if (map->data_fd < 0) {
245  G3d_error(_("G3d_openCellNew: could not open file"));
246  return (void *)NULL;
247  }
248 
249  G3d_makeMapsetMapDirectory(map->fileName);
250 
251  map->useXdr = G3D_USE_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 = G3D_MIN(precision, 23);
270  }
271 
272  if (compression == G3D_NO_COMPRESSION)
273  precision = G3D_MAX_PRECISION;
274  if (compression == G3D_COMPRESSION)
275  map->useXdr = G3D_USE_XDR;
276 
277  if (G3D_HAS_INDEX) {
278  map->indexLongNbytes = sizeof(long);
279 
280  /* at the beginning of the file write */
281  /* nof bytes of "long" */
282  /* max nof bytes used for index */
283  /* position of index in file */
284  /* the index is appended at the end of the file at closing time. since */
285  /* we do not know this position yet we write dummy values */
286 
287  if ((!G3d_writeInts(map->data_fd, map->useXdr,
288  &(map->indexLongNbytes), 1)) ||
289  (!G3d_writeInts(map->data_fd, map->useXdr, &dummy, 1))) {
290  G3d_error(_("G3d_openCellNew: can't write header"));
291  return (void *)NULL;
292  }
293  if (write(map->data_fd, &ldummy, map->indexLongNbytes) !=
294  map->indexLongNbytes) {
295  G3d_error(_("G3d_openCellNew: can't write header"));
296  return (void *)NULL;
297  }
298  }
299 
300  /* can't use a constant since this depends on sizeof (long) */
301  nofHeaderBytes = lseek(map->data_fd, (long)0, SEEK_CUR);
302 
303  G3d_range_init(map);
304  G3d_adjustRegion(region);
305 
308  g3d_file_type, precision, cache, G3D_HAS_INDEX,
309  map->useXdr, typeIntern, nofHeaderBytes,
312  region->proj, region->zone,
313  region->north, region->south, region->east,
314  region->west, region->top, region->bottom,
315  region->rows, region->cols, region->depths,
316  region->ew_res, region->ns_res, region->tb_res,
317  g3d_unit_default)) {
318  G3d_error(_("G3d_openCellNew: error in G3d_fillHeader"));
319  return (void *)NULL;
320  }
321 
322  /*Set the map window to the map region */
323  G3d_regionCopy(&(map->window), region);
324  /*Set the resampling function to nearest neighbor for data access */
325  G3d_getNearestNeighborFunPtr(&(map->resampleFun));
326 
327  G3d_maskOff(map);
328 
329  return (void *)map;
330 }