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