2
/****************************************************************************
6
* AUTHOR(S): Michael Shapiro - CERL
7
* Hamish Bowman, Dunedin, New Zealand (label creation opts)
9
* PURPOSE: Prints category values and labels associated with
10
* user-specified raster map layers.
12
* COPYRIGHT: (C) 2006 by the GRASS Development Team
14
* This program is free software under the GNU General Public
15
* License (>=v2). Read the file COPYING that comes with GRASS
18
***************************************************************************/
23
#include <grass/gis.h>
24
#include <grass/glocale.h>
25
#include "local_proto.h"
27
static char fs = '\t';
28
static struct Categories cats;
31
int main(int argc, char *argv[])
37
RASTER_MAP_TYPE map_type;
39
int from_stdin = FALSE;
40
struct GModule *module;
44
struct Option *map, *fs, *cats, *vals, *raster, *file, *fmt_str,
50
module = G_define_module();
51
module->keywords = _("raster");
53
_("Manages category values and labels associated "
54
"with user-specified raster map layers.");
56
parm.map = G_define_standard_option(G_OPT_R_MAP);
58
parm.cats = G_define_standard_option(G_OPT_V_CATS);
59
parm.cats->multiple = YES;
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");
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");
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");
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)");
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;
91
_("Default label or format string for dynamic labeling");
92
parm.fmt_str->description =
93
_("Used when no explicit label exists for the category");
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");
105
if (G_parser(argc, argv))
109
name = parm.map->answer;
111
/* see v.in.ascii for a better solution */
112
if (parm.fs->answer != NULL) {
113
if (strcmp(parm.fs->answer, "space") == 0)
115
else if (strcmp(parm.fs->answer, "tab") == 0)
117
else if (strcmp(parm.fs->answer, "\\t") == 0)
120
fs = parm.fs->answer[0];
123
mapset = G_find_cell2(name, "");
125
G_fatal_error(_("Raster map <%s> not found"), name);
127
map_type = G_raster_map_type(name, mapset);
130
/* create category labels */
131
if (parm.raster->answer || parm.file->answer ||
132
parm.fmt_str->answer || parm.fmt_coeff->answer) {
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"),
139
/* use cats from another map */
140
if (parm.raster->answer) {
144
cmapset = G_find_cell2(parm.raster->answer, "");
146
G_fatal_error(_("Raster map <%s> not found"),
147
parm.raster->answer);
149
if ((fd = G_open_cell_old(name, mapset)) < 0)
150
G_fatal_error(_("Unable to open raster map <%s>"), name);
152
G_init_raster_cats("", &cats);
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);
158
if (G_write_cats(name, &cats) >= 0)
159
G_message(_("Category table for <%s> set from <%s>"), name,
160
parm.raster->answer);
165
/* load cats from rules file */
166
/* TODO: respect fs= */
167
if (parm.file->answer) {
170
if (strcmp("-", parm.file->answer) == 0) {
175
fp = fopen(parm.file->answer, "r");
177
G_fatal_error(_("Unable to open file <%s>"),
181
G_init_raster_cats("", &cats);
184
char buf[1024], label[1024];
187
if (!G_getl2(buf, sizeof(buf), fp))
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);
196
if (G_write_cats(name, &cats) < 0)
197
G_fatal_error(_("Cannot create category file for <%s>"),
204
/* set dynamic cat rules for cats without explicit labels */
205
if (parm.fmt_str->answer || parm.fmt_coeff->answer) {
207
double m1, a1, m2, a2;
209
/* read existing values */
210
G_init_raster_cats("", &cats);
212
if (0 > G_read_cats(name, G_mapset(), &cats))
213
G_warning(_("Unable to read category file of raster map <%s@%s>"),
216
if (parm.fmt_str->answer) {
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);
224
fmt_str = G_malloc(strlen(cats.fmt) + 1);
225
strcpy(fmt_str, cats.fmt);
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]);
240
G_set_cats_fmt(fmt_str, m1, a1, m2, a2, &cats);
242
if (G_write_cats(name, &cats) != 1)
243
G_fatal_error(_("Cannot create category file for <%s>"),
251
if (G_read_cats(name, mapset, &cats) < 0)
252
G_fatal_error(_("Unable to read category file of raster map <%s> in <%s>"),
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);
267
if (map_type != CELL_TYPE)
268
G_warning(_("The map is floating point! Ignoring cats list, using vals list"));
269
else { /* integer map */
271
for (i = 0; parm.cats->answers[i]; i++)
272
if (!scan_cats(parm.cats->answers[i], &x, &y)) {
276
for (i = 0; parm.cats->answers[i]; i++) {
277
scan_cats(parm.cats->answers[i], &x, &y);
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)) {
291
for (i = 0; parm.vals->answers[i]; i++) {
292
scan_vals(parm.vals->answers[i], &dx);
300
int print_label(long x)
304
G_squeeze(label = G_get_cat((CELL) x, &cats));
305
fprintf(stdout, "%ld%c%s\n", x, fs, label);
310
int print_d_label(double x)
312
char *label, tmp[40];
316
G_squeeze(label = G_get_d_raster_cat(&dtmp, &cats));
317
sprintf(tmp, "%.10f", x);
319
fprintf(stdout, "%s%c%s\n", tmp, fs, label);
324
int scan_cats(char *s, long *x, long *y)
329
if (sscanf(s, "%ld-%ld%1s", x, y, dummy) == 2)
330
return (*dummy == 0 && *x <= *y);
332
if (sscanf(s, "%ld%1s", x, dummy) == 1 && *dummy == 0) {
339
int scan_vals(char *s, double *x)
344
if (sscanf(s, "%lf%1s", x, dummy) == 1 && *dummy == 0)