GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
edit_cats.c
Go to the documentation of this file.
1 
2 /****************************************************************************
3  *
4  * MODULE: edit library functions
5  * AUTHOR(S): Originally part of gis lib dir in CERL GRASS code
6  * Subsequent (post-CVS) contributors:
7  * Glynn Clements <glynn gclements.plus.com>,
8  * Radim Blazek <radim.blazek gmail.com>,
9  * Eric G. Miller <egm2 jps.net>,
10  * Markus Neteler <neteler itc.it>,
11  * Brad Douglas <rez touchofmadness.com>,
12  * Bernhard Reiter <bernhard intevation.de>
13  * PURPOSE: libraries for interactively editing raster support data
14  * COPYRIGHT: (C) 1996-2006 by the GRASS Development Team
15  *
16  * This program is free software under the GNU General Public
17  * License (>=v2). Read the file COPYING that comes with GRASS
18  * for details.
19  *
20  *****************************************************************************/
21 
22 /**********************************************************************
23  *
24  * E_edit_cats (name, cats, option)
25  * char *name
26  * struct Categories *cats
27  *
28  * Interactively prompts the user for category names for
29  * cats->ncats categories. Uses screen oriented prompting through
30  * the visual_ask library. Compile with $(VASKLIB) and $(CURSES)
31  *
32  * name is used for informatin on the screen only.
33  * No files are read or written
34  *
35  * If option is 0, user can change number of cats
36  * 1, user must initialize number of cats
37  * -1, user may not change number of cats
38  *
39  *
40  * Returns:
41  * -1 if user canceled the edit
42  * 1 if ok
43  *
44  * note:
45  * at present, this routine pretends to know nothing about the
46  * category label generation capabilities using the cats.fmt
47  * string. If it is necessary to let the user edit this
48  * a separate interface must be used
49  **********************************************************************/
50 #include <string.h>
51 #include <stdlib.h>
52 #include <grass/gis.h>
53 #include <grass/vask.h>
54 #include <grass/edit.h>
55 
56 
57 #define NLINES 10
58 
59 
60 int E_edit_cats(const char *name, struct Categories *cats, int option)
61 {
62  long incr;
63  long atnum;
64  long startcat;
65  long endcat;
66  long first_cat, last_cat;
67  long catnum[NLINES];
68  char buff[NLINES][80];
69  char next[20];
70  char next_line[80];
71  char title[80];
72  char msg1[80];
73  char msg2[80];
74  int line;
75  CELL max_ind, max_cat, min_ind;
76  DCELL max_val, min_val;
77 
79  (&cats->q, &min_val, &max_val, &min_ind, &max_ind) < 0)
80  max_cat = 0;
81  else
82  max_cat = (CELL) max_val;
83 
84  if (max_cat < 0)
85  option = 1;
86 
87  last_cat = (long)max_cat;
88  if (option >= 0) {
89  V_clear();
90  V_line(1, msg1);
91  V_line(2, msg2);
92 
93  if (option == 0) {
94  strcpy(msg1, "The current value for the highest category");
95  sprintf(msg2, "in [%s] is shown below", name);
96  V_line(3, "If you need to change it, enter another value");
97  }
98  else {
99  last_cat = 0;
100  strcpy(msg1, "Please enter the highest category value");
101  sprintf(msg2, "for [%s]", name);
102  }
103 
104  V_line(10, " Highest Category:");
105  V_ques(&last_cat, 'l', 10, 28, 5);
106  V_line(16, next_line);
107 
108  *next_line = 0;
109  while (1) {
110  V_intrpt_ok();
111  if (!V_call())
112  return -1;
113 
114  if (last_cat >= 0)
115  break;
116 
117  sprintf(next_line, "** Negative values not allowed **");
118  }
119  }
120 
121  max_cat = last_cat;
122 
123  first_cat = 0;
124  if (cats->ncats > 0 && min_val < 0)
125  first_cat = (CELL) min_val;
126 
127  *title = 0;
128  if (cats->title != NULL)
129  strcpy(title, cats->title);
130 
131  startcat = first_cat;
132  sprintf(msg1, "[%s] ENTER NEW CATEGORY NAMES FOR THESE CATEGORIES", name);
133 
134  while (1) {
135  V_clear();
136  V_line(0, msg1);
137  V_line(2, "TITLE: ");
138  V_line(3, "CAT NEW CATEGORY NAME");
139  V_line(4, "NUM");
140 
141  V_ques(title, 's', 2, 8, 60);
142 
143  endcat =
144  startcat + NLINES <=
145  last_cat + 1 ? startcat + NLINES : last_cat + 1;
146 
147  line = 5;
148  for (incr = startcat; incr < endcat; incr++) {
149  atnum = incr - startcat;
150  strcpy(buff[atnum], G_get_cat((CELL) incr, cats));
151  catnum[atnum] = incr;
152  V_const(&catnum[atnum], 'l', line, 1, 3);
153  V_ques(buff[atnum], 's', line, 5, 60);
154  line++;
155  }
156 
157  line += 2;
158  *next = 0;
159  if (endcat > last_cat)
160  strcpy(next, "end");
161  else
162  sprintf(next, "%ld", endcat);
163  sprintf(next_line, "%*s%*s (of %ld)", 41,
164  "Next category ('end' to end): ", 5, "", last_cat);
165  V_line(line, next_line);
166  V_ques(next, 's', line, 41, 5);
167 
168  V_intrpt_ok();
169  if (!V_call())
170  return -1;
171 
172  /* store new category name in structure */
173  for (incr = startcat; incr < endcat; incr++) {
174  atnum = incr - startcat;
175  G_strip(buff[atnum]);
176  if (strcmp(buff[atnum], G_get_cat((CELL) incr, cats)) != 0)
177  G_set_cat((CELL) incr, buff[atnum], cats);
178  }
179 
180  if (*next == 0)
181  break;
182  if (strcmp(next, "end") == 0)
183  break;
184  if (sscanf(next, "%ld", &endcat) != 1)
185  continue;
186 
187  if (endcat < first_cat)
188  endcat = first_cat;
189 
190  if (endcat > last_cat) {
191  endcat = last_cat - NLINES + 1;
192  if (endcat < 0)
193  endcat = 0;
194  }
195  startcat = endcat;
196  }
197  if (cats->title)
198  G_free(cats->title);
199 
200  G_strip(title);
201  cats->title = G_store(title);
202 
203  return (1);
204 }
205 
206 
207 /**********************************************************************
208  *
209  * E_edit_fp_cats (name, cats)
210  * char *name
211  * struct Categories *cats
212  *
213  * Interactively prompts the user for category names for
214  * fp ranges of data. Uses screen oriented prompting through
215  * the visual_ask library. Compile with $(VASKLIB) and $(CURSES)
216  *
217  * name is used for informatin on the screen only.
218  * No files are read or written
219  *
220  * Returns:
221  * -1 if user canceled the edit
222  * 1 if ok
223  *
224  * note:
225  * at present, this routine pretends to know nothing about the
226  * category label generation capabilities using the cats.fmt
227  * string. If it is necessary to let the user edit this
228  * a separate interface must be used
229  **********************************************************************/
230 
231 #define NLINES 10
232 
233 int E_edit_fp_cats(const char *name, struct Categories *cats)
234 {
235  long incr;
236  long atnum;
237  long startcat;
238  long endcat;
239  char buff[NLINES][60];
240  char next[20];
241  char next_line[80];
242  char title[80];
243  char msg1[80];
244  char msg2[80];
245  int line, ncats;
246  size_t lab_len;
247  DCELL max_val[NLINES], min_val[NLINES];
248  DCELL dmin, dmax;
249  CELL tmp_cell;
250  struct Categories old_cats;
251  struct FPRange fp_range;
252 
253  if (G_read_fp_range(name, G_mapset(), &fp_range) < 0)
254  G_fatal_error("can't read the floating point range for %s", name);
255 
256  G_get_fp_range_min_max(&fp_range, &dmin, &dmax);
257  /* first save old cats */
258  G_copy_raster_cats(&old_cats, cats);
259 
260  G_init_raster_cats(old_cats.title, cats);
261  G_free_raster_cats(cats);
262 
263  ncats = old_cats.ncats;
264  V_clear();
265 
266  if (!ncats)
267  sprintf(msg1, "There are no predefined fp ranges to label");
268  else
269  sprintf(msg1, "There are %d predefined fp ranges to label", ncats);
270  sprintf(msg2, "Enter the number of fp ranges you want to label");
271 
272  V_line(1, msg1);
273  V_line(2, msg2);
274  V_ques(&ncats, 'l', 2, 48, 5);
275  V_line(16, next_line);
276  *next_line = 0;
277  V_intrpt_ok();
278 
279  if (!V_call())
280  return -1;
281 
282  *title = 0;
283  if (old_cats.title != NULL)
284  strcpy(title, old_cats.title);
285 
286  startcat = 0;
287  sprintf(msg1, "The fp data in map %s ranges from %f to %f", name, dmin,
288  dmax);
289  sprintf(msg2, "[%s] ENTER NEW CATEGORY NAMES FOR THESE CATEGORIES", name);
290 
291  while (1) {
292  V_clear();
293  V_line(0, msg1);
294  V_line(1, msg2);
295  V_line(3, "TITLE: ");
296  V_line(4, "FP RANGE NEW CATEGORY NAME");
297 
298  V_ques(title, 's', 2, 8, 60);
299 
300  endcat = startcat + NLINES <= ncats ? startcat + NLINES : ncats;
301 
302  line = 6;
303  for (incr = startcat; incr < endcat; incr++) {
304  atnum = incr - startcat;
305  if (incr < old_cats.ncats) {
306  /* if editing existing range label */
307  lab_len = strlen(old_cats.labels[incr]);
308  if (lab_len > 58)
309  lab_len = 58;
310  strncpy(buff[atnum], old_cats.labels[incr], lab_len);
311  buff[atnum][lab_len] = 0;
312  G_quant_get_ith_rule(&old_cats.q, incr, &min_val[atnum],
313  &max_val[atnum], &tmp_cell, &tmp_cell);
314  }
315  else {
316  /* adding new range label */
317  strcpy(buff[atnum], "");
318  max_val[atnum] = min_val[atnum] = 0;
319  }
320 
321  V_ques(&min_val[atnum], 'd', line, 1, 8);
322  V_const("-", 's', line, 9, 1);
323  V_ques(&max_val[atnum], 'd', line, 10, 8);
324  V_ques(buff[atnum], 's', line, 19, 58);
325  line++;
326  }
327 
328  line += 2;
329  *next = 0;
330  if (endcat >= ncats)
331  strcpy(next, "end");
332  else
333  sprintf(next, "%ld", endcat);
334  sprintf(next_line, "%*s%*s (of %d)", 41,
335  "Next range number ('end' to end): ", 5, "", ncats);
336  V_line(line, next_line);
337  V_ques(next, 's', line, 41, 5);
338 
339  V_intrpt_ok();
340  if (!V_call())
341  return -1;
342 
343  /* store new category name in structure */
344  for (incr = startcat; incr < endcat; incr++) {
345  atnum = incr - startcat;
346  G_strip(buff[atnum]);
347 
348  /* adding new range label */
349  if (!(strcmp(buff[atnum], "") == 0 &&
350  min_val[atnum] == 0. && max_val[atnum] == 0.))
351  G_set_d_raster_cat(&min_val[atnum], &max_val[atnum],
352  buff[atnum], cats);
353  }
354 
355  if (*next == 0)
356  break;
357  if (strcmp(next, "end") == 0)
358  break;
359  if (sscanf(next, "%ld", &endcat) != 1)
360  continue;
361 
362  if (endcat < 0)
363  endcat = 0;
364 
365  if (endcat > ncats) {
366  endcat = ncats - NLINES + 1;
367  if (endcat < 0)
368  endcat = 0;
369  }
370  startcat = endcat;
371  }
372 
373  G_strip(title);
374  cats->title = G_store(title);
375  /* since label pointers in old_cats point to the old allocated strings,
376  and cats now has all the newly allocated strings, it never reuses
377  old ones, we need to free them */
378 
379  return (1);
380 }
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
int E_edit_fp_cats(const char *name, struct Categories *cats)
Definition: edit_cats.c:233
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
string name
Definition: render.py:1314
int E_edit_cats(const char *name, struct Categories *cats, int option)
Definition: edit_cats.c:60
void V_clear(void)
Zero out prompt and answer arrays.
Definition: V_clear.c:44
int V_line(int linenumber, const char *text)
Definition: V_line.c:50
#define NLINES
Definition: edit_cats.c:231
int V_call(void)
Interact with the user.
Definition: V_call.c:149
int G_set_cat(CELL num, char *label, struct Categories *pcats)
set a category label
Definition: gis/cats.c:1001
DCELL dmin
Definition: g3dcolor.c:53
char buff[1024]
Definition: g3dcats.c:89
void G_quant_get_ith_rule(const struct Quant *q, int i, DCELL *dLow, DCELL *dHigh, CELL *cLow, CELL *cHigh)
Definition: quant.c:562
char * G_get_cat(CELL num, struct Categories *pcats)
get a category label
Definition: gis/cats.c:583
int G_quant_get_limits(const struct Quant *q, DCELL *dMin, DCELL *dMax, CELL *cMin, CELL *cMax)
Extracts the minimum and maximum floating-point and integer values from all the rules (except the &quot;in...
Definition: quant.c:534
int G_init_raster_cats(const char *title, struct Categories *pcats)
Same as existing G_init_raster_cats() only ncats argument is missign. ncats has no meaning in new Cat...
Definition: gis/cats.c:1437
int G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:389
int V_const(void *src, int var_type, int row, int col, int length)
Definition: V_const.c:51
return NULL
Definition: dbfopen.c:1394
int G_get_fp_range_min_max(const struct FPRange *range, DCELL *min, DCELL *max)
Extract the min/max from the range structure r. If the range structure has no defined min/max (first!...
Definition: range.c:667
int G_read_fp_range(const char *name, const char *mapset, struct FPRange *drange)
Read the floating point range file f_range. This file is written in binary using XDR format...
Definition: range.c:139
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
DCELL dmax
Definition: g3dcolor.c:53
int G_free_raster_cats(struct Categories *pcats)
Same as existing G_free_cats()
Definition: gis/cats.c:1556
int V_ques(void *src, int var_type, int row, int col, int length)
Definition: V_ques.c:80
int G_set_d_raster_cat(DCELL *rast1, DCELL *rast2, char *label, struct Categories *pcats)
Adds the label for range rast1 through rast2 in category structure pcats.
Definition: gis/cats.c:1059
int G_copy_raster_cats(struct Categories *pcats_to, const struct Categories *pcats_from)
Allocates NEW space for quant rules and labels n pcats_to and copies all info from pcats_from cats to...
Definition: gis/cats.c:1598
void V_intrpt_ok(void)
Allow CTRL-C.
Definition: V_call.c:455