GRASS GIS 7 Programmer's Manual  7.4.0(2018)-exported
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 
60  Vect_set_open_level(1);
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,
77  wind.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX);
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  {
92  G_warning(_("Unable to read vector map <%s>"),
93  G_fully_qualified_name(name, mapset));
94  return NULL;
95  }
96  case -2: /* EOF */
97  {
98  eof = 1;
99  continue;
100  }
101  }
102  if ((ltype & GV_POINTS)) {
103  np++;
104  gpt->p3[X] = Points->x[0];
105  gpt->p3[Y] = Points->y[0];
106 
107  if (ndim > 2) {
108  gpt->dims = 3;
109  gpt->p3[Z] = Points->z[0];
110  }
111  else {
112  gpt->dims = 2;
113  }
114 
115  /* Store category info for thematic display */
116  if (Cats->n_cats > 0) {
117  gpt->cats = Cats;
118  Cats = Vect_new_cats_struct();
119  }
120  else {
121  Vect_reset_cats(Cats);
122  }
123  /* initialize style */
124  gpt->highlighted = 0;
125 
126  G_debug(5, "loading vector point %d x=%f y=%f ncats=%d",
127  np, Points->x[0], Points->y[0], Cats->n_cats);
128 
129  gpt->next = (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  }
140  if (np > 0) {
141  prev->next = NULL;
142  G_free(gpt);
143  }
144 
145  Vect_close(&map);
146 
147  if (!np) {
148  G_warning(_("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 
194  Vect_set_open_level(1);
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 {
206  driver = db_start_driver_open_database(Fi->driver, Fi->database);
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, colors)) {
235  G_warning(_("No color rule defined for category %d"), cat);
236  gpt->style->color = gp->style->color;
237  }
238  gpt->style->color = (red & RED_MASK) + ((int)((grn) << 8) & GRN_MASK) +
239  ((int)((blu) << 16) & BLU_MASK);
240  }
241  if (gp->tstyle->color_column) {
242  nvals = db_select_value(driver, Fi->table, Fi->key, cat, gp->tstyle->color_column, &value);
243  if (nvals < 1)
244  continue;
245  str = db_get_value_string(&value);
246  if (!str)
247  continue;
248  if (G_str_to_color(str, &red, &grn, &blu) != 1) {
249  G_warning(_("Invalid color definition (%s)"),
250  str);
251  gpt->style->color = gp->style->color;
252  }
253  else {
254  gpt->style->color = (red & RED_MASK) + ((int)((grn) << 8) & GRN_MASK) +
255  ((int)((blu) << 16) & BLU_MASK);
256  }
257  }
258 
259  /* size */
260  if (gp->tstyle->size_column) {
261  nvals = db_select_value(driver, Fi->table, Fi->key, cat, gp->tstyle->size_column, &value);
262  if (nvals < 1)
263  continue;
264  gpt->style->size = db_get_value_int(&value);
265  }
266 
267  /* width */
268  if (gp->tstyle->width_column) {
269  nvals = db_select_value(driver, Fi->table, Fi->key, cat, gp->tstyle->width_column, &value);
270  if (nvals < 1)
271  continue;
272  gpt->style->width = db_get_value_int(&value);
273  }
274 
275  /* symbol/marker */
276  if (gp->tstyle->symbol_column) {
277  nvals = db_select_value(driver, Fi->table, Fi->key, cat, gp->tstyle->symbol_column, &value);
278  if (nvals < 1)
279  continue;
280  str = db_get_value_string(&value);
281  gpt->style->symbol = GP_str_to_marker(str);
282  }
283 
284  npts++;
285  }
286 
287  if (nskipped > 0)
288  G_warning(_("%d points without category. "
289  "Unable to determine color rules for features without category."),
290  nskipped);
291  return npts;
292 }
#define RED_MASK
Definition: gsd_prim.c:38
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: zero.c:23
#define Y(j)
#define X(j)
#define BLU_MASK
Definition: gsd_prim.c:40
#define GRN_MASK
Definition: gsd_prim.c:39
#define NULL
Definition: ccmath.h:32
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
int Gp_load_sites_thematic(geosite *gp, struct Colors *colors)
Load styles for geopoints based on thematic mapping.
Definition: gp3.c:171
const struct driver * driver
Definition: driver/init.c:25
int GP_str_to_marker(const char *str)
Determine point marker symbol for string.
Definition: gp2.c:680
geopoint * Gp_load_sites(const char *name, int *nsites, int *has_z)
Load to points to memory.
Definition: gp3.c:40
void G_get_set_window(struct Cell_head *window)
Get the current working window (region)
void G_message(const char *msg,...)
Print a message to stderr.
Definition: gis/error.c:89
char * G_fully_qualified_name(const char *name, const char *mapset)
Get fully qualified element name.
Definition: nme_in_mps.c:101
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:112
const char * name
Definition: named_colr.c:7
const char * G_find_vector2(const char *name, const char *mapset)
Find a vector map (look but don&#39;t touch)
Definition: find_vect.c:62
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:203