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