GRASS Programmer's Manual  6.4.2(2012)
edit_cats.c
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines