GRASS Programmer's Manual
6.4.2(2012)
|
00001 00002 /**************************************************************************** 00003 * 00004 * MODULE: edit library functions 00005 * AUTHOR(S): Originally part of gis lib dir in CERL GRASS code 00006 * Subsequent (post-CVS) contributors: 00007 * Glynn Clements <glynn gclements.plus.com>, 00008 * Radim Blazek <radim.blazek gmail.com>, 00009 * Eric G. Miller <egm2 jps.net>, 00010 * Markus Neteler <neteler itc.it>, 00011 * Brad Douglas <rez touchofmadness.com>, 00012 * Bernhard Reiter <bernhard intevation.de> 00013 * PURPOSE: libraries for interactively editing raster support data 00014 * COPYRIGHT: (C) 1996-2006 by the GRASS Development Team 00015 * 00016 * This program is free software under the GNU General Public 00017 * License (>=v2). Read the file COPYING that comes with GRASS 00018 * for details. 00019 * 00020 *****************************************************************************/ 00021 00022 /********************************************************************** 00023 * 00024 * E_edit_cats (name, cats, option) 00025 * char *name 00026 * struct Categories *cats 00027 * 00028 * Interactively prompts the user for category names for 00029 * cats->ncats categories. Uses screen oriented prompting through 00030 * the visual_ask library. Compile with $(VASKLIB) and $(CURSES) 00031 * 00032 * name is used for informatin on the screen only. 00033 * No files are read or written 00034 * 00035 * If option is 0, user can change number of cats 00036 * 1, user must initialize number of cats 00037 * -1, user may not change number of cats 00038 * 00039 * 00040 * Returns: 00041 * -1 if user canceled the edit 00042 * 1 if ok 00043 * 00044 * note: 00045 * at present, this routine pretends to know nothing about the 00046 * category label generation capabilities using the cats.fmt 00047 * string. If it is necessary to let the user edit this 00048 * a separate interface must be used 00049 **********************************************************************/ 00050 #include <string.h> 00051 #include <stdlib.h> 00052 #include <grass/gis.h> 00053 #include <grass/vask.h> 00054 #include <grass/edit.h> 00055 00056 00057 #define NLINES 10 00058 00059 00060 int E_edit_cats(const char *name, struct Categories *cats, int option) 00061 { 00062 long incr; 00063 long atnum; 00064 long startcat; 00065 long endcat; 00066 long first_cat, last_cat; 00067 long catnum[NLINES]; 00068 char buff[NLINES][80]; 00069 char next[20]; 00070 char next_line[80]; 00071 char title[80]; 00072 char msg1[80]; 00073 char msg2[80]; 00074 int line; 00075 CELL max_ind, max_cat, min_ind; 00076 DCELL max_val, min_val; 00077 00078 if (G_quant_get_limits 00079 (&cats->q, &min_val, &max_val, &min_ind, &max_ind) < 0) 00080 max_cat = 0; 00081 else 00082 max_cat = (CELL) max_val; 00083 00084 if (max_cat < 0) 00085 option = 1; 00086 00087 last_cat = (long)max_cat; 00088 if (option >= 0) { 00089 V_clear(); 00090 V_line(1, msg1); 00091 V_line(2, msg2); 00092 00093 if (option == 0) { 00094 strcpy(msg1, "The current value for the highest category"); 00095 sprintf(msg2, "in [%s] is shown below", name); 00096 V_line(3, "If you need to change it, enter another value"); 00097 } 00098 else { 00099 last_cat = 0; 00100 strcpy(msg1, "Please enter the highest category value"); 00101 sprintf(msg2, "for [%s]", name); 00102 } 00103 00104 V_line(10, " Highest Category:"); 00105 V_ques(&last_cat, 'l', 10, 28, 5); 00106 V_line(16, next_line); 00107 00108 *next_line = 0; 00109 while (1) { 00110 V_intrpt_ok(); 00111 if (!V_call()) 00112 return -1; 00113 00114 if (last_cat >= 0) 00115 break; 00116 00117 sprintf(next_line, "** Negative values not allowed **"); 00118 } 00119 } 00120 00121 max_cat = last_cat; 00122 00123 first_cat = 0; 00124 if (cats->ncats > 0 && min_val < 0) 00125 first_cat = (CELL) min_val; 00126 00127 *title = 0; 00128 if (cats->title != NULL) 00129 strcpy(title, cats->title); 00130 00131 startcat = first_cat; 00132 sprintf(msg1, "[%s] ENTER NEW CATEGORY NAMES FOR THESE CATEGORIES", name); 00133 00134 while (1) { 00135 V_clear(); 00136 V_line(0, msg1); 00137 V_line(2, "TITLE: "); 00138 V_line(3, "CAT NEW CATEGORY NAME"); 00139 V_line(4, "NUM"); 00140 00141 V_ques(title, 's', 2, 8, 60); 00142 00143 endcat = 00144 startcat + NLINES <= 00145 last_cat + 1 ? startcat + NLINES : last_cat + 1; 00146 00147 line = 5; 00148 for (incr = startcat; incr < endcat; incr++) { 00149 atnum = incr - startcat; 00150 strcpy(buff[atnum], G_get_cat((CELL) incr, cats)); 00151 catnum[atnum] = incr; 00152 V_const(&catnum[atnum], 'l', line, 1, 3); 00153 V_ques(buff[atnum], 's', line, 5, 60); 00154 line++; 00155 } 00156 00157 line += 2; 00158 *next = 0; 00159 if (endcat > last_cat) 00160 strcpy(next, "end"); 00161 else 00162 sprintf(next, "%ld", endcat); 00163 sprintf(next_line, "%*s%*s (of %ld)", 41, 00164 "Next category ('end' to end): ", 5, "", last_cat); 00165 V_line(line, next_line); 00166 V_ques(next, 's', line, 41, 5); 00167 00168 V_intrpt_ok(); 00169 if (!V_call()) 00170 return -1; 00171 00172 /* store new category name in structure */ 00173 for (incr = startcat; incr < endcat; incr++) { 00174 atnum = incr - startcat; 00175 G_strip(buff[atnum]); 00176 if (strcmp(buff[atnum], G_get_cat((CELL) incr, cats)) != 0) 00177 G_set_cat((CELL) incr, buff[atnum], cats); 00178 } 00179 00180 if (*next == 0) 00181 break; 00182 if (strcmp(next, "end") == 0) 00183 break; 00184 if (sscanf(next, "%ld", &endcat) != 1) 00185 continue; 00186 00187 if (endcat < first_cat) 00188 endcat = first_cat; 00189 00190 if (endcat > last_cat) { 00191 endcat = last_cat - NLINES + 1; 00192 if (endcat < 0) 00193 endcat = 0; 00194 } 00195 startcat = endcat; 00196 } 00197 if (cats->title) 00198 G_free(cats->title); 00199 00200 G_strip(title); 00201 cats->title = G_store(title); 00202 00203 return (1); 00204 } 00205 00206 00207 /********************************************************************** 00208 * 00209 * E_edit_fp_cats (name, cats) 00210 * char *name 00211 * struct Categories *cats 00212 * 00213 * Interactively prompts the user for category names for 00214 * fp ranges of data. Uses screen oriented prompting through 00215 * the visual_ask library. Compile with $(VASKLIB) and $(CURSES) 00216 * 00217 * name is used for informatin on the screen only. 00218 * No files are read or written 00219 * 00220 * Returns: 00221 * -1 if user canceled the edit 00222 * 1 if ok 00223 * 00224 * note: 00225 * at present, this routine pretends to know nothing about the 00226 * category label generation capabilities using the cats.fmt 00227 * string. If it is necessary to let the user edit this 00228 * a separate interface must be used 00229 **********************************************************************/ 00230 00231 #define NLINES 10 00232 00233 int E_edit_fp_cats(const char *name, struct Categories *cats) 00234 { 00235 long incr; 00236 long atnum; 00237 long startcat; 00238 long endcat; 00239 char buff[NLINES][60]; 00240 char next[20]; 00241 char next_line[80]; 00242 char title[80]; 00243 char msg1[80]; 00244 char msg2[80]; 00245 int line, ncats; 00246 size_t lab_len; 00247 DCELL max_val[NLINES], min_val[NLINES]; 00248 DCELL dmin, dmax; 00249 CELL tmp_cell; 00250 struct Categories old_cats; 00251 struct FPRange fp_range; 00252 00253 if (G_read_fp_range(name, G_mapset(), &fp_range) < 0) 00254 G_fatal_error("can't read the floating point range for %s", name); 00255 00256 G_get_fp_range_min_max(&fp_range, &dmin, &dmax); 00257 /* first save old cats */ 00258 G_copy_raster_cats(&old_cats, cats); 00259 00260 G_init_raster_cats(old_cats.title, cats); 00261 G_free_raster_cats(cats); 00262 00263 ncats = old_cats.ncats; 00264 V_clear(); 00265 00266 if (!ncats) 00267 sprintf(msg1, "There are no predefined fp ranges to label"); 00268 else 00269 sprintf(msg1, "There are %d predefined fp ranges to label", ncats); 00270 sprintf(msg2, "Enter the number of fp ranges you want to label"); 00271 00272 V_line(1, msg1); 00273 V_line(2, msg2); 00274 V_ques(&ncats, 'l', 2, 48, 5); 00275 V_line(16, next_line); 00276 *next_line = 0; 00277 V_intrpt_ok(); 00278 00279 if (!V_call()) 00280 return -1; 00281 00282 *title = 0; 00283 if (old_cats.title != NULL) 00284 strcpy(title, old_cats.title); 00285 00286 startcat = 0; 00287 sprintf(msg1, "The fp data in map %s ranges from %f to %f", name, dmin, 00288 dmax); 00289 sprintf(msg2, "[%s] ENTER NEW CATEGORY NAMES FOR THESE CATEGORIES", name); 00290 00291 while (1) { 00292 V_clear(); 00293 V_line(0, msg1); 00294 V_line(1, msg2); 00295 V_line(3, "TITLE: "); 00296 V_line(4, "FP RANGE NEW CATEGORY NAME"); 00297 00298 V_ques(title, 's', 2, 8, 60); 00299 00300 endcat = startcat + NLINES <= ncats ? startcat + NLINES : ncats; 00301 00302 line = 6; 00303 for (incr = startcat; incr < endcat; incr++) { 00304 atnum = incr - startcat; 00305 if (incr < old_cats.ncats) { 00306 /* if editing existing range label */ 00307 lab_len = strlen(old_cats.labels[incr]); 00308 if (lab_len > 58) 00309 lab_len = 58; 00310 strncpy(buff[atnum], old_cats.labels[incr], lab_len); 00311 buff[atnum][lab_len] = 0; 00312 G_quant_get_ith_rule(&old_cats.q, incr, &min_val[atnum], 00313 &max_val[atnum], &tmp_cell, &tmp_cell); 00314 } 00315 else { 00316 /* adding new range label */ 00317 strcpy(buff[atnum], ""); 00318 max_val[atnum] = min_val[atnum] = 0; 00319 } 00320 00321 V_ques(&min_val[atnum], 'd', line, 1, 8); 00322 V_const("-", 's', line, 9, 1); 00323 V_ques(&max_val[atnum], 'd', line, 10, 8); 00324 V_ques(buff[atnum], 's', line, 19, 58); 00325 line++; 00326 } 00327 00328 line += 2; 00329 *next = 0; 00330 if (endcat >= ncats) 00331 strcpy(next, "end"); 00332 else 00333 sprintf(next, "%ld", endcat); 00334 sprintf(next_line, "%*s%*s (of %d)", 41, 00335 "Next range number ('end' to end): ", 5, "", ncats); 00336 V_line(line, next_line); 00337 V_ques(next, 's', line, 41, 5); 00338 00339 V_intrpt_ok(); 00340 if (!V_call()) 00341 return -1; 00342 00343 /* store new category name in structure */ 00344 for (incr = startcat; incr < endcat; incr++) { 00345 atnum = incr - startcat; 00346 G_strip(buff[atnum]); 00347 00348 /* adding new range label */ 00349 if (!(strcmp(buff[atnum], "") == 0 && 00350 min_val[atnum] == 0. && max_val[atnum] == 0.)) 00351 G_set_d_raster_cat(&min_val[atnum], &max_val[atnum], 00352 buff[atnum], cats); 00353 } 00354 00355 if (*next == 0) 00356 break; 00357 if (strcmp(next, "end") == 0) 00358 break; 00359 if (sscanf(next, "%ld", &endcat) != 1) 00360 continue; 00361 00362 if (endcat < 0) 00363 endcat = 0; 00364 00365 if (endcat > ncats) { 00366 endcat = ncats - NLINES + 1; 00367 if (endcat < 0) 00368 endcat = 0; 00369 } 00370 startcat = endcat; 00371 } 00372 00373 G_strip(title); 00374 cats->title = G_store(title); 00375 /* since label pointers in old_cats point to the old allocated strings, 00376 and cats now has all the newly allocated strings, it never reuses 00377 old ones, we need to free them */ 00378 00379 return (1); 00380 }