GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
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  { \
40  if (!BM_GET_BYOFFSET(nm, size)) \
41  { \
42  min = max = *p; \
43  found = 1; \
44  break; \
45  } \
46  p--; \
47  }
48 
49 /*!
50  \brief Used in the function Gs_update_attrange()
51  */
52 #define SET_MINMAX(p, nm, size, min, max) \
53  p+=(size-1); \
54  while(size--) \
55  { \
56  if (!BM_GET_BYOFFSET(nm, size)) \
57  { \
58  if (*p < min) \
59  { \
60  min = *p; \
61  } \
62  else if (*p > max) \
63  { \
64  max = *p; \
65  } \
66  } \
67  p--; \
68  }
69 
70 typedef int FILEDESC;
71 
72 #define NO_DATA_COL 0xffffff
73 
74 /*!
75  \brief Calculates distance in METERS between two points in current projection (2D)
76 
77  Uses G_distance().
78 
79  \param from 'from' point (X, Y)
80  \param to 'to' point (X, Y)
81 
82  \return distance
83  */
84 double Gs_distance(double *from, double *to)
85 {
86  static int first = 1;
87 
88  if (first) {
89  first = 0;
91  }
92 
93  return G_distance(from[0], from[1], to[0], to[1]);
94 }
95 
96 /*!
97  \brief Load raster map as floating point map
98 
99  Calling function must have already allocated space in buff for
100  wind->rows * wind->cols floats.
101 
102  This routine simply loads the map into a 2d array by repetitve calls
103  to get_f_raster_row.
104 
105  \param wind current window
106  \param map_name raster map name
107  \param[out] buff data buffer
108  \param[out] nullmap null map buffer
109  \param[out] has_null indicates if raster map contains null-data
110 
111  \return 1 on success
112  \return 0 on failure
113  */
114 int Gs_loadmap_as_float(struct Cell_head *wind, const char *map_name,
115  float *buff, struct BM *nullmap, int *has_null)
116 {
117  FILEDESC cellfile;
118  const char *map_set;
119  int offset, row, col;
120 
121  G_debug(3, "Gs_loadmap_as_float(): name=%s", map_name);
122 
123  map_set = G_find_raster2(map_name, "");
124  if (!map_set) {
125  G_warning(_("Raster map <%s> not found"), map_name);
126  return 0;
127  }
128  *has_null = 0;
129 
130  cellfile = Rast_open_old(map_name, map_set);
131 
132  G_message(_("Loading raster map <%s>..."),
133  G_fully_qualified_name(map_name, map_set));
134 
135  for (row = 0; row < wind->rows; row++) {
136  offset = row * wind->cols;
137  Rast_get_f_row(cellfile, &(buff[offset]), row);
138 
139  G_percent(row, wind->rows, 2);
140 
141  for (col = 0; col < wind->cols; col++) {
142  if (Rast_is_f_null_value(buff + offset + col)) {
143  *has_null = 1;
144  BM_set(nullmap, col, row, 1);
145  }
146  /* set nm */
147  }
148  }
149  G_percent(1, 1, 1);
150 
151  G_debug(4, " has_null=%d", *has_null);
152 
153  Rast_close(cellfile);
154 
155  return (1);
156 }
157 
158 /*!
159  \brief Load raster map as integer map
160 
161  Calling function must have already allocated space in buff for
162  wind->rows * wind->cols floats.
163 
164  This routine simply loads the map into a 2d array by repetitve calls
165  to get_f_raster_row.
166 
167  \todo fn body of Gs_loadmap_as_float()
168 
169  \param wind current window
170  \param map_name raster map name
171  \param[out] buff data buffer
172  \param[out] nullmap null map buffer
173  \param[out] has_null indicates if raster map contains null-data
174 
175  \return 1 on success
176  \return 0 on failure
177  */
178 int Gs_loadmap_as_int(struct Cell_head *wind, const char *map_name, int *buff,
179  struct BM *nullmap, int *has_null)
180 {
181  FILEDESC cellfile;
182  const char *map_set;
183  int offset, row, col;
184 
185  G_debug(3, "Gs_loadmap_as_int");
186 
187  map_set = G_find_raster2(map_name, "");
188  if (!map_set) {
189  G_warning(_("Raster map <%s> not found"), map_name);
190  return 0;
191  }
192  *has_null = 0;
193 
194  cellfile = Rast_open_old(map_name, map_set);
195 
196  G_message(_("Loading raster map <%s>..."),
197  G_fully_qualified_name(map_name, map_set));
198 
199  for (row = 0; row < wind->rows; row++) {
200  offset = row * wind->cols;
201  Rast_get_c_row(cellfile, &(buff[offset]), row);
202 
203  G_percent(row, wind->rows, 2);
204 
205  for (col = 0; col < wind->cols; col++) {
206  if (Rast_is_f_null_value(buff + offset + col)) {
207  *has_null = 1;
208  BM_set(nullmap, col, row, 1);
209  }
210 
211  /* set nm */
212  }
213  }
214  G_percent(1, 1, 1);
215 
216  Rast_close(cellfile);
217 
218  return (1);
219 }
220 
221 /*!
222  \brief Get map data type
223 
224  \param filename raster map name
225  \param negflag
226 
227  \return -1 if map is integer and Rast_read_range() fails
228  \return data type (ARRY_*)
229  */
230 int Gs_numtype(const char *filename, int *negflag)
231 {
232  CELL max = 0, min = 0;
233  struct Range range;
234  const char *mapset;
235  int shortbits, charbits, bitplace;
236  static int max_short, max_char;
237  static int first = 1;
238 
239  if (first) {
240  max_short = max_char = 1;
241  shortbits = 8 * sizeof(short);
242 
243  for (bitplace = 1; bitplace < shortbits; ++bitplace) {
244  /*1 bit for sign */
245  max_short *= 2;
246  }
247 
248  max_short -= 1;
249 
250  /* NO bits for sign, using unsigned char */
251  charbits = 8 * sizeof(unsigned char);
252 
253  for (bitplace = 0; bitplace < charbits; ++bitplace) {
254  max_char *= 2;
255  }
256 
257  max_char -= 1;
258 
259  first = 0;
260  }
261 
262  mapset = G_find_raster2(filename, "");
263  if (!mapset) {
264  G_warning(_("Raster map <%s> not found"), filename);
265  return -1;
266  }
267 
268  if (Rast_map_is_fp(filename, mapset)) {
269  G_debug(3, "Gs_numtype(): fp map detected");
270 
271  return (ATTY_FLOAT);
272  }
273 
274  if (-1 == Rast_read_range(filename, mapset, &range)) {
275  return (-1);
276  }
277 
278  Rast_get_range_min_max(&range, &min, &max);
279  *negflag = (min < 0);
280 
281  if (max < max_char && min > 0) {
282  return (ATTY_CHAR);
283  }
284 
285  if (max < max_short && min > -max_short) {
286  return (ATTY_SHORT);
287  }
288 
289  return (ATTY_INT);
290 }
291 
292 /*!
293  \brief Load raster map as integer map
294 
295  Calling function must have already allocated space in buff for
296  wind->rows * wind->cols shorts.
297 
298  This routine simply loads the map into a 2d array by repetitve calls
299  to get_map_row.
300 
301  \param wind current window
302  \param map_name raster map name
303  \param[out] buff data buffer
304  \param[out] nullmap null map buffer
305  \param[out] has_null indicates if raster map contains null-data
306 
307  \return 1 on success
308  \return -1 on failure,
309  \return -2 if read ok, but 1 or more values were too large (small)
310  to fit into a short (in which case the max (min) short is used)
311  */
312 int Gs_loadmap_as_short(struct Cell_head *wind, const char *map_name,
313  short *buff, struct BM *nullmap, int *has_null)
314 {
315  FILEDESC cellfile;
316  const char *map_set;
317  int *ti, *tmp_buf;
318  int offset, row, col, val, max_short, overflow, shortsize, bitplace;
319  short *ts;
320 
321  G_debug(3, "Gs_loadmap_as_short");
322 
323  overflow = 0;
324  shortsize = 8 * sizeof(short);
325 
326  /* 1 bit for sign */
327  /* same as 2 << (shortsize-1) */
328  for (max_short = bitplace = 1; bitplace < shortsize; ++bitplace) {
329  max_short *= 2;
330  }
331 
332  max_short -= 1;
333 
334  map_set = G_find_raster2(map_name, "");
335  if (!map_set) {
336  G_warning(_("Raster map <%s> not found"), map_name);
337  return -1;
338  }
339  *has_null = 0;
340 
341  cellfile = Rast_open_old(map_name, map_set);
342 
343  tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
344  if (!tmp_buf) {
345  return -1;
346  }
347 
348  G_message(_("Loading raster map <%s>..."),
349  G_fully_qualified_name(map_name, map_set));
350 
351  for (row = 0; row < wind->rows; row++) {
352  offset = row * wind->cols;
353  Rast_get_c_row(cellfile, tmp_buf, row);
354 
355  G_percent(row, wind->rows, 2);
356 
357  ts = &(buff[offset]);
358  ti = tmp_buf;
359 
360  for (col = 0; col < wind->cols; col++) {
361  if (Rast_is_c_null_value(&tmp_buf[col])) {
362  *has_null = 1;
363  BM_set(nullmap, col, row, 1);
364  }
365  else {
366  val = *ti;
367  if (abs(val) > max_short) {
368  overflow = 1;
369  /* assign floor/ceiling value?
370  */
371  *ts = (short)(max_short * val / abs(val));
372  }
373  else {
374  *ts = (short)val;
375  }
376  }
377 
378  ti++;
379  ts++;
380  }
381  }
382  G_percent(1, 1, 1);
383 
384  Rast_close(cellfile);
385 
386  G_free(tmp_buf);
387 
388  return (overflow ? -2 : 1);
389 }
390 
391 /*!
392  \brief Load raster map as integer map
393 
394  Calling function must have already allocated space in buff for
395  wind->rows * wind->cols unsigned chars.
396 
397  This routine simply loads the map into a 2d array by repetitve calls
398  to get_map_row.
399 
400  Since signs of chars can be tricky, we only load positive chars
401  between 0-255.
402 
403  \todo fn body Gs_loadmap_as_float()
404 
405  \param wind current window
406  \param map_name raster map name
407  \param[out] buff data buffer
408  \param[out] nullmap null map buffer
409  \param[out] has_null indicates if raster map contains null-data
410 
411  \return 1 on success
412  \return -1 on failure
413  \return -2 if read ok, but 1 or more values
414  were too large (small) to fit into an unsigned char.
415  (in which case the max (min) char is used)
416  */
417 int Gs_loadmap_as_char(struct Cell_head *wind, const char *map_name,
418  unsigned char *buff, struct BM *nullmap, int *has_null)
419 {
420  FILEDESC cellfile;
421  const char *map_set;
422  int *ti, *tmp_buf;
423  int offset, row, col, val, max_char, overflow, charsize, bitplace;
424  unsigned char *tc;
425 
426  G_debug(3, "Gs_loadmap_as_char");
427 
428  overflow = 0;
429  charsize = 8 * sizeof(unsigned char);
430 
431  /* 0 bits for sign! */
432  max_char = 1;
433 
434  for (bitplace = 0; bitplace < charsize; ++bitplace) {
435  max_char *= 2;
436  }
437 
438  max_char -= 1;
439 
440  map_set = G_find_raster2(map_name, "");
441  if (!map_set) {
442  G_warning(_("Raster map <%s> not found"), map_name);
443  return -1;
444  }
445  *has_null = 0;
446 
447  cellfile = Rast_open_old(map_name, map_set);
448 
449  tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
450  if (!tmp_buf) {
451  return -1;
452  }
453 
454  G_message(_("Loading raster map <%s>..."),
455  G_fully_qualified_name(map_name, map_set));
456 
457  for (row = 0; row < wind->rows; row++) {
458  offset = row * wind->cols;
459  Rast_get_c_row(cellfile, tmp_buf, row);
460  tc = (unsigned char *)&(buff[offset]);
461  ti = tmp_buf;
462 
463  G_percent(row, wind->rows, 2);
464 
465  for (col = 0; col < wind->cols; col++) {
466  if (Rast_is_c_null_value(&tmp_buf[col])) {
467  *has_null = 1;
468  BM_set(nullmap, col, row, 1);
469  }
470  else {
471  val = *ti;
472  if (val > max_char) {
473  overflow = 1;
474  *tc = (unsigned char)max_char;
475  }
476  else if (val < 0) {
477  overflow = 1;
478  *tc = 0;
479  }
480  else {
481  *tc = (unsigned char)val;
482  }
483  }
484 
485  ti++;
486  tc++;
487  }
488  }
489  G_percent(1, 1, 1);
490 
491  Rast_close(cellfile);
492 
493  G_free(tmp_buf);
494 
495  return (overflow ? -2 : 1);
496 }
497 
498 /*!
499  \brief Load raster map as integer map
500 
501  Calling function must have already allocated space in buff for
502  struct BM of wind->rows & wind->cols.
503 
504  This routine simply loads the map into the bitmap by repetitve calls
505  to get_map_row. Any value other than 0 in the map will set the bitmap.
506  (may want to change later to allow specific value to set)
507 
508  Changed to use null.
509 
510  \param wind current window
511  \param map_name raster map name
512  \param[out] buff data buffer
513 
514  \returns 1 on success
515  \return -1 on failure
516  */
517 int Gs_loadmap_as_bitmap(struct Cell_head *wind, const char *map_name,
518  struct BM *buff)
519 {
520  FILEDESC cellfile;
521  const char *map_set;
522  int *tmp_buf;
523  int row, col;
524 
525  G_debug(3, "Gs_loadmap_as_bitmap");
526 
527  map_set = G_find_raster2(map_name, "");
528  if (!map_set) {
529  G_warning(_("Raster map <%s> not found"), map_name);
530  return -1;
531  }
532 
533  cellfile = Rast_open_old(map_name, map_set);
534 
535  tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
536  if (!tmp_buf) {
537  return -1;
538  }
539 
540  G_message(_("Loading raster map <%s>..."),
541  G_fully_qualified_name(map_name, map_set));
542 
543  for (row = 0; row < wind->rows; row++) {
544  Rast_get_c_row(cellfile, tmp_buf, row);
545 
546  for (col = 0; col < wind->cols; col++) {
547  if (Rast_is_c_null_value(&tmp_buf[col])) {
548  /* no data */
549  BM_set(buff, col, row, 1);
550  }
551  else {
552  BM_set(buff, col, row, 0);
553  }
554  }
555  }
556 
557  Rast_close(cellfile);
558 
559  G_free(tmp_buf);
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(_("Color table range doesn't match data (mincol=%d, maxcol=%d"),
597  min, max);
598 
599  min = min < 0 ? 0 : min;
600  max = max > 255 ? 255 : max;
601  }
602 
603  G_zero(cats, 256 * sizeof(CELL));
604 
605  for (i = min; i <= max; i++) {
606  cats[i] = i;
607  }
608 
609  Rast_lookup_c_colors(cats, r, g, b, set, 256, &colrules);
610 
611  for (i = 0; i < 256; i++) {
612 
613  if (set[i]) {
614  buff[i] =
615  (r[i] & 0xff) | ((g[i] & 0xff) << 8) | ((b[i] & 0xff) << 16);
616  }
617  else {
618  buff[i] = NO_DATA_COL;
619  }
620  }
621 
622  return (1);
623 }
624 
625 /*!
626  \brief Pack color table
627 
628  Passed an array of 32 bit ints that is converted from cell values
629  to packed colors (0xbbggrr)
630 
631  \param filename raster map name
632  \param buff
633  \param rows number of rows
634  \param cols number of cols
635  */
636 void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
637 {
638  const char *mapset;
639  struct Colors colrules;
640  unsigned char *r, *g, *b, *set;
641  int *cur, i, j;
642 
643  mapset = G_find_raster2(filename, "");
644  if (!mapset) {
645  G_warning(_("Raster map <%s> not found"), filename);
646  return;
647  }
648 
649  r = (unsigned char *)G_malloc(cols);
650  g = (unsigned char *)G_malloc(cols);
651  b = (unsigned char *)G_malloc(cols);
652  set = (unsigned char *)G_malloc(cols);
653 
654  Rast_read_colors(filename, mapset, &colrules);
655 
656  cur = buff;
657 
658  G_message(_("Translating colors from raster map <%s>..."),
659  G_fully_qualified_name(filename, mapset));
660 
661  for (i = 0; i < rows; i++) {
662  Rast_lookup_c_colors(cur, r, g, b, set, cols, &colrules);
663  G_percent(i, rows, 2);
664 
665  for (j = 0; j < cols; j++) {
666  if (set[j]) {
667  cur[j] =
668  (r[j] & 0xff) | ((g[j] & 0xff) << 8) | ((b[j] & 0xff) <<
669  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 
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 
730  G_message(_("Translating colors from raster map <%s>..."),
731  G_fully_qualified_name(filename, mapset));
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] =
740  (r[j] & 0xff) | ((g[j] & 0xff) << 8) | ((b[j] & 0xff) <<
741  16);
742  }
743  else {
744  icur[j] = NO_DATA_COL;
745  }
746  }
747 
748  icur = &(icur[cols]);
749  fcur = &(fcur[cols]);
750  }
751  G_percent(1, 1, 1);
752 
753  Rast_free_colors(&colrules);
754 
755  G_free(r);
756  G_free(g);
757  G_free(b);
758  G_free(set);
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",
800  Rast_get_c_cat(&buf[dcol], &cats));
801  }
802  else {
803  sprintf(catstr, "(%d) %s", buf[dcol],
804  Rast_get_c_cat(&buf[dcol], &cats));
805  }
806 
807  G_free(buf);
808  }
809 
810  else {
811  /* fp map */
812  dbuf = Rast_allocate_d_buf();
813 
814  Rast_get_d_row(fd, dbuf, drow);
815  if (Rast_is_d_null_value(&dbuf[dcol])) {
816  sprintf(catstr, "(NULL) %s",
817  Rast_get_d_cat(&dbuf[dcol], &cats));
818  }
819  else {
820  sprintf(catstr, "(%g) %s", dbuf[dcol],
821  Rast_get_d_cat(&dbuf[dcol], &cats));
822  }
823 
824  G_free(dbuf);
825  }
826  }
827  else {
828  strcpy(catstr, "no category label");
829  return 0;
830  }
831 
832  /* TODO: may want to keep these around for multiple queries */
833  Rast_free_cats(&cats);
834 
835  if (fd >= 0)
836  Rast_close(fd);
837 
838  return (1);
839 }
840 
841 /*!
842  \brief Save 3dview
843 
844  \param vname view name
845  \param gv pointer to geoview struct
846  \param gd pointer to geodisplay struct
847  \param w current window
848  \param defsurf default geosurf struct
849 
850  \return -1 on error
851  \return ?
852  */
853 int Gs_save_3dview(const char *vname, geoview * gv, geodisplay * gd,
854  struct Cell_head *w, geosurf * defsurf)
855 {
856  const char *mapset;
857  struct G_3dview v;
858  float zmax, zmin;
859 
860  GS_get_zrange(&zmin, &zmax, 0);
861 
862  G_get_3dview_defaults(&v, w);
863  mapset = G_mapset();
864 
865  if (mapset != NULL) {
866  if (defsurf) {
867  if (defsurf->draw_mode & DM_WIRE_POLY) {
868  v.display_type = 3;
869  }
870  else if (defsurf->draw_mode & DM_WIRE ||
871  defsurf->draw_mode & DM_COL_WIRE) {
872  v.display_type = 1;
873  }
874  else if (defsurf->draw_mode & DM_POLY) {
875  v.display_type = 2;
876  }
877 
878  v.mesh_freq = defsurf->x_modw; /* mesh resolution */
879  v.poly_freq = defsurf->x_mod; /* poly resolution */
880  v.dozero = !(defsurf->nz_topo);
881  v.colorgrid = (defsurf->draw_mode & DM_COL_WIRE) ? 1 : 0;
882  v.shading = (defsurf->draw_mode & DM_GOURAUD) ? 1 : 0;
883  }
884 
885  if (gv->infocus) {
886  GS_v3eq(v.from_to[TO], gv->real_to);
887  v.from_to[TO][Z] -= zmin;
888  GS_v3mult(v.from_to[TO], gv->scale);
889  v.from_to[TO][Z] *= gv->vert_exag;
890  }
891  else {
892  GS_v3eq(v.from_to[TO], gv->from_to[TO]);
893  }
894 
896 
897  GS_v3eq(v.from_to[FROM], gv->from_to[FROM]);
899 
900  v.exag = gv->vert_exag;
901  v.fov = gv->fov / 10.;
902  v.twist = gv->twist;
903  v.fringe = 0; /* not implemented here */
904 
905  v.lightson = 1; /* always true, curently */
906 
907  if (gv->lights[0].position[W] == 1) {
908  /* local */
909  v.lightpos[X] = gv->lights[0].position[X];
910  v.lightpos[Y] = gv->lights[0].position[Y];
911  v.lightpos[Z] = gv->lights[0].position[Z];
913  v.lightpos[W] = 1.0; /* local */
914  }
915  else {
916  v.lightpos[X] = gv->lights[0].position[X];
917  v.lightpos[Y] = gv->lights[0].position[Y];
918  v.lightpos[Z] = gv->lights[0].position[Z];
919  v.lightpos[W] = 0.0; /* inf */
920  }
921 
922  v.lightcol[0] = gv->lights[0].color[0];
923  v.lightcol[1] = gv->lights[0].color[1];
924  v.lightcol[2] = gv->lights[0].color[2];
925 
926  v.ambient = (gv->lights[0].ambient[0] + gv->lights[0].ambient[1] +
927  gv->lights[0].ambient[2]) / 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, mapset, &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
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,
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 inconsistancies"));
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  pt[0] = (v.from_to[TO][X] - w->west) - w->ew_res / 2.;
978  pt[1] = (v.from_to[TO][Y] - w->south) - w->ns_res / 2.;
979  pt[2] = v.from_to[TO][Z];
980  GS_set_focus(pt);
981 
982  /* FROM */
983  pt[0] = (float)v.from_to[FROM][X];
984  pt[1] = (float)v.from_to[FROM][Y];
985  pt[2] = (float)v.from_to[FROM][Z];
986  GS_moveto_real(pt);
987 
988  if (defsurf) {
989  int dmode = 0;
990 
992  v.mesh_freq, v.mesh_freq);
993 
994  while (v.display_type >= 10) {
995  /* globe stuff not used */
996  v.display_type -= 10;
997  }
998 
999  /* set drawing modes */
1000  if (v.colorgrid) {
1001  dmode |= DM_COL_WIRE;
1002  }
1003 
1004  if (v.shading) {
1005  dmode |= DM_GOURAUD;
1006  }
1007 
1008  switch (v.display_type) {
1009  case 1:
1010  dmode |= DM_WIRE;
1011 
1012  break;
1013  case 2:
1014  dmode |= DM_POLY;
1015 
1016  break;
1017  case 3:
1018  dmode |= DM_WIRE_POLY;
1019 
1020  break;
1021  }
1022  GS_setall_drawmode(dmode);
1023 
1024  /* should also set nozeros here */
1025  }
1026 
1027  /* set exaggeration */
1028  if (v.exag)
1030 
1031  /* Set FOV */
1032  if (v.fov) {
1033  GS_set_fov((int)
1034  (v.fov > 0 ? v.fov * 10. + 0.5 : v.fov * 10. - 0.5));
1035  }
1036  else {
1037  /* TODO: do ortho */
1038  }
1039 
1040  /* Set twist */
1041  if (v.twist)
1042  GS_set_twist((int)(v.twist > 0 ? v.twist + 0.5 : v.twist - 0.5));
1043 
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 
1068  } /* Done with lights */
1069 
1070 
1071  GS_alldraw_wire();
1072 
1073  } /* Done with file */
1074  return (1);
1075 
1076 }
1077 
1078 /*!
1079  \brief Update no_zero ranges for attribute (actually no_null now)
1080 
1081  \param gs pointer to geosurf struct
1082  \param desc attribute id (descriptor)
1083 
1084  \return -1 on error
1085  \return 1 on success
1086  */
1087 int Gs_update_attrange(geosurf * gs, int desc)
1088 {
1089  size_t size;
1090  float min = 0.0;
1091  float max = 0.0;
1092  typbuff *tb;
1093  struct BM *nm;
1094  int found;
1095 
1096  gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].range_nz =
1097  0.0;
1098 
1099  if (CONST_ATT == gs_get_att_src(gs, desc)) {
1100  gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].constant;
1101  min = max = gs->att[desc].constant;
1102  gs->att[desc].range_nz = 0.0;
1103  }
1104  else if (CF_COLOR_PACKED & gsds_get_changed(gs->att[desc].hdata)) {
1105  gs->att[desc].max_nz = 0xFFFFFF;
1106  gs->att[desc].min_nz = 0x010101;
1107  gs->att[desc].range_nz = 0xFFFFFF;
1108  }
1109  else {
1110  if (NULL == (tb = gsds_get_typbuff(gs->att[desc].hdata, 0))) {
1111  return (-1);
1112  }
1113 
1114  nm = tb->nm;
1115 
1116  if (tb->ib) {
1117  int *p;
1118 
1119  size = (size_t)gs->rows * gs->cols;
1120  p = tb->ib;
1121  INIT_MINMAX(p, nm, size, min, max, found);
1122 
1123  if (!found) {
1124  /* all nulls! */
1125  return (-1);
1126  }
1127 
1128  size = (size_t)gs->rows * gs->cols;
1129  p = tb->ib;
1130  SET_MINMAX(p, nm, size, min, max);
1131  }
1132  else if (tb->sb) {
1133  short *p;
1134 
1135  size = (size_t)gs->rows * gs->cols;
1136  p = tb->sb;
1137  INIT_MINMAX(p, nm, size, min, max, found);
1138 
1139  if (!found) {
1140  /* all nulls! */
1141  return (-1);
1142  }
1143 
1144  size = (size_t)gs->rows * gs->cols;
1145  p = tb->sb;
1146  SET_MINMAX(p, nm, size, min, max);
1147  }
1148  else if (tb->cb) {
1149  char *p;
1150 
1151  size = (size_t)gs->rows * gs->cols;
1152  p = (char *)tb->cb;
1153  INIT_MINMAX(p, nm, size, min, max, found);
1154 
1155  if (!found) {
1156  /* all nulls! */
1157  return (-1);
1158  }
1159 
1160  size = (size_t)gs->rows * gs->cols;
1161  p = (char *)tb->cb;
1162  SET_MINMAX(p, nm, size, min, max);
1163  }
1164  else if (tb->fb) {
1165  float *p;
1166 
1167  size = (size_t)gs->rows * gs->cols;
1168  p = tb->fb;
1169  INIT_MINMAX(p, nm, size, min, max, found);
1170 
1171  if (!found) {
1172  /* all nulls! */
1173  return (-1);
1174  }
1175 
1176  size = (size_t)gs->rows * gs->cols;
1177  p = tb->fb;
1178  SET_MINMAX(p, nm, size, min, max);
1179  }
1180 
1181  gs->att[desc].max_nz = max;
1182  gs->att[desc].min_nz = min;
1183  gs->att[desc].range_nz = gs->att[desc].max_nz - gs->att[desc].min_nz;
1184  }
1185 
1186  if (ATT_TOPO == desc) {
1187  gs->zmin = min;
1188  gs->zmax = max;
1189  gs->zrange = gs->zmax - gs->zmin;
1190  gs->zminmasked = gs->zmin;
1191  gs->zmax_nz = gs->zmax;
1192  gs->zmin_nz = gs->zmin;
1193  gs->zrange_nz = gs->zmax_nz - gs->zmin_nz;
1194  }
1195 
1196  G_debug(3, "Gs_update_attrange(): min=%f max=%f", gs->zmin, gs->zmax);
1197 
1198  return (1);
1199 }
float scale
Definition: ogsf.h:487
#define CELL_TYPE
Definition: raster.h:11
#define G_malloc(n)
Definition: defs/gis.h:112
int colorgrid
Definition: gis.h:497
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&#39;t touch) ...
Definition: find_file.c:249
float min_nz
Definition: ogsf.h:253
float zmin
Definition: ogsf.h:268
#define ATTY_CHAR
Definition: ogsf.h:168
float from_to[2][3]
Definition: gis.h:488
float ambient[3]
Definition: ogsf.h:465
int FILEDESC
Definition: gs3.c:70
#define DM_WIRE_POLY
Definition: ogsf.h:62
float twist
Definition: gis.h:490
typbuff * gsds_get_typbuff(int, IFLAG)
Get data buffer.
Definition: gsds.c:281
float max_nz
Definition: ogsf.h:253
short * sb
Definition: ogsf.h:208
float zrange_nz
Definition: ogsf.h:270
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:417
int G_get_3dview(const char *, const char *, struct G_3dview *)
Gets a 3D View.
Definition: view.c:251
2D/3D raster map header (used also for region)
Definition: gis.h:423
void GS_set_focus(float *)
Set focus.
Definition: gs2.c:2520
#define Rast_is_d_null_value(dcellVal)
Definition: defs/raster.h:414
int BM_set(struct BM *, int, int, int)
Sets bitmap value to &#39;val&#39; at location &#39;x&#39; &#39;y&#39;.
Definition: bitmap.c:190
float lightcol[3]
Definition: gis.h:506
#define min(x, y)
Definition: draw2.c:31
int Gs_update_attrange(geosurf *gs, int desc)
Update no_zero ranges for attribute (actually no_null now)
Definition: gs3.c:1087
double west
Extent coordinates (west)
Definition: gis.h:475
int rows
Definition: ogsf.h:260
double DCELL
Definition: gis.h:614
int poly_freq
Definition: gis.h:493
float zmax_nz
Definition: ogsf.h:270
#define ATT_TOPO
Definition: ogsf.h:73
int gs_get_att_src(geosurf *, int)
Get attribute source.
Definition: gs.c:656
#define NO_DATA_COL
Definition: gs3.c:72
int Gs_build_256lookup(const char *filename, int *buff)
Build color table (256)
Definition: gs3.c:576
int G_put_3dview(const char *, const char *, const struct G_3dview *, const struct Cell_head *)
Saves info to a 3d.view file.
Definition: view.c:170
int fringe
Definition: gis.h:499
void Rast_get_d_row(int, DCELL *, int)
Get raster row (DCELL type)
float range_nz
Definition: ogsf.h:253
int * ib
Definition: ogsf.h:207
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
Definition: bitmap.h:17
#define INIT_MINMAX(p, nm, size, min, max, found)
Used in the function Gs_update_attrange()
Definition: gs3.c:35
int GS_setall_drawres(int, int, int, int)
Set all draw resolutions.
Definition: gs2.c:2198
int gsds_get_changed(int)
ADD.
Definition: gsds.c:615
#define Rast_is_f_null_value(fcellVal)
Definition: defs/raster.h:412
#define DM_COL_WIRE
Definition: ogsf.h:60
#define NULL
Definition: ccmath.h:32
char pgm_id[40]
Definition: gis.h:487
int display_type
Definition: gis.h:494
float ambient
Definition: gis.h:507
float shine
Definition: gis.h:508
#define max(x, y)
Definition: draw2.c:32
void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
Pack color table.
Definition: gs3.c:636
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
Definition: range.c:160
float lightpos[4]
Definition: gis.h:505
int GS_setall_drawmode(int)
Set all draw-modes.
Definition: gs2.c:2061
void GS_moveto_real(float *)
Move position to (real)
Definition: gs2.c:2647
#define W
Definition: ogsf.h:140
int shading
Definition: gis.h:498
float zrange
Definition: ogsf.h:269
void GS_alldraw_wire(void)
Draw all wires.
Definition: gs2.c:1919
#define ATTY_SHORT
Definition: ogsf.h:167
int dozero
Definition: gis.h:496
void G_message(const char *,...) __attribute__((format(printf
int cols
Definition: ogsf.h:260
void Rast_get_c_row(int, CELL *, int)
Get raster row (CELL type)
double Gs_distance(double *from, double *to)
Calculates distance in METERS between two points in current projection (2D)
Definition: gs3.c:84
IFLAG draw_mode
Definition: ogsf.h:262
#define ATTY_FLOAT
Definition: ogsf.h:165
int x_mod
Definition: ogsf.h:271
char * Rast_get_c_cat(CELL *, struct Categories *)
Get a raster category label (CELL)
Definition: raster/cats.c:323
DCELL * Rast_allocate_d_buf(void)
Allocates memory for a raster map of type DCELL.
Definition: alloc_cell.c:108
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition: nme_in_mps.c:101
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:517
double b
Definition: r_raster.c:39
#define ATTY_INT
Definition: ogsf.h:166
char * Rast_get_d_cat(DCELL *, struct Categories *)
Get a raster category label (DCELL)
Definition: raster/cats.c:371
float zminmasked
Definition: ogsf.h:268
double south
Extent coordinates (south)
Definition: gis.h:471
int fov
Definition: ogsf.h:485
void GS_set_twist(int)
Set viewpoint twist value.
Definition: gs2.c:2877
#define DM_POLY
Definition: ogsf.h:61
int mesh_freq
Definition: gis.h:492
Definition: ogsf.h:478
float zmin_nz
Definition: ogsf.h:270
int nz_topo
Definition: ogsf.h:272
struct Cell_head vwin
Definition: gis.h:509
#define DM_GOURAUD
Definition: ogsf.h:54
int hdata
Definition: ogsf.h:249
float fov
Definition: gis.h:489
float g
Definition: named_colr.c:8
void Rast_free_colors(struct Colors *)
Free color structure memory.
Definition: color_free.c:30
int lightson
Definition: gis.h:495
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
float vert_exag
Definition: ogsf.h:486
int Rast_open_old(const char *, const char *)
Open an existing integer raster map (cell)
Definition: raster/open.c:112
int G_get_3dview_defaults(struct G_3dview *, struct Cell_head *)
Sets default for v based on w.
Definition: view.c:62
#define FROM
Definition: ogsf.h:141
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:178
#define Z
Definition: ogsf.h:139
gsurf_att att[MAX_ATTS]
Definition: ogsf.h:261
Definition: raster.h:225
float shine
Definition: ogsf.h:467
float FCELL
Definition: gis.h:615
int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr)
Get categories/labels.
Definition: gs3.c:776
#define DM_WIRE
Definition: ogsf.h:59
Definition: gis.h:676
void G_percent(long, long, int)
Print percent complete messages.
Definition: percent.c:62
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:114
#define Y
Definition: ogsf.h:138
Definition: gis.h:485
#define CF_COLOR_PACKED
Definition: ogsf.h:180
int int G_begin_distance_calculations(void)
Begin distance calculations.
Definition: gis/distance.c:42
int cols
Number of columns for 2D data.
Definition: gis.h:442
void GS_v3eq(float *, float *)
Copy vector values.
Definition: gs_util.c:178
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:312
int infocus
Definition: ogsf.h:482
int Rast_read_cats(const char *, const char *, struct Categories *)
Read raster category file.
Definition: raster/cats.c:104
double ns_res
Resolution - north to south cell size for 2D data.
Definition: gis.h:463
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
int Rast_read_colors(const char *, const char *, struct Colors *)
Read color table of raster map.
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
void Rast_get_c_color_range(CELL *, CELL *, const struct Colors *)
Get color range values (CELL)
Definition: color_range.c:64
void G_warning(const char *,...) __attribute__((format(printf
Definition: ogsf.h:204
int CELL
Definition: gis.h:613
float real_to[4]
Definition: ogsf.h:486
float color[3]
Definition: ogsf.h:464
void Rast_free_cats(struct Categories *)
Free category structure memory.
Definition: raster/cats.c:1213
#define TO
Definition: ogsf.h:142
RASTER_MAP_TYPE Rast_get_map_type(int)
Determine raster type from descriptor.
Definition: raster/open.c:918
float position[4]
Definition: ogsf.h:463
#define _(str)
Definition: glocale.h:10
double G_distance(double, double, double, double)
Returns distance in meters.
Definition: gis/distance.c:75
int RASTER_MAP_TYPE
Definition: raster.h:25
#define X
Definition: ogsf.h:137
const char * G_find_raster2(const char *, const char *)
Find a raster map (look but don&#39;t touch)
Definition: find_rast.c:76
float zmax
Definition: ogsf.h:268
int Gs_numtype(const char *filename, int *negflag)
Get map data type.
Definition: gs3.c:230
float exag
Definition: gis.h:491
int GS_get_zrange(float *, float *, int)
Get z-extent for all loaded surfaces.
Definition: gs2.c:2689
int Gs_load_3dview(const char *vname, geoview *gv, geodisplay *gd, struct Cell_head *w, const geosurf *defsurf)
Load 3dview.
Definition: gs3.c:951
void gsd_model2real(Point3)
Convert model to real coordinates.
Definition: gsd_views.c:393
#define SET_MINMAX(p, nm, size, min, max)
Used in the function Gs_update_attrange()
Definition: gs3.c:52
int Gs_save_3dview(const char *vname, geoview *gv, geodisplay *gd, struct Cell_head *w, geosurf *defsurf)
Save 3dview.
Definition: gs3.c:853
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
double ew_res
Resolution - east to west cell size for 2D data.
Definition: gis.h:459
int x_modw
Definition: ogsf.h:271
struct BM * nm
Definition: ogsf.h:211
void GS_set_global_exag(float)
Set global z-exag value.
Definition: gs2.c:1977
#define CONST_ATT
Definition: ogsf.h:84
int surfonly
Definition: gis.h:500
int rows
Number of rows for 2D data.
Definition: gis.h:438
float * fb
Definition: ogsf.h:206
#define Rast_is_c_null_value(cellVal)
Definition: defs/raster.h:410
int G_debug(int, const char *,...) __attribute__((format(printf
CELL * Rast_allocate_c_buf(void)
Allocate memory for a CELL type raster map.
Definition: alloc_cell.c:82
int twist
Definition: ogsf.h:485
Definition: ogsf.h:257
float constant
Definition: ogsf.h:251
double r
Definition: r_raster.c:39
unsigned char * cb
Definition: ogsf.h:209
void Rast_close(int)
Close a raster map.
Definition: raster/close.c:99
int Rast_map_is_fp(const char *, const char *)
Check if raster map is floating-point.
Definition: raster/open.c:847
float from_to[2][4]
Definition: ogsf.h:483
void GS_v3mult(float *, float)
Multiple vectors.
Definition: gs_util.c:229
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
Definition: range.c:714
void Rast_get_f_row(int, FCELL *, int)
Get raster row (FCELL type)
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:113
struct lightdefs lights[MAX_LIGHTS]
Definition: ogsf.h:488
void GS_set_fov(int)
Set field of view.
Definition: gs2.c:2843