GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-f9cfab5903
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gsd_legend.c
Go to the documentation of this file.
1 /*!
2  \file lib/ogsf/gsd_legend.c
3 
4  \brief OGSF library - legend creation
5 
6  GRASS OpenGL gsurf OGSF Library
7 
8  Converted code from legend.c in SG3d
9  routines to set viewport, close viewport, and make legend
10 
11  (C) 1999-2008 by the GRASS Development Team
12 
13  This program is free software under the
14  GNU General Public License (>=v2).
15  Read the file COPYING that comes with GRASS
16  for details.
17 
18  \author Bill Brown USACERL
19  \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
20  */
21 
22 #include <stdlib.h>
23 
24 #include <grass/config.h>
25 
26 #if defined(OPENGL_X11) || defined(OPENGL_WINDOWS)
27 #include <GL/gl.h>
28 #include <GL/glu.h>
29 #elif defined(OPENGL_AQUA)
30 #include <OpenGL/gl.h>
31 #include <OpenGL/glu.h>
32 #endif
33 
34 #include <grass/gis.h>
35 #include <grass/raster.h>
36 #include <grass/glocale.h>
37 #include <grass/ogsf.h>
38 
39 #include "rgbpack.h"
40 
41 static float *Listcats;
42 static int Listnum = 0;
43 
44 /**** TODO
45 static int bigger(float *f1, float *f2)
46 {
47  return (*f1 < *f2 ? -1 : (*f1 > *f2));
48 }
49 *****/
50 
51 #define MAX_LEGEND 256
52 
53 /*!
54  \brief ADD
55 
56  \param wl
57  \param wb
58  \param wr
59  \param wt
60  */
61 void gsd_bgn_legend_viewport(GLint wl, GLint wb, GLint wr, GLint wt)
62 {
63  /* sets the viewport for the legend and the model matrix */
64 
66  glPushAttrib(GL_VIEWPORT);
67 
68  glMatrixMode(GL_PROJECTION);
69 
72  GS_ready_draw();
73 
74  gsd_linewidth(1);
75 
76  gsd_popmatrix();
77 
78  glViewport(wl, wb, (wr - wl), (wt - wb));
79  glLoadIdentity();
80  gluOrtho2D(-0.5, (wr - wl) + 0.5, -0.5, (wt - wb) + 0.5);
81  glMatrixMode(GL_MODELVIEW);
82  glPushMatrix();
83  glLoadIdentity();
84 
85  return;
86 }
87 
88 /*!
89  \brief ADD
90  */
92 {
93  /* closes the legend viewport and resets matrix and buffers */
94 
95  gsd_popmatrix();
96  glMatrixMode(GL_PROJECTION);
97  gsd_popmatrix();
98 
99  glPopAttrib();
100  glMatrixMode(GL_MODELVIEW);
101  gsd_popmatrix();
102 
103  GS_done_draw();
105 
106  return;
107 }
108 
109 /*!
110  \brief ADD
111 
112  \param lownum
113  \param highnum
114  \param numvals
115  \param vals
116 
117  \return 0 on failure
118  \return range value
119  */
120 int gsd_get_nice_range(float lownum, float highnum, int numvals, float *vals)
121 {
122  /* get a nice range for displaying legend */
123 
124  int num = 0;
125  float curnum, step, start;
126 
127  if (!numvals)
128  return (0);
129 
130  step = (highnum - lownum) / (float)numvals;
131  gsd_make_nice_number(&step);
132 
133  /* get a starting point */
134  start = step * (int)(1 + lownum / step);
135  if (start - lownum < .65 * step)
136  start += step;
137 
138  for (curnum = start; curnum < (highnum - .65 * step); curnum += step) {
139  vals[num++] = curnum;
140  }
141 
142  return (num);
143 }
144 
145 /*!
146  \brief ADD
147 
148  \param num
149 
150  \return 0 on error
151  \return 1 on success
152  */
153 int gsd_make_nice_number(float *num)
154 {
155  float newnum, nextnum;
156 
157  if (*num < 0)
158  return (0);
159 
160  if (*num < 1) {
161  newnum = 1.;
162  while (.5 * newnum > *num) {
163  nextnum = newnum / 10.;
164  newnum /= 2.;
165  if (.5 * newnum > *num)
166  newnum /= 2.;
167  if (.5 * newnum > *num)
168  newnum = nextnum;
169  }
170  }
171  else {
172  newnum = 1.;
173  while (2 * newnum <= *num) {
174  nextnum = newnum * 10.;
175  newnum *= 2.5;
176  if (2 * newnum <= *num)
177  newnum *= 2.;
178  if (2 * newnum <= *num)
179  newnum = nextnum;
180  }
181  if (newnum == 2.5)
182  newnum = 3;
183  /* 2.5 isn't nice, but .25, 25, 250 ... are */
184  }
185  *num = newnum;
186  return (1);
187 }
188 
189 /*!
190  \brief Put legend
191 
192  \param name
193  \param fontbase font-base
194  \param size
195  \param flags
196  \param rangef
197  \param pt
198 
199  \return
200  */
201 GLuint gsd_put_legend(const char *name, GLuint fontbase, int size, int *flags,
202  float *rangef, int *pt)
203 {
204  GLint sl, sr, sb, st;
205  GLuint legend_list;
206  int cat_labs = 0, cat_vals = 0, do_invert = 0, discrete = 0;
207  int is_fp, fprec, iprec;
208  struct Categories cats;
209  struct Range range;
210  struct FPRange fp_range;
211  const char *mapset;
212  struct Colors colors;
213  CELL min, max;
214  DCELL fmin, fmax;
215  float labvals[12];
216 
217  legend_list = gsd_makelist();
218  gsd_bgnlist(legend_list, 1);
219 
220  /* set coords from pt */
221  sl = pt[0];
222  sr = pt[1];
223  sb = pt[2];
224  st = pt[3];
225 
226  /* set legend flags */
227  if (flags[0])
228  cat_vals = 1;
229  if (flags[1])
230  cat_labs = 1;
231  if (flags[3])
232  discrete = 1;
233  if (flags[2])
234  do_invert = 1;
235 
236  mapset = G_find_raster2(name, "");
237  if (mapset == NULL) {
238  G_warning(_("Raster map <%s> not found"), name);
239  return (-1);
240  }
241 
242  is_fp = Rast_map_is_fp(name, mapset);
243 
244  if (Rast_read_colors(name, mapset, &colors) == -1) {
245  G_warning(_("Unable to read color file of raster map <%s>"), name);
246  return (-1);
247  }
248 
249  if (cat_labs)
250  if (Rast_read_cats(name, mapset, &cats) == -1) {
251  G_warning(_("Unable to read category file of raster map <%s>"),
252  name);
253  cat_labs = 0;
254  }
255 
256  if (flags[4] && rangef[0] != -9999. && rangef[1] != -9999.) {
257  fmin = rangef[0];
258  fmax = rangef[1];
259  if (!is_fp) {
260  min = (int)fmin;
261  max = (int)fmax;
262  }
263  }
264  else {
265  if (is_fp) {
266  if (Rast_read_fp_range(name, mapset, &fp_range) != 1) {
267  G_warning(_("Unable to read fp range of raster map <%s>"),
268  name);
269  return (-1);
270  }
271  Rast_get_fp_range_min_max(&fp_range, &fmin, &fmax);
272  if (flags[4] && rangef[0] != -9999.)
273  fmin = rangef[0];
274  if (flags[4] && rangef[1] != -9999.)
275  fmax = rangef[1];
276  }
277  else {
278  if (Rast_read_range(name, mapset, &range) == -1) {
279  G_warning(_("Unable to read range of raster map <%s>"), name);
280  return (-1);
281  }
282  Rast_get_range_min_max(&range, &min, &max);
283  if (flags[4] && rangef[0] != -9999.)
284  min = rangef[0];
285  if (flags[4] && rangef[1] != -9999.)
286  max = rangef[1];
287  fmin = min;
288  fmax = max;
289  }
290  }
291 
292  if (fmin == fmax)
293  G_warning(_("Range request error for legend"));
294 
295  /* set a reasonable precision */
296  if (is_fp) {
297  float df;
298 
299  df = fmax - fmin;
300  if (df < .1)
301  fprec = 6;
302  else if (df < 1)
303  fprec = 4;
304  else if (df < 10)
305  fprec = 3;
306  else if (df < 100)
307  fprec = 2;
308  else
309  fprec = 1;
310  }
311  else {
312  int tmp, p1, p2;
313 
314  iprec = p1 = p2 = 1;
315  if (max > 0)
316  for (tmp = 1; tmp < max; tmp *= 10, p1++)
317  ;
318  if (min < 0)
319  for (tmp = -1; tmp > min; tmp *= 10, p2++)
320  ;
321 
322  iprec = (p1 > p2 ? p1 : p2);
323  }
324 
325  /*********
326  * TODO incorp lists
327 
328  if(list && (legend_type & LT_LIST)){
329  Listcats = list;
330  Listnum = nlist;
331  qsort(Listcats, Listnum, sizeof(float), bigger);
332  discrete = 1;
333  }
334  else
335  Listnum = 0;
336 
337  *********/
338 
339  /* how many labels? */
340  /*
341  numlabs can't be = max - min + 1 any more because of floating point
342  maybe shouldn't allow discrete legend for floating point maps (unless
343  list) or else check number of different values in floating point map and
344  use each if "reasonable" gs_get_values_in_range(gs, att, low, high,
345  values, &nvals) the nvals sent has a max number to return, nvals returned
346  is the actual number set in values, return val is 1 on success, -1 if >
347  max vals found
348 
349  might need to think about doing histograms first & use same routines here
350  could also have a LT_MOST that would limit # to some N most frequent
351  */
352 
353  /*!
354  ???
355  */
356  {
357  int i, k, lleg, horiz;
358  int red, green, blue;
359  CELL tcell;
360  DCELL tdcell, pdcell;
361  float vert1[2], vert2[2], vert3[2], vert4[2];
362  float *dv1, *dv2; /* changing vertex coord */
363  float *sv1, *sv2; /* stable vertex coord */
364  float stab1, stab2;
365  unsigned long colr;
366  float *dividers;
367  int labw, maxlabw, numlabs;
368  float labpos, labpt[3];
369  const char *cstr;
370  char buff[80];
371  GLint wt, wb, wl, wr; /* Whole legend area, not just box */
372  int xoff, yoff;
373  int incr; /* for do_invert */
374 
375  horiz = (sr - sl > st - sb);
376  dividers = NULL;
377 
378  if (discrete) {
379  numlabs = Listnum ? Listnum : max - min + 1;
380  /* watch out for trying to display mega cats */
381  if (is_fp && !Listnum) {
382  discrete = 0; /* maybe later do stats & allow if few #s */
383  G_warning(_("Unable to show discrete FP range (use list)"));
384  return (-1);
385  }
386  if (numlabs < MAX_LEGEND)
387  dividers = (float *)G_malloc(numlabs * sizeof(float));
388  }
389  else {
390  numlabs = gsd_get_nice_range(fmin, fmax, 4, labvals + 1);
391  labvals[0] = fmin;
392  labvals[numlabs + 1] = fmax;
393  numlabs += 2;
394  }
395 
396  /* find longest string, reset viewport & saveunder */
397  maxlabw = 0;
398 
399  if (cat_labs || cat_vals) {
400  for (k = 0; k < numlabs; k++) {
401  if (is_fp) {
402  tdcell = discrete ? Listcats[k] : labvals[k];
403  if (cat_labs) {
404  cstr = Rast_get_d_cat(&tdcell, &cats);
405  }
406  if (cat_labs && !cat_vals) {
407  snprintf(buff, sizeof(buff), "%s", cstr);
408  }
409  else {
410  if (cat_labs && cat_vals) {
411  if (cstr)
412  snprintf(buff, sizeof(buff), "%.*lf) %s", fprec,
413  tdcell, cstr);
414  else
415  snprintf(buff, sizeof(buff), "%.*lf", fprec,
416  tdcell);
417  }
418  else if (cat_vals)
419  snprintf(buff, sizeof(buff), "%.*lf", fprec,
420  tdcell);
421  }
422  }
423  else {
424  tcell =
425  discrete ? Listnum ? Listcats[k] : min + k : labvals[k];
426  if (cat_labs && !cat_vals)
427  snprintf(buff, sizeof(buff), "%s",
428  Rast_get_c_cat(&tcell, &cats));
429  else {
430  if (cat_labs && cat_vals) {
431  cstr = Rast_get_c_cat(&tcell, &cats);
432  if (cstr[0])
433  snprintf(buff, sizeof(buff), "%*d) %s", iprec,
434  tcell, cstr);
435  else
436  snprintf(buff, sizeof(buff), "%d", tcell);
437  }
438  else if (cat_vals)
439  snprintf(buff, sizeof(buff), "%d", tcell);
440  }
441  }
442  labw = gsd_get_txtwidth(buff, size);
443  if (labw > maxlabw) {
444  maxlabw = labw;
445  }
446  }
447  }
448 
449  if (horiz) {
450  xoff = maxlabw / 2 + get_txtxoffset();
451  wl = sl - xoff;
452  wr = sr + xoff;
453  yoff = 0;
454  wb = sb;
455  /*
456  wt = st + gsd_get_txtheight() + get_txtdescender() +3;
457  */
458  wt = st + gsd_get_txtheight(size) * 2 + 3;
459  }
460  else {
461  xoff = 0;
462  wl = sl;
463  wr = sr + maxlabw + get_txtxoffset() + 3;
464  /*
465  yoff = gsd_get_txtheight()/2 + get_txtdescender();
466  */
467  yoff = gsd_get_txtheight(size);
468  wb = sb - yoff;
469  wt = st + yoff;
470  }
471 
472  /* initialize viewport */
473  gsd_bgn_legend_viewport(wl, wb, wr, wt);
474 
475  vert1[X] = vert2[X] = xoff;
476  vert1[Y] = vert2[Y] = yoff;
477  if (horiz) {
478  lleg = sr - sl;
479  dv1 = vert1 + X;
480  dv2 = vert2 + X;
481  sv1 = vert1 + Y;
482  sv2 = vert2 + Y;
483  stab2 = vert2[Y] = st - sb + yoff;
484  stab1 = vert1[Y] = yoff;
485  if (do_invert)
486  vert1[X] = vert2[X] = sr - sl + xoff;
487  }
488  else {
489  lleg = st - sb;
490  dv1 = vert1 + Y;
491  dv2 = vert2 + Y;
492  sv1 = vert1 + X;
493  sv2 = vert2 + X;
494  stab2 = vert2[X] = sr - sl + xoff;
495  stab1 = vert1[X] = xoff;
496  if (do_invert)
497  vert1[Y] = vert2[Y] = st - sb + yoff;
498  }
499 
500  if (discrete) {
501  if (numlabs > lleg / 5)
502  G_warning(_("Too many categories to show as discrete!"));
503  else if (numlabs > 1.2 * lleg / gsd_get_txtheight(size))
504  G_warning(_("Try using smaller font!"));
505  }
506 
507  incr = do_invert ? -1 : 1;
508  for (k = 0, i = 0; k < lleg; k++) {
509  if (discrete && Listnum)
510  tdcell = Listcats[(int)((float)k * numlabs / lleg)];
511  else {
512  tcell = min + k * (max - min + 1) / lleg;
513  tdcell = fmin + k * (fmax - fmin) / lleg;
514  if (!is_fp)
515  tdcell = tcell;
516  }
517  if (k == 0 || tdcell != pdcell) {
518  if (is_fp)
519  Rast_get_d_color(&tdcell, &red, &green, &blue, &colors);
520  else
521  Rast_get_c_color((CELL *)&tdcell, &red, &green, &blue,
522  &colors);
523 
524  RGB_TO_INT(red, green, blue, colr);
525  if (discrete) { /* draw black-white-black separator */
526  if (k > 0) {
527  *dv1 -= 2. * incr;
528  *dv2 -= 2. * incr;
529  gsd_color_func(0x0);
530  gsd_bgnline();
531  glVertex2fv(vert1);
532  glVertex2fv(vert2);
533  gsd_endline();
534 
535  *dv1 += 1. * incr;
536  *dv2 += 1. * incr;
537  if (dividers)
538  dividers[i++] = *dv1;
539 
540  *dv1 += 1. * incr;
541  *dv2 += 1. * incr;
542  gsd_color_func(0x0);
543  gsd_bgnline();
544  glVertex2fv(vert1);
545  glVertex2fv(vert2);
546  gsd_endline();
547 
548  *dv1 += 1. * incr;
549  *dv2 += 1. * incr;
550  pdcell = tdcell;
551  continue;
552  }
553  }
554  }
555 
556  gsd_color_func(colr);
557  gsd_bgnline();
558  glVertex2fv(vert1);
559  glVertex2fv(vert2);
560  gsd_endline();
561  glFlush();
562  *dv1 += 1. * incr;
563  *dv2 += 1. * incr;
564  pdcell = tdcell;
565  }
566 
567  /* Black box */
568  vert1[X] = vert2[X] = 1. + xoff;
569  vert1[Y] = vert4[Y] = 1. + yoff;
570  vert3[X] = vert4[X] = sr - sl - 1. + xoff;
571  vert3[Y] = vert2[Y] = st - sb - 1. + yoff;
572 
573  gsd_color_func(0x000000);
574  gsd_bgnline();
575  glVertex2fv(vert1);
576  glVertex2fv(vert2);
577  glVertex2fv(vert3);
578  glVertex2fv(vert4);
579  glVertex2fv(vert1);
580  gsd_endline();
581 
582  /* White box */
583  vert1[X] = vert2[X] = xoff;
584  vert1[Y] = vert4[Y] = yoff;
585  vert3[X] = vert4[X] = sr - sl + xoff;
586  vert3[Y] = vert2[Y] = st - sb + yoff;
587 
588  gsd_color_func(0xFFFFFF);
589  gsd_bgnline();
590  glVertex2fv(vert1);
591  glVertex2fv(vert2);
592  glVertex2fv(vert3);
593  glVertex2fv(vert4);
594  glVertex2fv(vert1);
595  gsd_endline();
596 
597  /* draw discrete dividers */
598  if (dividers) {
599  gsd_color_func(0xFFFFFFFF);
600  *sv1 = stab1;
601  *sv2 = stab2;
602  for (k = 0; k < i; k++) {
603  *dv1 = *dv2 = dividers[k];
604  gsd_bgnline();
605  glVertex2fv(vert1);
606  glVertex2fv(vert2);
607  gsd_endline();
608  }
609  }
610 
611  if (cat_labs || cat_vals) {
612  labpt[Z] = 0;
613  for (k = 0; k < numlabs; k++) {
614  if (is_fp) {
615  if (discrete && Listnum) {
616  tdcell = Listcats[k];
617  labpos = (k + .5) / numlabs;
618  }
619  else {
620  /* show_all not supported unless Listnum */
621  tdcell = labvals[k];
622  labpos = (tdcell - fmin) / (fmax - fmin);
623  }
624  }
625  else {
626  if (discrete && Listnum) {
627  tcell = Listcats[k];
628  labpos = (k + .5) / numlabs;
629  }
630  else {
631  tcell = discrete ? min + k : labvals[k];
632  labpos = (tcell - min + .5) / (max - min + 1);
633  }
634  }
635  if (do_invert)
636  labpos = 1. - labpos;
637  if (cat_labs) {
638  if (!is_fp)
639  cstr = Rast_get_c_cat(&tcell, &cats);
640  else
641  cstr = Rast_get_d_cat(&tdcell, &cats);
642  }
643  if (cat_labs && !cat_vals)
644  snprintf(buff, sizeof(buff), "%s", cstr);
645  else {
646  if (cat_labs && cat_vals) {
647  if (cstr)
648  if (is_fp)
649  snprintf(buff, sizeof(buff), "%.*lf) %s", fprec,
650  tdcell, cstr);
651  else
652  snprintf(buff, sizeof(buff), "%*d) %s", iprec,
653  tcell, cstr);
654  else if (is_fp)
655  snprintf(buff, sizeof(buff), "%.*lf", fprec,
656  tdcell);
657  else
658  snprintf(buff, sizeof(buff), "%d", tcell);
659  }
660  else if (cat_vals) {
661  if (is_fp)
662  snprintf(buff, sizeof(buff), "%.*lf", fprec,
663  tdcell);
664  else
665  snprintf(buff, sizeof(buff), "%d", tcell);
666  }
667  }
668  if (horiz) {
669  labpt[X] = labpos * (sr - sl) + xoff -
670  gsd_get_txtwidth(buff, size) / 2 -
671  get_txtxoffset();
672  labpt[Y] = st - sb + yoff + 3 + gsd_get_txtheight(size) / 2;
673  }
674  else {
675  labpt[X] = sr - sl + xoff + get_txtxoffset() + 3;
676  /*
677  labpt[Y] = labpos * (st - sb) + yoff -
678  gsd_get_txtheight()/2 + get_txtdescender();
679  */
680  labpt[Y] =
681  labpos * (st - sb) + yoff - gsd_get_txtheight(size);
682  }
683  /* set color for black text -- maybe add option for color
684  * supplied with font ??
685  */
686  gsd_color_func(0x000000);
687  do_label_display(fontbase, labpt, buff);
688  }
689  }
690 
691  if (discrete)
692  G_free(dividers);
693  }
694 
695  if (cat_labs)
696  Rast_free_cats(&cats);
697 
698  Rast_free_colors(&colors);
699 
701 
702  /*
703  gsd_unset_font(fontbase);
704  */
705 
706  gsd_endlist();
707 
708  return (legend_list);
709 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition: defs/gis.h:94
const char * G_find_raster2(const char *, const char *)
Find a raster map (look but don't touch)
Definition: find_rast.c:76
void gsd_endlist(void)
End list.
Definition: gsd_prim.c:1140
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:511
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2459
void do_label_display(GLuint, float *, const char *)
Display label.
Definition: gsd_fonts.c:97
void gsd_bgnlist(int, int)
ADD.
Definition: gsd_prim.c:1125
int gsd_makelist(void)
ADD.
Definition: gsd_prim.c:1094
int gsd_get_txtwidth(const char *, int)
Get text width.
Definition: gsd_fonts.c:36
int gsd_get_txtheight(int size)
Get text height.
Definition: gsd_fonts.c:53
void gsd_color_func(unsigned int)
Set current color.
Definition: gsd_prim.c:698
void GS_ready_draw(void)
Definition: gs2.c:2485
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:501
int get_txtxoffset(void)
Get text offset.
Definition: gsd_fonts.c:85
void gsd_linewidth(short)
Set width of rasterized lines.
Definition: gsd_prim.c:267
void gsd_endline(void)
End line.
Definition: gsd_prim.c:407
void gsd_colormode(int)
Set color mode.
Definition: gsd_prim.c:98
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:397
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2498
void Rast_free_cats(struct Categories *)
Free category structure memory.
Definition: raster/cats.c:1213
int Rast_get_c_color(const CELL *, int *, int *, int *, struct Colors *)
Gets color from raster map (CELL)
Definition: color_get.c:67
int Rast_read_colors(const char *, const char *, struct Colors *)
Read color table of raster map.
int Rast_read_cats(const char *, const char *, struct Categories *)
Read raster category file.
Definition: raster/cats.c:104
int Rast_read_fp_range(const char *, const char *, struct FPRange *)
Read floating-point range.
Definition: raster/range.c:71
void Rast_free_colors(struct Colors *)
Free color structure memory.
Definition: color_free.c:30
void Rast_get_fp_range_min_max(const struct FPRange *, DCELL *, DCELL *)
Get minimum and maximum value from fp range.
Definition: raster/range.c:785
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
Definition: raster/range.c:735
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
Definition: raster/range.c:163
char * Rast_get_c_cat(CELL *, struct Categories *)
Get a raster category label (CELL)
Definition: raster/cats.c:321
char * Rast_get_d_cat(DCELL *, struct Categories *)
Get a raster category label (DCELL)
Definition: raster/cats.c:369
int Rast_map_is_fp(const char *, const char *)
Check if raster map is floating-point.
Definition: raster/open.c:861
int Rast_get_d_color(const DCELL *, int *, int *, int *, struct Colors *)
Gets color from raster map (DCELL)
Definition: color_get.c:109
#define min(x, y)
Definition: draw2.c:29
#define max(x, y)
Definition: draw2.c:30
double DCELL
Definition: gis.h:635
int CELL
Definition: gis.h:634
#define _(str)
Definition: glocale.h:10
int gsd_make_nice_number(float *num)
ADD.
Definition: gsd_legend.c:153
GLuint gsd_put_legend(const char *name, GLuint fontbase, int size, int *flags, float *rangef, int *pt)
Put legend.
Definition: gsd_legend.c:201
int gsd_get_nice_range(float lownum, float highnum, int numvals, float *vals)
ADD.
Definition: gsd_legend.c:120
void gsd_end_legend_viewport(void)
ADD.
Definition: gsd_legend.c:91
void gsd_bgn_legend_viewport(GLint wl, GLint wb, GLint wr, GLint wt)
ADD.
Definition: gsd_legend.c:61
#define MAX_LEGEND
Definition: gsd_legend.c:51
const char * name
Definition: named_colr.c:6
#define X
Definition: ogsf.h:140
#define Z
Definition: ogsf.h:142
#define GSD_FRONT
Definition: ogsf.h:104
#define Y
Definition: ogsf.h:141
#define CM_COLOR
Definition: ogsf.h:148
#define GSD_BACK
Definition: ogsf.h:105
struct state * st
Definition: parser.c:104
#define RGB_TO_INT(r, g, b, i)
Definition: rgbpack.h:12
Definition: gis.h:692
Definition: raster.h:220