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