GRASS 8 Programmer's Manual 8.6.0dev(2026)-56a9afeb9f
Loading...
Searching...
No Matches
gv3.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gv3.c
3
4 \brief OGSF library - loading vector sets (lower level functions)
5
6 GRASS OpenGL gsurf OGSF Library
7
8 (C) 1999-2008, 2011 by the GRASS Development Team
9
10 This program is free software under the GNU General Public License
11 (>=v2). Read the file COPYING that comes with GRASS for details.
12
13 \author Bill Brown USACERL (December 1993)
14 \author Updated by Martin Landa <landa.martin gmail.com>
15 (doxygenized in May 2008, thematic mapping in August 2011)
16 */
17
18#include <stdlib.h>
19
20#include <grass/gis.h>
21#include <grass/colors.h>
22#include <grass/raster.h>
23#include <grass/vector.h>
24#include <grass/dbmi.h>
25#include <grass/glocale.h>
26#include <grass/ogsf.h>
27
28/*
29 #define TRAK_MEM
30 */
31
32#ifdef TRAK_MEM
33static int Tot_mem = 0;
34#endif
35
36/*!
37 \brief Load vector map to memory
38
39 The other alternative may be to load to a tmp file
40
41 \param grassname vector map name
42 \param[out] nlines number of loaded features
43
44 \return pointer to geoline struct
45 \return NULL on failure
46 */
47geoline *Gv_load_vect(const char *grassname, int *nlines)
48{
49 struct Map_info map;
50 struct line_pnts *points;
51 struct line_cats *Cats = NULL;
52 geoline *top, *gln, *prev;
53 int np, i, n, nareas, nl = 0, area, type, is3d;
54 struct Cell_head wind;
55 float vect[2][3];
56 const char *mapset;
57
58 mapset = G_find_vector2(grassname, "");
59 if (!mapset) {
60 G_warning(_("Vector map <%s> not found"), grassname);
61 return NULL;
62 }
63
65 if (Vect_open_old(&map, grassname, "") == -1) {
66 G_warning(_("Unable to open vector map <%s>"),
68 return NULL;
69 }
70
71 top = gln = (geoline *)G_malloc(sizeof(geoline)); /* G_fatal_error */
72 if (!top) {
73 return NULL;
74 }
75
76 prev = top;
77
78#ifdef TRAK_MEM
79 Tot_mem += sizeof(geoline);
80#endif
81
82 points = Vect_new_line_struct();
84
85 G_get_set_window(&wind);
86 Vect_set_constraint_region(&map, wind.north, wind.south, wind.east,
88
89 is3d = Vect_is_3d(&map);
90
91 /* Read areas */
92 n = Vect_get_num_areas(&map);
93 nareas = 0;
94 G_debug(3, "Reading vector areas (nareas = %d)", n);
95 for (area = 1; area <= n; area++) {
96 G_debug(3, " area %d", area);
97 Vect_get_area_points(&map, area, points);
98 if (points->n_points < 3)
99 continue;
100
101 /* initialize style */
102 gln->highlighted = 0;
103
104 gln->type = OGSF_POLYGON;
105 gln->npts = np = points->n_points;
106 G_debug(3, " np = %d", np);
107
108 if (is3d) {
109 gln->dims = 3;
110 gln->p3 =
111 (Point3 *)G_calloc(np, sizeof(Point3)); /* G_fatal_error */
112 if (!gln->p3) {
113 return (NULL);
114 }
115#ifdef TRAK_MEM
116 Tot_mem += (np * sizeof(Point3));
117#endif
118 }
119 else {
120 gln->dims = 2;
121 gln->p2 =
122 (Point2 *)G_calloc(np, sizeof(Point2)); /* G_fatal_error */
123 if (!gln->p2) {
124 return (NULL);
125 }
126#ifdef TRAK_MEM
127 Tot_mem += (np * sizeof(Point2));
128#endif
129 }
130
131 for (i = 0; i < np; i++) {
132 if (is3d) {
133 gln->p3[i][X] = points->x[i];
134 gln->p3[i][Y] = points->y[i];
135 gln->p3[i][Z] = points->z[i];
136 }
137 else {
138 gln->p2[i][X] = points->x[i];
139 gln->p2[i][Y] = points->y[i];
140 }
141 }
142 /* Calc normal (should be average) */
143 if (is3d) {
144 vect[0][X] = (float)(gln->p3[0][X] - gln->p3[1][X]);
145 vect[0][Y] = (float)(gln->p3[0][Y] - gln->p3[1][Y]);
146 vect[0][Z] = (float)(gln->p3[0][Z] - gln->p3[1][Z]);
147 vect[1][X] = (float)(gln->p3[2][X] - gln->p3[1][X]);
148 vect[1][Y] = (float)(gln->p3[2][Y] - gln->p3[1][Y]);
149 vect[1][Z] = (float)(gln->p3[2][Z] - gln->p3[1][Z]);
150 GS_v3cross(vect[1], vect[0], gln->norm);
151 }
152
153 gln->cats = NULL;
154 gln->next = (geoline *)G_malloc(sizeof(geoline)); /* G_fatal_error */
155 if (!gln->next) {
156 return (NULL);
157 }
158
159#ifdef TRAK_MEM
160 Tot_mem += sizeof(geoline);
161#endif
162
163 prev = gln;
164 gln = gln->next;
165 nareas++;
166 }
167 G_debug(3, "%d areas loaded", nareas);
168
169 /* Read all lines */
170 G_debug(3, "Reading vector lines ...");
171 while (-1 < (type = Vect_read_next_line(&map, points, Cats))) {
172 G_debug(3, "line type = %d", type);
173 if (type & (GV_LINES | GV_FACE)) {
174 if (type & (GV_LINES)) {
175 gln->type = OGSF_LINE;
176 }
177 else {
178 gln->type = OGSF_POLYGON;
179 /* Vect_append_point ( points, points->x[0], points->y[0],
180 * points->z[0] ); */
181 }
182
183 /* initialize style */
184 gln->highlighted = 0;
185
186 gln->npts = np = points->n_points;
187 G_debug(3, " np = %d", np);
188
189 if (is3d) {
190 gln->dims = 3;
191 gln->p3 =
192 (Point3 *)G_calloc(np, sizeof(Point3)); /* G_fatal_error */
193 if (!gln->p3) {
194 return (NULL);
195 }
196#ifdef TRAK_MEM
197 Tot_mem += (np * sizeof(Point3));
198#endif
199 }
200 else {
201 gln->dims = 2;
202 gln->p2 =
203 (Point2 *)G_calloc(np, sizeof(Point2)); /* G_fatal_error */
204 if (!gln->p2) {
205 return (NULL);
206 }
207#ifdef TRAK_MEM
208 Tot_mem += (np * sizeof(Point2));
209#endif
210 }
211
212 for (i = 0; i < np; i++) {
213 if (is3d) {
214 gln->p3[i][X] = points->x[i];
215 gln->p3[i][Y] = points->y[i];
216 gln->p3[i][Z] = points->z[i];
217 }
218 else {
219 gln->p2[i][X] = points->x[i];
220 gln->p2[i][Y] = points->y[i];
221 }
222 }
223 /* Calc normal (should be average) */
224 if (is3d && gln->type == OGSF_POLYGON) {
225 vect[0][X] = (float)(gln->p3[0][X] - gln->p3[1][X]);
226 vect[0][Y] = (float)(gln->p3[0][Y] - gln->p3[1][Y]);
227 vect[0][Z] = (float)(gln->p3[0][Z] - gln->p3[1][Z]);
228 vect[1][X] = (float)(gln->p3[2][X] - gln->p3[1][X]);
229 vect[1][Y] = (float)(gln->p3[2][Y] - gln->p3[1][Y]);
230 vect[1][Z] = (float)(gln->p3[2][Z] - gln->p3[1][Z]);
231 GS_v3cross(vect[1], vect[0], gln->norm);
232 G_debug(3, "norm %f %f %f", gln->norm[0], gln->norm[1],
233 gln->norm[2]);
234 }
235
236 /* Store category info for thematic display */
237 if (Cats->n_cats > 0) {
238 gln->cats = Cats;
240 }
241 else {
242 gln->cats = NULL;
244 }
245
246 gln->next =
247 (geoline *)G_malloc(sizeof(geoline)); /* G_fatal_error */
248 if (!gln->next) {
249 return (NULL);
250 }
251#ifdef TRAK_MEM
252 Tot_mem += sizeof(geoline);
253#endif
254
255 prev = gln;
256 gln = gln->next;
257 nl++;
258 }
259 }
260 G_debug(3, "%d lines loaded", nl);
261
262 nl += nareas;
263
264 prev->next = NULL;
265 G_free(gln);
266
267#ifdef TRAK_MEM
268 Tot_mem -= sizeof(geoline);
269#endif
270
271 Vect_close(&map);
272
273 if (!nl) {
274 G_warning(
275 _("No features from vector map <%s> fall within current region"),
277 return (NULL);
278 }
279 else {
280 G_message(_("Vector map <%s> loaded (%d features)"),
282 }
283
284 *nlines = nl;
285
286#ifdef TRAK_MEM
287 G_debug(3, "Total vect memory = %d Kbytes", Tot_mem / 1000);
288#endif
289
290 return (top);
291}
292
293/*!
294 \brief Tracking memory
295
296 \param minus mimus number
297 */
299{
300 G_debug(5, "sub_Vectmem(): minus=%d", minus);
301#ifdef TRAK_MEM
302 {
303 Tot_mem -= minus;
304 }
305#endif
306
307 return;
308}
309
310/*!
311 \brief Load styles for geolines based on thematic mapping
312
313 \param gv pointer to geovect structure
314 \param colors pointer to Colors structure or NULL
315
316 \return number of features defined by thematic mapping
317 \return -1 on error
318 */
320{
321 geoline *gvt;
322
323 struct Map_info Map;
324 struct field_info *Fi;
325
326 int nvals, cat, nlines, nskipped;
327 int red, blu, grn;
328 const char *str;
329 const char *mapset;
330
332 dbValue value;
333
334 if (!gv || !gv->tstyle || !gv->filename)
335 return -1;
336
337 mapset = G_find_vector2(gv->filename, "");
338 if (!mapset) {
339 G_fatal_error(_("Vector map <%s> not found"), gv->filename);
340 }
341
343 if (Vect_open_old(&Map, gv->filename, "") == -1) {
344 G_fatal_error(_("Unable to open vector map <%s>"),
345 G_fully_qualified_name(gv->filename, mapset));
346 }
347
348 Fi = Vect_get_field(&Map, gv->tstyle->layer);
349 if (!Fi) {
350 G_warning(_("Database connection not defined for layer %d"),
351 gv->tstyle->layer);
352 }
353 else {
354 driver = db_start_driver_open_database(Fi->driver, Fi->database);
355 if (!driver)
356 G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
357 Fi->database, Fi->driver);
358 }
359 G_message(_("Loading thematic vector layer <%s>..."),
360 G_fully_qualified_name(gv->filename, mapset));
361 nlines = nskipped = 0;
362 for (gvt = gv->lines; gvt; gvt = gvt->next) {
363 gvt->style = (gvstyle *)G_malloc(sizeof(gvstyle));
364 G_zero(gvt->style, sizeof(gvstyle));
365
366 /* use default style */
367 gvt->style->color = gv->style->color;
368 gvt->style->symbol = gv->style->symbol;
369 gvt->style->size = gv->style->size;
370 gvt->style->width = gv->style->width;
371
372 cat = -1;
373 if (gvt->cats)
374 Vect_cat_get(gvt->cats, gv->tstyle->layer, &cat);
375 if (cat < 0) {
376 nskipped++;
377 continue;
378 }
379
380 /* color */
381 if (colors) {
382 if (!Rast_get_c_color((const CELL *)&cat, &red, &grn, &blu,
383 colors)) {
384 G_warning(_("No color rule defined for category %d"), cat);
385 gvt->style->color = gv->style->color;
386 }
387 gvt->style->color = (red & RED_MASK) +
388 ((int)((grn) << 8) & GRN_MASK) +
389 ((int)((blu) << 16) & BLU_MASK);
390 }
391
392 if (gv->tstyle->color_column) {
393 nvals = db_select_value(driver, Fi->table, Fi->key, cat,
394 gv->tstyle->color_column, &value);
395 if (nvals < 1)
396 continue;
397 str = db_get_value_string(&value);
398 if (!str)
399 continue;
400 if (G_str_to_color(str, &red, &grn, &blu) != 1) {
401 G_warning(_("Invalid color definition (%s)"), str);
402 gvt->style->color = gv->style->color;
403 }
404 else {
405 gvt->style->color = (red & RED_MASK) +
406 ((int)((grn) << 8) & GRN_MASK) +
407 ((int)((blu) << 16) & BLU_MASK);
408 }
409 }
410
411 /* width */
412 if (gv->tstyle->width_column) {
413 nvals = db_select_value(driver, Fi->table, Fi->key, cat,
414 gv->tstyle->width_column, &value);
415 if (nvals < 1)
416 continue;
417 gvt->style->width = db_get_value_int(&value);
418 }
419
420 nlines++;
421 }
422
423 if (nskipped > 0)
424 G_warning(
425 _("%d features without category. "
426 "Unable to determine color rules for features without category."),
427 nskipped);
428
429 return nlines;
430}
#define NULL
Definition ccmath.h:32
Main header of GRASS DataBase Management Interface.
int G_str_to_color(const char *, int *, int *, int *)
Parse color string and set red,green,blue.
Definition color_str.c:103
int db_select_value(dbDriver *, const char *, const char *, int, const char *, dbValue *)
Select one (first) value from table/column for key/id.
int db_get_value_int(dbValue *)
Get integer value.
Definition value.c:38
dbDriver * db_start_driver_open_database(const char *, const char *)
Open driver/database connection.
Definition db.c:28
const char * db_get_value_string(dbValue *)
Get string value.
Definition value.c:92
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:147
#define G_calloc(m, n)
Definition defs/gis.h:140
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
void G_get_set_window(struct Cell_head *)
Get the current working window (region)
#define G_malloc(n)
Definition defs/gis.h:139
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition nme_in_mps.c:101
void G_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_find_vector2(const char *, const char *)
Find a vector map (look but don't touch)
Definition find_vect.c:62
void GS_v3cross(float *, float *, float *)
Get the cross product v3 = v1 cross v2.
Definition gs_util.c:403
int Rast_get_c_color(const CELL *, int *, int *, int *, struct Colors *)
Gets color from raster map (CELL)
Definition color_get.c:67
plus_t Vect_get_num_areas(struct Map_info *)
Get number of areas in vector map.
Definition level_two.c:87
int Vect_reset_cats(struct line_cats *)
Reset category structure to make sure cats structure is clean to be re-used.
int Vect_cat_get(const struct line_cats *, int, int *)
Get first found category of given field.
int Vect_set_constraint_region(struct Map_info *, double, double, double, double, double, double)
Set constraint region.
Definition constraint.c:48
int Vect_get_area_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points (outer ring) of given area.
int Vect_close(struct Map_info *)
Close vector map.
struct field_info * Vect_get_field(struct Map_info *, int)
Get information about link to database (by layer number)
Definition field.c:510
int Vect_open_old(struct Map_info *, const char *, const char *)
Open existing vector map for reading.
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_read_next_line(struct Map_info *, struct line_pnts *, struct line_cats *)
Read next vector feature.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:45
int Vect_set_open_level(int)
Predetermine level at which a vector map will be opened for reading.
int Vect_is_3d(struct Map_info *)
Check if vector map is 3D.
#define GV_LINES
#define GV_FACE
#define PORT_DOUBLE_MAX
Limits for portable types.
Definition dig_defines.h:66
int CELL
Definition gis.h:634
#define _(str)
Definition glocale.h:10
int Gv_load_vect_thematic(geovect *gv, struct Colors *colors)
Load styles for geolines based on thematic mapping.
Definition gv3.c:319
void sub_Vectmem(int minus)
Tracking memory.
Definition gv3.c:298
geoline * Gv_load_vect(const char *grassname, int *nlines)
Load vector map to memory.
Definition gv3.c:47
OGSF header file (structures)
struct g_line geoline
Line instance.
#define RED_MASK
Definition ogsf.h:200
#define X
Definition ogsf.h:140
#define BLU_MASK
Definition ogsf.h:202
float Point2[2]
Definition ogsf.h:206
float Point3[3]
Definition ogsf.h:205
#define Z
Definition ogsf.h:142
#define GRN_MASK
Definition ogsf.h:201
#define Y
Definition ogsf.h:141
#define OGSF_LINE
Definition ogsf.h:197
#define OGSF_POLYGON
Definition ogsf.h:198
2D/3D raster map header (used also for region)
Definition gis.h:446
double north
Extent coordinates (north)
Definition gis.h:492
double east
Extent coordinates (east)
Definition gis.h:496
double top
Extent coordinates (top) - 3D data.
Definition gis.h:500
double south
Extent coordinates (south)
Definition gis.h:494
double west
Extent coordinates (west)
Definition gis.h:498
Definition gis.h:692
Vector map info.
Layer (old: field) information.
char * driver
Name of DB driver ('sqlite', 'dbf', ...)
Line instance.
Definition ogsf.h:352
struct g_line * next
Definition ogsf.h:368
Struct for vector feature displaying attributes.
Definition ogsf.h:307
Vector map (lines)
Definition ogsf.h:372
Feature category info.
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
int n_points
Number of points.
double * z
Array of Z coordinates.