GRASS Programmer's Manual  6.4.2(2012)
g3dopen.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <fcntl.h>
00004 #include <sys/types.h>
00005 #include <unistd.h>
00006 #include <grass/G3d.h>
00007 #include <grass/glocale.h>
00008 #include "G3d_intern.h"
00009 
00010 /*---------------------------------------------------------------------------*/
00011 
00012 void *G3d_openCellOldNoHeader(const char *name, const char *mapset)
00013 {
00014     G3D_Map *map;
00015     char buf[200], buf2[200], xname[512], xmapset[512];
00016 
00017     G3d_initDefaults();
00018 
00019     if (!G3d_maskOpenOld()) {
00020         G3d_error(_("G3d_openCellOldNoHeader: error in G3d_maskOpenOld"));
00021         return (void *)NULL;
00022     }
00023 
00024     map = G3d_malloc(sizeof(G3D_Map));
00025     if (map == NULL) {
00026         G3d_error(_("G3d_openCellOldNoHeader: error in G3d_malloc"));
00027         return (void *)NULL;
00028     }
00029 
00030     if (G__name_is_fully_qualified(name, xname, xmapset)) {
00031         sprintf(buf, "%s/%s", G3D_DIRECTORY, xname);
00032         sprintf(buf2, "%s@%s", G3D_CELL_ELEMENT, xmapset);      /* == cell@mapset */
00033         map->fileName = G_store(xname);
00034     }
00035     else {
00036         sprintf(buf, "%s/%s", G3D_DIRECTORY, name);
00037         sprintf(buf2, "%s", G3D_CELL_ELEMENT);
00038         map->fileName = G_store(name);
00039     }
00040 
00041     map->mapset = G_store(mapset);
00042 
00043     map->data_fd = G_open_old(buf, buf2, mapset);
00044     if (map->data_fd < 0) {
00045         G3d_error(_("G3d_openCellOldNoHeader: error in G_open_old"));
00046         return (void *)NULL;
00047     }
00048 
00049     G3d_range_init(map);
00050     G3d_maskOff(map);
00051 
00052     return map;
00053 }
00054 
00055 /*---------------------------------------------------------------------------*/
00056 
00057 
00085 void *G3d_openCellOld(const char *name, const char *mapset,
00086                       G3D_Region * window, int typeIntern, int cache)
00087 {
00088     G3D_Map *map;
00089     int proj, zone;
00090     int compression, useRle, useLzw, type, tileX, tileY, tileZ;
00091     int rows, cols, depths, precision;
00092     double ew_res, ns_res, tb_res;
00093     int nofHeaderBytes, dataOffset, useXdr, hasIndex;
00094     char *ltmp, *unit;
00095     double north, south, east, west, top, bottom;
00096 
00097     map = G3d_openCellOldNoHeader(name, mapset);
00098     if (map == NULL) {
00099         G3d_error(_("G3d_openCellOld: error in G3d_openCellOldNoHeader"));
00100         return (void *)NULL;
00101     }
00102 
00103     if (lseek(map->data_fd, (long)0, SEEK_SET) == -1) {
00104         G3d_error(_("G3d_openCellOld: can't rewind file"));
00105         return (void *)NULL;
00106     }
00107 
00108     if (!G3d_readHeader(map,
00109                         &proj, &zone,
00110                         &north, &south, &east, &west, &top, &bottom,
00111                         &rows, &cols, &depths,
00112                         &ew_res, &ns_res, &tb_res,
00113                         &tileX, &tileY, &tileZ,
00114                         &type, &compression, &useRle, &useLzw,
00115                         &precision, &dataOffset, &useXdr, &hasIndex, &unit)) {
00116         G3d_error(_("G3d_openCellOld: error in G3d_readHeader"));
00117         return 0;
00118     }
00119 
00120     if (window == G3D_DEFAULT_WINDOW)
00121         window = G3d_windowPtr();
00122 
00123     if (proj != window->proj) {
00124         G3d_error(_("G3d_openCellOld: projection does not match window projection"));
00125         return (void *)NULL;
00126     }
00127     if (zone != window->zone) {
00128         G3d_error(_("G3d_openCellOld: zone does not match window zone"));
00129         return (void *)NULL;
00130     }
00131 
00132     map->useXdr = useXdr;
00133 
00134     if (hasIndex) {
00135         /* see G3D_openCell_new () for format of header */
00136         if ((!G3d_readInts(map->data_fd, map->useXdr,
00137                            &(map->indexLongNbytes), 1)) ||
00138             (!G3d_readInts(map->data_fd, map->useXdr,
00139                            &(map->indexNbytesUsed), 1))) {
00140             G3d_error(_("G3d_openCellOld: can't read header"));
00141             return (void *)NULL;
00142         }
00143 
00144         /* if our long is to short to store offsets we can't read the file */
00145         if (map->indexNbytesUsed > sizeof(long))
00146             G3d_fatalError(_("G3d_openCellOld: index does not fit into long"));
00147 
00148         ltmp = G3d_malloc(map->indexLongNbytes);
00149         if (ltmp == NULL) {
00150             G3d_error(_("G3d_openCellOld: error in G3d_malloc"));
00151             return (void *)NULL;
00152         }
00153 
00154         /* convert file long to long */
00155         if (read(map->data_fd, ltmp, map->indexLongNbytes) !=
00156             map->indexLongNbytes) {
00157             G3d_error(_("G3d_openCellOld: can't read header"));
00158             return (void *)NULL;
00159         }
00160         G3d_longDecode(ltmp, &(map->indexOffset), 1, map->indexLongNbytes);
00161         G3d_free(ltmp);
00162     }
00163 
00164     nofHeaderBytes = dataOffset;
00165 
00166     if (typeIntern == G3D_TILE_SAME_AS_FILE)
00167         typeIntern = type;
00168 
00169     if (!G3d_fillHeader(map, G3D_READ_DATA, compression, useRle, useLzw,
00170                         type, precision, cache,
00171                         hasIndex, map->useXdr, typeIntern,
00172                         nofHeaderBytes, tileX, tileY, tileZ,
00173                         proj, zone,
00174                         north, south, east, west, top, bottom,
00175                         rows, cols, depths, ew_res, ns_res, tb_res, unit)) {
00176         G3d_error(_("G3d_openCellOld: error in G3d_fillHeader"));
00177         return (void *)NULL;
00178     }
00179 
00180     G3d_regionCopy(&(map->window), window);
00181     G3d_adjustRegion(&(map->window));
00182     G3d_getNearestNeighborFunPtr(&(map->resampleFun));
00183 
00184     return map;
00185 }
00186 
00187 /*---------------------------------------------------------------------------*/
00188 
00189 
00213 void *G3d_openCellNew(const char *name, int typeIntern, int cache,
00214                       G3D_Region * region)
00215 {
00216     G3D_Map *map;
00217     int nofHeaderBytes, dummy = 0, compression, precision;
00218     long ldummy = 0;
00219     char xname[512], xmapset[512];
00220 
00221     G3d_initDefaults();
00222     if (!G3d_maskOpenOld()) {
00223         G3d_error(_("G3d_openCellNew: error in G3d_maskOpenOld"));
00224         return (void *)NULL;
00225     }
00226 
00227     compression = g3d_do_compression;
00228     precision = g3d_precision;
00229 
00230     map = G3d_malloc(sizeof(G3D_Map));
00231     if (map == NULL) {
00232         G3d_error(_("G3d_openCellNew: error in G3d_malloc"));
00233         return (void *)NULL;
00234     }
00235 
00236     if (G__name_is_fully_qualified(name, xname, xmapset))
00237         map->fileName = G_store(xname);
00238     else
00239         map->fileName = G_store(name);
00240     map->mapset = G_store(G_mapset());
00241 
00242     map->tempName = G_tempfile();
00243     map->data_fd = open(map->tempName, O_RDWR | O_CREAT | O_TRUNC, 0666);
00244     if (map->data_fd < 0) {
00245         G3d_error(_("G3d_openCellNew: could not open file"));
00246         return (void *)NULL;
00247     }
00248 
00249     G3d_makeMapsetMapDirectory(map->fileName);
00250 
00251     map->useXdr = G3D_USE_XDR;
00252 
00253     if (g3d_file_type == FCELL_TYPE) {
00254         if (precision > 23)
00255             precision = 23;     /* 32 - 8 - 1 */
00256         else if (precision < -1)
00257             precision = 0;
00258     }
00259     else if (precision > 52)
00260         precision = 52;         /* 64 - 11 - 1 */
00261     else if (precision < -1)
00262         precision = 0;
00263 
00264     /* no need to write trailing zeros */
00265     if ((typeIntern == FCELL_TYPE) && (g3d_file_type == DCELL_TYPE)) {
00266         if (precision == -1)
00267             precision = 23;
00268         else
00269             precision = G3D_MIN(precision, 23);
00270     }
00271 
00272     if (compression == G3D_NO_COMPRESSION)
00273         precision = G3D_MAX_PRECISION;
00274     if (compression == G3D_COMPRESSION)
00275         map->useXdr = G3D_USE_XDR;
00276 
00277     if (G3D_HAS_INDEX) {
00278         map->indexLongNbytes = sizeof(long);
00279 
00280         /* at the beginning of the file write */
00281         /*      nof bytes of "long" */
00282         /*      max nof bytes used for index */
00283         /*      position of index in file */
00284         /* the index is appended at the end of the file at closing time. since */
00285         /* we do not know this position yet we write dummy values */
00286 
00287         if ((!G3d_writeInts(map->data_fd, map->useXdr,
00288                             &(map->indexLongNbytes), 1)) ||
00289             (!G3d_writeInts(map->data_fd, map->useXdr, &dummy, 1))) {
00290             G3d_error(_("G3d_openCellNew: can't write header"));
00291             return (void *)NULL;
00292         }
00293         if (write(map->data_fd, &ldummy, map->indexLongNbytes) !=
00294             map->indexLongNbytes) {
00295             G3d_error(_("G3d_openCellNew: can't write header"));
00296             return (void *)NULL;
00297         }
00298     }
00299 
00300     /* can't use a constant since this depends on sizeof (long) */
00301     nofHeaderBytes = lseek(map->data_fd, (long)0, SEEK_CUR);
00302 
00303     G3d_range_init(map);
00304     G3d_adjustRegion(region);
00305 
00306     if (!G3d_fillHeader(map, G3D_WRITE_DATA, compression,
00307                         g3d_do_rle_compression, g3d_do_lzw_compression,
00308                         g3d_file_type, precision, cache, G3D_HAS_INDEX,
00309                         map->useXdr, typeIntern, nofHeaderBytes,
00310                         g3d_tile_dimension[0], g3d_tile_dimension[1],
00311                         g3d_tile_dimension[2],
00312                         region->proj, region->zone,
00313                         region->north, region->south, region->east,
00314                         region->west, region->top, region->bottom,
00315                         region->rows, region->cols, region->depths,
00316                         region->ew_res, region->ns_res, region->tb_res,
00317                         g3d_unit_default)) {
00318         G3d_error(_("G3d_openCellNew: error in G3d_fillHeader"));
00319         return (void *)NULL;
00320     }
00321 
00322     /*Set the map window to the map region */
00323     G3d_regionCopy(&(map->window), region);
00324     /*Set the resampling function to nearest neighbor for data access */
00325     G3d_getNearestNeighborFunPtr(&(map->resampleFun));
00326 
00327     G3d_maskOff(map);
00328 
00329     return (void *)map;
00330 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines