GRASS Programmer's Manual
6.4.2(2012)
|
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 }