GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
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  \brief Load to points to memory
30 
31  The other alternative may be to load to a tmp file.
32 
33  \param name name of vector map to be loaded
34  \param[out] nsites number of loaded points
35  \param[out] has_z 2D or 3D points data loaded?
36 
37  \return pointer to geopoint struct (array)
38  \return NULL on failure
39  */
40 geopoint *Gp_load_sites(const char *name, int *nsites, int *has_z)
41 {
42  struct Map_info map;
43  static struct line_pnts *Points = NULL;
44  struct line_cats *Cats = NULL;
45  geopoint *top, *gpt, *prev;
46  int np, ltype, eof;
47  struct Cell_head wind;
48  int ndim;
49  const char *mapset;
50 
51  np = 0;
52  eof = 0;
53 
54  mapset = G_find_vector2(name, "");
55  if (!mapset) {
56  G_warning(_("Vector map <%s> not found"), name);
57  return NULL;
58  }
59 
61  if (Vect_open_old(&map, name, "") == -1) {
62  G_fatal_error(_("Unable to open vector map <%s>"),
63  G_fully_qualified_name(name, mapset));
64  }
65 
66  Points = Vect_new_line_struct();
67  Cats = Vect_new_cats_struct();
68 
69  top = gpt = (geopoint *)G_malloc(sizeof(geopoint));
70  G_zero(gpt, sizeof(geopoint));
71  if (!top) {
72  return NULL;
73  }
74 
75  G_get_set_window(&wind);
76  Vect_set_constraint_region(&map, wind.north, wind.south, wind.east,
78 
79  /* get ndim */
80  *has_z = 0;
81  ndim = 2;
82  if (Vect_is_3d(&map)) {
83  *has_z = 1;
84  ndim = 3;
85  }
86 
87  while (eof == 0) {
88  ltype = Vect_read_next_line(&map, Points, Cats);
89  switch (ltype) {
90  case -1: {
91  G_warning(_("Unable to read vector map <%s>"),
92  G_fully_qualified_name(name, mapset));
93  return NULL;
94  }
95  case -2: /* EOF */
96  {
97  eof = 1;
98  continue;
99  }
100  }
101  if ((ltype & GV_POINTS)) {
102  np++;
103  gpt->p3[X] = Points->x[0];
104  gpt->p3[Y] = Points->y[0];
105 
106  if (ndim > 2) {
107  gpt->dims = 3;
108  gpt->p3[Z] = Points->z[0];
109  }
110  else {
111  gpt->dims = 2;
112  }
113 
114  /* Store category info for thematic display */
115  if (Cats->n_cats > 0) {
116  gpt->cats = Cats;
117  Cats = Vect_new_cats_struct();
118  }
119  else {
120  Vect_reset_cats(Cats);
121  }
122  /* initialize style */
123  gpt->highlighted = 0;
124 
125  G_debug(5, "loading vector point %d x=%f y=%f ncats=%d", np,
126  Points->x[0], Points->y[0], Cats->n_cats);
127 
128  gpt->next =
129  (geopoint *)G_malloc(sizeof(geopoint)); /* G_fatal_error */
130  G_zero(gpt->next, sizeof(geopoint));
131  if (!gpt->next) {
132  return NULL;
133  }
134 
135  prev = gpt;
136  gpt = gpt->next;
137  }
138  }
139  if (np > 0) {
140  prev->next = NULL;
141  G_free(gpt);
142  }
143 
144  Vect_close(&map);
145 
146  if (!np) {
147  G_warning(
148  _("No points from vector map <%s> fall within current region"),
149  G_fully_qualified_name(name, mapset));
150  return (NULL);
151  }
152  else {
153  G_message(_("Vector map <%s> loaded (%d points)"),
154  G_fully_qualified_name(name, mapset), np);
155  }
156 
157  *nsites = np;
158 
159  return top;
160 }
161 
162 /*!
163  \brief Load styles for geopoints based on thematic mapping
164 
165  \param gp pointer to geosite structure
166  \param colors pointer to Colors structure or NULL
167 
168  \return number of points defined by thematic mapping
169  \return -1 on error
170  */
171 int Gp_load_sites_thematic(geosite *gp, struct Colors *colors)
172 {
173  geopoint *gpt;
174 
175  struct Map_info Map;
176  struct field_info *Fi;
177 
178  int nvals, cat, npts, nskipped;
179  int red, blu, grn;
180  const char *str;
181  const char *mapset;
182 
183  dbDriver *driver;
184  dbValue value;
185 
186  if (!gp || !gp->tstyle || !gp->filename)
187  return -1;
188 
189  mapset = G_find_vector2(gp->filename, "");
190  if (!mapset) {
191  G_fatal_error(_("Vector map <%s> not found"), gp->filename);
192  }
193 
195  if (Vect_open_old(&Map, gp->filename, "") == -1) {
196  G_fatal_error(_("Unable to open vector map <%s>"),
197  G_fully_qualified_name(gp->filename, mapset));
198  }
199 
200  Fi = Vect_get_field(&Map, gp->tstyle->layer);
201  if (!Fi) {
202  G_warning(_("Database connection not defined for layer %d"),
203  gp->tstyle->layer);
204  }
205  else {
207  if (!driver)
208  G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
209  Fi->database, Fi->driver);
210  }
211  G_message(_("Loading thematic points layer <%s>..."),
212  G_fully_qualified_name(gp->filename, mapset));
213  npts = nskipped = 0;
214  for (gpt = gp->points; gpt; gpt = gpt->next) {
215  gpt->style = (gvstyle *)G_malloc(sizeof(gvstyle));
216  G_zero(gpt->style, sizeof(gvstyle));
217 
218  /* use default style */
219  gpt->style->color = gp->style->color;
220  gpt->style->symbol = gp->style->symbol;
221  gpt->style->size = gp->style->size;
222  gpt->style->width = gp->style->width;
223 
224  cat = -1;
225  if (gpt->cats)
226  Vect_cat_get(gpt->cats, gp->tstyle->layer, &cat);
227  if (cat < 0) {
228  nskipped++;
229  continue;
230  }
231 
232  /* color */
233  if (colors) {
234  if (!Rast_get_c_color((const CELL *)&cat, &red, &grn, &blu,
235  colors)) {
236  G_warning(_("No color rule defined for category %d"), cat);
237  gpt->style->color = gp->style->color;
238  }
239  gpt->style->color = (red & RED_MASK) +
240  ((int)((grn) << 8) & GRN_MASK) +
241  ((int)((blu) << 16) & BLU_MASK);
242  }
243  if (gp->tstyle->color_column) {
244  nvals = db_select_value(driver, Fi->table, Fi->key, cat,
245  gp->tstyle->color_column, &value);
246  if (nvals < 1)
247  continue;
248  str = db_get_value_string(&value);
249  if (!str)
250  continue;
251  if (G_str_to_color(str, &red, &grn, &blu) != 1) {
252  G_warning(_("Invalid color definition (%s)"), str);
253  gpt->style->color = gp->style->color;
254  }
255  else {
256  gpt->style->color = (red & RED_MASK) +
257  ((int)((grn) << 8) & GRN_MASK) +
258  ((int)((blu) << 16) & BLU_MASK);
259  }
260  }
261 
262  /* size */
263  if (gp->tstyle->size_column) {
264  nvals = db_select_value(driver, Fi->table, Fi->key, cat,
265  gp->tstyle->size_column, &value);
266  if (nvals < 1)
267  continue;
268  gpt->style->size = db_get_value_int(&value);
269  }
270 
271  /* width */
272  if (gp->tstyle->width_column) {
273  nvals = db_select_value(driver, Fi->table, Fi->key, cat,
274  gp->tstyle->width_column, &value);
275  if (nvals < 1)
276  continue;
277  gpt->style->width = db_get_value_int(&value);
278  }
279 
280  /* symbol/marker */
281  if (gp->tstyle->symbol_column) {
282  nvals = db_select_value(driver, Fi->table, Fi->key, cat,
283  gp->tstyle->symbol_column, &value);
284  if (nvals < 1)
285  continue;
286  str = db_get_value_string(&value);
287  gpt->style->symbol = GP_str_to_marker(str);
288  }
289 
290  npts++;
291  }
292 
293  if (nskipped > 0)
294  G_warning(
295  _("%d points without category. "
296  "Unable to determine color rules for features without category."),
297  nskipped);
298  return npts;
299 }
#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:101
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_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
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
const struct driver * driver
Definition: driver/init.c:25
int CELL
Definition: gis.h:628
#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:171
geopoint * Gp_load_sites(const char *name, int *nsites, int *has_z)
Load to points to memory.
Definition: gp3.c:40
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:440
double north
Extent coordinates (north)
Definition: gis.h:486
double east
Extent coordinates (east)
Definition: gis.h:490
double top
Extent coordinates (top) - 3D data.
Definition: gis.h:494
double south
Extent coordinates (south)
Definition: gis.h:488
double west
Extent coordinates (west)
Definition: gis.h:492
Definition: gis.h:686
Vector map info.
Definition: dig_structs.h:1243
Definition: driver.h:21
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