~grass/grass/releasebranch_7_0

« back to all changes in this revision

Viewing changes to raster/r.cats/main.c

  • Committer: glynn
  • Date: 2008-08-16 11:51:17 UTC
  • Revision ID: svn-v4:15284696-431f-4ddb-bdfa-cd5b030d7da7:grass/trunk:32813
Rename directories r.univar2 -> r.univar, r.grow2 -> r.grow, r.cats -> r.category
Remove r.proj

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/****************************************************************************
3
 
 *
4
 
 * MODULE:       r.cats
5
 
 *
6
 
 * AUTHOR(S):    Michael Shapiro - CERL
7
 
 *               Hamish Bowman, Dunedin, New Zealand  (label creation opts)
8
 
 *
9
 
 * PURPOSE:      Prints category values and labels associated with
10
 
 *               user-specified raster map layers.
11
 
 *
12
 
 * COPYRIGHT:    (C) 2006 by the GRASS Development Team
13
 
 *
14
 
 *               This program is free software under the GNU General Public
15
 
 *               License (>=v2). Read the file COPYING that comes with GRASS
16
 
 *               for details.
17
 
 *
18
 
 ***************************************************************************/
19
 
 
20
 
#include <stdlib.h>
21
 
#include <stdio.h>
22
 
#include <string.h>
23
 
#include <grass/gis.h>
24
 
#include <grass/glocale.h>
25
 
#include "local_proto.h"
26
 
 
27
 
static char fs = '\t';
28
 
static struct Categories cats;
29
 
 
30
 
 
31
 
int main(int argc, char *argv[])
32
 
{
33
 
    char *name;
34
 
    char *mapset;
35
 
    long x, y;
36
 
    double dx;
37
 
    RASTER_MAP_TYPE map_type;
38
 
    int i;
39
 
    int from_stdin = FALSE;
40
 
    struct GModule *module;
41
 
 
42
 
    struct
43
 
    {
44
 
        struct Option *map, *fs, *cats, *vals, *raster, *file, *fmt_str,
45
 
            *fmt_coeff;
46
 
    } parm;
47
 
 
48
 
    G_gisinit(argv[0]);
49
 
 
50
 
    module = G_define_module();
51
 
    module->keywords = _("raster");
52
 
    module->description =
53
 
        _("Manages category values and labels associated "
54
 
          "with user-specified raster map layers.");
55
 
 
56
 
    parm.map = G_define_standard_option(G_OPT_R_MAP);
57
 
 
58
 
    parm.cats = G_define_standard_option(G_OPT_V_CATS);
59
 
    parm.cats->multiple = YES;
60
 
 
61
 
    parm.vals = G_define_option();
62
 
    parm.vals->key = "vals";
63
 
    parm.vals->type = TYPE_DOUBLE;
64
 
    parm.vals->multiple = YES;
65
 
    parm.vals->required = NO;
66
 
    parm.vals->label = _("Comma separated value list");
67
 
    parm.vals->description = _("Example: 1.4,3.8,13");
68
 
 
69
 
    parm.fs = G_define_standard_option(G_OPT_F_SEP);
70
 
    parm.fs->key_desc = "character|space|tab";
71
 
    parm.fs->answer = "tab";
72
 
    parm.fs->description = _("Output field separator");
73
 
 
74
 
    parm.raster = G_define_standard_option(G_OPT_R_INPUT);
75
 
    parm.raster->key = "raster";
76
 
    parm.raster->required = NO;
77
 
    parm.raster->description =
78
 
        _("Raster map from which to copy category table");
79
 
 
80
 
    parm.file = G_define_standard_option(G_OPT_F_INPUT);
81
 
    parm.file->key = "rules";
82
 
    parm.file->required = NO;
83
 
    parm.file->description =
84
 
        _("File containing category label rules (or \"-\" to read from stdin)");
85
 
 
86
 
    parm.fmt_str = G_define_option();
87
 
    parm.fmt_str->key = "format";
88
 
    parm.fmt_str->type = TYPE_STRING;
89
 
    parm.fmt_str->required = NO;
90
 
    parm.fmt_str->label =
91
 
        _("Default label or format string for dynamic labeling");
92
 
    parm.fmt_str->description =
93
 
        _("Used when no explicit label exists for the category");
94
 
 
95
 
    parm.fmt_coeff = G_define_option();
96
 
    parm.fmt_coeff->key = "coefficients";
97
 
    parm.fmt_coeff->type = TYPE_DOUBLE;
98
 
    parm.fmt_coeff->required = NO;
99
 
    parm.fmt_coeff->key_desc = "mult1,offset1,mult2,offset2";
100
 
    /*    parm.fmt_coeff->answer   = "0.0,0.0,0.0,0.0"; */
101
 
    parm.fmt_coeff->label = _("Dynamic label coefficients");
102
 
    parm.fmt_coeff->description =
103
 
        _("Two pairs of category multiplier and offsets, for $1 and $2");
104
 
 
105
 
    if (G_parser(argc, argv))
106
 
        exit(EXIT_FAILURE);
107
 
 
108
 
 
109
 
    name = parm.map->answer;
110
 
 
111
 
    /* see v.in.ascii for a better solution */
112
 
    if (parm.fs->answer != NULL) {
113
 
        if (strcmp(parm.fs->answer, "space") == 0)
114
 
            fs = ' ';
115
 
        else if (strcmp(parm.fs->answer, "tab") == 0)
116
 
            fs = '\t';
117
 
        else if (strcmp(parm.fs->answer, "\\t") == 0)
118
 
            fs = '\t';
119
 
        else
120
 
            fs = parm.fs->answer[0];
121
 
    }
122
 
 
123
 
    mapset = G_find_cell2(name, "");
124
 
    if (mapset == NULL)
125
 
        G_fatal_error(_("Raster map <%s> not found"), name);
126
 
 
127
 
    map_type = G_raster_map_type(name, mapset);
128
 
 
129
 
 
130
 
    /* create category labels */
131
 
    if (parm.raster->answer || parm.file->answer ||
132
 
        parm.fmt_str->answer || parm.fmt_coeff->answer) {
133
 
 
134
 
        /* restrict editing to current mapset */
135
 
        if (strcmp(mapset, G_mapset()) != 0)
136
 
            G_fatal_error(_("Raster map <%s> not found in current mapset"),
137
 
                          name);
138
 
 
139
 
        /* use cats from another map */
140
 
        if (parm.raster->answer) {
141
 
            int fd;
142
 
            char *cmapset;
143
 
 
144
 
            cmapset = G_find_cell2(parm.raster->answer, "");
145
 
            if (cmapset == NULL)
146
 
                G_fatal_error(_("Raster map <%s> not found"),
147
 
                              parm.raster->answer);
148
 
 
149
 
            if ((fd = G_open_cell_old(name, mapset)) < 0)
150
 
                G_fatal_error(_("Unable to open raster map <%s>"), name);
151
 
 
152
 
            G_init_raster_cats("", &cats);
153
 
 
154
 
            if (0 > G_read_cats(parm.raster->answer, cmapset, &cats))
155
 
                G_fatal_error(_("Unable to read category file of raster map <%s@%s>"),
156
 
                              parm.raster->answer, cmapset);
157
 
 
158
 
            if (G_write_cats(name, &cats) >= 0)
159
 
                G_message(_("Category table for <%s> set from <%s>"), name,
160
 
                          parm.raster->answer);
161
 
 
162
 
            G_close_cell(fd);
163
 
        }
164
 
 
165
 
        /* load cats from rules file */
166
 
        /*  TODO: respect fs= */
167
 
        if (parm.file->answer) {
168
 
            FILE *fp;
169
 
 
170
 
            if (strcmp("-", parm.file->answer) == 0) {
171
 
                from_stdin = TRUE;
172
 
                fp = stdin;
173
 
            }
174
 
            else {
175
 
                fp = fopen(parm.file->answer, "r");
176
 
                if (!fp)
177
 
                    G_fatal_error(_("Unable to open file <%s>"),
178
 
                                  parm.file->answer);
179
 
            }
180
 
 
181
 
            G_init_raster_cats("", &cats);
182
 
 
183
 
            for (;;) {
184
 
                char buf[1024], label[1024];
185
 
                DCELL d1, d2;
186
 
 
187
 
                if (!G_getl2(buf, sizeof(buf), fp))
188
 
                    break;
189
 
 
190
 
                if (sscanf(buf, "%lf:%lf:%[^\n]", &d1, &d2, label) == 3)
191
 
                    G_set_d_raster_cat(&d1, &d2, label, &cats);
192
 
                else if (sscanf(buf, "%lf:%[^\n]", &d1, label) == 2)
193
 
                    G_set_d_raster_cat(&d1, &d1, label, &cats);
194
 
            }
195
 
 
196
 
            if (G_write_cats(name, &cats) < 0)
197
 
                G_fatal_error(_("Cannot create category file for <%s>"),
198
 
                              name);
199
 
 
200
 
            if (!from_stdin)
201
 
                fclose(fp);
202
 
        }
203
 
 
204
 
        /* set dynamic cat rules for cats without explicit labels */
205
 
        if (parm.fmt_str->answer || parm.fmt_coeff->answer) {
206
 
            char *fmt_str;
207
 
            double m1, a1, m2, a2;
208
 
 
209
 
            /* read existing values */
210
 
            G_init_raster_cats("", &cats);
211
 
 
212
 
            if (0 > G_read_cats(name, G_mapset(), &cats))
213
 
                G_warning(_("Unable to read category file of raster map <%s@%s>"),
214
 
                          name, G_mapset());
215
 
 
216
 
            if (parm.fmt_str->answer) {
217
 
                fmt_str =
218
 
                    G_malloc(strlen(parm.fmt_str->answer) > strlen(cats.fmt)
219
 
                             ? strlen(parm.fmt_str->answer) +
220
 
                             1 : strlen(cats.fmt) + 1);
221
 
                strcpy(fmt_str, parm.fmt_str->answer);
222
 
            }
223
 
            else {
224
 
                fmt_str = G_malloc(strlen(cats.fmt) + 1);
225
 
                strcpy(fmt_str, cats.fmt);
226
 
            }
227
 
 
228
 
            m1 = cats.m1;
229
 
            a1 = cats.a1;
230
 
            m2 = cats.m2;
231
 
            a2 = cats.a2;
232
 
 
233
 
            if (parm.fmt_coeff->answer) {
234
 
                m1 = atof(parm.fmt_coeff->answers[0]);
235
 
                a1 = atof(parm.fmt_coeff->answers[1]);
236
 
                m2 = atof(parm.fmt_coeff->answers[2]);
237
 
                a2 = atof(parm.fmt_coeff->answers[3]);
238
 
            }
239
 
 
240
 
            G_set_cats_fmt(fmt_str, m1, a1, m2, a2, &cats);
241
 
 
242
 
            if (G_write_cats(name, &cats) != 1)
243
 
                G_fatal_error(_("Cannot create category file for <%s>"),
244
 
                              name);
245
 
        }
246
 
 
247
 
        G_free_cats(&cats);
248
 
        exit(EXIT_SUCCESS);
249
 
    }
250
 
    else {
251
 
        if (G_read_cats(name, mapset, &cats) < 0)
252
 
            G_fatal_error(_("Unable to read category file of raster map <%s> in <%s>"),
253
 
                          name, mapset);
254
 
    }
255
 
 
256
 
    /* describe the category labels */
257
 
    /* if no cats requested, use r.describe to get the cats */
258
 
    if (parm.cats->answer == NULL) {
259
 
        if (map_type == CELL_TYPE) {
260
 
            get_cats(name, mapset);
261
 
            while (next_cat(&x))
262
 
                print_label(x);
263
 
            exit(EXIT_SUCCESS);
264
 
        }
265
 
    }
266
 
    else {
267
 
        if (map_type != CELL_TYPE)
268
 
            G_warning(_("The map is floating point! Ignoring cats list, using vals list"));
269
 
        else {                  /* integer map */
270
 
 
271
 
            for (i = 0; parm.cats->answers[i]; i++)
272
 
                if (!scan_cats(parm.cats->answers[i], &x, &y)) {
273
 
                    G_usage();
274
 
                    exit(EXIT_FAILURE);
275
 
                }
276
 
            for (i = 0; parm.cats->answers[i]; i++) {
277
 
                scan_cats(parm.cats->answers[i], &x, &y);
278
 
                while (x <= y)
279
 
                    print_label(x++);
280
 
            }
281
 
            exit(EXIT_SUCCESS);
282
 
        }
283
 
    }
284
 
    if (parm.vals->answer == NULL)
285
 
        G_fatal_error(_("vals argument is required for floating point map!"));
286
 
    for (i = 0; parm.vals->answers[i]; i++)
287
 
        if (!scan_vals(parm.vals->answers[i], &dx)) {
288
 
            G_usage();
289
 
            exit(EXIT_FAILURE);
290
 
        }
291
 
    for (i = 0; parm.vals->answers[i]; i++) {
292
 
        scan_vals(parm.vals->answers[i], &dx);
293
 
        print_d_label(dx);
294
 
    }
295
 
    exit(EXIT_SUCCESS);
296
 
}
297
 
 
298
 
 
299
 
 
300
 
int print_label(long x)
301
 
{
302
 
    char *label;
303
 
 
304
 
    G_squeeze(label = G_get_cat((CELL) x, &cats));
305
 
    fprintf(stdout, "%ld%c%s\n", x, fs, label);
306
 
 
307
 
    return 0;
308
 
}
309
 
 
310
 
int print_d_label(double x)
311
 
{
312
 
    char *label, tmp[40];
313
 
    DCELL dtmp;
314
 
 
315
 
    dtmp = x;
316
 
    G_squeeze(label = G_get_d_raster_cat(&dtmp, &cats));
317
 
    sprintf(tmp, "%.10f", x);
318
 
    G_trim_decimal(tmp);
319
 
    fprintf(stdout, "%s%c%s\n", tmp, fs, label);
320
 
 
321
 
    return 0;
322
 
}
323
 
 
324
 
int scan_cats(char *s, long *x, long *y)
325
 
{
326
 
    char dummy[2];
327
 
 
328
 
    *dummy = 0;
329
 
    if (sscanf(s, "%ld-%ld%1s", x, y, dummy) == 2)
330
 
        return (*dummy == 0 && *x <= *y);
331
 
    *dummy = 0;
332
 
    if (sscanf(s, "%ld%1s", x, dummy) == 1 && *dummy == 0) {
333
 
        *y = *x;
334
 
        return 1;
335
 
    }
336
 
    return 0;
337
 
}
338
 
 
339
 
int scan_vals(char *s, double *x)
340
 
{
341
 
    char dummy[10];
342
 
 
343
 
    *dummy = 0;
344
 
    if (sscanf(s, "%lf%1s", x, dummy) == 1 && *dummy == 0)
345
 
        return 1;
346
 
    return 0;
347
 
}