GRASS Programmer's Manual 6.4.1(2011)
|
00001 00002 /********************************************************************** 00003 * 00004 * int 00005 * G__quant_import (name, mapset, quant) 00006 * 00007 * char *name; 00008 * char *mapset; 00009 * struct Quant *quant; 00010 * 00011 * reads quantization rules for "name" in "mapset" and stores them 00012 * in the quantization structure "quant". If the map is in another 00013 * mapset, first checks for quant2 table for this map in current 00014 * mapset. 00015 * 00016 * returns: -2 if raster map is of type integer. 00017 * -1 if (! G__name_is_fully_qualified ()). 00018 * 0 if quantization file does not exist, or the file is empty, 00019 * 1 if non-empty quantization file exists. 00020 * read. 00021 * 00022 * note: in the case of negative return value, the result of using the 00023 * quantization structure is not defined. 00024 * in case of return value 0, calls to G_quant_perform_d () 00025 * and G_quant_perform_f () return NO_DATA (see description of 00026 * G_quant_perform_d () for more details). in case of 00027 * return values 2 and 3, the explicit rule for quant is set: 00028 * floating range is mapped to integer range. 00029 * 00030 * note: use G_quant_init () to allocate and initialize the quantization 00031 * staructure quant before the first usage of G_quant_import (). 00032 * 00033 * note: this function uses G_quant_free () to clear all previously 00034 * stored rules in quant. 00035 * 00036 ********************************************************************** 00037 * 00038 * int 00039 * G__quant_export (name, mapset, quant) 00040 * 00041 * char *name, *mapset; 00042 * struct Quant *quant; 00043 * 00044 * writes the quantization rules stored in "quant" for "name" . if the 00045 * mapset is the same as the current mapset, the quant file is created 00046 * in cell_misc/name directory, otherwise it is created in quant2/mapset 00047 * directory, much like writing colors for map in another mapset. 00048 * The rules are written in decreasing order 00049 * of priority (i.e. rules added earlier are written later). 00050 * 00051 * returns: -1 if (! G__name_is_fully_qualified) or file could not be 00052 * opened. 00053 * 1 otherwise. 00054 * 00055 * note: if no rules are defined an empty file is created. 00056 * 00057 **********************************************************************/ 00058 00059 /*--------------------------------------------------------------------------*/ 00060 00061 #include <grass/gis.h> 00062 #include <grass/glocale.h> 00063 #include <string.h> 00064 00065 /*--------------------------------------------------------------------------*/ 00066 00067 #define QUANT_FILE_NAME "f_quant" 00068 00069 /*--------------------------------------------------------------------------*/ 00070 00071 static int quant_parse_file(FILE *, struct Quant *); 00072 00073 #if 0 00074 static int 00075 /* redundant: integer range doesn't exist now: it is defined by 00076 the quant rules */ 00077 quant_load_range(struct Quant *quant, const char *name, const char *mapset) 00078 { 00079 struct FPRange fprange; 00080 struct Range range; 00081 char buf[300]; 00082 DCELL dMin, dMax; 00083 CELL min, max; 00084 00085 if (G_read_fp_range(name, mapset, &fprange) <= 0) 00086 return 0; 00087 G_get_fp_range_min_max(&fprange, &dMin, &dMax); 00088 if (G_is_d_null_value(&dMin) || G_is_d_null_value(&dMax)) { 00089 sprintf(buf, _("The floating data range for %s@%s is empty"), name, 00090 mapset); 00091 G_warning(buf); 00092 return -3; 00093 } 00094 00095 if (G_read_range(name, mapset, &range) < 0) 00096 return 0; 00097 G_get_range_min_max(&range, &min, &max); 00098 if (G_is_c_null_value(&min) && G_is_c_null_value(&max)) { 00099 sprintf(buf, _("The integer data range for %s@%s is empty"), name, 00100 mapset); 00101 G_warning(buf); 00102 return -3; 00103 } 00104 00105 G_quant_add_rule(quant, dMin, dMax, min, max); 00106 00107 return 1; 00108 } 00109 #endif 00110 00111 /*--------------------------------------------------------------------------*/ 00112 00113 int G__quant_import(const char *name, const char *mapset, struct Quant *quant) 00114 { 00115 char buf[1024]; 00116 char *err; 00117 char xname[GNAME_MAX], xmapset[GMAPSET_MAX], element[GNAME_MAX + 7]; 00118 int parsStat; 00119 FILE *fd; 00120 00121 G_quant_free(quant); 00122 00123 if (G_raster_map_type(name, mapset) == CELL_TYPE) { 00124 sprintf(buf, 00125 "G__quant_import: attempt to open quantization table for CELL_TYPE file [%s] in mapset {%s]", 00126 name, mapset); 00127 G_warning(buf); 00128 return -2; 00129 } 00130 00131 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00132 if (strcmp(xmapset, mapset) != 0) 00133 return -1; 00134 name = xname; 00135 } 00136 00137 /* first check if quant2/mapset/name exists in the current mapset */ 00138 sprintf(element, "quant2/%s", mapset); 00139 if ((fd = G_fopen_old(element, name, G_mapset()))) { 00140 parsStat = quant_parse_file(fd, quant); 00141 fclose(fd); 00142 if (parsStat) 00143 return 1; 00144 sprintf(buf, 00145 "quantization file in quant2 for [%s] in mapset [%s] is empty", 00146 name, mapset); 00147 } 00148 00149 /* now try reading regular : cell_misc/name/quant file */ 00150 if (!(fd = G_fopen_old_misc("cell_misc", QUANT_FILE_NAME, name, mapset))) { 00151 00152 /* int range doesn't exist anymore if (quant_load_range (quant, name, mapset)>0) return 3; */ 00153 err = "missing"; 00154 00155 } 00156 else { 00157 parsStat = quant_parse_file(fd, quant); 00158 fclose(fd); 00159 00160 if (parsStat) 00161 return 1; 00162 /* int range doesn't exist anymore if (quant_load_range (quant, name, mapset)>0) return 2; */ 00163 00164 err = "empty"; 00165 } 00166 00167 sprintf(buf, 00168 _("quantization file [%s] in mapset [%s] %s"), name, mapset, err); 00169 G_warning(buf); 00170 00171 return 0; 00172 } 00173 00174 /*--------------------------------------------------------------------------*/ 00175 00176 /* parse input lines with the following formats 00177 * 00178 * d_high:d_low:c_high:c_low 00179 * d_high:d_low:c_val (i.e. c_high == c_low) 00180 * *:d_val:c_val (interval [inf, d_val]) (**) 00181 * d_val:*:c_val (interval [d_val, inf]) (**) 00182 * 00183 * all other lines are ignored 00184 * 00185 * (**) only the first appearances in the file are considered. 00186 * 00187 */ 00188 00189 /*--------------------------------------------------------------------------*/ 00190 00191 static int quant_parse_file(FILE * fd, struct Quant *quant) 00192 { 00193 CELL cLow, cHigh; 00194 DCELL dLow, dHigh; 00195 char buf[1024]; 00196 int foundNegInf = 0, foundPosInf = 0; 00197 00198 while (fgets(buf, sizeof(buf), fd)) { 00199 if (strncmp(buf, "truncate", 8) == 0) { 00200 quant->truncate_only = 1; 00201 return 1; 00202 } 00203 if (strncmp(buf, "round", 5) == 0) { 00204 quant->round_only = 1; 00205 return 1; 00206 } 00207 switch (sscanf(buf, "%lf:%lf:%d:%d", &dLow, &dHigh, &cLow, &cHigh)) { 00208 case 3: 00209 G_quant_add_rule(quant, dLow, dHigh, cLow, cLow); 00210 break; 00211 case 4: 00212 G_quant_add_rule(quant, dLow, dHigh, cLow, cHigh); 00213 break; 00214 default: 00215 switch (sscanf(buf, "*:%lf:%d", &dLow, &cLow)) { 00216 case 2: 00217 if (!foundNegInf) { 00218 G_quant_set_neg_infinite_rule(quant, dLow, cLow); 00219 foundNegInf = 1; 00220 } 00221 break; 00222 default: 00223 switch (sscanf(buf, "%lf:*:%d", &dLow, &cLow)) { 00224 case 2: 00225 if (!foundPosInf) { 00226 G_quant_set_pos_infinite_rule(quant, dLow, cLow); 00227 foundPosInf = 1; 00228 } 00229 break; 00230 default: 00231 continue; /* other lines are ignored */ 00232 } 00233 } 00234 } 00235 } 00236 00237 if (G_quant_nof_rules(quant) > 0) 00238 G_quant_reverse_rule_order(quant); 00239 00240 return ((G_quant_nof_rules(quant) > 0) || 00241 (G_quant_get_neg_infinite_rule(quant, &dLow, &cLow) > 0) || 00242 (G_quant_get_pos_infinite_rule(quant, &dLow, &cLow) > 0)); 00243 } 00244 00245 /*--------------------------------------------------------------------------*/ 00246 00247 /*--------------------------------------------------------------------------*/ 00248 00249 static void quant_write(FILE * fd, const struct Quant *quant) 00250 { 00251 DCELL dLow, dHigh; 00252 CELL cLow, cHigh; 00253 int i; 00254 00255 if (quant->truncate_only) { 00256 fprintf(fd, "truncate"); 00257 return; 00258 } 00259 if (quant->round_only) { 00260 fprintf(fd, "round"); 00261 return; 00262 } 00263 if (G_quant_get_neg_infinite_rule(quant, &dLow, &cLow) > 0) 00264 fprintf(fd, "*:%.20g:%d\n", dLow, cLow); 00265 00266 if (G_quant_get_pos_infinite_rule(quant, &dLow, &cLow) > 0) 00267 fprintf(fd, "%.20g:*:%d\n", dLow, cLow); 00268 00269 for (i = G_quant_nof_rules(quant) - 1; i >= 0; i--) { 00270 G_quant_get_ith_rule(quant, i, &dLow, &dHigh, &cLow, &cHigh); 00271 fprintf(fd, "%.20g:%.20g:%d", dLow, dHigh, cLow); 00272 if (cLow != cHigh) 00273 fprintf(fd, ":%d", cHigh); 00274 fprintf(fd, "\n"); 00275 } 00276 } 00277 00278 /*--------------------------------------------------------------------------*/ 00279 00280 int 00281 G__quant_export(const char *name, const char *mapset, 00282 const struct Quant *quant) 00283 { 00284 char element[GNAME_MAX + 7]; 00285 char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; 00286 FILE *fd; 00287 00288 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00289 if (strcmp(xmapset, mapset) != 0) 00290 return -1; 00291 name = xname; 00292 } 00293 00294 if (strcmp(G_mapset(), mapset) == 0) { 00295 G_remove_misc("cell_misc", QUANT_FILE_NAME, name); 00296 G__make_mapset_element_misc("cell_misc", name); 00297 if (!(fd = G_fopen_new_misc("cell_misc", QUANT_FILE_NAME, name))) 00298 return -1; 00299 } 00300 else { 00301 sprintf(element, "quant2/%s", mapset); 00302 G_remove(element, name); 00303 G__make_mapset_element(element); 00304 if (!(fd = G_fopen_new(element, name))) 00305 return -1; 00306 } 00307 00308 00309 00310 quant_write(fd, quant); 00311 fclose(fd); 00312 00313 return 1; 00314 } 00315 00316 /*--------------------------------------------------------------------------*/ 00317 00318 /*--------------------------------------------------------------------------*/ 00319 00320 /*--------------------------------------------------------------------------*/