GRASS GIS 7 Programmer's Manual  7.0.5(2016)-r00000
gv3.c
Go to the documentation of this file.
1 
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  #define TRAK_MEM
30 */
31 
32 #ifdef TRAK_MEM
33 static int Tot_mem = 0;
34 #endif
35 
47 geoline *Gv_load_vect(const char *grassname, int *nlines)
48 {
49  struct Map_info map;
50  struct line_pnts *points;
51  struct line_cats *Cats = NULL;
52  geoline *top, *gln, *prev;
53  int np, i, n, nareas, nl = 0, area, type, is3d;
54  struct Cell_head wind;
55  float vect[2][3];
56  const char *mapset;
57 
58  mapset = G_find_vector2(grassname, "");
59  if (!mapset) {
60  G_warning(_("Vector map <%s> not found"), grassname);
61  return NULL;
62  }
63 
64  Vect_set_open_level(2);
65  if (Vect_open_old(&map, grassname, "") == -1) {
66  G_warning(_("Unable to open vector map <%s>"),
67  G_fully_qualified_name(grassname, mapset));
68  return NULL;
69  }
70 
71  top = gln = (geoline *) G_malloc(sizeof(geoline)); /* G_fatal_error */
72  if (!top) {
73  return NULL;
74  }
75 
76  prev = top;
77 
78 #ifdef TRAK_MEM
79  Tot_mem += sizeof(geoline);
80 #endif
81 
82  points = Vect_new_line_struct();
83  Cats = Vect_new_cats_struct();
84 
85  G_get_set_window(&wind);
86  Vect_set_constraint_region(&map, wind.north, wind.south, wind.east,
87  wind.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX);
88 
89  is3d = Vect_is_3d(&map);
90 
91  /* Read areas */
92  n = Vect_get_num_areas(&map);
93  nareas = 0;
94  G_debug(3, "Reading vector areas (nareas = %d)", n);
95  for (area = 1; area <= n; area++) {
96  G_debug(3, " area %d", area);
97  Vect_get_area_points(&map, area, points);
98  if (points->n_points < 3)
99  continue;
100 
101  /* initialize style */
102  gln->highlighted = 0;
103 
104  gln->type = OGSF_POLYGON;
105  gln->npts = np = points->n_points;
106  G_debug(3, " np = %d", np);
107 
108  if (is3d) {
109  gln->dims = 3;
110  gln->p3 = (Point3 *) G_calloc(np, sizeof(Point3)); /* G_fatal_error */
111  if (!gln->p3) {
112  return (NULL);
113  }
114 #ifdef TRAK_MEM
115  Tot_mem += (np * sizeof(Point3));
116 #endif
117  }
118  else {
119  gln->dims = 2;
120  gln->p2 = (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 
152  gln->cats = NULL;
153  gln->next = (geoline *) G_malloc(sizeof(geoline)); /* G_fatal_error */
154  if (!gln->next) {
155  return (NULL);
156  }
157 
158 #ifdef TRAK_MEM
159  Tot_mem += sizeof(geoline);
160 #endif
161 
162  prev = gln;
163  gln = gln->next;
164  nareas++;
165  }
166  G_debug(3, "%d areas loaded", nareas);
167 
168  /* Read all lines */
169  G_debug(3, "Reading vector lines ...");
170  while (-1 < (type = Vect_read_next_line(&map, points, Cats))) {
171  G_debug(3, "line type = %d", type);
172  if (type & (GV_LINES | GV_FACE)) {
173  if (type & (GV_LINES)) {
174  gln->type = OGSF_LINE;
175  }
176  else {
177  gln->type = OGSF_POLYGON;
178  /* Vect_append_point ( points, points->x[0], points->y[0], 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 = (Point3 *) G_calloc(np, sizeof(Point3)); /* G_fatal_error */
190  if (!gln->p3) {
191  return (NULL);
192  }
193 #ifdef TRAK_MEM
194  Tot_mem += (np * sizeof(Point3));
195 #endif
196  }
197  else {
198  gln->dims = 2;
199  gln->p2 = (Point2 *) G_calloc(np, sizeof(Point2)); /* G_fatal_error */
200  if (!gln->p2) {
201  return (NULL);
202  }
203 #ifdef TRAK_MEM
204  Tot_mem += (np * sizeof(Point2));
205 #endif
206  }
207 
208  for (i = 0; i < np; i++) {
209  if (is3d) {
210  gln->p3[i][X] = points->x[i];
211  gln->p3[i][Y] = points->y[i];
212  gln->p3[i][Z] = points->z[i];
213  }
214  else {
215  gln->p2[i][X] = points->x[i];
216  gln->p2[i][Y] = points->y[i];
217  }
218  }
219  /* Calc normal (should be average) */
220  if (is3d && gln->type == OGSF_POLYGON) {
221  vect[0][X] = (float)(gln->p3[0][X] - gln->p3[1][X]);
222  vect[0][Y] = (float)(gln->p3[0][Y] - gln->p3[1][Y]);
223  vect[0][Z] = (float)(gln->p3[0][Z] - gln->p3[1][Z]);
224  vect[1][X] = (float)(gln->p3[2][X] - gln->p3[1][X]);
225  vect[1][Y] = (float)(gln->p3[2][Y] - gln->p3[1][Y]);
226  vect[1][Z] = (float)(gln->p3[2][Z] - gln->p3[1][Z]);
227  GS_v3cross(vect[1], vect[0], gln->norm);
228  G_debug(3, "norm %f %f %f", gln->norm[0], gln->norm[1],
229  gln->norm[2]);
230  }
231 
232  /* Store category info for thematic display */
233  if (Cats->n_cats > 0) {
234  gln->cats = Cats;
235  Cats = Vect_new_cats_struct();
236  }
237  else {
238  gln->cats = NULL;
239  Vect_reset_cats(Cats);
240  }
241 
242  gln->next = (geoline *) G_malloc(sizeof(geoline)); /* G_fatal_error */
243  if (!gln->next) {
244  return (NULL);
245  }
246 #ifdef TRAK_MEM
247  Tot_mem += sizeof(geoline);
248 #endif
249 
250  prev = gln;
251  gln = gln->next;
252  nl++;
253  }
254  }
255  G_debug(3, "%d lines loaded", nl);
256 
257  nl += nareas;
258 
259  prev->next = NULL;
260  G_free(gln);
261 
262 #ifdef TRAK_MEM
263  Tot_mem -= sizeof(geoline);
264 #endif
265 
266  Vect_close(&map);
267 
268  if (!nl) {
269  G_warning(_("No features from vector map <%s> fall within current region"),
270  G_fully_qualified_name(grassname, mapset));
271  return (NULL);
272  }
273  else {
274  G_message(_("Vector map <%s> loaded (%d features)"),
275  G_fully_qualified_name(grassname, mapset), nl);
276  }
277 
278  *nlines = nl;
279 
280 #ifdef TRAK_MEM
281  G_debug(3, "Total vect memory = %d Kbytes", Tot_mem / 1000);
282 #endif
283 
284  return (top);
285 }
286 
292 void sub_Vectmem(int minus)
293 {
294  G_debug(5, "sub_Vectmem(): minus=%d", minus);
295 #ifdef TRAK_MEM
296  {
297  Tot_mem -= minus;
298  }
299 #endif
300 
301  return;
302 }
303 
313 int Gv_load_vect_thematic(geovect *gv, struct Colors *colors)
314 {
315  geoline *gvt;
316 
317  struct Map_info Map;
318  struct field_info *Fi;
319 
320  int nvals, cat, nlines, nskipped;
321  int red, blu, grn;
322  const char *str;
323  const char *mapset;
324 
325  dbDriver *driver;
326  dbValue value;
327 
328  if(!gv || !gv->tstyle || !gv->filename)
329  return -1;
330 
331  mapset = G_find_vector2(gv->filename, "");
332  if (!mapset) {
333  G_fatal_error(_("Vector map <%s> not found"), gv->filename);
334  }
335 
336  Vect_set_open_level(1);
337  if (Vect_open_old(&Map, gv->filename, "") == -1) {
338  G_fatal_error(_("Unable to open vector map <%s>"),
339  G_fully_qualified_name(gv->filename, mapset));
340  }
341 
342  Fi = Vect_get_field(&Map, gv->tstyle->layer);
343  if (!Fi) {
344  G_warning(_("Database connection not defined for layer %d"),
345  gv->tstyle->layer);
346  }
347  else {
348  driver = db_start_driver_open_database(Fi->driver, Fi->database);
349  if (!driver)
350  G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
351  Fi->database, Fi->driver);
352  }
353  G_message(_("Loading thematic vector layer <%s>..."),
354  G_fully_qualified_name(gv->filename, mapset));
355  nlines = nskipped = 0;
356  for(gvt = gv->lines; gvt; gvt = gvt->next) {
357  gvt->style = (gvstyle *) G_malloc(sizeof(gvstyle));
358  G_zero(gvt->style, sizeof(gvstyle));
359 
360  /* use default style */
361  gvt->style->color = gv->style->color;
362  gvt->style->symbol = gv->style->symbol;
363  gvt->style->size = gv->style->size;
364  gvt->style->width = gv->style->width;
365 
366  cat = -1;
367  if (gvt->cats)
368  Vect_cat_get(gvt->cats, gv->tstyle->layer, &cat);
369  if (cat < 0) {
370  nskipped++;
371  continue;
372  }
373 
374  /* color */
375  if (colors) {
376  if (!Rast_get_c_color((const CELL *) &cat, &red, &grn, &blu, colors)) {
377  G_warning(_("No color rule defined for category %d"), cat);
378  gvt->style->color = gv->style->color;
379  }
380  gvt->style->color = (red & RED_MASK) + ((int)((grn) << 8) & GRN_MASK) +
381  ((int)((blu) << 16) & BLU_MASK);
382  }
383 
384  if (gv->tstyle->color_column) {
385  nvals = db_select_value(driver, Fi->table, Fi->key, cat, gv->tstyle->color_column, &value);
386  if (nvals < 1)
387  continue;
388  str = db_get_value_string(&value);
389  if (!str)
390  continue;
391  if (G_str_to_color(str, &red, &grn, &blu) != 1) {
392  G_warning(_("Invalid color definition (%s)"),
393  str);
394  gvt->style->color = gv->style->color;
395  }
396  else {
397  gvt->style->color = (red & RED_MASK) + ((int)((grn) << 8) & GRN_MASK) +
398  ((int)((blu) << 16) & BLU_MASK);
399  }
400  }
401 
402  /* width */
403  if (gv->tstyle->width_column) {
404  nvals = db_select_value(driver, Fi->table, Fi->key, cat, gv->tstyle->width_column, &value);
405  if (nvals < 1)
406  continue;
407  gvt->style->width = db_get_value_int(&value);
408  }
409 
410  nlines++;
411  }
412 
413  if (nskipped > 0)
414  G_warning(_("%d features without category. "
415  "Unable to determine color rules for features without category."),
416  nskipped);
417 
418  return nlines;
419 }
#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 BLU_MASK
Definition: gsd_prim.c:40
#define GRN_MASK
Definition: gsd_prim.c:39
#define NULL
Definition: ccmath.h:32
geoline * Gv_load_vect(const char *grassname, int *nlines)
Load vector map to memory.
Definition: gv3.c:47
void GS_v3cross(float *v1, float *v2, float *v3)
Get the cross product v3 = v1 cross v2.
Definition: gs_util.c:406
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
#define Y(n)
Definition: plot.c:141
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
const struct driver * driver
Definition: driver/init.c:25
int Gv_load_vect_thematic(geovect *gv, struct Colors *colors)
Load styles for geolines based on thematic mapping.
Definition: gv3.c:313
void G_get_set_window(struct Cell_head *window)
Get the current working window (region)
void sub_Vectmem(int minus)
Tracking memory.
Definition: gv3.c:292
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
#define X(e)
Definition: plot.c:140
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 * 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