GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <sys/types.h> 00004 #include <unistd.h> 00005 #include <rpc/types.h> 00006 #include <rpc/xdr.h> 00007 #include <grass/gis.h> 00008 #include "G3d_intern.h" 00009 00010 /*---------------------------------------------------------------------------*/ 00011 00012 void 00013 G3d_range_updateFromTile(G3D_Map * map, const void *tile, int rows, int cols, 00014 int depths, int xRedundant, int yRedundant, 00015 int zRedundant, int nofNum, int type) 00016 { 00017 int y, z, cellType; 00018 struct FPRange *range; 00019 00020 range = &(map->range); 00021 cellType = G3d_g3dType2cellType(type); 00022 00023 if (nofNum == map->tileSize) { 00024 G_row_update_fp_range(tile, map->tileSize, range, cellType); 00025 return; 00026 } 00027 00028 if (xRedundant) { 00029 for (z = 0; z < depths; z++) { 00030 for (y = 0; y < rows; y++) { 00031 G_row_update_fp_range(tile, cols, range, cellType); 00032 tile = G_incr_void_ptr(tile, map->tileX * G3d_length(type)); 00033 } 00034 if (yRedundant) 00035 tile = 00036 G_incr_void_ptr(tile, 00037 map->tileX * yRedundant * 00038 G3d_length(type)); 00039 } 00040 return; 00041 } 00042 00043 if (yRedundant) { 00044 for (z = 0; z < depths; z++) { 00045 G_row_update_fp_range(tile, map->tileX * rows, range, cellType); 00046 tile = G_incr_void_ptr(tile, map->tileXY * G3d_length(type)); 00047 } 00048 return; 00049 } 00050 00051 G_row_update_fp_range(tile, map->tileXY * depths, range, cellType); 00052 } 00053 00054 /*---------------------------------------------------------------------------*/ 00055 00056 int 00057 G3d_readRange(const char *name, const char *mapset, struct FPRange *drange) 00058 /* adapted from G_read_fp_range */ 00059 { 00060 int fd; 00061 char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; 00062 char buf[GNAME_MAX + sizeof(G3D_DIRECTORY) + 2], 00063 buf2[GMAPSET_MAX + sizeof(G3D_RANGE_ELEMENT) + 2]; 00064 char xdr_buf[100]; 00065 DCELL dcell1, dcell2; 00066 XDR xdr_str; 00067 00068 G_init_fp_range(drange); 00069 00070 fd = -1; 00071 00072 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00073 sprintf(buf, "%s/%s", G3D_DIRECTORY, xname); 00074 sprintf(buf2, "%s@%s", G3D_RANGE_ELEMENT, xmapset); /* == range@mapset */ 00075 } 00076 else { 00077 sprintf(buf, "%s/%s", G3D_DIRECTORY, name); 00078 sprintf(buf2, "%s", G3D_RANGE_ELEMENT); 00079 } 00080 00081 if (G_find_file2(buf, buf2, mapset)) { 00082 fd = G_open_old(buf, buf2, mapset); 00083 if (fd < 0) 00084 goto error; 00085 00086 if (read(fd, xdr_buf, 2 * G3D_XDR_DOUBLE_LENGTH) != 00087 2 * G3D_XDR_DOUBLE_LENGTH) 00088 return 2; 00089 00090 xdrmem_create(&xdr_str, xdr_buf, (u_int) G3D_XDR_DOUBLE_LENGTH * 2, 00091 XDR_DECODE); 00092 00093 /* if the f_range file exists, but empty */ 00094 if (!xdr_double(&xdr_str, &dcell1) || !xdr_double(&xdr_str, &dcell2)) 00095 goto error; 00096 00097 G_update_fp_range(dcell1, drange); 00098 G_update_fp_range(dcell2, drange); 00099 close(fd); 00100 return 1; 00101 } 00102 00103 error: 00104 if (fd > 0) 00105 close(fd); 00106 G_warning("can't read range file for [%s in %s]", name, mapset); 00107 return -1; 00108 } 00109 00110 /*---------------------------------------------------------------------------*/ 00111 00112 00123 int G3d_range_load(G3D_Map * map) 00124 { 00125 if (map->operation == G3D_WRITE_DATA) 00126 return 1; 00127 if (G3d_readRange(map->fileName, map->mapset, &(map->range)) == -1) { 00128 return 0; 00129 } 00130 00131 return 1; 00132 } 00133 00134 /*---------------------------------------------------------------------------*/ 00135 00136 00149 void G3d_range_min_max(G3D_Map * map, double *min, double *max) 00150 { 00151 G_get_fp_range_min_max(&(map->range), min, max); 00152 } 00153 00154 /*-------------------------------------------------------------------------*/ 00155 00156 static int writeRange(const char *name, struct FPRange *range) 00157 /* adapted from G_write_fp_range */ 00158 { 00159 char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; 00160 char buf[GNAME_MAX + sizeof(G3D_DIRECTORY) + 2], 00161 buf2[GMAPSET_MAX + sizeof(G3D_RANGE_ELEMENT) + 2]; 00162 char xdr_buf[100]; 00163 int fd; 00164 XDR xdr_str; 00165 00166 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00167 sprintf(buf, "%s/%s", G3D_DIRECTORY, xname); 00168 sprintf(buf2, "%s@%s", G3D_RANGE_ELEMENT, xmapset); /* == range@mapset */ 00169 } 00170 else { 00171 sprintf(buf, "%s/%s", G3D_DIRECTORY, name); 00172 sprintf(buf2, "%s", G3D_RANGE_ELEMENT); 00173 } 00174 00175 fd = G_open_new(buf, buf2); 00176 if (fd < 0) 00177 goto error; 00178 00179 if (range->first_time) { 00180 /* if range hasn't been updated, write empty file meaning NULLs */ 00181 close(fd); 00182 return 0; 00183 } 00184 00185 xdrmem_create(&xdr_str, xdr_buf, (u_int) G3D_XDR_DOUBLE_LENGTH * 2, 00186 XDR_ENCODE); 00187 00188 if (!xdr_double(&xdr_str, &(range->min))) 00189 goto error; 00190 if (!xdr_double(&xdr_str, &(range->max))) 00191 goto error; 00192 00193 write(fd, xdr_buf, G3D_XDR_DOUBLE_LENGTH * 2); 00194 close(fd); 00195 return 0; 00196 00197 error: 00198 G_remove(buf, buf2); /* remove the old file with this name */ 00199 sprintf(buf, "can't write range file for [%s in %s]", name, G_mapset()); 00200 G_warning(buf); 00201 return -1; 00202 } 00203 00204 /*---------------------------------------------------------------------------*/ 00205 00206 00218 int G3d_range_write(G3D_Map * map) 00219 { 00220 char path[GPATH_MAX]; 00221 00222 G3d_filename(path, G3D_RANGE_ELEMENT, map->fileName, map->mapset); 00223 remove(path); 00224 00225 if (writeRange(map->fileName, &(map->range)) == -1) { 00226 G3d_error("G3d_closeCellNew: error in writeRange"); 00227 return 0; 00228 } 00229 00230 return 1; 00231 } 00232 00233 /*---------------------------------------------------------------------------*/ 00234 00235 int G3d_range_init(G3D_Map * map) 00236 { 00237 return G_init_fp_range(&(map->range)); 00238 }