1 /*!
2 \file vector.c
3
4 \brief Vector subroutines
5
6 (C) 2008-2013 by the GRASS Development Team
7
8 This program is free software under the GNU General Public
9 License (>=v2). Read the file COPYING that comes with GRASS
10 for details.
11
12 \author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
13 */
14
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include <grass/vector.h>
19 #include <grass/dbmi.h>
20 #include <grass/glocale.h>
21
22 #include "local_proto.h"
23
24 static int load_vectors(const struct Option *, const struct Option *,
25 const struct Option *, const struct Option *, int,
26 nv_data *);
27
28 /*!
29 \brief Load vector maps (lines)
30
31 \param params module parameters
32 \param data nviz data
33
34 \return number of loaded vectors
35 */
load_vlines(const struct GParams * params,nv_data * data)36 int load_vlines(const struct GParams *params, nv_data * data)
37 {
38 return load_vectors(params->elev_map, params->elev_const,
39 params->vlines, params->vline_pos,
40 MAP_OBJ_VECT, data);
41 }
42
43 /*!
44 \brief Load vector maps (points)
45
46 \param params module parameters
47 \param data nviz data
48
49 \return number of loaded vectors
50 */
load_vpoints(const struct GParams * params,nv_data * data)51 int load_vpoints(const struct GParams *params, nv_data * data)
52 {
53 return load_vectors(params->elev_map, params->elev_const,
54 params->vpoints, params->vpoint_pos,
55 MAP_OBJ_SITE, data);
56 }
57
load_vectors(const struct Option * elev_map,const struct Option * elev_const,const struct Option * vect,const struct Option * position,int map_obj_type,nv_data * data)58 int load_vectors(const struct Option *elev_map,
59 const struct Option *elev_const, const struct Option *vect,
60 const struct Option *position,
61 int map_obj_type, nv_data * data)
62 {
63 int i, id;
64 int nvects;
65
66 const char *mapset;
67
68 double x, y, z;
69
70 if ((!elev_map->answer || elev_const->answer) && GS_num_surfs() == 0) { /* load base surface if no loaded */
71 int *surf_list, nsurf;
72
73 Nviz_new_map_obj(MAP_OBJ_SURF, NULL, 0.0, data);
74
75 surf_list = GS_get_surf_list(&nsurf);
76 GS_set_att_const(surf_list[0], ATT_TRANSP, 255);
77 }
78
79 nvects = 0;
80
81 for (i = 0; vect->answers[i]; i++) {
82 mapset = G_find_vector2(vect->answers[i], "");
83 if (mapset == NULL) {
84 G_fatal_error(_("Vector map <%s> not found"), vect->answers[i]);
85 }
86 id = Nviz_new_map_obj(map_obj_type,
87 G_fully_qualified_name(vect->answers[i],
88 mapset), 0.0, data);
89
90 /* set position */
91 x = atof(position->answers[i * 3 + 0]);
92 y = atof(position->answers[i * 3 + 1]);
93 z = atof(position->answers[i * 3 + 2]);
94
95 if (map_obj_type == MAP_OBJ_VECT)
96 GV_set_trans(id, x, y, z);
97 else
98 GP_set_trans(id, x, y, z);
99
100 nvects++;
101 }
102
103 return nvects;
104 }
105
106 /*!
107 \brief Set vector lines mode
108
109 \param params parameters
110
111 \return 1 on success
112 \return 0 on failure
113 */
vlines_set_attrb(const struct GParams * params)114 int vlines_set_attrb(const struct GParams *params)
115 {
116 int i, layer, color, width, flat, height;
117 int *vect_list, nvects;
118 int have_colors;
119
120 char *color_column, *width_column;
121 struct Colors colors;
122
123 vect_list = GV_get_vect_list(&nvects);
124
125 for (i = 0; i < nvects; i++) {
126 check_map(params, i, TRUE, &layer, NULL);
127
128 color = Nviz_color_from_str(params->vline_color->answers[i]);
129 color_column = params->vline_color_column->answers ?
130 params->vline_color_column->answers[i] : NULL;
131 width = atoi(params->vline_width->answers[i]);
132 width_column = params->vline_width_column->answers ?
133 params->vline_width_column->answers[i] : NULL;
134
135 if (strcmp(params->vline_mode->answers[i], "flat") == 0)
136 flat = 1;
137 else
138 flat = 0;
139
140 /* style (mode -- use memory by default) */
141 if (GV_set_style(vect_list[i], TRUE, color, width, flat) < 0)
142 return 0;
143
144 /* check for vector color table */
145 have_colors = Vect_read_colors(params->vlines->answers[i], "",
146 &colors);
147
148 if (have_colors || color_column || width_column)
149 if (GV_set_style_thematic(vect_list[i], layer, color_column,
150 width_column,
151 have_colors ? &colors : NULL) < 0)
152 return 0;
153
154 /* height */
155 height = atoi(params->vline_height->answers[i]);
156 if (height > 0)
157 GV_set_trans(vect_list[i], 0.0, 0.0, height);
158 }
159
160 return 1;
161 }
162
163 /*!
164 \brief Set vector points style
165
166 \param params parameters
167
168 \return 1 on success
169 \return 0 on failure
170 */
vpoints_set_attrb(const struct GParams * params)171 int vpoints_set_attrb(const struct GParams *params)
172 {
173 int i, layer, have_colors, with_z;
174 int *site_list, nsites;
175 int marker, color, width;
176 float size;
177 char *marker_str, *color_column, *size_column, *width_column,
178 *marker_column;
179
180 struct Colors colors;
181
182 site_list = GP_get_site_list(&nsites);
183
184 for (i = 0; i < nsites; i++) {
185 check_map(params, i, FALSE, &layer, &with_z);
186
187 color = Nviz_color_from_str(params->vpoint_color->answers[i]);
188 color_column = params->vpoint_color_column->answers ?
189 params->vpoint_color_column->answers[i] : NULL;
190 size = atof(params->vpoint_size->answers[i]);
191 size_column = params->vpoint_size_column->answers ?
192 params->vpoint_size_column->answers[i] : NULL;
193 width = atoi(params->vpoint_width->answers[i]);
194 width_column = params->vpoint_width_column->answers ?
195 params->vpoint_width_column->answers[i] : NULL;
196 marker_str = params->vpoint_marker->answers[i];
197 marker_column = params->vpoint_marker_column->answers ?
198 params->vpoint_marker_column->answers[i] : NULL;
199 marker = GP_str_to_marker(marker_str);
200
201 if (with_z) {
202 if (strcmp(params->vpoint_mode->answers[i], "surface") == 0)
203 GP_set_zmode(site_list[i], FALSE);
204 else
205 GP_set_zmode(site_list[i], TRUE);
206 }
207
208 if (GP_set_style(site_list[i], color, width, size, marker) < 0)
209 return 0;
210
211 /* check for vector color table */
212 have_colors = Vect_read_colors(params->vpoints->answers[i], "",
213 &colors);
214
215 if (have_colors || color_column || width_column ||
216 size_column || marker_column) {
217 if (GP_set_style_thematic(site_list[i], layer, color_column,
218 width_column, size_column,
219 marker_column,
220 have_colors ? &colors : NULL) < 0)
221 return 0;
222 }
223 }
224
225 return 1;
226 }
227
228 /*!
229 \brief Check vector map
230
231 \param params parameters
232 \param index answers array index
233 \param vlines TRUE for lines otherwise points
234 \param[out] field number
235 \param[out] WITH_Z for 3D maps
236
237 \return 0 on success otherwise 1
238 */
check_map(const struct GParams * params,int index,int vlines,int * field,int * with_z)239 int check_map(const struct GParams *params, int index, int vlines,
240 int *field, int *with_z)
241 {
242 int type;
243 struct Map_info Map;
244 const char *map, *layer, *color, *size, *width, *marker;
245 struct field_info *Fi;
246
247 dbDriver *driver;
248 dbColumn *column;
249
250 Fi = NULL;
251 driver = NULL;
252
253 if (vlines) {
254 map = params->vlines->answers[index];
255 layer = params->vline_layer->answers[index];
256 color = params->vline_color_column->answers ?
257 params->vline_color_column->answers[index] : NULL;
258 size = NULL;
259 width = params->vline_width_column->answers ?
260 params->vline_width_column->answers[index] : NULL;
261 marker = NULL;
262 }
263 else {
264 map = params->vpoints->answers[index];
265 layer = params->vpoint_layer->answers[index];
266 color = params->vpoint_color_column->answers ?
267 params->vpoint_color_column->answers[index] : NULL;
268 size = params->vpoint_size_column->answers ?
269 params->vpoint_size_column->answers[index] : NULL;
270 width = params->vpoint_width_column->answers ?
271 params->vpoint_width_column->answers[index] : NULL;
272 marker = params->vpoint_marker_column->answers ?
273 params->vpoint_marker_column->answers[index] : NULL;
274 }
275
276 if (!map)
277 return 1;
278
279 if (1 > Vect_open_old(&Map, map, ""))
280 G_fatal_error(_("Unable to open vector map <%s>"), map);
281 Vect_set_error_handler_io(&Map, NULL);
282
283 if (with_z)
284 *with_z = Vect_is_3d(&Map);
285
286 *field = -1;
287 Fi = Vect_get_field2(&Map, layer);
288 if (Fi) {
289 *field = Fi->number;
290
291 driver = db_start_driver_open_database(Fi->driver, Fi->database);
292 if (!driver)
293 G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
294 Fi->database, Fi->driver);
295 db_set_error_handler_driver(driver);
296
297 if (color) {
298 db_get_column(driver, Fi->table, color, &column);
299 if (!column)
300 G_fatal_error(_("Column <%s> in table <%s> not found"),
301 color, Fi->table);
302
303 if (db_column_Ctype(driver, Fi->table, color) != DB_C_TYPE_STRING)
304 G_fatal_error(_("Data type of color column must be character"));
305 }
306 if (size) {
307 db_get_column(driver, Fi->table, size, &column);
308 if (!column)
309 G_fatal_error(_("Column <%s> in table <%s> not found"),
310 size, Fi->table);
311
312 type = db_column_Ctype(driver, Fi->table, size);
313 if (type != DB_C_TYPE_INT && type != DB_C_TYPE_DOUBLE)
314 G_fatal_error(_("Data type of size column must be numeric"));
315 }
316 if (width) {
317 db_get_column(driver, Fi->table, width, &column);
318 if (!column)
319 G_fatal_error(_("Column <%s> in table <%s> not found"),
320 width, Fi->table);
321
322 type = db_column_Ctype(driver, Fi->table, width);
323 if (type != DB_C_TYPE_INT && type != DB_C_TYPE_DOUBLE)
324 G_fatal_error(_("Data type of width column must be numeric"));
325 }
326 if (marker) {
327 db_get_column(driver, Fi->table, marker, &column);
328 if (!column)
329 G_fatal_error(_("Column <%s> in table <%s> not found"),
330 marker, Fi->table);
331
332 type = db_column_Ctype(driver, Fi->table, marker);
333 if (db_column_Ctype(driver, Fi->table, marker) !=
334 DB_C_TYPE_STRING)
335 G_fatal_error(_("Data type of marker column must be character"));
336 }
337
338 db_close_database_shutdown_driver(driver);
339 }
340
341 Vect_close(&Map);
342
343 return 0;
344 }
345