GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d37ee165c
map_obj.c
Go to the documentation of this file.
1 /*!
2  \file lib/nviz/map_obj.c
3 
4  \brief Nviz library -- Define creation and interface functions for map objects.
5 
6  Map objects are considered to be surfaces, vector plots, or site
7  files.
8 
9  Based on visualization/nviz/src/map_obj.c
10 
11  (C) 2008, 2010 by the GRASS Development Team
12  This program is free software under the GNU General Public License
13  (>=v2). Read the file COPYING that comes with GRASS for details.
14 
15  \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
16  */
17 
18 #include <stdlib.h>
19 #include <time.h>
20 
21 #include <grass/glocale.h>
22 #include <grass/nviz.h>
23 
24 /*!
25  \brief Create a new map object which can be one of surf, vect, vol or site.
26 
27  This routine creates the object internally in the gsf libraryb.
28  Optionally, a logical name may be specified for the new map object.
29  If no name is specified, a logical name is assigned to the new
30  object automatically. Note that maintaining unique logical names is
31  not the responsibility of the library (currently).
32 
33  Initially map objects contain no data, use the attribute commands to
34  set attributes such as topology, color, etc.
35 
36  \param type map object type
37  \param name map name (NULL for constant)
38  \param value constant (used if <i>name</i> is NULL)
39  \param data nviz data
40 
41  \return map object id
42  \return -1 on error
43  */
44 int Nviz_new_map_obj(int type, const char *name, double value, nv_data * data)
45 {
46  int new_id, i;
47  int num_surfs, *surf_list;
48 
49  /*
50  * For each type of map obj do the following --
51  * 1) Verify we haven't maxed out the number of
52  * allowed objects.
53  * 2) Call the internal library to generate a new
54  * map object of the specified type.
55  */
56  /* raster -> surface */
57  if (type == MAP_OBJ_SURF) {
58  if (GS_num_surfs() >= MAX_SURFS) {
59  G_warning(_("Maximum surfaces loaded!"));
60  return -1;
61  }
62 
63  new_id = GS_new_surface();
64 
65  if (new_id < 0) {
66  return -1;
67  }
68 
69  if (name) {
70  /* map */
71  if (!Nviz_set_attr(new_id, MAP_OBJ_SURF, ATT_TOPO,
72  MAP_ATT, name, -1.0, data)) {
73  return -1;
74  }
75  }
76  else {
77  /* constant */
78  if (!Nviz_set_attr(new_id, MAP_OBJ_SURF, ATT_TOPO,
79  CONST_ATT, NULL, value,
80  data)) {
81  return -1;
82  }
83  }
84  }
85  /* vector overlay */
86  else if (type == MAP_OBJ_VECT) {
87  if (GV_num_vects() >= MAX_VECTS) {
88  G_warning(_("Maximum vector line maps loaded!"));
89  return -1;
90  }
91 
92  new_id = GV_new_vector();
93 
94  if (name) {
95  if (GV_load_vector(new_id, name) < 0) {
96  GV_delete_vector(new_id);
97  G_warning(_("Error loading vector map <%s>"), name);
98  return -1;
99  }
100  }
101 
102  /* initialize display parameters
103  automatically select all surfaces to draw vector */
104  GV_set_style(new_id, 1, 0x000000, 2, 0);
105  surf_list = GS_get_surf_list(&num_surfs);
106  if (num_surfs) {
107  for (i = 0; i < num_surfs; i++) {
108  GV_select_surf(new_id, surf_list[i]);
109  }
110  }
111  G_free(surf_list);
112  }
113  /* vector points overlay */
114  else if (type == MAP_OBJ_SITE) {
115  if (GP_num_sites() >= MAX_SITES) {
116  G_warning(_("Maximum vector point maps loaded!"));
117  return -1;
118  }
119 
120  new_id = GP_new_site();
121 
122  /* initizalize site attributes */
124 
125  /* load vector points */
126  if (0 > GP_load_site(new_id, name)) {
127  GP_delete_site(new_id);
128  G_warning(_("Error loading vector map <%s>"), name);
129  return -1;
130  }
131 
132  /* initialize display parameters */
133  GP_set_style(new_id, 0x000000, 2, 100, ST_X);
134  surf_list = GS_get_surf_list(&num_surfs);
135  for (i = 0; i < num_surfs; i++) {
136  GP_select_surf(new_id, surf_list[i]);
137  }
138  G_free(surf_list);
139  }
140  /* 3d raster map -> volume */
141  else if (type == MAP_OBJ_VOL) {
142  if (GVL_num_vols() >= MAX_VOLS) {
143  G_warning(_("Maximum volumes loaded!"));
144  return -1;
145  }
146 
147  new_id = GVL_new_vol();
148 
149  /* load volume */
150  if (0 > GVL_load_vol(new_id, name)) {
151  GVL_delete_vol(new_id);
152  G_warning(_("Error loading 3d raster map <%s>"), name);
153  return -1;
154  }
155 
156  /* initilaze volume attributes */
158  }
159  else {
160  G_warning(_("Nviz_new_map_obj(): unsupported data type"));
161  return -1;
162  }
163 
164  return new_id;
165 }
166 
167 /*!
168  Set map object attribute
169 
170  \param id map object id
171  \param type map object type (MAP_OBJ_SURF, MAP_OBJ_VECT, ...)
172  \param desc attribute descriptor
173  \param src attribute source
174  \param str_value attribute value as string (if NULL, check for <i>num_value</i>)
175  \param num_value attribute value as double
176 
177  \return 1 on success
178  \return 0 on failure
179  */
180 int Nviz_set_attr(int id, int type, int desc, int src,
181  const char *str_value, double num_value, nv_data * data)
182 {
183  int ret;
184  double value;
185 
186  switch (type) {
187  case (MAP_OBJ_SURF):{
188  /* Basically two cases, either we are setting to a constant field, or
189  * we are loading an actual file. Setting a constant is the easy part
190  * so we try and do that first.
191  */
192  if (src == CONST_ATT) {
193  /* Get the value for the constant
194  * Note that we require the constant to be an integer
195  */
196  if (str_value)
197  value = (double)atof(str_value);
198  else
199  value = num_value;
200 
201  /* Only special case is setting constant color.
202  * In this case we have to decode the constant Tcl
203  * returns so that the gsf library understands it.
204  */
205  if (desc == ATT_COLOR) {
206  /* TODO check this - sometimes gets reversed when save state
207  saves a surface with constant color
208 
209  int r, g, b;
210  r = (((int) value) & RED_MASK) >> 16;
211  g = (((int) value) & GRN_MASK) >> 8;
212  b = (((int) value) & BLU_MASK);
213  value = r + (g << 8) + (b << 16);
214  */
215  }
216 
217  /* Once the value is parsed, set it */
218  ret = GS_set_att_const(id, desc, value);
219  }
220  else if (src == MAP_ATT) {
221  ret = GS_load_att_map(id, str_value, desc);
222  }
223  else
224  ret = -1;
225 
226  /* After we've loaded a constant map or a file,
227  * may need to adjust resolution if we are resetting
228  * topology (for example)
229  */
230  if (0 <= ret) {
231  if (desc == ATT_TOPO) {
232  int rows, cols, max;
233  int max2;
234 
235  /* If topology attribute is being set then need to set
236  * resolution of incoming map to some sensible value so we
237  * don't wait all day for drawing.
238  */
239  GS_get_dims(id, &rows, &cols);
240  max = (rows > cols) ? rows : cols;
241  max = max / 50;
242  if (max < 1)
243  max = 1;
244  max2 = max / 5;
245  if (max2 < 1)
246  max2 = 1;
247  /* reset max to finer for coarse surf drawing */
248  max = max2 + max2 / 2;
249  if (max < 1)
250  max = 1;
251 
252  GS_set_drawres(id, max2, max2, max, max);
254  }
255 
256  /* Not sure about this next line, should probably just
257  * create separate routines to figure the Z range as well
258  * as the XYrange
259  */
260  Nviz_update_ranges(data);
261 
262  break;
263  }
264  default:{
265  return 0;
266  }
267  }
268  }
269 
270  return 1;
271 }
272 
273 /*!
274  \brief Set default surface attributes
275  */
277 {
278  float defs[MAX_ATTS];
279 
280  defs[ATT_TOPO] = 0;
282  defs[ATT_MASK] = 0;
283  defs[ATT_TRANSP] = 0;
284  defs[ATT_SHINE] = 60;
285  defs[ATT_EMIT] = 0;
286 
287  GS_set_att_defaults(defs, defs);
288 
289  return;
290 }
291 
292 /*!
293  \brief Set default vector point attributes
294 
295  \param id vector point set id
296 
297  \return 1 on success
298  \return 0 on failure
299  */
301 {
302  geosite *gp;
303 
304  gp = gp_get_site(id);
305 
306  if (!gp)
307  return 0;
308 
309  return 1;
310 }
311 
312 /*!
313  \brief Set default volume attributes
314 
315  \param id volume set id
316 
317  \return 1 on success
318  \return 0 on failure
319  */
321 {
322  int rows, cols, depths;
323  int max;
324 
325  GVL_get_dims(id, &rows, &cols, &depths);
326  max = (rows > cols) ? rows : cols;
327  max = (depths > max) ? depths : max;
328  max = max / 35;
329  if (max < 1)
330  max = 1;
331 
332  if (max > cols)
333  max = cols / 2;
334  if (max > rows)
335  max = rows / 2;
336  if (max > depths)
337  max = depths / 2;
338 
339  /* set default drawres and drawmode for isosurfaces */
340  GVL_isosurf_set_drawres(id, max, max, max);
342 
343  /* set default drawres and drawmode for slices */
344  GVL_slice_set_drawres(id, 1, 1, 1);
346 
347  return 1;
348 }
349 
350 /*!
351  Unset map object attribute
352 
353  \param id map object id
354  \param type map object type (MAP_OBJ_SURF, MAP_OBJ_VECT, ...)
355  \param desc attribute descriptor
356 
357  \return 1 on success
358  \return 0 on failure
359  */
360 int Nviz_unset_attr(int id, int type, int desc)
361 {
362  if (type == MAP_OBJ_SURF) {
363  return GS_unset_att(id, desc);
364  }
365 
366  return 0;
367 }
#define MAP_OBJ_SITE
Definition: nviz.h:46
int GV_select_surf(int, int)
Select surface identified by hs to have vector identified by hv draped over it.
Definition: gv2.c:393
int GV_load_vector(int, const char *)
Load vector set.
Definition: gv2.c:171
int GVL_new_vol(void)
Create new volume set.
Definition: gvl2.c:136
#define ATT_SHINE
Definition: ogsf.h:77
#define DEFAULT_SURF_COLOR
Definition: nviz.h:63
int GVL_num_vols(void)
Get number of loaded volume sets.
Definition: gvl2.c:166
#define ATT_TOPO
Definition: ogsf.h:73
Definition: ogsf.h:365
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
int GVL_load_vol(int, const char *)
Load 3d raster map to volume set.
Definition: gvl2.c:256
int GP_num_sites(void)
Get number of loaded point sets.
Definition: gp2.c:86
int GS_set_drawmode(int, int)
Set draw mode.
Definition: gs2.c:2083
#define NULL
Definition: ccmath.h:32
int Nviz_set_attr(int id, int type, int desc, int src, const char *str_value, double num_value, nv_data *data)
Definition: map_obj.c:180
#define max(x, y)
Definition: draw2.c:32
#define MAX_SURFS
Definition: ogsf.h:38
int GVL_slice_set_drawmode(int, int)
Set slice draw mode.
Definition: gvl2.c:1165
void GS_set_att_defaults(float *, float *)
Set default attributes for map objects.
Definition: gs2.c:172
int Nviz_set_volume_attr_default(int id)
Set default volume attributes.
Definition: map_obj.c:320
int GVL_isosurf_set_drawres(int, int, int, int)
Set isosurface draw resolution.
Definition: gvl2.c:575
int Nviz_update_ranges(nv_data *)
Update ranges.
Definition: change_view.c:60
int GP_select_surf(int, int)
Select surface for given point set.
Definition: gp2.c:480
void GS_get_dims(int, int *, int *)
Get dimension of surface.
Definition: gs2.c:2279
int GP_delete_site(int)
Delete registrated point set.
Definition: gp2.c:131
int GS_new_surface(void)
Add new surface.
Definition: gs2.c:224
int GS_set_att_const(int, int, float)
Set attribute constant.
Definition: gs2.c:1412
geosite * gp_get_site(int)
Get geosite struct.
Definition: gp.c:32
int GVL_slice_set_drawres(int, int, int, int)
Set slice draw resolution.
Definition: gvl2.c:1104
#define DM_POLY
Definition: ogsf.h:61
#define MAP_ATT
Definition: ogsf.h:83
#define DM_GOURAUD
Definition: ogsf.h:54
#define ST_X
Definition: ogsf.h:89
int Nviz_unset_attr(int id, int type, int desc)
Definition: map_obj.c:360
int GP_new_site(void)
Create new point set.
Definition: gp2.c:63
#define ATT_COLOR
Definition: ogsf.h:74
#define MAP_OBJ_VOL
Definition: nviz.h:44
#define MAX_VOLS
Definition: ogsf.h:41
int * GS_get_surf_list(int *)
Get surface list.
Definition: gs2.c:1539
int GV_delete_vector(int)
Delete vector set from list.
Definition: gv2.c:128
int Nviz_set_vpoint_attr_default(int id)
Set default vector point attributes.
Definition: map_obj.c:300
void GVL_get_dims(int, int *, int *, int *)
Get volume dimensions.
Definition: gvl2.c:309
#define MAP_OBJ_SURF
Definition: nviz.h:43
int GS_load_att_map(int, const char *, int)
Load raster map as attribute.
Definition: gs2.c:1608
#define MAX_SITES
Definition: ogsf.h:40
int GVL_delete_vol(int)
Delete volume set from list.
Definition: gvl2.c:210
#define ATT_TRANSP
Definition: ogsf.h:76
Definition: nviz.h:101
void G_warning(const char *,...) __attribute__((format(printf
void Nviz_set_surface_attr_default()
Set default surface attributes.
Definition: map_obj.c:276
#define _(str)
Definition: glocale.h:10
#define DM_GRID_SURF
Definition: ogsf.h:65
int GVL_isosurf_set_drawmode(int, int)
Set isosurface draw mode.
Definition: gvl2.c:636
int Nviz_new_map_obj(int type, const char *name, double value, nv_data *data)
Create a new map object which can be one of surf, vect, vol or site.
Definition: map_obj.c:44
#define MAX_ATTS
Definition: ogsf.h:43
int GS_set_drawres(int, int, int, int, int)
Set draw resolution for surface.
Definition: gs2.c:2221
int GV_set_style(int, int, int, int, int)
Set vector style.
Definition: gv2.c:228
#define ATT_MASK
Definition: ogsf.h:75
const char * name
Definition: named_colr.c:7
#define MAP_OBJ_VECT
Definition: nviz.h:45
int GP_set_style(int, int, int, float, int)
Set point style.
Definition: gp2.c:273
#define ATT_EMIT
Definition: ogsf.h:78
int GV_num_vects(void)
Get number of available vector sets.
Definition: gv2.c:83
#define CONST_ATT
Definition: ogsf.h:84
int GS_unset_att(int, int)
Unset attribute.
Definition: gs2.c:1393
int GV_new_vector(void)
Register new vector set.
Definition: gv2.c:60
int GP_load_site(int, const char *)
Load point set from file.
Definition: gp2.c:172
#define MAX_VECTS
Definition: ogsf.h:39
int GS_num_surfs(void)
Get number of surfaces.
Definition: gs2.c:1524