GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vector/vedit/render.c
Go to the documentation of this file.
1 
14 #include <math.h>
15 
16 #include <grass/vedit.h>
17 
18 static struct _region
19 {
20  double center_easting;
21  double center_northing;
22  double map_west;
23  double map_north;
24  int map_width;
25  int map_height;
26  double map_res;
27 } region;
28 
29 static struct _state
30 {
31  int nitems_alloc;
32 
33  int type;
34  struct line_pnts *Points;
35 } state;
36 
37 static struct robject *draw_line(struct Map_info *, int, int);
38 static struct robject *draw_line_vertices();
39 static void draw_line_nodes(struct Map_info *, int, int,
40  struct robject_list *);
41 static int draw_line_dir(struct robject_list *, int);
42 static void list_append(struct robject_list *, struct robject *);
43 static struct robject *robj_alloc(int, int);
44 static void robj_points(struct robject *, const struct line_pnts *);
45 static double dist_in_px(double);
46 static void en_to_xy(double, double, int *, int *);
47 static void draw_arrow(int, int, int, int, double, int, int,
48  struct robject_list *);
49 static void draw_area(struct Map_info *, int, struct robject_list *);
50 
61 struct robject_list *Vedit_render_map(struct Map_info *Map,
62  struct bound_box *box, int draw_flag,
63  double center_easting,
64  double center_northing, int map_width,
65  int map_height, double map_res)
66 {
67  int i, nfeat, fid;
68  struct ilist *list;
69  struct robject_list *list_obj;
70  struct robject *robj;
71 
72  /* define region */
73  region.center_easting = center_easting;
74  region.center_northing = center_northing;
75  region.map_width = map_width;
76  region.map_height = map_height;
77  region.map_res = map_res;
78  region.map_west = center_easting - (map_width / 2.) * map_res;
79  region.map_north = center_northing + (map_height / 2.) * map_res;
80 
81  list = Vect_new_list();
82  list_obj = NULL;
83  state.nitems_alloc = 1000;
84 
85  list_obj = (struct robject_list *)G_malloc(sizeof(struct robject_list));
86  list_obj->nitems = 0;
87  list_obj->item =
88  (struct robject **)G_malloc(state.nitems_alloc *
89  sizeof(struct robject *));
90 
91  /* area */
92  if (draw_flag & DRAW_AREA) {
93  nfeat = Vect_select_areas_by_box(Map, box, list);
94  for (i = 0; i < nfeat; i++) {
95  fid = list->value[i];
96  draw_area(Map, fid, list_obj);
97  }
98  }
99 
100  /* draw lines inside of current display region */
101  nfeat = Vect_select_lines_by_box(Map, box, GV_POINTS | GV_LINES, /* fixme */
102  list);
103  G_debug(1, "Vedit_render_map(): region: w=%f, e=%f, s=%f, n=%f nlines=%d",
104  box->W, box->E, box->S, box->N, nfeat);
105 
106  /* features */
107  for (i = 0; i < list->n_values; i++) {
108  fid = list->value[i];
109  robj = draw_line(Map, fid, draw_flag);
110  if (!robj)
111  continue;
112  list_append(list_obj, robj);
113 
114  if (state.type & GV_LINES) {
115  /* vertices */
116  if (draw_flag & DRAW_VERTEX) {
117  robj = draw_line_vertices();
118  robj->fid = fid;
119  if (robj)
120  list_append(list_obj, robj);
121  }
122  /* nodes */
123  if (draw_flag & (DRAW_NODEONE | DRAW_NODETWO)) {
124  draw_line_nodes(Map, fid, draw_flag, list_obj);
125  }
126  /* direction */
127  if (draw_flag & DRAW_DIRECTION) {
128  draw_line_dir(list_obj, fid);
129  }
130  }
131  }
132 
133  list_obj->item =
134  (struct robject **)G_realloc(list_obj->item,
135  list_obj->nitems *
136  sizeof(struct robject *));
137 
138  G_debug(1, "Vedit_render_map(): -> nitems = %d",
139  list_obj->nitems);
140 
141  Vect_destroy_list(list);
142 
143  return list_obj;
144 }
145 
149 struct robject *draw_line(struct Map_info *Map, int line, int draw_flag)
150 {
151  int draw;
152  struct robject *obj;
153 
154  if (!state.Points)
155  state.Points = Vect_new_line_struct();
156 
157  if (!Vect_line_alive(Map, line))
158  return NULL;
159 
160  state.type = Vect_read_line(Map, state.Points, NULL, line);
161 
162  obj = (struct robject *)G_malloc(sizeof(struct robject));
163  obj->fid = line;
164  draw = FALSE;
165  if (state.type & GV_LINES) {
166  if (state.type == GV_LINE) {
167  obj->type = TYPE_LINE;
168  draw = draw_flag & DRAW_LINE;
169  }
170  else if (state.type == GV_BOUNDARY) {
171  int left, right;
172 
173  Vect_get_line_areas(Map, line, &left, &right);
174  if (left == 0 && right == 0) {
175  obj->type = TYPE_BOUNDARYNO;
176  draw = draw_flag & DRAW_BOUNDARYNO;
177  }
178  else if (left > 0 && right > 0) {
179  obj->type = TYPE_BOUNDARYTWO;
180  draw = draw_flag & DRAW_BOUNDARYTWO;
181  }
182  else {
183  obj->type = TYPE_BOUNDARYONE;
184  draw = draw_flag & DRAW_BOUNDARYONE;
185  }
186  }
187  }
188  else if (state.type & GV_POINTS) {
189  if (state.type == GV_POINT) {
190  obj->type = TYPE_POINT;
191  draw = draw_flag & DRAW_POINT;
192  }
193  else if (state.type == GV_CENTROID) {
194  int cret = Vect_get_centroid_area(Map, line);
195 
196  if (cret > 0) { /* -> area */
197  obj->type = TYPE_CENTROIDIN;
198  draw = draw_flag & DRAW_CENTROIDIN;
199  }
200  else if (cret == 0) {
201  obj->type = TYPE_CENTROIDOUT;
202  draw = draw_flag & DRAW_CENTROIDOUT;
203  }
204  else {
205  obj->type = TYPE_CENTROIDDUP;
206  draw = draw_flag & DRAW_CENTROIDDUP;
207  }
208  }
209  }
210  G_debug(3, " draw_line(): type=%d rtype=%d npoints=%d draw=%d",
211  state.type, obj->type, state.Points->n_points, draw);
212 
213  if (!draw)
214  return NULL;
215 
216  obj->npoints = state.Points->n_points;
217  obj->point =
218  (struct rpoint *)G_malloc(obj->npoints * sizeof(struct rpoint));
219  robj_points(obj, state.Points);
220 
221  return obj;
222 }
223 
227 void en_to_xy(double east, double north, int *x, int *y)
228 {
229  double n, w;
230 
231  w = region.center_easting - (region.map_width / 2) * region.map_res;
232  n = region.center_northing + (region.map_height / 2) * region.map_res;
233 
234  if (x)
235  *x = (east - w) / region.map_res;
236  if (y)
237  *y = (n - north) / region.map_res;
238 
239  return;
240 }
241 
245 void draw_line_nodes(struct Map_info *Map, int line, int draw_flag,
246  struct robject_list *list)
247 {
248  unsigned int i;
249  int type, nodes[2];
250  int x, y;
251  double east, north;
252  struct robject *robj;
253 
254  Vect_get_line_nodes(Map, line, &(nodes[0]), &(nodes[1]));
255 
256  for (i = 0; i < sizeof(nodes) / sizeof(int); i++) {
257  type = 0;
258  if (Vect_get_node_n_lines(Map, nodes[i]) == 1) {
259  if (draw_flag & DRAW_NODEONE) {
260  type = TYPE_NODEONE;
261  }
262  }
263  else {
264  if (draw_flag & DRAW_NODETWO) {
265  type = TYPE_NODETWO;
266  }
267  }
268 
269  if (type == 0)
270  continue;
271 
272  Vect_get_node_coor(Map, nodes[i], &east, &north, NULL);
273 
274  robj = robj_alloc(type, 1);
275  en_to_xy(east, north, &x, &y);
276  robj->fid = line;
277  robj->point->x = x;
278  robj->point->y = y;
279 
280  list_append(list, robj);
281  }
282 }
283 
287 void list_append(struct robject_list *list, struct robject *obj)
288 {
289  if (list->nitems >= state.nitems_alloc) {
290  state.nitems_alloc += 1000;
291  list->item =
292  (struct robject **)G_realloc(list->item,
293  state.nitems_alloc *
294  sizeof(struct robject *));
295  }
296  list->item[list->nitems++] = obj;
297 }
298 
302 struct robject *robj_alloc(int type, int npoints)
303 {
304  struct robject *robj;
305 
306  robj = (struct robject *)G_malloc(sizeof(struct robject));
307  robj->type = type;
308  robj->npoints = npoints;
309  robj->point = (struct rpoint *)G_malloc(npoints * sizeof(struct rpoint));
310 
311  return robj;
312 }
313 
317 struct robject *draw_line_vertices()
318 {
319  int i;
320  int x, y;
321  struct robject *robj;
322 
323  robj = robj_alloc(TYPE_VERTEX, state.Points->n_points - 2); /* ignore nodes */
324 
325  for (i = 1; i < state.Points->n_points - 1; i++) {
326  en_to_xy(state.Points->x[i], state.Points->y[i], &x, &y);
327  robj->point[i - 1].x = x;
328  robj->point[i - 1].y = y;
329  }
330 
331  return robj;
332 }
333 
337 int draw_line_dir(struct robject_list *list, int line)
338 {
339  int narrows;
340  int size; /* arrow length in pixels */
341  int limit; /* segment length limit for drawing symbol (in pixels) */
342  double dist, angle, pos;
343  double e, n;
344  int x0, y0, x1, y1;
345 
346  narrows = 0;
347  size = 5;
348  limit = 5; /* 5px for line segment */
349 
350  dist = Vect_line_length(state.Points);
351  G_debug(5, " draw_line_dir() line=%d", line);
352 
353  if (dist_in_px(dist) >= limit) {
354  while (1) {
355  pos = (narrows + 1) * 8 * limit * region.map_res;
356 
357  if (Vect_point_on_line(state.Points, pos,
358  &e, &n, NULL, NULL, NULL) < 1) {
359  break;
360  }
361 
362  en_to_xy(e, n, &x0, &y0);
363 
365  (state.Points, pos - 3 * size * region.map_res, &e, &n, NULL,
366  &angle, NULL) < 1) {
367  break;
368  }
369 
370  en_to_xy(e, n, &x1, &y1);
371 
372  draw_arrow(x0, y0, x1, y1, angle, size, line, list);
373 
374  if (narrows > 1e2) /* low resolution, break */
375  break;
376 
377  narrows++;
378  }
379 
380  /* draw at least one arrow in the middle of line */
381  if (narrows < 1) {
382  dist /= 2.;
383  if (Vect_point_on_line(state.Points, dist,
384  &e, &n, NULL, NULL, NULL) > 0) {
385 
386  en_to_xy(e, n, &x0, &y0);
387 
389  (state.Points, dist - 3 * size * region.map_res, &e, &n,
390  NULL, &angle, NULL) > 0) {
391 
392  en_to_xy(e, n, &x1, &y1);
393 
394  draw_arrow(x0, y0, x1, y1, angle, size, line, list);
395  }
396  }
397  }
398  }
399 
400  return narrows;
401 }
402 
406 double dist_in_px(double dist)
407 {
408  int x, y;
409 
410  en_to_xy(region.map_west + dist, region.map_north, &x, &y);
411 
412  return sqrt(x * x);
413 }
414 
418 void draw_arrow(int x0, int y0, int x1, int y1, double angle, int size, int line,
419  struct robject_list *list)
420 {
421  double angle_symb;
422  struct robject *robj;
423 
424  robj = robj_alloc(TYPE_DIRECTION, 3);
425  robj->fid = line;
426 
427  angle_symb = angle - M_PI / 2.;
428  robj->point[0].x = (int)x1 + size * cos(angle_symb);
429  robj->point[0].y = (int)y1 - size * sin(angle_symb);
430 
431  robj->point[1].x = x0;
432  robj->point[1].y = y0;
433 
434  angle_symb = M_PI / 2. + angle;
435  robj->point[2].x = (int)x1 + size * cos(angle_symb);
436  robj->point[2].y = (int)y1 - size * sin(angle_symb);
437 
438  list_append(list, robj);
439 }
440 
444 void draw_area(struct Map_info *Map, int area, struct robject_list *list)
445 {
446  int i, centroid, isle;
447  int num_isles;
448  struct line_pnts *ipoints;
449 
450  struct robject *robj;
451 
452  if (!state.Points)
453  state.Points = Vect_new_line_struct();
454 
455  if (!Vect_area_alive(Map, area))
456  return;
457 
458  /* check for other centroids -- only area with one centroid is valid */
459  centroid = Vect_get_area_centroid(Map, area);
460  if (centroid <= 0)
461  return;
462 
463  ipoints = Vect_new_line_struct();
464  /* get area's boundary */
465  Vect_get_area_points(Map, area, state.Points);
466  robj = robj_alloc(TYPE_AREA, state.Points->n_points);
467  robj->fid = centroid;
468  robj_points(robj, state.Points);
469  list_append(list, robj);
470 
471  /* check for isles */
472  num_isles = Vect_get_area_num_isles(Map, area);
473  for (i = 0; i < num_isles; i++) {
474  isle = Vect_get_area_isle(Map, area, i);
475  if (!Vect_isle_alive(Map, isle))
476  continue;
477 
478  Vect_get_isle_points(Map, isle, ipoints);
479  robj = robj_alloc(TYPE_ISLE, ipoints->n_points);
480  robj->fid = -1;
481  robj_points(robj, ipoints);
482  list_append(list, robj);
483  }
484 
485  Vect_destroy_line_struct(ipoints);
486 }
487 
491 void robj_points(struct robject *robj, const struct line_pnts *points)
492 {
493  int i;
494  int x, y;
495 
496  for (i = 0; i < points->n_points; i++) {
497  en_to_xy(points->x[i], points->y[i], &x, &y);
498  robj->point[i].x = x;
499  robj->point[i].y = y;
500  }
501 }
int Vect_destroy_list(struct ilist *list)
Frees all memory associated with a struct ilist, including the struct itself.
int Vect_get_area_centroid(struct Map_info *Map, int area)
Returns centroid number of area.
int Vect_get_isle_points(struct Map_info *Map, int isle, struct line_pnts *BPoints)
Returns the polygon array of points in BPoints.
#define FALSE
Definition: dbfopen.c:117
int Vect_get_line_nodes(struct Map_info *Map, int line, int *n1, int *n2)
Get line nodes.
Definition: level_two.c:247
int Vect_get_line_areas(struct Map_info *Map, int line, int *left, int *right)
Get area/isle ids on the left and right.
Definition: level_two.c:272
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
Definition: line.c:57
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
tuple pos
Definition: tools.py:1367
int Vect_get_area_num_isles(struct Map_info *Map, int area)
Returns number of isles for area.
int Vect_get_area_isle(struct Map_info *Map, int area, int isle)
Returns isle for area.
int y
Definition: plot.c:34
int Vect_isle_alive(struct Map_info *Map, int isle)
Check if isle is alive or dead.
tuple box
surface = wx.CheckBox(parent = panel, id = wx.ID_ANY, label = _(&quot;Follow source viewpoint&quot;)) pageSizer...
Definition: tools.py:1527
int Vect_get_area_points(struct Map_info *Map, int area, struct line_pnts *BPoints)
Returns the polygon array of points in BPoints.
tuple size
value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
Definition: tools.py:2334
struct robject_list * Vedit_render_map(struct Map_info *Map, struct bound_box *box, int draw_flag, double center_easting, double center_northing, int map_width, int map_height, double map_res)
Render vector features into list.
#define limit(a, x, b)
Definition: display/draw.c:62
int Vect_point_on_line(struct line_pnts *Points, double distance, double *x, double *y, double *z, double *angle, double *slope)
Find point on line in the specified distance.
Definition: line.c:393
int GV_LINES
Definition: vdigit/main.py:24
int
Definition: g3dcolor.c:48
if(!YY_CURRENT_BUFFER)
Definition: lex.yy.c:799
int Vect_line_alive(struct Map_info *Map, int line)
Check if feature is alive or dead.
int Vect_select_lines_by_box(struct Map_info *Map, BOUND_BOX *Box, int type, struct ilist *list)
Select lines by box.
int Vect_select_areas_by_box(struct Map_info *Map, BOUND_BOX *Box, struct ilist *list)
Select areas by box.
return NULL
Definition: dbfopen.c:1394
double Vect_line_length(struct line_pnts *Points)
Calculate line length, 3D-length in case of 3D vector line.
Definition: line.c:555
tuple Map
Definition: render.py:1310
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int Vect_get_centroid_area(struct Map_info *Map, int centroid)
Get area id the centroid is within.
Definition: level_two.c:353
int Vect_get_node_coor(struct Map_info *map, int num, double *x, double *y, double *z)
Get node coordinates.
Definition: level_two.c:223
int Vect_area_alive(struct Map_info *Map, int area)
Check if area is alive or dead.
int n
Definition: dataquad.c:291
int Vect_destroy_line_struct(struct line_pnts *p)
Frees all memory associated with a struct line_pnts, including the struct itself. ...
Definition: line.c:90
int Vect_read_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature.
int Vect_get_node_n_lines(struct Map_info *Map, int node)
Get number of lines for node.
Definition: level_two.c:296