GRASS Programmer's Manual
6.4.1(2011)
|
00001 00002 /********************************************************************** 00003 * 00004 * Code in this file works with category files. There are two formats: 00005 * Pre 3.0 direct category encoding form: 00006 * 00007 * 2 categories 00008 * Map Title 00009 * Elevation: 1000.00 to 1005.00 feet 00010 * Elevation: 1005.00 to 1010.00 feet 00011 * Elevation: 1010.00 to 1015.00 feet 00012 * 00013 * 3.0 format 00014 * 00015 * # 2 categories 00016 * Map Title 00017 * Elevation: $1.2 to $2.2 feet ## Format Statement 00018 * 5.0 1000 5.0 1005 ## Coefficients 00019 * 00020 * The coefficient line can be followed by explicit category labels 00021 * which override the format label generation. 00022 * 0:no data 00023 * 2: . 00024 * 5: . ## explicit category labels 00025 * 7: . 00026 * explicit labels can be also of the form: 00027 * 5.5:5:9 label description 00028 * or 00029 * 15:30 label description 00030 * 00031 * In the format line 00032 * $1 refers to the value num*5.0+1000 (ie, using the first 2 coefficients) 00033 * $2 refers to the value num*5.0+1005 (ie, using the last 2 coefficients) 00034 * 00035 * $1.2 will print $1 with 2 decimal places. 00036 * 00037 * Also, the form $?xxx$yyy$ translates into yyy if the category is 1, xxx 00038 * otherwise. The $yyy$ is optional. Thus 00039 * 00040 * $1 meter$?s 00041 * 00042 * will become: 1 meter (for category 1) 00043 * 2 meters (for category 2), etc. 00044 * 00045 * The format and coefficients above would be used to generate the 00046 * following statement in creation of the format appropriate category 00047 * string for category "num": 00048 * 00049 * sprintf(buff,"Elevation: %.2f to %.2f feet", num*5.0+1000, num*5.0*1005) 00050 * 00051 * Note: while both the format and coefficent lins must be present 00052 * a blank line for the fmt will effectively suppress automatic 00053 * label generation 00054 * 00055 * Note: quant rules of Categories structures are heavily dependent 00056 * on the fact that rules are stored in the same order they are entered. 00057 * since i-th rule and i-th label are entered at the same time, we 00058 * know that i-th rule maps fp range to i, thus we know for sure 00059 * that cats.labels[i] corresponds to i-th quant rule 00060 * 00061 ********************************************************************** 00062 * 00063 * G_read_[raster]_cats (name, mapset, pcats) 00064 * char *name name of cell file 00065 * char *mapset mapset that cell file belongs to 00066 * struct Categories *pcats structure to hold category info 00067 * 00068 * Reads the category information associated with cell file "name" 00069 * in mapset "mapset" into the structure "pcats". 00070 * 00071 * returns: 0 if successful 00072 * -1 on fail 00073 * 00074 * note: a warning message is printed if the file is 00075 * "missing" or "invalid". 00076 ********************************************************************** 00077 * 00078 * G_copy_raster_cats (pcats_to, pcats_from) 00079 * struct Categories *pcats_to 00080 * const struct Categories *pcats_from 00081 * 00082 * Allocates NEW space for quant rules and labels and copies 00083 * all info from "from" cats to "to" cats 00084 * 00085 * returns: 0 if successful 00086 * -1 on fail 00087 * 00088 ********************************************************************** 00089 * 00090 * G_read_vector_cats (name, mapset, pcats) 00091 * char *name name of vector map 00092 * char *mapset mapset that vector map belongs to 00093 * struct Categories *pcats structure to hold category info 00094 * 00095 * 00096 * returns: 0 if successful 00097 * -1 on fail 00098 * 00099 * note: a warning message is printed if the file is 00100 * "missing" or "invalid". 00101 ********************************************************************** 00102 * Returns pointer to a string describing category. 00103 ********************************************************************** 00104 * 00105 * G_number_of_cats(name, mapset) 00106 * returns the largest category number in the map. 00107 * -1 on error 00108 * WARING: do not use for fp maps! 00109 ********************************************************************** 00110 * 00111 * char * 00112 * G_get_c/f/d_raster_cat (num, pcats) 00113 * [F/D]CELL *val pointer to cell value 00114 * struct Categories *pcats structure to hold category info 00115 * 00116 * Returns pointer to a string describing category. 00117 * 00118 ********************************************************************** 00119 * 00120 * char * 00121 * G_get_raster_cat (val, pcats, data_type) 00122 * void *val pointer to cell value 00123 * struct Categories *pcats structure to hold category info 00124 * RASTER_MAP_TYPE data_type type of raster cell 00125 * 00126 * Returns pointer to a string describing category. 00127 * 00128 ********************************************************************** 00129 * 00130 * char * 00131 * G_get_ith_c/f/d_raster_cat (pcats, i, rast1, rast2) 00132 * [F/D]CELL *rast1, *rast2 cat range 00133 * struct Categories *pcats structure to hold category info 00134 * 00135 * Returns pointer to a string describing category. 00136 * 00137 ********************************************************************** 00138 * 00139 * int 00140 * G_number_of_raster_cats (pcats) 00141 * struct Categories *pcats structure to hold category info 00142 * 00143 * Returns pcats->ncats number of labels 00144 * 00145 ********************************************************************** 00146 * 00147 * char * 00148 * G_get_ith_raster_cat (pcats, i, rast1, rast2, data_type) 00149 * void *rast1, *rast2 cat range 00150 * struct Categories *pcats structure to hold category info 00151 * RASTER_MAP_TYPE data_type type of raster cell 00152 * 00153 * Returns pointer to a string describing category. 00154 * 00155 ********************************************************************** 00156 * 00157 * char * 00158 * G_get_[raster]_cats_title (pcats) 00159 * struct Categories *pcats structure to hold category info 00160 * 00161 * Returns pointer to a string with title 00162 * 00163 ********************************************************************** 00164 * 00165 * G_init_cats (ncats, title, pcats) 00166 * CELL ncats number of categories 00167 * char *title cell title 00168 * struct Categories *pcats structure to hold category info 00169 * 00170 * Initializes the cats structure for subsequent calls to G_set_cat() 00171 ********************************************************************** 00172 * 00173 * G_unmark_raster_cats (pcats) 00174 * struct Categories *pcats structure to hold category info 00175 * 00176 * initialize cats.marks: the statistics of how many values of map 00177 * have each label 00178 * 00179 ********************************************************************** 00180 * 00181 * G_rewind_raster_cats (pcats) 00182 * struct Categories *pcats structure to hold category info 00183 * 00184 * after calll to this function G_get_next_marked_raster_cat() returns 00185 * rhe first marked cat label. 00186 * 00187 ********************************************************************** 00188 * 00189 * char* G_get_next_marked_raster_cat(pcats, rast1, rast2, stats, data_type) 00190 * struct Categories *pcats structure to hold category info 00191 * void *rast1, *rast2; pointers to raster range 00192 * long *stats; 00193 * RASTER_MAP_TYPE data_type 00194 * 00195 * returns the next marked label. 00196 * NULL if none found 00197 * 00198 ********************************************************************** 00199 * 00200 * char* G_get_next_marked_f/d/craster_cat(pcats, rast1, rast2, stats) 00201 * struct Categories *pcats structure to hold category info 00202 * [D/F]CELL *rast1, *rast2; pointers to raster range 00203 * long *stats; 00204 * 00205 * returns the next marked label. 00206 * NULL if none found 00207 * 00208 ********************************************************************** 00209 * 00210 * G_mark_raster_cats (rast_row, ncols, pcats, data_type) 00211 * void *raster_row; raster row to update stats 00212 * struct Categories *pcats structure to hold category info 00213 * RASTER_MAP_TYPE data_type; 00214 * Finds the index of label for each raster cell in a row, and 00215 * increases pcats->marks[index] 00216 * Note: if there are no explicit cats: only rules for cats, no 00217 * marking is done. 00218 * 00219 ********************************************************************** 00220 * 00221 * G_mark_c/d/f_raster_cats (rast_row, ncols, pcats) 00222 * int ncols; 00223 * [D?F]CELL *raster_row; raster row to update stats 00224 * struct Categories *pcats structure to hold category info 00225 * 00226 * Finds the index of label for each raster cell in a row, and 00227 * increases pcats->marks[index] 00228 * 00229 ********************************************************************** 00230 * 00231 * G_init_raster_cats (title, pcats) 00232 * char *title cell title 00233 * struct Categories *pcats structure to hold category info 00234 * 00235 * Initializes the cats structure for subsequent calls to G_set_cat() 00236 * 00237 ********************************************************************** 00238 * 00239 * G_set_[raster]_cats_fmt (fmt, m1, a1, m2, a2, pcats) 00240 * char *fmt user form of the equation format 00241 * float m1,a1,m2,a2 coefficients 00242 * struct Categories *pcats structure to hold category info 00243 * 00244 * configures the cats structure for the equation. Must be called 00245 * after G_init_cats(). 00246 * 00247 ********************************************************************** 00248 * 00249 * G_set_[raster]_cats_title (title, pcats) 00250 * char *title cell file title 00251 * struct Categories *pcats structure holding category info 00252 * 00253 * Store title as cell file in cats structure 00254 * Returns nothing. 00255 * 00256 ********************************************************************** 00257 * 00258 * G_set_cat (num, label, pcats) 00259 * CELL num category number 00260 * char *label category label 00261 * struct Categories *pcats structure to hold category info 00262 * 00263 * Adds the string buff to represent category "num" in category structure 00264 * pcats. 00265 * 00266 * Returns: 0 is cat is null value -1 too many cats, 1 ok. 00267 * 00268 ********************************************************************** 00269 * 00270 * G_set_[f/d/c]_raster_cat (&val1, &val2, label, pcats) 00271 * [D/F]CELL *val1, *val2; pointers to raster values 00272 * char *label category label 00273 * struct Categories *pcats structure to hold category info 00274 * 00275 * Adds the label for range val1 through val2 in category structure 00276 * pcats. 00277 * 00278 * Returns: 0 if cat is null value -1 too many cats, 1 ok. 00279 * 00280 ********************************************************************** 00281 * 00282 * G_set_raster_cat (val1, val2, label, pcats, data_type) 00283 * void *val1, *val2; pointers to raster values 00284 * char *label category label 00285 * struct Categories *pcats structure to hold category info 00286 * RASTER_MAP_TYPE data_type type of raster cell 00287 * 00288 * Adds the label for range val1 through val2 in category structure 00289 * pcats. 00290 * 00291 * Returns: 0 if cat is null value -1 too many cats, 1 ok. 00292 * 00293 ********************************************************************** 00294 * 00295 * G_write_[raster]_cats (name, pcats) 00296 * char *name name of cell file 00297 * struct Categories *pcats structure holding category info 00298 * 00299 * Writes the category information associated with cell file "name" 00300 * into current mapset from the structure "pcats". 00301 * 00302 * returns: 1 if successful 00303 * -1 on fail 00304 ********************************************************************** 00305 * 00306 * G_write_vector_cats (name, pcats) 00307 * char *name name of vector map 00308 * struct Categories *pcats structure holding category info 00309 * 00310 * Writes the category information associated with vector map "name" 00311 * into current mapset from the structure "pcats". 00312 * 00313 * returns: 1 if successful 00314 * -1 on fail 00315 ********************************************************************** 00316 * 00317 * G_free_[raster]_cats (pcats) 00318 * struct Categories *pcats structure holding category info 00319 * 00320 * Releases memory allocated for the cats structure 00321 **********************************************************************/ 00322 00323 #include <stdlib.h> 00324 #include <string.h> 00325 #include <grass/gis.h> 00326 #include <grass/glocale.h> 00327 00328 static int get_cond(char **, char *, DCELL); 00329 static int get_fmt(char **, char *, int *); 00330 static int cmp(const void *, const void *); 00331 00332 00347 int G_read_cats(const char *name, 00348 const char *mapset, struct Categories *pcats) 00349 { 00350 return G_read_raster_cats(name, mapset, pcats); 00351 } 00352 00353 00365 int G_read_raster_cats(const char *name, 00366 const char *mapset, struct Categories *pcats) 00367 { 00368 char *type; 00369 00370 switch (G__read_cats("cats", name, mapset, pcats, 1)) { 00371 case -2: 00372 type = "missing"; 00373 break; 00374 case -1: 00375 type = "invalid"; 00376 break; 00377 default: 00378 return 0; 00379 } 00380 00381 G_warning(_("category support for [%s] in mapset [%s] %s"), 00382 name, mapset, type); 00383 return -1; 00384 } 00385 00386 00401 int G_read_vector_cats(const char *name, 00402 const char *mapset, struct Categories *pcats) 00403 { 00404 char *type; 00405 00406 switch (G__read_cats("dig_cats", name, mapset, pcats, 1)) { 00407 case -2: 00408 type = "missing"; 00409 break; 00410 case -1: 00411 type = "invalid"; 00412 break; 00413 default: 00414 return 0; 00415 } 00416 00417 G_warning(_("category support for vector map [%s] in mapset [%s] %s"), 00418 name, mapset, type); 00419 return -1; 00420 } 00421 00422 CELL G_number_of_cats(const char *name, const char *mapset) 00423 { 00424 struct Range range; 00425 CELL min, max; 00426 00427 /* return the max category number */ 00428 if (G_read_range(name, mapset, &range) < 0) 00429 return -1; 00430 G_get_range_min_max(&range, &min, &max); 00431 if (G_is_c_null_value(&max)) 00432 max = 0; 00433 return max; 00434 } 00435 00436 CELL G__read_cats(const char *element, 00437 const char *name, 00438 const char *mapset, struct Categories * pcats, int full) 00439 { 00440 FILE *fd; 00441 char buff[1024]; 00442 CELL cat; 00443 DCELL val1, val2; 00444 int old = 0, fp_map; 00445 long num = -1; 00446 00447 00448 if (strncmp(element, "dig", 3) == 0) 00449 fp_map = 0; 00450 else 00451 fp_map = G_raster_map_is_fp(name, mapset); 00452 00453 if (!(fd = G_fopen_old(element, name, mapset))) 00454 return -2; 00455 00456 /* Read the number of categories */ 00457 if (G_getl(buff, sizeof buff, fd) == 0) 00458 goto error; 00459 00460 if (sscanf(buff, "# %ld", &num) == 1) 00461 old = 0; 00462 else if (sscanf(buff, "%ld", &num) == 1) 00463 old = 1; 00464 00465 if (!full) { 00466 fclose(fd); 00467 if (num < 0) 00468 return 0; /* coorect */ 00469 return (CELL) num; 00470 } 00471 00472 /* Read the title for the file */ 00473 if (G_getl(buff, sizeof buff, fd) == 0) 00474 goto error; 00475 G_strip(buff); 00476 /* G_ascii_check(buff) ; */ 00477 00478 G_init_raster_cats(buff, pcats); 00479 if (num >= 0) 00480 pcats->num = num; 00481 00482 if (!old) { 00483 char fmt[256]; 00484 float m1, a1, m2, a2; 00485 00486 if (G_getl(fmt, sizeof fmt, fd) == 0) 00487 goto error; 00488 /* next line contains equation coefficients */ 00489 if (G_getl(buff, sizeof buff, fd) == 0) 00490 goto error; 00491 if (sscanf(buff, "%f %f %f %f", &m1, &a1, &m2, &a2) != 4) 00492 goto error; 00493 G_set_raster_cats_fmt(fmt, m1, a1, m2, a2, pcats); 00494 } 00495 00496 /* Read all category names */ 00497 for (cat = 0;; cat++) { 00498 char label[1024]; 00499 00500 if (G_getl(buff, sizeof buff, fd) == 0) 00501 break; 00502 if (old) 00503 G_set_cat(cat, buff, pcats); 00504 else { 00505 *label = 0; 00506 if (sscanf(buff, "%1s", label) != 1) 00507 continue; 00508 if (*label == '#') 00509 continue; 00510 *label = 0; 00511 /* for fp maps try to read a range of data */ 00512 if (fp_map 00513 && sscanf(buff, "%lf:%lf:%[^\n]", &val1, &val2, label) == 3) 00514 G_set_raster_cat(&val1, &val2, label, pcats, DCELL_TYPE); 00515 else if (sscanf(buff, "%d:%[^\n]", &cat, label) >= 1) 00516 G_set_raster_cat(&cat, &cat, label, pcats, CELL_TYPE); 00517 else if (sscanf(buff, "%lf:%[^\n]", &val1, label) >= 1) 00518 G_set_raster_cat(&val1, &val1, label, pcats, DCELL_TYPE); 00519 else 00520 goto error; 00521 } 00522 } 00523 00524 fclose(fd); 00525 return 0; 00526 error: 00527 fclose(fd); 00528 return -1; 00529 } 00530 00531 00545 char *G_get_cats_title(const struct Categories *pcats) 00546 { 00547 return G_get_raster_cats_title(pcats); 00548 } 00549 00550 00560 char *G_get_raster_cats_title(const struct Categories *pcats) 00561 { 00562 static char *none = ""; 00563 00564 return pcats->title ? pcats->title : none; 00565 } 00566 00567 00583 char *G_get_cat(CELL num, struct Categories *pcats) 00584 { 00585 return G_get_c_raster_cat(&num, pcats); 00586 } 00587 00588 00600 char *G_get_c_raster_cat(CELL * rast, struct Categories *pcats) 00601 { 00602 return G_get_raster_cat(rast, pcats, CELL_TYPE); 00603 } 00604 00605 00617 char *G_get_f_raster_cat(FCELL * rast, struct Categories *pcats) 00618 { 00619 return G_get_raster_cat(rast, pcats, FCELL_TYPE); 00620 } 00621 00622 00634 char *G_get_d_raster_cat(DCELL * rast, struct Categories *pcats) 00635 { 00636 return G_get_raster_cat(rast, pcats, DCELL_TYPE); 00637 } 00638 00639 00652 char *G_get_raster_cat(void *rast, 00653 struct Categories *pcats, RASTER_MAP_TYPE data_type) 00654 { 00655 static char label[1024]; 00656 char *f, *l, *v; 00657 CELL i; 00658 DCELL val; 00659 float a[2]; 00660 char fmt[30], value_str[30]; 00661 00662 if (G_is_null_value(rast, data_type)) { 00663 sprintf(label, "no data"); 00664 return label; 00665 } 00666 00667 /* first search the list of labels */ 00668 *label = 0; 00669 val = G_get_raster_value_d(rast, data_type); 00670 i = G_quant_get_cell_value(&pcats->q, val); 00671 00672 G_debug(5, "G_get_raster_cat(): val %lf found i %d", val, i); 00673 00674 if (!G_is_c_null_value(&i) && i < pcats->ncats) { 00675 if (pcats->labels[i] != NULL) 00676 return pcats->labels[i]; 00677 return label; 00678 } 00679 00680 /* generate the label */ 00681 if ((f = pcats->fmt) == NULL) 00682 return label; 00683 00684 a[0] = (float)val *pcats->m1 + pcats->a1; 00685 a[1] = (float)val *pcats->m2 + pcats->a2; 00686 00687 l = label; 00688 while (*f) { 00689 if (*f == '$') { 00690 f++; 00691 if (*f == '$') 00692 *l++ = *f++; 00693 else if (*f == '?') { 00694 f++; 00695 get_cond(&f, v = value_str, val); 00696 while (*v) 00697 *l++ = *v++; 00698 } 00699 else if (get_fmt(&f, fmt, &i)) { 00700 sprintf(v = value_str, fmt, a[i]); 00701 while (*v) 00702 *l++ = *v++; 00703 } 00704 else 00705 *l++ = '$'; 00706 } 00707 else { 00708 *l++ = *f++; 00709 } 00710 } 00711 *l = 0; 00712 return label; 00713 } 00714 00715 00731 int G_unmark_raster_cats(struct Categories *pcats) 00732 { /* structure to hold category info */ 00733 register int i; 00734 00735 for (i = 0; i < pcats->ncats; i++) 00736 pcats->marks[i] = 0; 00737 return 0; 00738 } 00739 00740 00755 int G_mark_c_raster_cats(CELL * rast_row, /* raster row to update stats */ 00756 int ncols, struct Categories *pcats) 00757 { /* structure to hold category info */ 00758 G_mark_raster_cats(rast_row, ncols, pcats, CELL_TYPE); 00759 return 0; 00760 } 00761 00762 00777 int G_mark_f_raster_cats(FCELL * rast_row, /* raster row to update stats */ 00778 int ncols, struct Categories *pcats) 00779 { /* structure to hold category info */ 00780 G_mark_raster_cats(rast_row, ncols, pcats, FCELL_TYPE); 00781 return 0; 00782 } 00783 00784 00799 int G_mark_d_raster_cats(DCELL * rast_row, /* raster row to update stats */ 00800 int ncols, struct Categories *pcats) 00801 { /* structure to hold category info */ 00802 G_mark_raster_cats(rast_row, ncols, pcats, DCELL_TYPE); 00803 return 0; 00804 } 00805 00806 00823 int G_mark_raster_cats(void *rast_row, /* raster row to update stats */ 00824 int ncols, struct Categories *pcats, /* structure to hold category info */ 00825 RASTER_MAP_TYPE data_type) 00826 { 00827 CELL i; 00828 00829 while (ncols-- > 0) { 00830 i = G_quant_get_cell_value(&pcats->q, 00831 G_get_raster_value_d(rast_row, data_type)); 00832 if (G_is_c_null_value(&i)) 00833 continue; 00834 if (i > pcats->ncats) 00835 return -1; 00836 pcats->marks[i]++; 00837 rast_row = G_incr_void_ptr(rast_row, G_raster_size(data_type)); 00838 } 00839 return 1; 00840 } 00841 00842 00854 int G_rewind_raster_cats(struct Categories *pcats) 00855 { 00856 pcats->last_marked_rule = -1; 00857 return 0; 00858 } 00859 00860 char *G_get_next_marked_d_raster_cat(struct Categories *pcats, /* structure to hold category info */ 00861 DCELL * rast1, DCELL * rast2, /* pointers to raster range */ 00862 long *count) 00863 { 00864 char *descr = NULL; 00865 int found, i; 00866 00867 found = 0; 00868 /* pcats->ncats should be == G_quant_nof_rules(&pcats->q) */ 00869 /* DEBUG 00870 fprintf (stderr, "last marked %d nrules %d\n", pcats->last_marked_rule, G_quant_nof_rules(&pcats->q)); 00871 */ 00872 for (i = pcats->last_marked_rule + 1; i < G_quant_nof_rules(&pcats->q); 00873 i++) { 00874 descr = G_get_ith_d_raster_cat(pcats, i, rast1, rast2); 00875 /* DEBUG fprintf (stderr, "%d %d\n", i, pcats->marks[i]); */ 00876 if (pcats->marks[i]) { 00877 found = 1; 00878 break; 00879 } 00880 } 00881 00882 if (!found) 00883 return NULL; 00884 00885 *count = pcats->marks[i]; 00886 pcats->last_marked_rule = i; 00887 return descr; 00888 } 00889 00890 char *G_get_next_marked_c_raster_cat(struct Categories *pcats, /* structure to hold category info */ 00891 CELL * rast1, CELL * rast2, /* pointers to raster range */ 00892 long *count) 00893 { 00894 return G_get_next_marked_raster_cat(pcats, rast1, rast2, count, 00895 CELL_TYPE); 00896 } 00897 00898 char *G_get_next_marked_f_raster_cat(struct Categories *pcats, /* structure to hold category info */ 00899 FCELL * rast1, FCELL * rast2, /* pointers to raster range */ 00900 long *count) 00901 { 00902 return G_get_next_marked_raster_cat(pcats, rast1, rast2, count, 00903 FCELL_TYPE); 00904 } 00905 00906 char *G_get_next_marked_raster_cat(struct Categories *pcats, /* structure to hold category info */ 00907 void *rast1, void *rast2, /* pointers to raster range */ 00908 long *count, RASTER_MAP_TYPE data_type) 00909 { 00910 DCELL val1, val2; 00911 char *lab; 00912 00913 lab = G_get_next_marked_d_raster_cat(pcats, &val1, &val2, count); 00914 G_set_raster_value_d(rast1, val1, data_type); 00915 G_set_raster_value_d(rast2, val2, data_type); 00916 return lab; 00917 } 00918 00919 static int get_fmt(char **f, char *fmt, int *i) 00920 { 00921 char *ff; 00922 00923 ff = *f; 00924 if (*ff == 0) 00925 return 0; 00926 if (*ff == '$') { 00927 *f = ff + 1; 00928 return 0; 00929 } 00930 switch (*ff++) { 00931 case '1': 00932 *i = 0; 00933 break; 00934 case '2': 00935 *i = 1; 00936 break; 00937 default: 00938 return 0; 00939 } 00940 *fmt++ = '%'; 00941 *fmt++ = '.'; 00942 if (*ff++ != '.') { 00943 *f = ff - 1; 00944 *fmt++ = '0'; 00945 *fmt++ = 'f'; 00946 *fmt = 0; 00947 return 1; 00948 } 00949 *fmt = '0'; 00950 while (*ff >= '0' && *ff <= '9') 00951 *fmt++ = *ff++; 00952 *fmt++ = 'f'; 00953 *fmt = 0; 00954 *f = ff; 00955 return 1; 00956 } 00957 00958 static int get_cond(char **f, char *value, DCELL val) 00959 { 00960 char *ff; 00961 00962 ff = *f; 00963 if (val == 1.) { 00964 while (*ff) 00965 if (*ff++ == '$') 00966 break; 00967 } 00968 00969 while (*ff) 00970 if (*ff == '$') { 00971 ff++; 00972 break; 00973 } 00974 else 00975 *value++ = *ff++; 00976 00977 if (val != 1.) { 00978 while (*ff) 00979 if (*ff++ == '$') 00980 break; 00981 } 00982 *value = 0; 00983 *f = ff; 00984 00985 return 0; 00986 } 00987 00988 01001 int G_set_cat(CELL num, char *label, struct Categories *pcats) 01002 { 01003 CELL tmp = num; 01004 01005 return G_set_c_raster_cat(&tmp, &tmp, label, pcats); 01006 } 01007 01008 01021 int G_set_c_raster_cat(CELL * rast1, CELL * rast2, 01022 char *label, struct Categories *pcats) 01023 { 01024 return G_set_raster_cat(rast1, rast2, label, pcats, CELL_TYPE); 01025 } 01026 01027 01040 int G_set_f_raster_cat(FCELL * rast1, FCELL * rast2, 01041 char *label, struct Categories *pcats) 01042 { 01043 return G_set_raster_cat(rast1, rast2, label, pcats, FCELL_TYPE); 01044 } 01045 01046 01059 int G_set_d_raster_cat(DCELL * rast1, DCELL * rast2, 01060 char *label, struct Categories *pcats) 01061 { 01062 long len; 01063 DCELL dtmp1, dtmp2; 01064 int i; 01065 char *descr; 01066 01067 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(rast1 = %p,rast2 = %p,label = '%s',pcats = %p)\n", 01068 rast1,rast2,label,pcats); */ 01069 if (G_is_d_null_value(rast1)) 01070 return 0; 01071 if (G_is_d_null_value(rast2)) 01072 return 0; 01073 /* DEBUG fprintf (stderr, "G_set_d_raster_cat(): adding quant rule: %f %f %d %d\n", *rast1, *rast2, pcats->ncats, pcats->ncats); */ 01074 /* the set_cat() functions are used in many places to reset the labels 01075 for the range (or cat) with existing label. In this case we don't 01076 want to store both rules with identical range even though the result 01077 of get_cat() will be correct, since it will use rule added later. 01078 we don't want to overuse memory and we don't want rules which are 01079 not used to be writen out in cats file. So we first look if 01080 the label for this range has been sen, and if it has, overwrite it */ 01081 01082 for (i = 0; i < pcats->ncats; i++) { 01083 descr = G_get_ith_d_raster_cat(pcats, i, &dtmp1, &dtmp2); 01084 if ((dtmp1 == *rast1 && dtmp2 == *rast2) 01085 || (dtmp1 == *rast2 && dtmp2 == *rast1)) { 01086 if (pcats->labels[i] != NULL) 01087 G_free(pcats->labels[i]); 01088 pcats->labels[i] = G_store(label); 01089 G_newlines_to_spaces(pcats->labels[i]); 01090 G_strip(pcats->labels[i]); 01091 return 1; 01092 } 01093 } 01094 /* when rule for this range does not exist */ 01095 /* DEBUG fprintf (stderr, "G_set_d_raster_cat(): New rule: adding %d %p\n", i, pcats->labels); */ 01096 G_quant_add_rule(&pcats->q, *rast1, *rast2, pcats->ncats, pcats->ncats); 01097 pcats->ncats++; 01098 if (pcats->nalloc < pcats->ncats) { 01099 /* DEBUG fprintf (stderr, "G_set_d_raster_cat(): need more space nalloc = %d ncats = %d\n", pcats->nalloc,pcats->ncats); */ 01100 len = (pcats->nalloc + 256) * sizeof(char *); 01101 /* DEBUG fprintf (stderr, "G_set_d_raster_cat(): allocating %d labels(%d)\n", pcats->nalloc + 256,(int)len); */ 01102 if (len != (int)len) { /* make sure len doesn't overflow int */ 01103 pcats->ncats--; 01104 return -1; 01105 } 01106 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(): pcats->nalloc = %d, pcats->labels = (%p), len = %d\n",pcats->nalloc,pcats->labels,(int)len); */ 01107 if (pcats->nalloc) { 01108 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(): Realloc-ing pcats->labels (%p)\n",pcats->labels); */ 01109 pcats->labels = 01110 (char **)G_realloc((char *)pcats->labels, (int)len); 01111 } 01112 else { 01113 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(): alloc-ing new labels pointer array\n"); */ 01114 pcats->labels = (char **)G_malloc((int)len); 01115 } 01116 /* fflush(stderr); */ 01117 /* DEBUG fprintf (stderr, "G_set_d_raster_cats(): allocating %d marks(%d)\n", pcats->nalloc + 256,(int)len); */ 01118 len = (pcats->nalloc + 256) * sizeof(int); 01119 if (len != (int)len) { /* make sure len doesn't overflow int */ 01120 pcats->ncats--; 01121 return -1; 01122 } 01123 if (pcats->nalloc) 01124 pcats->marks = (int *)G_realloc((char *)pcats->marks, (int)len); 01125 else 01126 pcats->marks = (int *)G_malloc((int)len); 01127 pcats->nalloc += 256; 01128 } 01129 /* DEBUG fprintf(stderr,"G_set_d_raster_cats(): store new label\n"); */ 01130 pcats->labels[pcats->ncats - 1] = G_store(label); 01131 G_newlines_to_spaces(pcats->labels[pcats->ncats - 1]); 01132 G_strip(pcats->labels[pcats->ncats - 1]); 01133 /* DEBUG 01134 fprintf (stderr, "%d %s\n", pcats->ncats - 1, pcats->labels[pcats->ncats - 1]); 01135 */ 01136 /* updates cats.num = max cat values. This is really just used in old 01137 raster programs, and I am doing it for backwards cmpatibility (Olga) */ 01138 if ((CELL) * rast1 > pcats->num) 01139 pcats->num = (CELL) * rast1; 01140 if ((CELL) * rast2 > pcats->num) 01141 pcats->num = (CELL) * rast2; 01142 /* DEBUG fprintf(stderr,"G_set_d_raster_cat(): done\n"); */ 01143 /* DEBUG fflush(stderr); */ 01144 return 1; 01145 } 01146 01147 01160 int G_set_raster_cat(void *rast1, void *rast2, 01161 char *label, 01162 struct Categories *pcats, RASTER_MAP_TYPE data_type) 01163 { 01164 DCELL val1, val2; 01165 01166 val1 = G_get_raster_value_d(rast1, data_type); 01167 val2 = G_get_raster_value_d(rast2, data_type); 01168 return G_set_d_raster_cat(&val1, &val2, label, pcats); 01169 } 01170 01171 01185 int G_write_cats(char *name, struct Categories *cats) 01186 { 01187 return G__write_cats("cats", name, cats); 01188 } 01189 01190 01201 int G_write_raster_cats(char *name, struct Categories *cats) 01202 { 01203 return G__write_cats("cats", name, cats); 01204 } 01205 01206 01221 int G_write_vector_cats(char *name, struct Categories *cats) 01222 { 01223 return G__write_cats("dig_cats", name, cats); 01224 } 01225 01226 int G__write_cats(char *element, char *name, struct Categories *cats) 01227 { 01228 FILE *fd; 01229 int i, fp_map; 01230 char *descr; 01231 DCELL val1, val2; 01232 char str1[100], str2[100]; 01233 01234 /* DEBUG fprintf(stderr,"G__write_cats(*element = '%s', name = '%s', cats = %p\n",element,name,cats); */ 01235 if (!(fd = G_fopen_new(element, name))) 01236 return -1; 01237 01238 /* write # cats - note # indicate 3.0 or later */ 01239 fprintf(fd, "# %ld categories\n", (long)cats->num); 01240 01241 /* title */ 01242 fprintf(fd, "%s\n", cats->title != NULL ? cats->title : ""); 01243 01244 /* write format and coefficients */ 01245 fprintf(fd, "%s\n", cats->fmt != NULL ? cats->fmt : ""); 01246 fprintf(fd, "%.2f %.2f %.2f %.2f\n", 01247 cats->m1, cats->a1, cats->m2, cats->a2); 01248 01249 /* if the map is integer or if this is a vector map, sort labels */ 01250 if (strncmp(element, "dig", 3) == 0) 01251 fp_map = 0; 01252 else 01253 fp_map = G_raster_map_is_fp(name, G_mapset()); 01254 /* DEBUG fprintf(stderr,"G__write_cats(): fp_map = %d\n",fp_map); */ 01255 if (!fp_map) 01256 G_sort_cats(cats); 01257 01258 /* write the cat numbers:label */ 01259 for (i = 0; i < G_quant_nof_rules(&cats->q); i++) { 01260 descr = G_get_ith_d_raster_cat(cats, i, &val1, &val2); 01261 if ((cats->fmt && cats->fmt[0]) 01262 || (descr && descr[0])) { 01263 if (val1 == val2) { 01264 sprintf(str1, "%.10f", val1); 01265 G_trim_decimal(str1); 01266 fprintf(fd, "%s:%s\n", str1, descr != NULL ? descr : ""); 01267 } 01268 else { 01269 sprintf(str1, "%.10f", val1); 01270 G_trim_decimal(str1); 01271 sprintf(str2, "%.10f", val2); 01272 G_trim_decimal(str2); 01273 fprintf(fd, "%s:%s:%s\n", str1, str2, 01274 descr != NULL ? descr : ""); 01275 } 01276 } 01277 } 01278 fclose(fd); 01279 /* DEBUG fprintf(stderr,"G__write_cats(): done\n"); */ 01280 return (1); 01281 } 01282 01283 01298 char *G_get_ith_d_raster_cat(const struct Categories *pcats, 01299 int i, DCELL * rast1, DCELL * rast2) 01300 { 01301 int index; 01302 01303 if (i > pcats->ncats) { 01304 G_set_d_null_value(rast1, 1); 01305 G_set_d_null_value(rast2, 1); 01306 return ""; 01307 } 01308 G_quant_get_ith_rule(&pcats->q, i, rast1, rast2, &index, &index); 01309 return pcats->labels[index]; 01310 } 01311 01312 01327 char *G_get_ith_f_raster_cat(const struct Categories *pcats, 01328 int i, void *rast1, void *rast2) 01329 { 01330 RASTER_MAP_TYPE data_type = FCELL_TYPE; 01331 char *tmp; 01332 DCELL val1, val2; 01333 01334 tmp = G_get_ith_d_raster_cat(pcats, i, &val1, &val2); 01335 G_set_raster_value_d(rast1, val1, data_type); 01336 G_set_raster_value_d(rast2, val2, data_type); 01337 return tmp; 01338 } 01339 01340 01355 char *G_get_ith_c_raster_cat(const struct Categories *pcats, 01356 int i, void *rast1, void *rast2) 01357 { 01358 RASTER_MAP_TYPE data_type = CELL_TYPE; 01359 char *tmp; 01360 DCELL val1, val2; 01361 01362 tmp = G_get_ith_d_raster_cat(pcats, i, &val1, &val2); 01363 G_set_raster_value_d(rast1, val1, data_type); 01364 G_set_raster_value_d(rast2, val2, data_type); 01365 return tmp; 01366 } 01367 01368 01385 char *G_get_ith_raster_cat(const struct Categories *pcats, int i, void *rast1, 01386 void *rast2, RASTER_MAP_TYPE data_type) 01387 { 01388 char *tmp; 01389 DCELL val1, val2; 01390 01391 tmp = G_get_ith_d_raster_cat(pcats, i, &val1, &val2); 01392 G_set_raster_value_d(rast1, val1, data_type); 01393 G_set_raster_value_d(rast2, val2, data_type); 01394 return tmp; 01395 } 01396 01397 01417 int G_init_cats(CELL num, const char *title, struct Categories *pcats) 01418 { 01419 G_init_raster_cats(title, pcats); 01420 pcats->num = num; 01421 return 0; 01422 } 01423 01424 01437 int G_init_raster_cats(const char *title, struct Categories *pcats) 01438 { 01439 G_set_raster_cats_title(title, pcats); 01440 pcats->labels = NULL; 01441 pcats->nalloc = 0; 01442 pcats->ncats = 0; 01443 pcats->num = 0; 01444 pcats->fmt = NULL; 01445 pcats->m1 = 0.0; 01446 pcats->a1 = 0.0; 01447 pcats->m2 = 0.0; 01448 pcats->a2 = 0.0; 01449 pcats->last_marked_rule = -1; 01450 G_quant_init(&pcats->q); 01451 return 0; 01452 } 01453 01454 01466 int G_set_cats_title(const char *title, struct Categories *pcats) 01467 { 01468 G_set_raster_cats_title(title, pcats); 01469 return 0; 01470 } 01471 01472 01483 int G_set_raster_cats_title(const char *title, struct Categories *pcats) 01484 { 01485 if (title == NULL) 01486 title = ""; 01487 pcats->title = G_store(title); 01488 G_newlines_to_spaces(pcats->title); 01489 G_strip(pcats->title); 01490 return 0; 01491 } 01492 01493 int G_set_cats_fmt(const char *fmt, double m1, double a1, double m2, 01494 double a2, struct Categories *pcats) 01495 { 01496 G_set_raster_cats_fmt(fmt, m1, a1, m2, a2, pcats); 01497 return 0; 01498 } 01499 01500 01515 int G_set_raster_cats_fmt(const char *fmt, double m1, double a1, double m2, 01516 double a2, struct Categories *pcats) 01517 { 01518 pcats->m1 = m1; 01519 pcats->a1 = a1; 01520 pcats->m2 = m2; 01521 pcats->a2 = a2; 01522 01523 pcats->fmt = G_store(fmt); 01524 G_newlines_to_spaces(pcats->fmt); 01525 G_strip(pcats->fmt); 01526 return 0; 01527 } 01528 01529 01540 int G_free_cats(struct Categories *pcats) 01541 { 01542 G_free_raster_cats(pcats); 01543 return 0; 01544 } 01545 01546 01556 int G_free_raster_cats(struct Categories *pcats) 01557 { 01558 int i; 01559 01560 if (pcats->title != NULL) { 01561 G_free(pcats->title); 01562 pcats->title = NULL; 01563 } 01564 if (pcats->fmt != NULL) { 01565 G_free(pcats->fmt); 01566 pcats->fmt = NULL; 01567 } 01568 if (pcats->ncats > 0) { 01569 for (i = 0; i < pcats->ncats; i++) 01570 if (pcats->labels[i] != NULL) 01571 G_free(pcats->labels[i]); 01572 G_free(pcats->labels); 01573 G_free(pcats->marks); 01574 pcats->labels = NULL; 01575 } 01576 G_quant_free(&pcats->q); 01577 pcats->ncats = 0; 01578 pcats->nalloc = 0; 01579 return 0; 01580 } 01581 01582 01597 int 01598 G_copy_raster_cats(struct Categories *pcats_to, 01599 const struct Categories *pcats_from) 01600 { 01601 int i; 01602 char *descr; 01603 DCELL d1, d2; 01604 01605 G_init_raster_cats(pcats_from->title, pcats_to); 01606 for (i = 0; i < pcats_from->ncats; i++) { 01607 descr = G_get_ith_d_raster_cat(pcats_from, i, &d1, &d2); 01608 G_set_d_raster_cat(&d1, &d2, descr, pcats_to); 01609 } 01610 return 0; 01611 } 01612 01613 int G_number_of_raster_cats(struct Categories *pcats) 01614 { 01615 return pcats->ncats; 01616 } 01617 01618 static struct Categories save_cats; 01619 01620 int G_sort_cats(struct Categories *pcats) 01621 { 01622 int *indexes, i, ncats; 01623 char *descr; 01624 DCELL d1, d2; 01625 01626 if (pcats->ncats <= 1) 01627 return -1; 01628 01629 ncats = pcats->ncats; 01630 /* DEBUG fprintf(stderr,"G_sort_cats(): Copying to save cats buffer\n"); */ 01631 G_copy_raster_cats(&save_cats, pcats); 01632 G_free_raster_cats(pcats); 01633 01634 indexes = (int *)G_malloc(sizeof(int) * ncats); 01635 for (i = 0; i < ncats; i++) 01636 indexes[i] = i; 01637 01638 qsort(indexes, ncats, sizeof(int), cmp); 01639 G_init_raster_cats(save_cats.title, pcats); 01640 for (i = 0; i < ncats; i++) { 01641 descr = G_get_ith_d_raster_cat(&save_cats, indexes[i], &d1, &d2); 01642 /* DEBUG fprintf(stderr,"G_sort_cats(): Write sorted cats, pcats = %p pcats->labels = %p\n",pcats,pcats->labels); */ 01643 G_set_d_raster_cat(&d1, &d2, descr, pcats); 01644 /* DEBUG fflush(stderr); */ 01645 } 01646 G_free_raster_cats(&save_cats); 01647 /* DEBUG fprintf(stderr,"G_sort_cats(): Done\n"); */ 01648 /* fflush(stderr); */ 01649 01650 return 0; 01651 } 01652 01653 static int cmp(const void *aa, const void *bb) 01654 { 01655 const int *a = aa, *b = bb; 01656 DCELL min_rast1, min_rast2, max_rast1, max_rast2; 01657 CELL index; 01658 01659 G_quant_get_ith_rule(&(save_cats.q), *a, 01660 &min_rast1, &max_rast1, &index, &index); 01661 G_quant_get_ith_rule(&(save_cats.q), *b, 01662 &min_rast2, &max_rast2, &index, &index); 01663 if (min_rast1 < min_rast2) 01664 return -1; 01665 if (min_rast1 > min_rast2) 01666 return 1; 01667 return 0; 01668 }