GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-565e82de51
gs3.c
Go to the documentation of this file.
1 /*!
2  \file lib/ogsf/gs3.c
3 
4  \brief OGSF library - loading surfaces (lower level functions)
5 
6  GRASS OpenGL gsurf OGSF Library
7 
8  (C) 1999-2008 by the GRASS Development Team
9 
10  This program is free software under the
11  GNU General Public License (>=v2).
12  Read the file COPYING that comes with GRASS
13  for details.
14 
15  \author Bill Brown USACERL, GMSL/University of Illinois (January 1993)
16  \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
17  */
18 
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include <grass/gis.h>
23 #include <grass/raster.h>
24 #include <grass/glocale.h>
25 #include <grass/bitmap.h>
26 
27 #include <grass/ogsf.h>
28 /* for geoview & geodisplay in 3dview stuff */
29 #include "gsget.h"
30 /* for update_attrange - might be able to move this func now */
31 
32 /*!
33  \brief Used in the function Gs_update_attrange()
34  */
35 #define INIT_MINMAX(p, nm, size, min, max, found) \
36  found = 0; \
37  p += (size - 1); \
38  while (size--) { \
39  if (!BM_GET_BYOFFSET(nm, size)) { \
40  min = max = *p; \
41  found = 1; \
42  break; \
43  } \
44  p--; \
45  }
46 
47 /*!
48  \brief Used in the function Gs_update_attrange()
49  */
50 #define SET_MINMAX(p, nm, size, min, max) \
51  p += (size - 1); \
52  while (size--) { \
53  if (!BM_GET_BYOFFSET(nm, size)) { \
54  if (*p < min) { \
55  min = *p; \
56  } \
57  else if (*p > max) { \
58  max = *p; \
59  } \
60  } \
61  p--; \
62  }
63 
64 typedef int FILEDESC;
65 
66 #define NO_DATA_COL 0xffffff
67 
68 /*!
69  \brief Calculates distance in METERS between two points in current projection
70  (2D)
71 
72  Uses G_distance().
73 
74  \param from 'from' point (X, Y)
75  \param to 'to' point (X, Y)
76 
77  \return distance
78  */
79 double Gs_distance(double *from, double *to)
80 {
81  static int first = 1;
82 
83  if (first) {
84  first = 0;
86  }
87 
88  return G_distance(from[0], from[1], to[0], to[1]);
89 }
90 
91 /*!
92  \brief Load raster map as floating point map
93 
94  Calling function must have already allocated space in buff for
95  wind->rows * wind->cols floats.
96 
97  This routine simply loads the map into a 2d array by repetitve calls
98  to get_f_raster_row.
99 
100  \param wind current window
101  \param map_name raster map name
102  \param[out] buff data buffer
103  \param[out] nullmap null map buffer
104  \param[out] has_null indicates if raster map contains null-data
105 
106  \return 1 on success
107  \return 0 on failure
108  */
109 int Gs_loadmap_as_float(struct Cell_head *wind, const char *map_name,
110  float *buff, struct BM *nullmap, int *has_null)
111 {
112  FILEDESC cellfile;
113  const char *map_set;
114  int offset, row, col;
115 
116  G_debug(3, "Gs_loadmap_as_float(): name=%s", map_name);
117 
118  map_set = G_find_raster2(map_name, "");
119  if (!map_set) {
120  G_warning(_("Raster map <%s> not found"), map_name);
121  return 0;
122  }
123  *has_null = 0;
124 
125  cellfile = Rast_open_old(map_name, map_set);
126  char *mname = G_fully_qualified_name(map_name, map_set);
127 
128  G_message(_("Loading raster map <%s>..."), mname);
129 
130  for (row = 0; row < wind->rows; row++) {
131  offset = row * wind->cols;
132  Rast_get_f_row(cellfile, &(buff[offset]), row);
133 
134  G_percent(row, wind->rows, 2);
135 
136  for (col = 0; col < wind->cols; col++) {
137  if (Rast_is_f_null_value(buff + offset + col)) {
138  *has_null = 1;
139  BM_set(nullmap, col, row, 1);
140  }
141  /* set nm */
142  }
143  }
144  G_percent(1, 1, 1);
145 
146  G_debug(4, " has_null=%d", *has_null);
147  G_free(mname);
148 
149  Rast_close(cellfile);
150 
151  return (1);
152 }
153 
154 /*!
155  \brief Load raster map as integer map
156 
157  Calling function must have already allocated space in buff for
158  wind->rows * wind->cols floats.
159 
160  This routine simply loads the map into a 2d array by repetitve calls
161  to get_f_raster_row.
162 
163  \todo fn body of Gs_loadmap_as_float()
164 
165  \param wind current window
166  \param map_name raster map name
167  \param[out] buff data buffer
168  \param[out] nullmap null map buffer
169  \param[out] has_null indicates if raster map contains null-data
170 
171  \return 1 on success
172  \return 0 on failure
173  */
174 int Gs_loadmap_as_int(struct Cell_head *wind, const char *map_name, int *buff,
175  struct BM *nullmap, int *has_null)
176 {
177  FILEDESC cellfile;
178  const char *map_set;
179  int offset, row, col;
180 
181  G_debug(3, "Gs_loadmap_as_int");
182 
183  map_set = G_find_raster2(map_name, "");
184  if (!map_set) {
185  G_warning(_("Raster map <%s> not found"), map_name);
186  return 0;
187  }
188  *has_null = 0;
189 
190  cellfile = Rast_open_old(map_name, map_set);
191  char *mname = G_fully_qualified_name(map_name, map_set);
192 
193  G_message(_("Loading raster map <%s>..."), mname);
194 
195  for (row = 0; row < wind->rows; row++) {
196  offset = row * wind->cols;
197  Rast_get_c_row(cellfile, &(buff[offset]), row);
198 
199  G_percent(row, wind->rows, 2);
200 
201  for (col = 0; col < wind->cols; col++) {
202  if (Rast_is_f_null_value(buff + offset + col)) {
203  *has_null = 1;
204  BM_set(nullmap, col, row, 1);
205  }
206 
207  /* set nm */
208  }
209  }
210  G_percent(1, 1, 1);
211 
212  Rast_close(cellfile);
213  G_free(mname);
214 
215  return (1);
216 }
217 
218 /*!
219  \brief Get map data type
220 
221  \param filename raster map name
222  \param negflag
223 
224  \return -1 if map is integer and Rast_read_range() fails
225  \return data type (ARRY_*)
226  */
227 int Gs_numtype(const char *filename, int *negflag)
228 {
229  CELL max = 0, min = 0;
230  struct Range range;
231  const char *mapset;
232  int shortbits, charbits, bitplace;
233  static int max_short, max_char;
234  static int first = 1;
235 
236  if (first) {
237  max_short = max_char = 1;
238  shortbits = 8 * sizeof(short);
239 
240  for (bitplace = 1; bitplace < shortbits; ++bitplace) {
241  /*1 bit for sign */
242  max_short *= 2;
243  }
244 
245  max_short -= 1;
246 
247  /* NO bits for sign, using unsigned char */
248  charbits = 8 * sizeof(unsigned char);
249 
250  for (bitplace = 0; bitplace < charbits; ++bitplace) {
251  max_char *= 2;
252  }
253 
254  max_char -= 1;
255 
256  first = 0;
257  }
258 
259  mapset = G_find_raster2(filename, "");
260  if (!mapset) {
261  G_warning(_("Raster map <%s> not found"), filename);
262  return -1;
263  }
264 
265  if (Rast_map_is_fp(filename, mapset)) {
266  G_debug(3, "Gs_numtype(): fp map detected");
267 
268  return (ATTY_FLOAT);
269  }
270 
271  if (-1 == Rast_read_range(filename, mapset, &range)) {
272  return (-1);
273  }
274 
275  Rast_get_range_min_max(&range, &min, &max);
276  *negflag = (min < 0);
277 
278  if (max < max_char && min > 0) {
279  return (ATTY_CHAR);
280  }
281 
282  if (max < max_short && min > -max_short) {
283  return (ATTY_SHORT);
284  }
285 
286  return (ATTY_INT);
287 }
288 
289 /*!
290  \brief Load raster map as integer map
291 
292  Calling function must have already allocated space in buff for
293  wind->rows * wind->cols shorts.
294 
295  This routine simply loads the map into a 2d array by repetitve calls
296  to get_map_row.
297 
298  \param wind current window
299  \param map_name raster map name
300  \param[out] buff data buffer
301  \param[out] nullmap null map buffer
302  \param[out] has_null indicates if raster map contains null-data
303 
304  \return 1 on success
305  \return -1 on failure,
306  \return -2 if read ok, but 1 or more values were too large (small)
307  to fit into a short (in which case the max (min) short is used)
308  */
309 int Gs_loadmap_as_short(struct Cell_head *wind, const char *map_name,
310  short *buff, struct BM *nullmap, int *has_null)
311 {
312  FILEDESC cellfile;
313  const char *map_set;
314  int *ti, *tmp_buf;
315  int offset, row, col, val, max_short, overflow, shortsize, bitplace;
316  short *ts;
317 
318  G_debug(3, "Gs_loadmap_as_short");
319 
320  overflow = 0;
321  shortsize = 8 * sizeof(short);
322 
323  /* 1 bit for sign */
324  /* same as 2 << (shortsize-1) */
325  for (max_short = bitplace = 1; bitplace < shortsize; ++bitplace) {
326  max_short *= 2;
327  }
328 
329  max_short -= 1;
330 
331  map_set = G_find_raster2(map_name, "");
332  if (!map_set) {
333  G_warning(_("Raster map <%s> not found"), map_name);
334  return -1;
335  }
336  *has_null = 0;
337 
338  cellfile = Rast_open_old(map_name, map_set);
339 
340  tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
341  if (!tmp_buf) {
342  return -1;
343  }
344 
345  char *mname = G_fully_qualified_name(map_name, map_set);
346  G_message(_("Loading raster map <%s>..."), mname);
347 
348  for (row = 0; row < wind->rows; row++) {
349  offset = row * wind->cols;
350  Rast_get_c_row(cellfile, tmp_buf, row);
351 
352  G_percent(row, wind->rows, 2);
353 
354  ts = &(buff[offset]);
355  ti = tmp_buf;
356 
357  for (col = 0; col < wind->cols; col++) {
358  if (Rast_is_c_null_value(&tmp_buf[col])) {
359  *has_null = 1;
360  BM_set(nullmap, col, row, 1);
361  }
362  else {
363  val = *ti;
364  if (abs(val) > max_short) {
365  overflow = 1;
366  /* assign floor/ceiling value?
367  */
368  *ts = (short)(max_short * val / abs(val));
369  }
370  else {
371  *ts = (short)val;
372  }
373  }
374 
375  ti++;
376  ts++;
377  }
378  }
379  G_percent(1, 1, 1);
380 
381  Rast_close(cellfile);
382 
383  G_free(tmp_buf);
384  G_free(mname);
385 
386  return (overflow ? -2 : 1);
387 }
388 
389 /*!
390  \brief Load raster map as integer map
391 
392  Calling function must have already allocated space in buff for
393  wind->rows * wind->cols unsigned chars.
394 
395  This routine simply loads the map into a 2d array by repetitve calls
396  to get_map_row.
397 
398  Since signs of chars can be tricky, we only load positive chars
399  between 0-255.
400 
401  \todo fn body Gs_loadmap_as_float()
402 
403  \param wind current window
404  \param map_name raster map name
405  \param[out] buff data buffer
406  \param[out] nullmap null map buffer
407  \param[out] has_null indicates if raster map contains null-data
408 
409  \return 1 on success
410  \return -1 on failure
411  \return -2 if read ok, but 1 or more values
412  were too large (small) to fit into an unsigned char.
413  (in which case the max (min) char is used)
414  */
415 int Gs_loadmap_as_char(struct Cell_head *wind, const char *map_name,
416  unsigned char *buff, struct BM *nullmap, int *has_null)
417 {
418  FILEDESC cellfile;
419  const char *map_set;
420  int *ti, *tmp_buf;
421  int offset, row, col, val, max_char, overflow, charsize, bitplace;
422  unsigned char *tc;
423 
424  G_debug(3, "Gs_loadmap_as_char");
425 
426  overflow = 0;
427  charsize = 8 * sizeof(unsigned char);
428 
429  /* 0 bits for sign! */
430  max_char = 1;
431 
432  for (bitplace = 0; bitplace < charsize; ++bitplace) {
433  max_char *= 2;
434  }
435 
436  max_char -= 1;
437 
438  map_set = G_find_raster2(map_name, "");
439  if (!map_set) {
440  G_warning(_("Raster map <%s> not found"), map_name);
441  return -1;
442  }
443  *has_null = 0;
444 
445  cellfile = Rast_open_old(map_name, map_set);
446 
447  tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
448  if (!tmp_buf) {
449  return -1;
450  }
451 
452  char *mname = G_fully_qualified_name(map_name, map_set);
453  G_message(_("Loading raster map <%s>..."), mname);
454 
455  for (row = 0; row < wind->rows; row++) {
456  offset = row * wind->cols;
457  Rast_get_c_row(cellfile, tmp_buf, row);
458  tc = (unsigned char *)&(buff[offset]);
459  ti = tmp_buf;
460 
461  G_percent(row, wind->rows, 2);
462 
463  for (col = 0; col < wind->cols; col++) {
464  if (Rast_is_c_null_value(&tmp_buf[col])) {
465  *has_null = 1;
466  BM_set(nullmap, col, row, 1);
467  }
468  else {
469  val = *ti;
470  if (val > max_char) {
471  overflow = 1;
472  *tc = (unsigned char)max_char;
473  }
474  else if (val < 0) {
475  overflow = 1;
476  *tc = 0;
477  }
478  else {
479  *tc = (unsigned char)val;
480  }
481  }
482 
483  ti++;
484  tc++;
485  }
486  }
487  G_percent(1, 1, 1);
488 
489  Rast_close(cellfile);
490 
491  G_free(tmp_buf);
492  G_free(mname);
493 
494  return (overflow ? -2 : 1);
495 }
496 
497 /*!
498  \brief Load raster map as integer map
499 
500  Calling function must have already allocated space in buff for
501  struct BM of wind->rows & wind->cols.
502 
503  This routine simply loads the map into the bitmap by repetitve calls
504  to get_map_row. Any value other than 0 in the map will set the bitmap.
505  (may want to change later to allow specific value to set)
506 
507  Changed to use null.
508 
509  \param wind current window
510  \param map_name raster map name
511  \param[out] buff data buffer
512 
513  \returns 1 on success
514  \return -1 on failure
515  */
516 int Gs_loadmap_as_bitmap(struct Cell_head *wind, const char *map_name,
517  struct BM *buff)
518 {
519  FILEDESC cellfile;
520  const char *map_set;
521  int *tmp_buf;
522  int row, col;
523 
524  G_debug(3, "Gs_loadmap_as_bitmap");
525 
526  map_set = G_find_raster2(map_name, "");
527  if (!map_set) {
528  G_warning(_("Raster map <%s> not found"), map_name);
529  return -1;
530  }
531 
532  cellfile = Rast_open_old(map_name, map_set);
533 
534  tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
535  if (!tmp_buf) {
536  return -1;
537  }
538 
539  char *mname = G_fully_qualified_name(map_name, map_set);
540  G_message(_("Loading raster map <%s>..."), mname);
541 
542  for (row = 0; row < wind->rows; row++) {
543  Rast_get_c_row(cellfile, tmp_buf, row);
544 
545  for (col = 0; col < wind->cols; col++) {
546  if (Rast_is_c_null_value(&tmp_buf[col])) {
547  /* no data */
548  BM_set(buff, col, row, 1);
549  }
550  else {
551  BM_set(buff, col, row, 0);
552  }
553  }
554  }
555 
556  Rast_close(cellfile);
557 
558  G_free(tmp_buf);
559  G_free(mname);
560 
561  return (1);
562 }
563 
564 /*!
565  \brief Build color table (256)
566 
567  Calling function must have already allocated space in buff for range of
568  data (256 for now) - simply calls get_color for each cat in color range
569 
570  \param filename raster map name
571  \param[out] buff data buffer
572 
573  \return 1 on success
574  \return 0 on failure
575  */
576 int Gs_build_256lookup(const char *filename, int *buff)
577 {
578  const char *mapset;
579  struct Colors colrules;
580  CELL min, max, cats[256];
581  int i;
582  unsigned char r[256], g[256], b[256], set[256];
583 
584  G_debug(3, "building color table");
585 
586  mapset = G_find_raster2(filename, "");
587  if (!mapset) {
588  G_warning(_("Raster map <%s> not found"), filename);
589  return 0;
590  }
591 
592  Rast_read_colors(filename, mapset, &colrules);
593  Rast_get_c_color_range(&min, &max, &colrules);
594 
595  if (min < 0 || max > 255) {
596  G_warning(
597  _("Color table range doesn't match data (mincol=%d, maxcol=%d"),
598  min, max);
599 
600  min = min < 0 ? 0 : min;
601  max = max > 255 ? 255 : max;
602  }
603 
604  G_zero(cats, 256 * sizeof(CELL));
605 
606  for (i = min; i <= max; i++) {
607  cats[i] = i;
608  }
609 
610  Rast_lookup_c_colors(cats, r, g, b, set, 256, &colrules);
611 
612  for (i = 0; i < 256; i++) {
613 
614  if (set[i]) {
615  buff[i] =
616  (r[i] & 0xff) | ((g[i] & 0xff) << 8) | ((b[i] & 0xff) << 16);
617  }
618  else {
619  buff[i] = NO_DATA_COL;
620  }
621  }
622 
623  return (1);
624 }
625 
626 /*!
627  \brief Pack color table
628 
629  Passed an array of 32 bit ints that is converted from cell values
630  to packed colors (0xbbggrr)
631 
632  \param filename raster map name
633  \param buff
634  \param rows number of rows
635  \param cols number of cols
636  */
637 void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
638 {
639  const char *mapset;
640  struct Colors colrules;
641  unsigned char *r, *g, *b, *set;
642  int *cur, i, j;
643 
644  mapset = G_find_raster2(filename, "");
645  if (!mapset) {
646  G_warning(_("Raster map <%s> not found"), filename);
647  return;
648  }
649 
650  r = (unsigned char *)G_malloc(cols);
651  g = (unsigned char *)G_malloc(cols);
652  b = (unsigned char *)G_malloc(cols);
653  set = (unsigned char *)G_malloc(cols);
654 
655  Rast_read_colors(filename, mapset, &colrules);
656 
657  cur = buff;
658  char *mname = G_fully_qualified_name(filename, mapset);
659 
660  G_message(_("Translating colors from raster map <%s>..."), mname);
661 
662  for (i = 0; i < rows; i++) {
663  Rast_lookup_c_colors(cur, r, g, b, set, cols, &colrules);
664  G_percent(i, rows, 2);
665 
666  for (j = 0; j < cols; j++) {
667  if (set[j]) {
668  cur[j] = (r[j] & 0xff) | ((g[j] & 0xff) << 8) |
669  ((b[j] & 0xff) << 16);
670  }
671  else {
672  cur[j] = NO_DATA_COL;
673  }
674  }
675 
676  cur = &(cur[cols]);
677  }
678  G_percent(1, 1, 1);
679 
680  Rast_free_colors(&colrules);
681 
682  G_free(r);
683  G_free(g);
684  G_free(b);
685  G_free(mname);
686  G_free(set);
687 
688  return;
689 }
690 
691 /*!
692  \brief Pack color table (floating-point map)
693 
694  Passed a array of floats that will be converted from cell values
695  to packed colors (0xbbggrr) and float to int
696  Floating point data not freed here, use:
697  gsds_free_data_buff(id, ATTY_FLOAT)
698 
699  \param filename raster map name
700  \param fbuf
701  \param ibuf
702  \param rows number of rows
703  \param cols number of cols
704  */
705 void Gs_pack_colors_float(const char *filename, float *fbuf, int *ibuf,
706  int rows, int cols)
707 {
708  const char *mapset;
709  struct Colors colrules;
710  unsigned char *r, *g, *b, *set;
711  int i, j, *icur;
712  FCELL *fcur;
713 
714  mapset = G_find_raster2(filename, "");
715  if (!mapset) {
716  G_warning(_("Raster map <%s> not found"), filename);
717  return;
718  }
719 
720  r = (unsigned char *)G_malloc(cols);
721  g = (unsigned char *)G_malloc(cols);
722  b = (unsigned char *)G_malloc(cols);
723  set = (unsigned char *)G_malloc(cols);
724 
725  Rast_read_colors(filename, mapset, &colrules);
726 
727  fcur = fbuf;
728  icur = ibuf;
729  char *mname = G_fully_qualified_name(filename, mapset);
730 
731  G_message(_("Translating colors from raster map <%s>..."), mname);
732 
733  for (i = 0; i < rows; i++) {
734  Rast_lookup_f_colors(fcur, r, g, b, set, cols, &colrules);
735  G_percent(i, rows, 2);
736 
737  for (j = 0; j < cols; j++) {
738  if (set[j]) {
739  icur[j] = (r[j] & 0xff) | ((g[j] & 0xff) << 8) |
740  ((b[j] & 0xff) << 16);
741  }
742  else {
743  icur[j] = NO_DATA_COL;
744  }
745  }
746 
747  icur = &(icur[cols]);
748  fcur = &(fcur[cols]);
749  }
750  G_percent(1, 1, 1);
751 
752  Rast_free_colors(&colrules);
753 
754  G_free(r);
755  G_free(g);
756  G_free(b);
757  G_free(set);
758  G_free(mname);
759 
760  return;
761 }
762 
763 /*!
764  \brief Get categories/labels
765 
766  Formats label as in d.what.rast -> (catval) catlabel
767 
768  \param filename raster map name
769  \param drow
770  \param dcol
771  \param catstr category string
772 
773  \return 1 on success
774  \return 0 on failure
775  */
776 int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr)
777 {
778  struct Categories cats;
779  const char *mapset;
780  CELL *buf;
781  DCELL *dbuf;
782  RASTER_MAP_TYPE map_type;
783  int fd = -1;
784 
785  if ((mapset = G_find_raster2(filename, "")) == NULL) {
786  G_warning(_("Raster map <%s> not found"), filename);
787  return 0;
788  }
789 
790  if (-1 != Rast_read_cats(filename, mapset, &cats)) {
791  fd = Rast_open_old(filename, mapset);
792  map_type = Rast_get_map_type(fd);
793 
794  if (map_type == CELL_TYPE) {
795  buf = Rast_allocate_c_buf();
796 
797  Rast_get_c_row(fd, buf, drow);
798  if (Rast_is_c_null_value(&buf[dcol])) {
799  sprintf(catstr, "(NULL) %s", Rast_get_c_cat(&buf[dcol], &cats));
800  }
801  else {
802  sprintf(catstr, "(%d) %s", buf[dcol],
803  Rast_get_c_cat(&buf[dcol], &cats));
804  }
805 
806  G_free(buf);
807  }
808 
809  else {
810  /* fp map */
811  dbuf = Rast_allocate_d_buf();
812 
813  Rast_get_d_row(fd, dbuf, drow);
814  if (Rast_is_d_null_value(&dbuf[dcol])) {
815  sprintf(catstr, "(NULL) %s",
816  Rast_get_d_cat(&dbuf[dcol], &cats));
817  }
818  else {
819  sprintf(catstr, "(%g) %s", dbuf[dcol],
820  Rast_get_d_cat(&dbuf[dcol], &cats));
821  }
822 
823  G_free(dbuf);
824  }
825  }
826  else {
827  strcpy(catstr, "no category label");
828  return 0;
829  }
830 
831  /* TODO: may want to keep these around for multiple queries */
832  Rast_free_cats(&cats);
833 
834  if (fd >= 0)
835  Rast_close(fd);
836 
837  return (1);
838 }
839 
840 /*!
841  \brief Save 3dview
842 
843  \param vname view name
844  \param gv pointer to geoview struct
845  \param gd pointer to geodisplay struct (unused)
846  \param w current window
847  \param defsurf default geosurf struct
848 
849  \return -1 on error
850  \return ?
851  */
852 int Gs_save_3dview(const char *vname, geoview *gv, geodisplay *gd UNUSED,
853  struct Cell_head *w, geosurf *defsurf)
854 {
855  const char *mapset;
856  struct G_3dview v;
857  float zmax, zmin;
858 
859  GS_get_zrange(&zmin, &zmax, 0);
860 
861  G_get_3dview_defaults(&v, w);
862  mapset = G_mapset();
863 
864  if (mapset != NULL) {
865  if (defsurf) {
866  if (defsurf->draw_mode & DM_WIRE_POLY) {
867  v.display_type = 3;
868  }
869  else if (defsurf->draw_mode & DM_WIRE ||
870  defsurf->draw_mode & DM_COL_WIRE) {
871  v.display_type = 1;
872  }
873  else if (defsurf->draw_mode & DM_POLY) {
874  v.display_type = 2;
875  }
876 
877  v.mesh_freq = defsurf->x_modw; /* mesh resolution */
878  v.poly_freq = defsurf->x_mod; /* poly resolution */
879  v.dozero = !(defsurf->nz_topo);
880  v.colorgrid = (defsurf->draw_mode & DM_COL_WIRE) ? 1 : 0;
881  v.shading = (defsurf->draw_mode & DM_GOURAUD) ? 1 : 0;
882  }
883 
884  if (gv->infocus) {
885  GS_v3eq(v.from_to[TO], gv->real_to);
886  v.from_to[TO][Z] -= zmin;
887  GS_v3mult(v.from_to[TO], gv->scale);
888  v.from_to[TO][Z] *= gv->vert_exag;
889  }
890  else {
891  GS_v3eq(v.from_to[TO], gv->from_to[TO]);
892  }
893 
895 
896  GS_v3eq(v.from_to[FROM], gv->from_to[FROM]);
898 
899  v.exag = gv->vert_exag;
900  v.fov = gv->fov / 10.;
901  v.twist = gv->twist;
902  v.fringe = 0; /* not implemented here */
903 
904  v.lightson = 1; /* always true, currently */
905 
906  if (gv->lights[0].position[W] == 1) {
907  /* local */
908  v.lightpos[X] = gv->lights[0].position[X];
909  v.lightpos[Y] = gv->lights[0].position[Y];
910  v.lightpos[Z] = gv->lights[0].position[Z];
912  v.lightpos[W] = 1.0; /* local */
913  }
914  else {
915  v.lightpos[X] = gv->lights[0].position[X];
916  v.lightpos[Y] = gv->lights[0].position[Y];
917  v.lightpos[Z] = gv->lights[0].position[Z];
918  v.lightpos[W] = 0.0; /* inf */
919  }
920 
921  v.lightcol[0] = gv->lights[0].color[0];
922  v.lightcol[1] = gv->lights[0].color[1];
923  v.lightcol[2] = gv->lights[0].color[2];
924 
925  v.ambient = (gv->lights[0].ambient[0] + gv->lights[0].ambient[1] +
926  gv->lights[0].ambient[2]) /
927  3.;
928  v.shine = gv->lights[0].shine;
929 
930  v.surfonly = 0; /* N/A - now uses constant color */
931  strcpy((v.pgm_id), "Nvision-ALPHA!");
932 
933  return (G_put_3dview(vname, &v, w));
934  }
935  else {
936  return (-1);
937  }
938 }
939 
940 /*!
941  \brief Load 3dview
942 
943  \param vname view name
944  \param gv pointer to geoview struct
945  \param gd pointer to geodisplay struct (unused)
946  \param w current window
947  \param defsurf default geosurf struct
948 
949  \return 1
950  */
951 int Gs_load_3dview(const char *vname, geoview *gv, geodisplay *gd UNUSED,
952  struct Cell_head *w, const geosurf *defsurf)
953 {
954  const char *mapset;
955  struct G_3dview v;
956  int ret = -1;
957 
958  mapset = G_find_file2("3d.view", vname, "");
959 
960  if (mapset != NULL) {
961  ret = G_get_3dview(vname, mapset, &v);
962  }
963 
964  if (ret >= 0) {
965  if (strcmp((v.pgm_id), "Nvision-ALPHA!")) {
966  G_warning(_("View not saved by this program,"
967  "there may be some inconsistencies"));
968  }
969 
970  /* set poly and mesh resolutions */
971  v.mesh_freq = (int)(v.mesh_freq * v.vwin.ns_res / w->ns_res);
972  v.poly_freq = (int)(v.poly_freq * v.vwin.ns_res / w->ns_res);
973 
974  /* Set To and FROM positions */
975  /* TO */
976  float pt[3];
977 
978  pt[0] = (v.from_to[TO][X] - w->west) - w->ew_res / 2.;
979  pt[1] = (v.from_to[TO][Y] - w->south) - w->ns_res / 2.;
980  pt[2] = v.from_to[TO][Z];
981  GS_set_focus(pt);
982 
983  /* FROM */
984  pt[0] = (float)v.from_to[FROM][X];
985  pt[1] = (float)v.from_to[FROM][Y];
986  pt[2] = (float)v.from_to[FROM][Z];
987  GS_moveto_real(pt);
988 
989  if (defsurf) {
990  int dmode = 0;
991 
993  v.mesh_freq);
994 
995  while (v.display_type >= 10) {
996  /* globe stuff not used */
997  v.display_type -= 10;
998  }
999 
1000  /* set drawing modes */
1001  if (v.colorgrid) {
1002  dmode |= DM_COL_WIRE;
1003  }
1004 
1005  if (v.shading) {
1006  dmode |= DM_GOURAUD;
1007  }
1008 
1009  switch (v.display_type) {
1010  case 1:
1011  dmode |= DM_WIRE;
1012 
1013  break;
1014  case 2:
1015  dmode |= DM_POLY;
1016 
1017  break;
1018  case 3:
1019  dmode |= DM_WIRE_POLY;
1020 
1021  break;
1022  }
1023  GS_setall_drawmode(dmode);
1024 
1025  /* should also set nozeros here */
1026  }
1027 
1028  /* set exaggeration */
1029  if (v.exag)
1031 
1032  /* Set FOV */
1033  if (v.fov) {
1034  GS_set_fov(
1035  (int)(v.fov > 0 ? v.fov * 10. + 0.5 : v.fov * 10. - 0.5));
1036  }
1037  else {
1038  /* TODO: do ortho */
1039  }
1040 
1041  /* Set twist */
1042  if (v.twist)
1043  GS_set_twist((int)(v.twist > 0 ? v.twist + 0.5 : v.twist - 0.5));
1044 
1045  /* TODO: OK to here - need to unravel/reverse lights stuff*** */
1046 
1047  if (v.lightson) {
1048  /* Lights are on */
1049 
1050  /* Light Position */
1051  gv->lights[0].position[X] = v.lightpos[X];
1052  gv->lights[0].position[Y] = v.lightpos[Y];
1053  gv->lights[0].position[Z] = v.lightpos[Z];
1054 
1055  /* Light Color */
1056  gv->lights[0].color[0] = v.lightcol[0];
1057  gv->lights[0].color[1] = v.lightcol[1];
1058  gv->lights[0].color[2] = v.lightcol[2];
1059 
1060  /* Light Shininess */
1061  gv->lights[0].shine = v.shine;
1062 
1063  /* Light Ambient */
1064  gv->lights[0].ambient[0] = gv->lights[0].ambient[1] =
1065  gv->lights[0].ambient[2] = v.ambient * 3.;
1066 
1067  } /* Done with lights */
1068 
1069  GS_alldraw_wire();
1070 
1071  } /* Done with file */
1072  return (1);
1073 }
1074 
1075 /*!
1076  \brief Update no_zero ranges for attribute (actually no_null now)
1077 
1078  \param gs pointer to geosurf struct
1079  \param desc attribute id (descriptor)
1080 
1081  \return -1 on error
1082  \return 1 on success
1083  */
1084 int Gs_update_attrange(geosurf *gs, int desc)
1085 {
1086  size_t size;
1087  float min = 0.0;
1088  float max = 0.0;
1089  typbuff *tb;
1090  struct BM *nm;
1091  int found;
1092 
1093  gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].range_nz = 0.0;
1094 
1095  if (CONST_ATT == gs_get_att_src(gs, desc)) {
1096  gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].constant;
1097  min = max = gs->att[desc].constant;
1098  gs->att[desc].range_nz = 0.0;
1099  }
1100  else if (CF_COLOR_PACKED & gsds_get_changed(gs->att[desc].hdata)) {
1101  gs->att[desc].max_nz = 0xFFFFFF;
1102  gs->att[desc].min_nz = 0x010101;
1103  gs->att[desc].range_nz = 0xFFFFFF;
1104  }
1105  else {
1106  if (NULL == (tb = gsds_get_typbuff(gs->att[desc].hdata, 0))) {
1107  return (-1);
1108  }
1109 
1110  nm = tb->nm;
1111 
1112  if (tb->ib) {
1113  int *p;
1114 
1115  size = (size_t)gs->rows * gs->cols;
1116  p = tb->ib;
1117  INIT_MINMAX(p, nm, size, min, max, found);
1118 
1119  if (!found) {
1120  /* all nulls! */
1121  return (-1);
1122  }
1123 
1124  size = (size_t)gs->rows * gs->cols;
1125  p = tb->ib;
1126  SET_MINMAX(p, nm, size, min, max);
1127  }
1128  else if (tb->sb) {
1129  short *p;
1130 
1131  size = (size_t)gs->rows * gs->cols;
1132  p = tb->sb;
1133  INIT_MINMAX(p, nm, size, min, max, found);
1134 
1135  if (!found) {
1136  /* all nulls! */
1137  return (-1);
1138  }
1139 
1140  size = (size_t)gs->rows * gs->cols;
1141  p = tb->sb;
1142  SET_MINMAX(p, nm, size, min, max);
1143  }
1144  else if (tb->cb) {
1145  char *p;
1146 
1147  size = (size_t)gs->rows * gs->cols;
1148  p = (char *)tb->cb;
1149  INIT_MINMAX(p, nm, size, min, max, found);
1150 
1151  if (!found) {
1152  /* all nulls! */
1153  return (-1);
1154  }
1155 
1156  size = (size_t)gs->rows * gs->cols;
1157  p = (char *)tb->cb;
1158  SET_MINMAX(p, nm, size, min, max);
1159  }
1160  else if (tb->fb) {
1161  float *p;
1162 
1163  size = (size_t)gs->rows * gs->cols;
1164  p = tb->fb;
1165  INIT_MINMAX(p, nm, size, min, max, found);
1166 
1167  if (!found) {
1168  /* all nulls! */
1169  return (-1);
1170  }
1171 
1172  size = (size_t)gs->rows * gs->cols;
1173  p = tb->fb;
1174  SET_MINMAX(p, nm, size, min, max);
1175  }
1176 
1177  gs->att[desc].max_nz = max;
1178  gs->att[desc].min_nz = min;
1179  gs->att[desc].range_nz = gs->att[desc].max_nz - gs->att[desc].min_nz;
1180  }
1181 
1182  if (ATT_TOPO == desc) {
1183  gs->zmin = min;
1184  gs->zmax = max;
1185  gs->zrange = gs->zmax - gs->zmin;
1186  gs->zminmasked = gs->zmin;
1187  gs->zmax_nz = gs->zmax;
1188  gs->zmin_nz = gs->zmin;
1189  gs->zrange_nz = gs->zmax_nz - gs->zmin_nz;
1190  }
1191 
1192  G_debug(3, "Gs_update_attrange(): min=%f max=%f", gs->zmin, gs->zmax);
1193 
1194  return (1);
1195 }
#define NULL
Definition: ccmath.h:32
int BM_set(struct BM *, int, int, int)
Sets bitmap value to 'val' at location 'x' 'y'.
Definition: bitmap.c:185
void G_percent(long, long, int)
Print percent complete messages.
Definition: percent.c:61
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
const char * G_find_file2(const char *, const char *, const char *)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
Definition: find_file.c:234
void G_warning(const char *,...) __attribute__((format(printf
int G_get_3dview(const char *, const char *, struct G_3dview *)
Gets a 3D View.
Definition: view.c:243
#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
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
int G_put_3dview(const char *, const struct G_3dview *, const struct Cell_head *)
Saves info to a 3d.view file in the current mapset.
Definition: view.c:163
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition: nme_in_mps.c:101
double G_distance(double, double, double, double)
Returns distance in meters.
Definition: gis/distance.c:75
void G_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
int G_get_3dview_defaults(struct G_3dview *, struct Cell_head *)
Sets default for v based on w.
Definition: view.c:58
int int G_begin_distance_calculations(void)
Begin distance calculations.
Definition: gis/distance.c:42
void GS_v3mult(float *, float)
Multiple vectors.
Definition: gs_util.c:229
void GS_set_fov(int)
Set field of view.
Definition: gs2.c:2838
void GS_alldraw_wire(void)
Draw all wires.
Definition: gs2.c:1917
typbuff * gsds_get_typbuff(int, IFLAG)
Get data buffer.
Definition: gsds.c:281
int GS_get_zrange(float *, float *, int)
Get z-extent for all loaded surfaces.
Definition: gs2.c:2685
int GS_setall_drawmode(int)
Set all draw-modes.
Definition: gs2.c:2059
int gs_get_att_src(geosurf *, int)
Get attribute source.
Definition: gs.c:656
void GS_set_focus(float *)
Set focus.
Definition: gs2.c:2517
void GS_set_twist(int)
Set viewpoint twist value.
Definition: gs2.c:2872
void GS_v3eq(float *, float *)
Copy vector values.
Definition: gs_util.c:178
int GS_setall_drawres(int, int, int, int)
Set all draw resolutions.
Definition: gs2.c:2196
void GS_set_global_exag(float)
Set global z-exag value.
Definition: gs2.c:1975
void GS_moveto_real(float *)
Move position to (real)
Definition: gs2.c:2643
int gsds_get_changed(int)
ADD.
Definition: gsds.c:613
void gsd_model2real(Point3)
Convert model to real coordinates.
Definition: gsd_views.c:393
void Rast_free_cats(struct Categories *)
Free category structure memory.
Definition: raster/cats.c:1213
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
#define Rast_is_f_null_value(fcellVal)
Definition: defs/raster.h:410
void Rast_lookup_f_colors(const FCELL *, unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, struct Colors *)
Lookup an array of colors (FCELL)
Definition: color_look.c:112
void Rast_close(int)
Close a raster map.
Definition: raster/close.c:99
int Rast_open_old(const char *, const char *)
Open an existing integer raster map (cell)
Definition: raster/open.c:112
void Rast_free_colors(struct Colors *)
Free color structure memory.
Definition: color_free.c:30
void Rast_get_c_row(int, CELL *, int)
Get raster row (CELL type)
CELL * Rast_allocate_c_buf(void)
Allocate memory for a CELL type raster map.
Definition: alloc_cell.c:81
void Rast_get_f_row(int, FCELL *, int)
Get raster row (FCELL type)
void Rast_get_d_row(int, DCELL *, int)
Get raster row (DCELL type)
void Rast_get_c_color_range(CELL *, CELL *, const struct Colors *)
Get color range values (CELL)
Definition: color_range.c:64
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
Definition: raster/range.c:718
DCELL * Rast_allocate_d_buf(void)
Allocates memory for a raster map of type DCELL.
Definition: alloc_cell.c:107
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
Definition: raster/range.c:160
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
#define Rast_is_d_null_value(dcellVal)
Definition: defs/raster.h:412
#define Rast_is_c_null_value(cellVal)
Definition: defs/raster.h:408
void Rast_lookup_c_colors(const CELL *, unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, struct Colors *)
Lookup an array of colors.
Definition: color_look.c:45
RASTER_MAP_TYPE Rast_get_map_type(int)
Determine raster type from descriptor.
Definition: raster/open.c:932
#define min(x, y)
Definition: draw2.c:29
#define max(x, y)
Definition: draw2.c:30
float FCELL
Definition: gis.h:631
double DCELL
Definition: gis.h:630
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:47
int CELL
Definition: gis.h:629
#define _(str)
Definition: glocale.h:10
int Gs_loadmap_as_short(struct Cell_head *wind, const char *map_name, short *buff, struct BM *nullmap, int *has_null)
Load raster map as integer map.
Definition: gs3.c:309
int Gs_loadmap_as_bitmap(struct Cell_head *wind, const char *map_name, struct BM *buff)
Load raster map as integer map.
Definition: gs3.c:516
int Gs_save_3dview(const char *vname, geoview *gv, geodisplay *gd UNUSED, struct Cell_head *w, geosurf *defsurf)
Save 3dview.
Definition: gs3.c:852
int Gs_numtype(const char *filename, int *negflag)
Get map data type.
Definition: gs3.c:227
void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
Pack color table.
Definition: gs3.c:637
void Gs_pack_colors_float(const char *filename, float *fbuf, int *ibuf, int rows, int cols)
Pack color table (floating-point map)
Definition: gs3.c:705
#define INIT_MINMAX(p, nm, size, min, max, found)
Used in the function Gs_update_attrange()
Definition: gs3.c:35
int Gs_load_3dview(const char *vname, geoview *gv, geodisplay *gd UNUSED, struct Cell_head *w, const geosurf *defsurf)
Load 3dview.
Definition: gs3.c:951
int Gs_loadmap_as_char(struct Cell_head *wind, const char *map_name, unsigned char *buff, struct BM *nullmap, int *has_null)
Load raster map as integer map.
Definition: gs3.c:415
#define NO_DATA_COL
Definition: gs3.c:66
int FILEDESC
Definition: gs3.c:64
int Gs_loadmap_as_float(struct Cell_head *wind, const char *map_name, float *buff, struct BM *nullmap, int *has_null)
Load raster map as floating point map.
Definition: gs3.c:109
int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr)
Get categories/labels.
Definition: gs3.c:776
#define SET_MINMAX(p, nm, size, min, max)
Used in the function Gs_update_attrange()
Definition: gs3.c:50
double Gs_distance(double *from, double *to)
Calculates distance in METERS between two points in current projection (2D)
Definition: gs3.c:79
int Gs_build_256lookup(const char *filename, int *buff)
Build color table (256)
Definition: gs3.c:576
int Gs_update_attrange(geosurf *gs, int desc)
Update no_zero ranges for attribute (actually no_null now)
Definition: gs3.c:1084
int Gs_loadmap_as_int(struct Cell_head *wind, const char *map_name, int *buff, struct BM *nullmap, int *has_null)
Load raster map as integer map.
Definition: gs3.c:174
float g
Definition: named_colr.c:7
#define ATTY_SHORT
Definition: ogsf.h:170
#define X
Definition: ogsf.h:140
#define ATT_TOPO
Definition: ogsf.h:75
#define DM_WIRE_POLY
Definition: ogsf.h:64
#define Z
Definition: ogsf.h:142
#define DM_WIRE
Definition: ogsf.h:61
#define W
Definition: ogsf.h:143
#define ATTY_FLOAT
Definition: ogsf.h:168
#define Y
Definition: ogsf.h:141
#define ATTY_INT
Definition: ogsf.h:169
#define ATTY_CHAR
Definition: ogsf.h:171
#define DM_POLY
Definition: ogsf.h:63
#define DM_GOURAUD
Definition: ogsf.h:56
#define CONST_ATT
Definition: ogsf.h:86
#define CF_COLOR_PACKED
Definition: ogsf.h:184
#define TO
Definition: ogsf.h:145
#define DM_COL_WIRE
Definition: ogsf.h:62
#define strcpy
Definition: parson.c:62
double b
Definition: r_raster.c:39
double r
Definition: r_raster.c:39
#define CELL_TYPE
Definition: raster.h:11
int RASTER_MAP_TYPE
Definition: raster.h:25
@ FROM
Definition: sqlp.tab.h:67
Definition: bitmap.h:17
2D/3D raster map header (used also for region)
Definition: gis.h:441
double ew_res
Resolution - east to west cell size for 2D data.
Definition: gis.h:477
double ns_res
Resolution - north to south cell size for 2D data.
Definition: gis.h:481
int rows
Number of rows for 2D data.
Definition: gis.h:456
int cols
Number of columns for 2D data.
Definition: gis.h:460
double south
Extent coordinates (south)
Definition: gis.h:489
double west
Extent coordinates (west)
Definition: gis.h:493
Definition: gis.h:687
Definition: gis.h:503
struct Cell_head vwin
Definition: gis.h:526
int mesh_freq
Definition: gis.h:509
float from_to[2][3]
Definition: gis.h:505
float fov
Definition: gis.h:506
char pgm_id[40]
Definition: gis.h:504
int colorgrid
Definition: gis.h:514
float lightcol[3]
Definition: gis.h:523
int shading
Definition: gis.h:515
int dozero
Definition: gis.h:513
int lightson
Definition: gis.h:512
float shine
Definition: gis.h:525
int display_type
Definition: gis.h:511
int poly_freq
Definition: gis.h:510
float ambient
Definition: gis.h:524
float exag
Definition: gis.h:508
float twist
Definition: gis.h:507
int fringe
Definition: gis.h:516
float lightpos[4]
Definition: gis.h:522
int surfonly
Definition: gis.h:517
Definition: raster.h:220
Definition: ogsf.h:256
int rows
Definition: ogsf.h:258
float zrange_nz
Definition: ogsf.h:269
int cols
Definition: ogsf.h:258
gsurf_att att[MAX_ATTS]
Definition: ogsf.h:259
int x_modw
Definition: ogsf.h:270
float zmax_nz
Definition: ogsf.h:269
int x_mod
Definition: ogsf.h:270
float zmin_nz
Definition: ogsf.h:269
int nz_topo
Definition: ogsf.h:271
float zmin
Definition: ogsf.h:267
float zrange
Definition: ogsf.h:268
IFLAG draw_mode
Definition: ogsf.h:260
float zminmasked
Definition: ogsf.h:267
float zmax
Definition: ogsf.h:267
Definition: ogsf.h:467
float vert_exag
Definition: ogsf.h:474
int twist
Definition: ogsf.h:473
float real_to[4]
Definition: ogsf.h:474
float from_to[2][4]
Definition: ogsf.h:471
int fov
Definition: ogsf.h:473
float scale
Definition: ogsf.h:475
int infocus
Definition: ogsf.h:470
struct lightdefs lights[MAX_LIGHTS]
Definition: ogsf.h:476
int hdata
Definition: ogsf.h:248
float range_nz
Definition: ogsf.h:252
float max_nz
Definition: ogsf.h:252
float constant
Definition: ogsf.h:250
float min_nz
Definition: ogsf.h:252
float ambient[3]
Definition: ogsf.h:455
float shine
Definition: ogsf.h:457
float position[4]
Definition: ogsf.h:453
float color[3]
Definition: ogsf.h:454
Definition: ogsf.h:208
float * fb
Definition: ogsf.h:209
struct BM * nm
Definition: ogsf.h:214
unsigned char * cb
Definition: ogsf.h:212
short * sb
Definition: ogsf.h:211
int * ib
Definition: ogsf.h:210