GRASS 8 Programmer's Manual 8.5.0RC1(2026)-3334b87d9c
Loading...
Searching...
No Matches
gp3.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gp3.c
3
4 \brief OGSF library - loading point 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, GMSL/University of Illinois (January 1994)
14 \author Updated by Martin Landa <landa.martin gmail.com>
15 (doxygenized in May 2008, thematic mapping in June 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 Free linked list of geopoint objects
30 */
31static void free_geopoint_list(geopoint *top);
32
33/*!
34 \brief Load to points to memory
35
36 The other alternative may be to load to a tmp file.
37
38 \param name name of vector map to be loaded
39 \param[out] nsites number of loaded points
40 \param[out] has_z 2D or 3D points data loaded?
41
42 \return pointer to geopoint struct (array)
43 \return NULL on failure
44 */
45geopoint *Gp_load_sites(const char *name, int *nsites, int *has_z)
46{
47 struct Map_info map;
48 static struct line_pnts *Points = NULL;
49 struct line_cats *Cats = NULL;
50 geopoint *top, *gpt, *prev;
51 int np, ltype, eof;
52 struct Cell_head wind;
53 int ndim;
54 const char *mapset;
55
56 np = 0;
57 eof = 0;
58
59 mapset = G_find_vector2(name, "");
60 if (!mapset) {
61 G_warning(_("Vector map <%s> not found"), name);
62 return NULL;
63 }
64
65 Vect_set_open_level(1);
66 if (Vect_open_old(&map, name, "") == -1) {
67 G_fatal_error(_("Unable to open vector map <%s>"),
69 }
70
71 Points = Vect_new_line_struct();
72 Cats = Vect_new_cats_struct();
73
74 top = gpt = (geopoint *)G_malloc(sizeof(geopoint));
75 G_zero(gpt, sizeof(geopoint));
76 if (!top) {
77 return NULL;
78 }
79
80 G_get_set_window(&wind);
81 Vect_set_constraint_region(&map, wind.north, wind.south, wind.east,
82 wind.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX);
83
84 /* get ndim */
85 *has_z = 0;
86 ndim = 2;
87 if (Vect_is_3d(&map)) {
88 *has_z = 1;
89 ndim = 3;
90 }
91 char *mname = G_fully_qualified_name(name, mapset);
92
93 while (eof == 0) {
94 ltype = Vect_read_next_line(&map, Points, Cats);
95 switch (ltype) {
96 case -1: {
97 G_warning(_("Unable to read vector map <%s>"), mname);
98 G_free(mname);
99 free_geopoint_list(top);
100 return NULL;
101 }
102 case -2: /* EOF */
103 {
104 eof = 1;
105 continue;
106 }
107 }
108 if ((ltype & GV_POINTS)) {
109 np++;
110 gpt->p3[X] = Points->x[0];
111 gpt->p3[Y] = Points->y[0];
112
113 if (ndim > 2) {
114 gpt->dims = 3;
115 gpt->p3[Z] = Points->z[0];
116 }
117 else {
118 gpt->dims = 2;
119 }
120
121 /* Store category info for thematic display */
122 if (Cats->n_cats > 0) {
123 gpt->cats = Cats;
124 Cats = Vect_new_cats_struct();
125 }
126 else {
127 Vect_reset_cats(Cats);
128 }
129 /* initialize style */
130 gpt->highlighted = 0;
131
132 G_debug(5, "loading vector point %d x=%f y=%f ncats=%d", np,
133 Points->x[0], Points->y[0], Cats->n_cats);
134
135 gpt->next =
136 (geopoint *)G_malloc(sizeof(geopoint)); /* G_fatal_error */
137 G_zero(gpt->next, sizeof(geopoint));
138 if (!gpt->next) {
139 free_geopoint_list(top);
140 return NULL;
141 }
142
143 prev = gpt;
144 gpt = gpt->next;
145 }
146 }
147 if (np > 0) {
148 prev->next = NULL;
149 G_free(gpt);
150 }
151
152 Vect_close(&map);
153
154 if (!np) {
155 G_warning(
156 _("No points from vector map <%s> fall within current region"),
157 mname);
158 G_free(mname);
159 free_geopoint_list(top);
160 return (NULL);
161 }
162 else {
163 G_message(_("Vector map <%s> loaded (%d points)"), mname, np);
164 G_free(mname);
165 }
166
167 *nsites = np;
168
169 return top;
170}
171
172/*!
173 \brief Load styles for geopoints based on thematic mapping
174
175 \param gp pointer to geosite structure
176 \param colors pointer to Colors structure or NULL
177
178 \return number of points defined by thematic mapping
179 \return -1 on error
180 */
181int Gp_load_sites_thematic(geosite *gp, struct Colors *colors)
182{
183 geopoint *gpt;
184
185 struct Map_info Map;
186 struct field_info *Fi;
187
188 int nvals, cat, npts, nskipped;
189 int red, blu, grn;
190 const char *str;
191 const char *mapset;
192 char *fname;
193
194 dbDriver *driver = NULL;
195 dbValue value;
196
197 if (!gp || !gp->tstyle || !gp->filename)
198 return -1;
199
200 mapset = G_find_vector2(gp->filename, "");
201 if (!mapset) {
202 G_fatal_error(_("Vector map <%s> not found"), gp->filename);
203 }
204
205 Vect_set_open_level(1);
206 if (Vect_open_old(&Map, gp->filename, "") == -1) {
207 G_fatal_error(_("Unable to open vector map <%s>"),
208 G_fully_qualified_name(gp->filename, mapset));
209 }
210
211 Fi = Vect_get_field(&Map, gp->tstyle->layer);
212 if (!Fi) {
213 G_warning(_("Database connection not defined for layer %d"),
214 gp->tstyle->layer);
215 }
216 else {
217 driver = db_start_driver_open_database(Fi->driver, Fi->database);
218 if (!driver)
219 G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
220 Fi->database, Fi->driver);
221 }
222 fname = G_fully_qualified_name(gp->filename, mapset);
223 G_message(_("Loading thematic points layer <%s>..."), fname);
224 G_free(fname);
225 npts = nskipped = 0;
226 for (gpt = gp->points; gpt; gpt = gpt->next) {
227 gpt->style = (gvstyle *)G_malloc(sizeof(gvstyle));
228 G_zero(gpt->style, sizeof(gvstyle));
229
230 /* use default style */
231 gpt->style->color = gp->style->color;
232 gpt->style->symbol = gp->style->symbol;
233 gpt->style->size = gp->style->size;
234 gpt->style->width = gp->style->width;
235
236 cat = -1;
237 if (gpt->cats)
238 Vect_cat_get(gpt->cats, gp->tstyle->layer, &cat);
239 if (cat < 0) {
240 nskipped++;
241 continue;
242 }
243
244 /* color */
245 if (colors) {
246 if (!Rast_get_c_color((const CELL *)&cat, &red, &grn, &blu,
247 colors)) {
248 G_warning(_("No color rule defined for category %d"), cat);
249 gpt->style->color = gp->style->color;
250 }
251 gpt->style->color = (red & RED_MASK) +
252 ((int)((grn) << 8) & GRN_MASK) +
253 ((int)((blu) << 16) & BLU_MASK);
254 }
255 if (gp->tstyle->color_column) {
256 if (driver) {
257 nvals = db_select_value(driver, Fi->table, Fi->key, cat,
258 gp->tstyle->color_column, &value);
259 if (nvals < 1)
260 continue;
261 str = db_get_value_string(&value);
262 if (!str)
263 continue;
264 }
265 if (G_str_to_color(str, &red, &grn, &blu) != 1) {
266 G_warning(_("Invalid color definition (%s)"), str);
267 gpt->style->color = gp->style->color;
268 }
269 else {
270 gpt->style->color = (red & RED_MASK) +
271 ((int)((grn) << 8) & GRN_MASK) +
272 ((int)((blu) << 16) & BLU_MASK);
273 }
274 }
275
276 /* size */
277 if (gp->tstyle->size_column) {
278 nvals = db_select_value(driver, Fi->table, Fi->key, cat,
279 gp->tstyle->size_column, &value);
280 if (nvals < 1)
281 continue;
282 gpt->style->size = db_get_value_int(&value);
283 }
284
285 /* width */
286 if (gp->tstyle->width_column) {
287 nvals = db_select_value(driver, Fi->table, Fi->key, cat,
288 gp->tstyle->width_column, &value);
289 if (nvals < 1)
290 continue;
291 gpt->style->width = db_get_value_int(&value);
292 }
293
294 /* symbol/marker */
295 if (gp->tstyle->symbol_column) {
296 nvals = db_select_value(driver, Fi->table, Fi->key, cat,
297 gp->tstyle->symbol_column, &value);
298 if (nvals < 1)
299 continue;
300 str = db_get_value_string(&value);
301 gpt->style->symbol = GP_str_to_marker(str);
302 }
303
304 npts++;
305 }
306
307 if (nskipped > 0)
308 G_warning(
309 _("%d points without category. "
310 "Unable to determine color rules for features without category."),
311 nskipped);
312 if (driver)
313 db_close_database_shutdown_driver(driver);
314 Vect_destroy_field_info(Fi);
315 return npts;
316}
317
318static void free_geopoint_list(geopoint *top)
319{
320 while (top) {
321 geopoint *next = top->next;
322 G_free(top);
323 top = next;
324 }
325}
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:147
#define NULL
Definition ccmath.h:32
int G_str_to_color(const char *str, int *red, int *grn, int *blu)
Parse color string and set red,green,blue.
Definition color_str.c:103
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
const char * G_find_vector2(const char *name, const char *mapset)
Find a vector map (look but don't touch).
Definition find_vect.c:62
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition gis/error.c:159
void G_message(const char *msg,...)
Print a message to stderr.
Definition gis/error.c:89
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
void G_get_set_window(struct Cell_head *window)
Get the current working window (region).
int GP_str_to_marker(const char *str)
Determine point marker symbol for string.
Definition gp2.c:688
geopoint * Gp_load_sites(const char *name, int *nsites, int *has_z)
Load to points to memory.
Definition gp3.c:45
int Gp_load_sites_thematic(geosite *gp, struct Colors *colors)
Load styles for geopoints based on thematic mapping.
Definition gp3.c:181
#define RED_MASK
Definition gsd_prim.c:48
#define BLU_MASK
Definition gsd_prim.c:50
#define GRN_MASK
Definition gsd_prim.c:49
const char * name
Definition named_colr.c:6
char * G_fully_qualified_name(const char *name, const char *mapset)
Get fully qualified element name.
Definition nme_in_mps.c:101
#define X(j)
#define Y(j)
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition zero.c:23