GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-3df7050671
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  */
31 static 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  */
45 geopoint *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 
66  if (Vect_open_old(&map, name, "") == -1) {
67  G_fatal_error(_("Unable to open vector map <%s>"),
68  G_fully_qualified_name(name, mapset));
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,
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  */
181 int 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 
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 {
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)
315  return npts;
316 }
317 
318 static void free_geopoint_list(geopoint *top)
319 {
320  while (top) {
321  geopoint *next = top->next;
322  G_free(top);
323  top = next;
324  }
325 }
#define NULL
Definition: ccmath.h:32
int G_str_to_color(const char *, int *, int *, int *)
Parse color string and set red,green,blue.
Definition: color_str.c:102
const char * db_get_value_string(dbValue *)
Get string value.
Definition: value.c:92
int db_select_value(dbDriver *, const char *, const char *, int, const char *, dbValue *)
Select one (first) value from table/column for key/id.
dbDriver * db_start_driver_open_database(const char *, const char *)
Open driver/database connection.
Definition: db.c:28
int db_close_database_shutdown_driver(dbDriver *)
Close driver/database connection.
Definition: db.c:61
int db_get_value_int(dbValue *)
Get integer value.
Definition: value.c:38
const char * G_find_vector2(const char *, const char *)
Find a vector map (look but don't touch)
Definition: find_vect.c:62
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:150
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:94
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
int GP_str_to_marker(const char *)
Determine point marker symbol for string.
Definition: gp2.c:684
int Rast_get_c_color(const CELL *, int *, int *, int *, struct Colors *)
Gets color from raster map (CELL)
Definition: color_get.c:67
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_close(struct Map_info *)
Close vector map.
int Vect_open_old(struct Map_info *, const char *, const char *)
Open existing vector map for reading.
struct field_info * Vect_get_field(struct Map_info *, int)
Get information about link to database (by layer number)
Definition: field.c:515
void Vect_destroy_field_info(struct field_info *)
Free a struct field_info and all memory associated with it.
Definition: field.c:633
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition: line.c:45
int Vect_read_next_line(struct Map_info *, struct line_pnts *, struct line_cats *)
Read next vector feature.
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
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 PORT_DOUBLE_MAX
Limits for portable types.
Definition: dig_defines.h:66
#define GV_POINTS
Definition: dig_defines.h:192
int CELL
Definition: gis.h:629
#define _(str)
Definition: glocale.h:10
int Gp_load_sites_thematic(geosite *gp, struct Colors *colors)
Load styles for geopoints based on thematic mapping.
Definition: gp3.c:181
geopoint * Gp_load_sites(const char *name, int *nsites, int *has_z)
Load to points to memory.
Definition: gp3.c:45
const char * name
Definition: named_colr.c:6
#define RED_MASK
Definition: ogsf.h:200
#define X
Definition: ogsf.h:140
#define BLU_MASK
Definition: ogsf.h:202
#define Z
Definition: ogsf.h:142
#define GRN_MASK
Definition: ogsf.h:201
#define Y
Definition: ogsf.h:141
2D/3D raster map header (used also for region)
Definition: gis.h:441
double north
Extent coordinates (north)
Definition: gis.h:487
double east
Extent coordinates (east)
Definition: gis.h:491
double top
Extent coordinates (top) - 3D data.
Definition: gis.h:495
double south
Extent coordinates (south)
Definition: gis.h:489
double west
Extent coordinates (west)
Definition: gis.h:493
Definition: gis.h:687
Vector map info.
Definition: dig_structs.h:1243
Definition: driver.h:27
Layer (old: field) information.
Definition: dig_structs.h:131
char * table
Name of DB table.
Definition: dig_structs.h:151
char * driver
Name of DB driver ('sqlite', 'dbf', ...)
Definition: dig_structs.h:143
char * database
Definition: dig_structs.h:147
char * key
Name of key column (usually 'cat')
Definition: dig_structs.h:155
Definition: ogsf.h:349
Point3 p3
Definition: ogsf.h:351
int dims
Definition: ogsf.h:350
struct g_point * next
Definition: ogsf.h:358
struct line_cats * cats
Definition: ogsf.h:353
gvstyle * style
Definition: ogsf.h:355
signed char highlighted
Definition: ogsf.h:356
Definition: ogsf.h:362
char * filename
Definition: ogsf.h:369
gvstyle_thematic * tstyle
Definition: ogsf.h:377
geopoint * points
Definition: ogsf.h:372
gvstyle * style
Definition: ogsf.h:378
char * symbol_column
Definition: ogsf.h:306
char * color_column
Definition: ogsf.h:305
char * size_column
Definition: ogsf.h:307
char * width_column
Definition: ogsf.h:308
int color
Definition: ogsf.h:286
int symbol
Definition: ogsf.h:287
float size
Definition: ogsf.h:288
int width
Definition: ogsf.h:289
Feature category info.
Definition: dig_structs.h:1677
int n_cats
Number of categories attached to element.
Definition: dig_structs.h:1689
Feature geometry info - coordinates.
Definition: dig_structs.h:1651
double * y
Array of Y coordinates.
Definition: dig_structs.h:1659
double * x
Array of X coordinates.
Definition: dig_structs.h:1655
double * z
Array of Z coordinates.
Definition: dig_structs.h:1663