~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to display/d.legend/main.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* d.legend a.k.a d.leg.thin
2
 
 *
 
1
/*
3
2
 * MODULE:      d.legend
4
3
 *
5
4
 *              Based on the old d.leg.thin, which replaced an even older
6
5
 *              module called "d.legend".
7
6
 *
8
 
 * PURPOSE:     Draw a graphical legend for a raster on the display mon
 
7
 * PURPOSE:     Draw a graphical legend for a raster on the display monitor
9
8
 *
10
9
 * AUTHORS:
11
10
 *      Original version:
17
16
 *      Late 2002: Rewrite of much of the code:
18
17
 *         Hamish Bowman, Otago University, New Zealand
19
18
 *
20
 
 * COPYRIGHT:   (c) 2006 The GRASS Development Team
 
19
 * COPYRIGHT:   (c) 2006-2014 by The GRASS Development Team
21
20
 *
22
21
 *              This program is free software under the GNU General Public
23
22
 *              License (>=v2). Read the file COPYING that comes with GRASS
30
29
#include <math.h>
31
30
#include <grass/gis.h>
32
31
#include <grass/raster.h>
 
32
#include <grass/raster3d.h>
33
33
#include <grass/display.h>
34
34
#include <grass/glocale.h>
35
35
#include "local_proto.h"
37
37
 
38
38
int main(int argc, char **argv)
39
39
{
40
 
    char *mapset;
41
40
    char buff[512];
42
41
    char *map_name;
43
 
    char window_name[64];
44
 
    int black;
 
42
    int maptype;
 
43
    int black, white, color;
45
44
    int cats_num;
46
 
    int color;
47
45
    int cur_dot_row;
48
46
    int do_cats;
49
47
    int dots_per_line;
50
 
    int thin;
51
48
    int i, j, k;
52
 
    int lines, steps;
 
49
    int thin, lines, steps;
53
50
    int fp;
54
 
    int t, b, l, r;
55
 
    int hide_catnum, hide_catstr, hide_nodata, do_smooth, use_mouse;
 
51
    double t, b, l, r;
 
52
    int hide_catnum, hide_catstr, hide_nodata, do_smooth;
56
53
    char *cstr;
57
 
    int white;
58
 
    int x_box[5];
59
 
    int y_box[5];
 
54
    double x_box[5], y_box[5];
60
55
    struct Categories cats;
61
56
    struct Colors colors;
62
57
    struct GModule *module;
63
 
    struct Option *opt1, *opt2, *opt4, *opt5, *opt6, *opt7, *opt8, *opt9;
64
 
    struct Flag *hidestr, *hidenum, *hidenodata, *smooth, *mouse, *flipit;
 
58
    struct Option *opt_rast2d, *opt_rast3d, *opt_color, *opt_lines,
 
59
                  *opt_thin, *opt_labelnum, *opt_at, *opt_use, *opt_range,
 
60
                  *opt_font, *opt_path, *opt_charset, *opt_fontsize;
 
61
    struct Flag *hidestr, *hidenum, *hidenodata, *smooth, *flipit, *histo;
65
62
    struct Range range;
66
63
    struct FPRange fprange;
67
 
    CELL min_ind, max_ind, null_cell;
 
64
    CELL min_ind, max_ind;
68
65
    DCELL dmin, dmax, val;
69
66
    CELL min_colr, max_colr;
70
67
    DCELL min_dcolr, max_dcolr;
77
74
    double UserRangeMin, UserRangeMax, UserRangeTemp;
78
75
    double *catlist, maxCat;
79
76
    int catlistCount, use_catlist;
 
77
    double fontsize;
 
78
    char *units;
80
79
 
81
80
 
82
81
    /* Initialize the GIS calls */
83
82
    G_gisinit(argv[0]);
84
83
 
85
84
    module = G_define_module();
86
 
    module->keywords = _("display, cartography");
 
85
    G_add_keyword(_("display"));
 
86
    G_add_keyword(_("cartography"));
87
87
    module->description =
88
 
        _("Displays a legend for a raster map in the active frame "
 
88
        _("Displays a legend for a 2D or 3D raster map in the active frame "
89
89
          "of the graphics monitor.");
90
90
 
91
 
    opt1 = G_define_standard_option(G_OPT_R_MAP);
92
 
    opt1->description = _("Name of raster map");
93
 
 
94
 
    opt2 = G_define_standard_option(G_OPT_C_FG);
95
 
    opt2->label = _("Text color");
96
 
 
97
 
    opt4 = G_define_option();
98
 
    opt4->key = "lines";
99
 
    opt4->type = TYPE_INTEGER;
100
 
    opt4->answer = "0";
101
 
    opt4->options = "0-1000";
102
 
    opt4->description =
 
91
    opt_rast2d = G_define_standard_option(G_OPT_R_MAP);
 
92
    opt_rast2d->key = "raster";
 
93
    opt_rast2d->required = NO;
 
94
    opt_rast2d->guisection = _("Input");
 
95
 
 
96
    opt_rast3d = G_define_standard_option(G_OPT_R3_MAP);
 
97
    opt_rast3d->key = "raster_3d";
 
98
    opt_rast3d->required = NO;
 
99
    opt_rast3d->guisection = _("Input");
 
100
 
 
101
    opt_lines = G_define_option();
 
102
    opt_lines->key = "lines";
 
103
    opt_lines->type = TYPE_INTEGER;
 
104
    opt_lines->answer = "0";
 
105
    opt_lines->options = "0-1000";
 
106
    opt_lines->description =
103
107
        _("Number of text lines (useful for truncating long legends)");
104
 
    opt4->guisection = _("Advanced");
105
 
 
106
 
    opt5 = G_define_option();
107
 
    opt5->key = "thin";
108
 
    opt5->type = TYPE_INTEGER;
109
 
    opt5->required = NO;
110
 
    opt5->answer = "1";
111
 
    opt5->options = "1-1000";
112
 
    opt5->description = _("Thinning factor (thin=10 gives cats 0,10,20...)");
113
 
    opt5->guisection = _("Advanced");
114
 
 
115
 
    opt6 = G_define_option();
116
 
    opt6->key = "labelnum";
117
 
    opt6->type = TYPE_INTEGER;
118
 
    opt6->answer = "5";
119
 
    opt6->options = "2-100";
120
 
    opt6->description = _("Number of text labels for smooth gradient legend");
121
 
    opt6->guisection = _("Advanced");
122
 
 
123
 
    opt7 = G_define_option();
124
 
    opt7->key = "at";
125
 
    opt7->key_desc = "bottom,top,left,right";
126
 
    opt7->type = TYPE_DOUBLE;   /* needs to be TYPE_DOUBLE to get past options check */
127
 
    opt7->required = NO;
128
 
    opt7->options = "0-100";
129
 
    opt7->label =
130
 
        _("Size and placement as percentage of screen coordinates (0,0 is lower left)");
131
 
    opt7->description = opt7->key_desc;
132
 
    opt7->answer = NULL;
133
 
 
134
 
    opt8 = G_define_option();
135
 
    opt8->key = "use";
136
 
    opt8->key_desc = "catnum";
137
 
    opt8->type = TYPE_DOUBLE;   /* string as it is fed through the parser? */
138
 
    opt8->required = NO;
139
 
    opt8->description =
 
108
    opt_lines->guisection = _("Advanced");
 
109
 
 
110
    opt_thin = G_define_option();
 
111
    opt_thin->key = "thin";
 
112
    opt_thin->type = TYPE_INTEGER;
 
113
    opt_thin->required = NO;
 
114
    opt_thin->answer = "1";
 
115
    opt_thin->options = "1-1000";
 
116
    opt_thin->description =
 
117
        _("Thinning factor (thin=10 gives cats 0,10,20...)");
 
118
    opt_thin->guisection = _("Advanced");
 
119
 
 
120
    opt_labelnum = G_define_option();
 
121
    opt_labelnum->key = "labelnum";
 
122
    opt_labelnum->type = TYPE_INTEGER;
 
123
    opt_labelnum->answer = "5";
 
124
    opt_labelnum->options = "2-100";
 
125
    opt_labelnum->description =
 
126
        _("Number of text labels for smooth gradient legend");
 
127
    opt_labelnum->guisection = _("Gradient");
 
128
 
 
129
    opt_at = G_define_option();
 
130
    opt_at->key = "at";
 
131
    opt_at->key_desc = "bottom,top,left,right";
 
132
    opt_at->type = TYPE_DOUBLE;  /* needs to be TYPE_DOUBLE to get past options check */
 
133
    opt_at->required = NO;
 
134
    opt_at->options = "0-100";
 
135
    opt_at->label =
 
136
        _("Size and placement as percentage of screen coordinates "
 
137
          "(0,0 is lower left)");
 
138
    opt_at->description = opt_at->key_desc;
 
139
    opt_at->answer = NULL;
 
140
 
 
141
    opt_use = G_define_option();
 
142
    opt_use->key = "use";
 
143
    opt_use->type = TYPE_DOUBLE;  /* string as it is fed through the parser? */
 
144
    opt_use->required = NO;
 
145
    opt_use->description =
140
146
        _("List of discrete category numbers/values for legend");
141
 
    opt8->multiple = YES;
142
 
    opt8->guisection = _("Advanced");
 
147
    opt_use->multiple = YES;
 
148
    opt_use->guisection = _("Subset");
143
149
 
144
 
    opt9 = G_define_option();
145
 
    opt9->key = "range";
146
 
    opt9->key_desc = "min,max";
147
 
    opt9->type = TYPE_DOUBLE;   /* should it be type_double or _string ?? */
148
 
    opt9->required = NO;
149
 
    opt9->description =
 
150
    opt_range = G_define_option();
 
151
    opt_range->key = "range";
 
152
    opt_range->key_desc = "min,max";
 
153
    opt_range->type = TYPE_DOUBLE;  /* should it be type_double or _string ?? */
 
154
    opt_range->required = NO;
 
155
    opt_range->description =
150
156
        _("Use a subset of the map range for the legend (min,max)");
151
 
    opt9->guisection = _("Advanced");
152
 
 
153
 
 
154
 
    mouse = G_define_flag();
155
 
    mouse->key = 'm';
156
 
    mouse->description = _("Use mouse to size & place legend");
 
157
    opt_range->guisection = _("Subset");
 
158
 
 
159
    opt_color = G_define_standard_option(G_OPT_C);
 
160
    opt_color->label = _("Text color");
 
161
    opt_color->guisection = _("Font settings");
 
162
 
 
163
    opt_font = G_define_option();
 
164
    opt_font->key = "font";
 
165
    opt_font->type = TYPE_STRING;
 
166
    opt_font->required = NO;
 
167
    opt_font->description = _("Font name");
 
168
    opt_font->guisection = _("Font settings");
 
169
 
 
170
    opt_fontsize = G_define_option();
 
171
    opt_fontsize->key = "fontsize";
 
172
    opt_fontsize->type = TYPE_DOUBLE;
 
173
    opt_fontsize->required = NO;
 
174
    opt_fontsize->options = "1-360";
 
175
    opt_fontsize->label = _("Font size");
 
176
    opt_fontsize->description = _("Default: Auto-scaled");
 
177
    opt_fontsize->guisection = _("Font settings");
 
178
 
 
179
    opt_path = G_define_standard_option(G_OPT_F_INPUT);
 
180
    opt_path->key = "path";
 
181
    opt_path->required = NO;
 
182
    opt_path->description = _("Path to font file");
 
183
    opt_path->gisprompt = "old_file,font,file";
 
184
    opt_path->guisection = _("Font settings");
 
185
 
 
186
    opt_charset = G_define_option();
 
187
    opt_charset->key = "charset";
 
188
    opt_charset->type = TYPE_STRING;
 
189
    opt_charset->required = NO;
 
190
    opt_charset->description =
 
191
        _("Text encoding (only applicable to TrueType fonts)");
 
192
    opt_charset->guisection = _("Font settings");
157
193
 
158
194
    hidestr = G_define_flag();
159
195
    hidestr->key = 'v';
173
209
    smooth = G_define_flag();
174
210
    smooth->key = 's';
175
211
    smooth->description = _("Draw smooth gradient");
176
 
    smooth->guisection = _("Advanced");
 
212
    smooth->guisection = _("Gradient");
177
213
 
178
214
    flipit = G_define_flag();
179
215
    flipit->key = 'f';
180
216
    flipit->description = _("Flip legend");
181
217
    flipit->guisection = _("Advanced");
182
218
 
 
219
    histo = G_define_flag();
 
220
    histo->key = 'd';
 
221
    histo->description = _("Add histogram to smoothed legend");
 
222
    histo->guisection = _("Gradient");
 
223
 
183
224
 
184
225
    /* Check command line */
185
226
    if (G_parser(argc, argv))
186
227
        exit(EXIT_FAILURE);
187
228
 
 
229
    /* FIXME: add GUI launching logic to G_parser() call */
 
230
    if ((opt_rast2d->answer && opt_rast3d->answer) ||
 
231
        !(opt_rast2d->answer || opt_rast3d->answer))
 
232
        G_fatal_error(_("Please specify a single map name. To launch GUI use d.legend --ui."));
188
233
 
189
 
    map_name = opt1->answer;
 
234
    if (opt_rast2d->answer) {
 
235
        map_name = opt_rast2d->answer;
 
236
        maptype = MAP_TYPE_RASTER2D;
 
237
    }
 
238
    else {
 
239
        map_name = opt_rast3d->answer;
 
240
        maptype = MAP_TYPE_RASTER3D;
 
241
    }
190
242
 
191
243
    hide_catstr = hidestr->answer;      /* note hide_catstr gets changed and re-read below */
192
244
    hide_catnum = hidenum->answer;
193
245
    hide_nodata = hidenodata->answer;
194
246
    do_smooth = smooth->answer;
195
 
    use_mouse = mouse->answer;
196
247
    flip = flipit->answer;
197
248
 
198
 
    color = D_parse_color(opt2->answer, TRUE);
 
249
    color = D_parse_color(opt_color->answer, TRUE);
199
250
 
200
 
    if (opt4->answer != NULL)
201
 
        sscanf(opt4->answer, "%d", &lines);
 
251
    if (opt_lines->answer != NULL)
 
252
        sscanf(opt_lines->answer, "%d", &lines);
202
253
 
203
254
    thin = 1;
204
 
    if (opt5->answer != NULL)
205
 
        sscanf(opt5->answer, "%d", &thin);
 
255
    if (opt_thin->answer != NULL)
 
256
        sscanf(opt_thin->answer, "%d", &thin);
206
257
    if (!thin)
207
258
        thin = 1;
208
259
 
209
 
    if (opt6->answer != NULL)
210
 
        sscanf(opt6->answer, "%d", &steps);
 
260
    if (opt_labelnum->answer != NULL)
 
261
        sscanf(opt_labelnum->answer, "%d", &steps);
211
262
 
212
263
    catlistCount = 0;
213
 
    if (opt8->answer != NULL) { /* should this be answerS ? */
 
264
    if (opt_use->answer != NULL) {      /* should this be answerS ? */
214
265
        use_catlist = TRUE;
215
266
 
216
267
        catlist = (double *)G_calloc(100 + 1, sizeof(double));
218
269
            catlist[i] = 1.0 * (i + 1);
219
270
        catlist[i] = 0;
220
271
 
221
 
        for (i = 0; (opt8->answers[i] != NULL) && i < 100; i++)
222
 
            catlist[i] = atof(opt8->answers[i]);
 
272
        for (i = 0; (opt_use->answers[i] != NULL) && i < 100; i++)
 
273
            catlist[i] = atof(opt_use->answers[i]);
223
274
 
224
275
        catlistCount = i;
225
276
    }
228
279
 
229
280
 
230
281
    UserRange = FALSE;
231
 
    if (opt9->answer != NULL) { /* should this be answerS ? */
232
 
        sscanf(opt9->answers[0], "%lf", &UserRangeMin);
233
 
        sscanf(opt9->answers[1], "%lf", &UserRangeMax);
 
282
    if (opt_range->answer != NULL) {    /* should this be answerS ? */
 
283
        sscanf(opt_range->answers[0], "%lf", &UserRangeMin);
 
284
        sscanf(opt_range->answers[1], "%lf", &UserRangeMax);
234
285
        UserRange = TRUE;
235
286
        if (UserRangeMin > UserRangeMax) {
236
287
            UserRangeTemp = UserRangeMax;
240
291
        }
241
292
    }
242
293
 
243
 
 
244
 
    /* Make sure map is available */
245
 
    mapset = G_find_cell2(map_name, "");
246
 
    if (mapset == NULL)
247
 
        G_fatal_error(_("Raster map <%s> not found"), map_name);
248
 
 
249
 
    if (G_read_colors(map_name, mapset, &colors) == -1)
250
 
        G_fatal_error(_("Color file for <%s> not available"), map_name);
251
 
 
252
 
    fp = G_raster_map_is_fp(map_name, mapset);
 
294
    if (maptype == MAP_TYPE_RASTER2D) {
 
295
        if (Rast_read_colors(map_name, "", &colors) == -1)
 
296
            G_fatal_error(_("Color file for <%s> not available"), map_name);
 
297
 
 
298
        fp = Rast_map_is_fp(map_name, "");
 
299
 
 
300
        Rast_read_cats(map_name, "", &cats);
 
301
    }
 
302
    else {
 
303
        if (Rast3d_read_colors(map_name, "", &colors) == -1)
 
304
            G_fatal_error(_("Color file for <%s> not available"), map_name);
 
305
 
 
306
        fp = TRUE;  /* currently raster 3D is always floating point */
 
307
 
 
308
        Rast3d_read_cats(map_name, "", &cats);
 
309
    }
 
310
 
253
311
    if (fp && !use_catlist) {
254
312
        do_smooth = TRUE;
255
313
        /* fprintf(stderr, "FP map found - switching gradient legend on\n"); */
256
314
        flip = !flip;
257
315
    }
258
316
 
259
 
    if (G_read_cats(map_name, mapset, &cats) == -1)
260
 
        G_warning(_("Category file for <%s> not available"), map_name);
261
 
 
262
 
    G_set_c_null_value(&null_cell, 1);
263
 
 
264
 
    if (R_open_driver() != 0)
265
 
        G_fatal_error(_("No graphics device selected"));
266
 
 
267
 
    if (D_get_cur_wind(window_name))
268
 
        G_fatal_error(_("No current window"));
269
 
 
270
 
    if (D_set_cur_wind(window_name))
271
 
        G_fatal_error(_("Current window not available"));
 
317
    D_open_driver();
272
318
 
273
319
    white = D_translate_color(DEFAULT_FG_COLOR);
274
320
    black = D_translate_color(DEFAULT_BG_COLOR);
275
321
 
 
322
    if (opt_font->answer)
 
323
        D_font(opt_font->answer);
 
324
    else if (opt_path->answer)
 
325
        D_font(opt_path->answer);
 
326
 
 
327
    if (opt_fontsize->answer != NULL)
 
328
        fontsize = atof(opt_fontsize->answer);
 
329
    else
 
330
        fontsize = 12; /* dummy placeholder, should never be called */
 
331
 
 
332
    if (opt_charset->answer)
 
333
        D_encoding(opt_charset->answer);
 
334
 
276
335
    /* Figure out where to put text */
277
 
    D_get_screen_window(&t, &b, &l, &r);
278
 
    R_set_window(t, b, l, r);
279
 
 
280
 
    if (use_mouse) {
281
 
        if (!get_legend_box(&x0, &x1, &y0, &y1))
282
 
            exit(EXIT_SUCCESS);
283
 
        G_debug(1, "mouse placement as percentage of display window "
284
 
                "[bottom,top,left,right]:\n  \"at=%.2f,%.2f,%.2f,%.2f\"",
285
 
                100. * (b - y1) / (b - t), 100. * (b - y0) / (b - t),
286
 
                100. * x0 / (r - l), 100. * x1 / (r - l));
287
 
 
288
 
        Y1 = 100. - (y1 - t) * 100. / (b - t);
289
 
        Y0 = 100. - (y0 - t) * 100. / (b - t);
290
 
        X0 = (x0 - l) * 100. / (r - l);
291
 
        X1 = (x1 - l) * 100. / (r - l);
292
 
    }
293
 
    else {
294
 
        if (opt7->answer != NULL) {
295
 
            sscanf(opt7->answers[0], "%lf", &Y1);
296
 
            sscanf(opt7->answers[1], "%lf", &Y0);
297
 
            sscanf(opt7->answers[2], "%lf", &X0);
298
 
            sscanf(opt7->answers[3], "%lf", &X1);
299
 
        }
300
 
        else {                  /* default */
301
 
            Y1 = 12;
302
 
            Y0 = 88;
303
 
            X0 = 3;
304
 
            X1 = 7;
305
 
        }
306
 
 
307
 
        x0 = l + (int)((r - l) * X0 / 100.);
308
 
        x1 = l + (int)((r - l) * X1 / 100.);
309
 
        y0 = t + (int)((b - t) * (100. - Y0) / 100.);   /* make lower left the origin */
310
 
        y1 = t + (int)((b - t) * (100. - Y1) / 100.);
311
 
    }
 
336
    D_setup_unity(0);
 
337
    D_get_src(&t, &b, &l, &r);
 
338
 
 
339
    if (opt_at->answer != NULL) {
 
340
        sscanf(opt_at->answers[0], "%lf", &Y1);
 
341
        sscanf(opt_at->answers[1], "%lf", &Y0);
 
342
        sscanf(opt_at->answers[2], "%lf", &X0);
 
343
        sscanf(opt_at->answers[3], "%lf", &X1);
 
344
    }
 
345
    else {                      /* default */
 
346
        Y1 = 12;
 
347
        Y0 = 88;
 
348
        X0 = 3;
 
349
        X1 = 7;
 
350
 
 
351
        if (histo->answer) {
 
352
            X0 += 5;
 
353
            X1 += 5;
 
354
        }
 
355
    }
 
356
 
 
357
    x0 = l + (int)((r - l) * X0 / 100.);
 
358
    x1 = l + (int)((r - l) * X1 / 100.);
 
359
    y0 = t + (int)((b - t) * (100. - Y0) / 100.);  /* make lower left the origin */
 
360
    y1 = t + (int)((b - t) * (100. - Y1) / 100.);
312
361
 
313
362
    if (y0 > y1) {              /* allow for variety in order of corner */
314
363
        flip = !flip;           /*   selection without broken output    */
342
391
 
343
392
    /* How many categories to show */
344
393
    if (!fp) {
345
 
        if (G_read_range(map_name, mapset, &range) == -1)
 
394
        if (Rast_read_range(map_name, "", &range) == -1)
346
395
            G_fatal_error(_("Range information for <%s> not available (run r.support)"),
347
396
                          map_name);
348
397
 
349
 
        G_get_range_min_max(&range, &min_ind, &max_ind);
350
 
        if (G_is_c_null_value(&min_ind))
 
398
        Rast_get_range_min_max(&range, &min_ind, &max_ind);
 
399
        if (Rast_is_c_null_value(&min_ind))
351
400
            G_fatal_error(_("Input map contains no data"));
352
401
 
353
 
        G_get_color_range(&min_colr, &max_colr, &colors);
 
402
        Rast_get_c_color_range(&min_colr, &max_colr, &colors);
354
403
 
355
404
        if (UserRange) {
356
405
            if (min_ind < UserRangeMin)
361
410
                min_ind =
362
411
                    UserRangeMin <
363
412
                    min_colr ? min_colr : (int)ceil(UserRangeMin);
364
 
                G_warning(_("Color range exceeds lower limit of actual data"));
 
413
                G_warning(_("Requested range exceeds lower limit of actual data"));
365
414
            }
366
415
            if (max_ind < UserRangeMax) {
367
416
                max_ind =
368
417
                    UserRangeMax >
369
418
                    max_colr ? max_colr : (int)floor(UserRangeMax);
370
 
                G_warning(_("Color range exceeds upper limit of actual data"));
 
419
                G_warning(_("Requested range exceeds upper limit of actual data"));
371
420
            }
372
421
        }
373
422
 
395
444
        for (i = min_ind, j = 1, k = 0; j <= do_cats && i <= max_ind;
396
445
             j++, i += thin) {
397
446
            if (!flip)
398
 
                cstr = G_get_cat(i, &cats);
399
 
            else
400
 
                cstr = G_get_cat((max_ind - (i - min_ind)), &cats);
 
447
                cstr = Rast_get_c_cat(&i, &cats);
 
448
            else {
 
449
                CELL cat = max_ind - (i - min_ind);
 
450
                cstr = Rast_get_c_cat(&cat, &cats);
 
451
            }
401
452
 
402
453
            if (!use_catlist)
403
454
                catlist[j - 1] = (double)i;
414
465
            if (!hide_catnum)
415
466
                if (i > maxCat)
416
467
                    maxCat = (double)i;
417
 
            k++;                /* count of actual boxes drawn (hide_nodata option invaidates using j-1) */
 
468
            k++;        /* count of actual boxes drawn (hide_nodata option invaidates using j-1) */
418
469
        }
419
470
        lines = k;
420
471
 
425
476
            for (i = 0, k = 0; i < catlistCount; i++) {
426
477
                if ((catlist[i] < min_ind) || (catlist[i] > max_ind)) {
427
478
                    G_fatal_error(_("use=%s out of range [%d,%d] (extend with range= ?)"),
428
 
                                  opt8->answers[i], min_ind, max_ind);
 
479
                                  opt_use->answers[i], min_ind, max_ind);
429
480
                }
430
481
 
431
 
                cstr = G_get_cat(catlist[i], &cats);
 
482
                cstr = Rast_get_d_cat(&catlist[i], &cats);
432
483
                if (!cstr[0]) { /* no cat label found, skip str output */
433
484
                    if (hide_nodata)
434
485
                        continue;
473
524
 
474
525
        /* switch to a smooth legend for CELL maps with too many cats */
475
526
        /*  an alternate solution is to set   dots_per_line=1         */
476
 
        if ((dots_per_line == 0) && (do_smooth == 0)) {
 
527
        if ((dots_per_line == 0) && (do_smooth == FALSE)) {
477
528
            if (!use_catlist) {
478
529
                G_message(_("Forcing a smooth legend: too many categories for current window height"));
479
 
                do_smooth = 1;
 
530
                do_smooth = TRUE;
480
531
            }
481
532
        }
482
533
 
483
534
        /* center really tiny legends */
484
 
        if (!use_mouse && opt7->answer == NULL) {       /* if defualt scaling */
 
535
        if (opt_at->answer == NULL) {   /* if defualt scaling */
485
536
            if (!do_smooth && (dots_per_line < 4))      /* if so small that there's no box */
486
537
                if ((b - (dots_per_line * lines)) / (b * 1.0) > 0.15)   /* if there's more than a 15% blank at the bottom */
487
538
                    y0 = ((b - t) - (dots_per_line * lines)) / 2;
488
539
        }
489
540
 
490
 
        /*      R_text_size((int)(dots_per_line*4/5), (int)(dots_per_line*4/5)) ;    redundant */
491
 
        /* if(G_is_c_null_value(&min_ind) && G_is_c_null_value(&max_ind))
 
541
        /* D_text_size(dots_per_line*4/5., dots_per_line*4/5.);    redundant */
 
542
        /* if(Rast_is_c_null_value(&min_ind) && Rast_is_c_null_value(&max_ind))
492
543
           {
493
544
           min_ind = 1;
494
545
           max_ind = 0;
503
554
                sprintf(DispFormat, "%%2d");
504
555
        }
505
556
    }
506
 
    else {                      /* is fp */
507
 
        if (G_read_fp_range(map_name, mapset, &fprange) == -1)
508
 
            G_fatal_error(_("Range information for <%s> not available"),
509
 
                          map_name);
510
 
 
511
 
        G_get_fp_range_min_max(&fprange, &dmin, &dmax);
512
 
 
513
 
        G_get_d_color_range(&min_dcolr, &max_dcolr, &colors);
 
557
    else {      /* is fp */
 
558
        if (maptype == MAP_TYPE_RASTER2D) {
 
559
            if (Rast_read_fp_range(map_name, "", &fprange) == -1)
 
560
                G_fatal_error(_("Range information for <%s> not available"),
 
561
                                map_name);
 
562
        }
 
563
        else {
 
564
            if (Rast3d_read_range(map_name, "", &fprange) == -1)
 
565
                G_fatal_error(_("Range information for <%s> not available"),
 
566
                                map_name);
 
567
        }
 
568
 
 
569
        Rast_get_fp_range_min_max(&fprange, &dmin, &dmax);
 
570
        Rast_get_d_color_range(&min_dcolr, &max_dcolr, &colors);
514
571
 
515
572
        if (UserRange) {
516
573
            if (dmin < UserRangeMin)
531
588
            for (i = 0; i < catlistCount; i++) {
532
589
                if ((catlist[i] < dmin) || (catlist[i] > dmax)) {
533
590
                    G_fatal_error(_("use=%s out of range [%.3f, %.3f] (extend with range= ?)"),
534
 
                                  opt8->answers[i], dmin, dmax);
 
591
                                  opt_use->answers[i], dmin, dmax);
535
592
                }
536
 
                if (strlen(opt8->answers[i]) > MaxLabelLen)
537
 
                    MaxLabelLen = strlen(opt8->answers[i]);
 
593
                if (strlen(opt_use->answers[i]) > MaxLabelLen)
 
594
                    MaxLabelLen = strlen(opt_use->answers[i]);
538
595
            }
539
596
        }
540
597
        do_cats = 0;            /* if only to get rid of the compiler warning  */
557
614
        cats_num = catlistCount;
558
615
        do_cats = catlistCount;
559
616
        lines = catlistCount;
560
 
        do_smooth = 0;
 
617
        do_smooth = FALSE;
561
618
    }
562
619
 
 
620
 
563
621
    if (do_smooth) {
564
622
        int wleg, lleg, dx, dy;
565
 
        int txsiz;
 
623
        double txsiz;
566
624
        int ppl;
567
625
        int tcell;
568
626
        float ScaleFactor = 1.0;
601
659
            }
602
660
 
603
661
            if (dx < dy)
604
 
                R_box_abs(x0 + k, y0, x0 + k + (dx ? -dx : 1),
 
662
                D_box_abs(x0 + k, y0, x0 + k + (dx ? -dx : 1),
605
663
                          y0 - (dy ? -dy : 1));
606
664
            else
607
 
                R_box_abs(x0, y0 + k, x0 - (dx ? -dx : 1),
 
665
                D_box_abs(x0, y0 + k, x0 - (dx ? -dx : 1),
608
666
                          y0 + k + (dy ? -dy : 1));
609
667
        }
610
668
 
627
685
                        max_ind - k * (double)(max_ind - min_ind) / (steps -
628
686
                                                                     1);
629
687
 
630
 
                cstr = G_get_cat(tcell, &cats);
 
688
                cstr = Rast_get_c_cat(&tcell, &cats);
 
689
 
631
690
                if (!cstr[0])   /* no cats found, disable str output */
632
691
                    hide_catstr = 1;
633
692
                else
656
715
                }
657
716
            }
658
717
 
659
 
            /* this probably shouldn't happen mid-loop as text sizes 
 
718
            /* this probably shouldn't happen mid-loop as text sizes
660
719
               might not end up being uniform, but it's a start */
661
720
            if (strlen(buff) > MaxLabelLen)
662
721
                MaxLabelLen = strlen(buff);
663
722
 
664
723
            /* Draw text */
665
724
            if (!horiz)
666
 
                txsiz = (int)((y1 - y0) / 20);
 
725
                txsiz = (y1 - y0) / 20;
667
726
            else
668
 
                txsiz = (int)((x1 - x0) / 20);
 
727
                txsiz = (x1 - x0) / 20;
669
728
 
670
729
            /* scale text to fit in window if position not manually set */
671
730
            /* usually not needed, except when frame is really narrow   */
672
 
            if (!use_mouse && opt7->answer == NULL) {   /* ie defualt scaling */
 
731
            if (opt_at->answer == NULL) {       /* ie default scaling */
673
732
                ScaleFactor = ((r - x1) / ((MaxLabelLen + 1) * txsiz * 0.81));  /* ?? txsiz*.81=actual text width. */
674
733
                if (ScaleFactor < 1.0) {
675
 
                    txsiz = (int)(txsiz * ScaleFactor);
 
734
                    txsiz = txsiz * ScaleFactor;
676
735
                }
677
736
            }
678
737
 
 
738
            if (opt_fontsize->answer != NULL)
 
739
                txsiz = fontsize;
 
740
 
679
741
            if (txsiz < 0)
680
742
                txsiz = 0;      /* keep it sane */
681
743
 
682
 
            R_text_size(txsiz, txsiz);
683
 
            D_raster_use_color(color);
 
744
            D_text_size(txsiz, txsiz);
 
745
            D_use_color(color);
684
746
 
685
747
            ppl = (lleg) / (steps - 1);
686
748
 
687
749
            if (!horiz) {
688
750
                if (!k)         /* first  */
689
 
                    R_move_abs(x1 + 4, y0 + txsiz);
 
751
                    D_pos_abs(x1 + 4, y0 + txsiz);
690
752
                else if (k == steps - 1)        /* last */
691
 
                    R_move_abs(x1 + 4, y1);
 
753
                    D_pos_abs(x1 + 4, y1);
692
754
                else
693
 
                    R_move_abs(x1 + 4, y0 + ppl * k + txsiz / 2);
 
755
                    D_pos_abs(x1 + 4, y0 + ppl * k + txsiz / 2);
694
756
            }
695
757
            else {
696
 
                /* text width is 0.81 of text height? so even though we set width 
697
 
                   to txsiz with R_text_size(), we still have to reduce.. hmmm */
 
758
                /* text width is 0.81 of text height? so even though we set width
 
759
                   to txsiz with D_text_size(), we still have to reduce.. hmmm */
698
760
                if (!k)         /* first  */
699
 
                    R_move_abs(x0 - (strlen(buff) * txsiz * .81 / 2),
700
 
                               y1 + 4 + txsiz);
 
761
                    D_pos_abs(x0 - (strlen(buff) * txsiz * .81 / 2),
 
762
                              y1 + 4 + txsiz);
701
763
                else if (k == steps - 1)        /* last */
702
 
                    R_move_abs(x1 - (strlen(buff) * txsiz * .81 / 2),
703
 
                               y1 + 4 + txsiz);
 
764
                    D_pos_abs(x1 - (strlen(buff) * txsiz * .81 / 2),
 
765
                              y1 + 4 + txsiz);
704
766
                else
705
 
                    R_move_abs(x0 + ppl * k -
706
 
                               (strlen(buff) * txsiz * .81 / 2),
707
 
                               y1 + 4 + txsiz);
 
767
                    D_pos_abs(x0 + ppl * k -
 
768
                              (strlen(buff) * txsiz * .81 / 2),
 
769
                              y1 + 4 + txsiz);
708
770
            }
709
771
 
710
 
            if(color)
711
 
                R_text(buff);
 
772
            if (color)
 
773
                D_text(buff);
712
774
 
713
 
        }                       /*for */
 
775
        }       /* for */
714
776
 
715
777
        lleg = y1 - y0;
716
778
        wleg = x1 - x0;
717
779
 
718
780
        /* Black box */
719
 
        R_standard_color(black);
720
 
        R_move_abs(x0 + 1, y0 + 1);
721
 
        R_cont_rel(0, lleg - 2);
722
 
        R_cont_rel(wleg - 2, 0);
723
 
        R_cont_rel(0, 2 - lleg);
724
 
        R_cont_rel(2 - wleg, 0);
 
781
        D_use_color(black);
 
782
        D_begin();
 
783
        D_move_abs(x0 + 1, y0 + 1);
 
784
        D_cont_rel(0, lleg - 2);
 
785
        D_cont_rel(wleg - 2, 0);
 
786
        D_cont_rel(0, 2 - lleg);
 
787
        D_close();
 
788
        D_end();
 
789
        D_stroke();
725
790
 
726
791
        /* White box */
727
 
        R_standard_color(white);
728
 
        R_move_abs(x0, y0);
729
 
        R_cont_rel(0, lleg);
730
 
        R_cont_rel(wleg, 0);
731
 
        R_cont_rel(0, -lleg);
732
 
        R_cont_rel(-wleg, 0);
 
792
        D_use_color(white);
 
793
        D_begin();
 
794
        D_move_abs(x0, y0);
 
795
        D_cont_rel(0, lleg);
 
796
        D_cont_rel(wleg, 0);
 
797
        D_cont_rel(0, -lleg);
 
798
        D_close();
 
799
        D_end();
 
800
        D_stroke();
 
801
 
 
802
 
 
803
        /* print units label, if present */
 
804
        if (maptype == MAP_TYPE_RASTER2D)
 
805
            units = Rast_read_units(map_name, "");
 
806
        else
 
807
            units = "";
 
808
/* FIXME: does the raster3d really need to be opened to read the units?
 
809
            units = Rast3d_get_unit(map_fid); */
 
810
 
 
811
        if (!units)
 
812
            units = "";
 
813
 
 
814
        if(strlen(units)) {
 
815
            double x_pos, y_pos;
 
816
            int default_pos = TRUE;
 
817
 
 
818
            D_use_color(color);
 
819
            /* D_text_size() should be already set */
 
820
 
 
821
            if (horiz) {
 
822
                x_pos = (x0 + x1)/2. - (strlen(units) * txsiz * 0.81)/2;
 
823
                y_pos = y1 + (txsiz * 3);
 
824
            }
 
825
            else {
 
826
                x_pos = x1 - 4;
 
827
                if (default_pos)
 
828
                    y_pos = y0 - (txsiz * 1.75);
 
829
                else
 
830
                    y_pos = y1 + (txsiz * 2.75);
 
831
            }
 
832
 
 
833
            D_pos_abs(x_pos, y_pos);
 
834
            D_text(units);
 
835
        }
 
836
 
 
837
 
 
838
        /* display sidebar histogram, if requested */
 
839
        if (histo->answer) {
 
840
            if (opt_range->answer != NULL)
 
841
                G_warning(_("Histogram constrained by range not yet implemented"));
 
842
            else
 
843
                draw_histogram(map_name, x0, y0, wleg, lleg, color, flip,
 
844
                               horiz, maptype, fp);
 
845
        }
733
846
 
734
847
    }
735
 
    else {                      /* non FP, no smoothing */
 
848
    else {      /* non FP, no smoothing */
736
849
 
737
 
        int txsiz, true_l, true_r;
 
850
        int true_l, true_r;
 
851
        double txsiz;
738
852
        float ScaleFactor = 1.0;
739
853
 
740
854
        /* set legend box bounds */
741
855
        true_l = l;
742
 
        true_r = r;             /* preserve window width */
 
856
        true_r = r;     /* preserve window width */
743
857
        l = x0;
744
858
        t = y0;
745
859
        r = x1;
746
860
        b = y1;
747
861
 
748
 
        R_move_abs(x0, y0);
 
862
        D_pos_abs(x0, y0);
749
863
 
750
864
        /* figure out box height  */
751
865
        if (do_cats == cats_num)
754
868
            dots_per_line = (b - t) / (lines + 2);      /* + another line for 'x of y categories' text */
755
869
 
756
870
        /* adjust text size */
757
 
        /*      txsiz = (int)((y1-y0)/(1.5*(lines+5))); */
758
 
        txsiz = (int)((y1 - y0) / (2.0 * lines));
 
871
        /*  txsiz = (int)((y1-y0)/(1.5*(lines+5))); */
 
872
        txsiz = (y1 - y0) / (2.0 * lines);
759
873
 
760
874
        /* scale text to fit in window if position not manually set */
761
 
        if (!use_mouse && opt7->answer == NULL) {       /* ie defualt scaling */
 
875
        if (opt_at->answer == NULL) {   /* ie defualt scaling */
762
876
            ScaleFactor = ((true_r - true_l) / ((MaxLabelLen + 3) * txsiz * 0.81));     /* ?? txsiz*.81=actual text width. */
763
877
            if (ScaleFactor < 1.0) {
764
 
                txsiz = (int)floor(txsiz * ScaleFactor);
 
878
                txsiz = txsiz * ScaleFactor;
765
879
                dots_per_line = (int)floor(dots_per_line * ScaleFactor);
766
880
            }
767
881
        }
769
883
        if (dots_per_line < txsiz)
770
884
            txsiz = dots_per_line;
771
885
 
772
 
        R_text_size(txsiz, txsiz);
 
886
        if (opt_fontsize->answer != NULL)
 
887
            txsiz = fontsize;
 
888
 
 
889
        D_text_size(txsiz, txsiz);
773
890
 
774
891
 
775
892
        /* Set up box arrays */
798
915
            /*              for(i=min_ind, j=1, k=0; j<=do_cats && i<=max_ind; j++, i+=thin)        */
799
916
        {
800
917
            if (!flip)
801
 
                cstr = G_get_cat(catlist[i], &cats);
 
918
                cstr = Rast_get_d_cat(&catlist[i], &cats);
802
919
            else
803
 
                cstr = G_get_cat(catlist[catlistCount - i - 1], &cats);
 
920
                cstr = Rast_get_d_cat(&catlist[catlistCount - i - 1], &cats);
804
921
 
805
922
 
806
923
            if (!cstr[0]) {     /* no cat label found, skip str output */
814
931
            k++;                /* count of actual boxes drawn (hide_nodata option invaidates using j-1) */
815
932
 
816
933
            /* White box */
817
 
            R_standard_color(white);
818
934
            cur_dot_row += dots_per_line;
819
 
            R_move_abs(l + 2, (cur_dot_row - 1));
820
 
            R_cont_rel(0, (2 - dots_per_line));
821
 
            R_cont_rel((dots_per_line - 2), 0);
822
 
            R_cont_rel(0, (dots_per_line - 2));
823
 
            R_cont_rel((2 - dots_per_line), 0);
 
935
            D_use_color(white);
 
936
            D_begin();
 
937
            D_move_abs(l + 2, (cur_dot_row - 1));
 
938
            D_cont_rel(0, (3 - dots_per_line));
 
939
            D_cont_rel((dots_per_line - 3), 0);
 
940
            D_cont_rel(0, (dots_per_line - 3));
 
941
            D_close();
 
942
            D_end();
 
943
            D_stroke();
824
944
 
825
945
            /* Black box */
826
 
            R_standard_color(black);
827
 
            R_move_abs(l + 3, (cur_dot_row - 2));
828
 
            R_cont_rel(0, (4 - dots_per_line));
829
 
            R_cont_rel((dots_per_line - 4), 0);
830
 
            R_cont_rel(0, (dots_per_line - 4));
831
 
            R_cont_rel((4 - dots_per_line), 0);
 
946
            D_use_color(black);
 
947
            D_begin();
 
948
            D_move_abs(l + 3, (cur_dot_row - 2));
 
949
            D_cont_rel(0, (5 - dots_per_line));
 
950
            D_cont_rel((dots_per_line - 5), 0);
 
951
            D_cont_rel(0, (dots_per_line - 5));
 
952
            D_close();
 
953
            D_end();
 
954
            D_stroke();
832
955
 
833
956
            /* Color solid box */
834
957
            if (!fp) {
845
968
                    D_d_color(catlist[catlistCount - i - 1], &colors);
846
969
            }
847
970
 
848
 
            R_move_abs(l + 4, (cur_dot_row - 2));
849
 
            R_polygon_rel(x_box, y_box, 5);
 
971
            D_pos_abs(l + 3, (cur_dot_row - 2));
 
972
            D_polygon_rel(x_box, y_box, 5);
850
973
 
851
974
            /* Draw text */
852
 
            D_raster_use_color(color);
 
975
            D_use_color(color);
853
976
 
854
977
            if (!fp) {
855
978
                /* nothing, box only */
869
992
            }
870
993
            else {              /* is fp */
871
994
                if (!flip) {
872
 
                    if(use_catlist)
 
995
                    if (use_catlist)
873
996
                        /* pass through format exactly as given by the user in
874
997
                           the use= command line parameter (helps with log scale) */
875
 
                        sprintf(buff, "%s", opt8->answers[i]);
876
 
                    else 
 
998
                        sprintf(buff, "%s", opt_use->answers[i]);
 
999
                    else
877
1000
                        /* automatically generated/tuned decimal precision format */
878
1001
                        sprintf(buff, DispFormat, catlist[i]);
879
1002
                }
880
1003
                else {
881
1004
                    if(use_catlist)
882
 
                        sprintf(buff, "%s", opt8->answers[catlistCount - i - 1]);
 
1005
                        sprintf(buff, "%s", opt_use->answers[catlistCount - i - 1]);
883
1006
                    else
884
1007
                        sprintf(buff, DispFormat, catlist[catlistCount - i - 1]);
885
1008
                }
886
1009
            }
887
1010
 
888
 
            R_move_abs((l + 3 + dots_per_line), (cur_dot_row) - 3);
 
1011
            D_pos_abs((l + 3 + dots_per_line), (cur_dot_row) - 3);
889
1012
 
890
 
            if(color)
891
 
                R_text(buff);
 
1013
            if (color)
 
1014
                D_text(buff);
892
1015
        }
893
1016
 
894
1017
        if (0 == k)
897
1020
 
898
1021
        if (do_cats != cats_num) {
899
1022
            cur_dot_row += dots_per_line;
900
 
            /*          sprintf(buff, "%d of %d categories\n", (j-1), cats_num) ;   */
 
1023
            /* sprintf(buff, "%d of %d categories\n", (j-1), cats_num); */
901
1024
 
902
1025
            sprintf(buff, "%d of %d categories\n", k, cats_num);
903
1026
 
905
1028
            MaxLabelLen = strlen(buff) + 4;
906
1029
            ScaleFactor = ((true_r - true_l) / (MaxLabelLen * txsiz * 0.81));   /* ?? txsiz*.81=actual text width. */
907
1030
            if (ScaleFactor < 1.0) {
908
 
                txsiz = (int)floor(txsiz * ScaleFactor);
909
 
                R_text_size(txsiz, txsiz);
 
1031
                txsiz = txsiz * ScaleFactor;
 
1032
 
 
1033
                if (opt_fontsize->answer != NULL)
 
1034
                    txsiz = fontsize;
 
1035
 
 
1036
                D_text_size(txsiz, txsiz);
910
1037
            }
911
 
            R_standard_color(white);
912
 
            R_move_abs((l + 3 + dots_per_line), (cur_dot_row));
913
 
            if(color)
914
 
                R_text(buff);
 
1038
            D_use_color(white);
 
1039
            D_pos_abs((l + 3 + dots_per_line), (cur_dot_row));
 
1040
            if (color)
 
1041
                D_text(buff);
915
1042
        }
916
1043
    }
917
 
    if (use_mouse) {
918
 
        char buf[512];
919
 
 
920
 
        mouse->answer = 0;
921
 
        sprintf(buf, "%s at=%.2f,%.2f,%.2f,%.2f", G_recreate_command(),
922
 
                Y1, Y0, X0, X1);
923
 
        D_add_to_list(buf);
924
 
    }
925
 
    else
926
 
        D_add_to_list(G_recreate_command());
927
 
 
928
 
    R_close_driver();
 
1044
 
 
1045
    D_save_command(G_recreate_command());
 
1046
    D_close_driver();
 
1047
 
929
1048
    exit(EXIT_SUCCESS);
930
1049
}