GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vector/vedit/select.c
Go to the documentation of this file.
1 
14 #include <math.h>
15 
16 #include <grass/glocale.h>
17 #include <grass/vedit.h>
18 
19 static int select_by_query(struct Map_info *, int, int, double,
20  int, struct line_pnts *, struct line_cats *);
21 
22 static int merge_lists(struct ilist *alist, struct ilist *blist);
23 
43 int Vedit_select_by_query(struct Map_info *Map,
44  int type, int layer, double thresh, int query,
45  struct ilist *List)
46 {
47  int num, line, i;
48  double thresh_tmp;
49  struct line_pnts *Points;
50  struct line_cats *Cats;
51  struct ilist *List_query;
52 
53  Points = Vect_new_line_struct();
54  Cats = Vect_new_cats_struct();
55 
56  if (List->n_values == 0) {
57  List_query = List;
58  }
59  else {
60  List_query = Vect_new_list();
61  }
62 
63  switch (query) {
64  case QUERY_LENGTH:{
65  if (List->n_values == 0) {
66  /* query all vector objects in vector map */
67  num = Vect_get_num_lines(Map);
68  for (line = 1; line <= num; line++) {
69  if (select_by_query(Map, line, type, thresh,
70  query, Points, Cats))
71  Vect_list_append(List_query, line);
72  }
73  }
74  else {
75  for (i = 0; i < List->n_values; i++) {
76  line = List->value[i];
77  if (select_by_query(Map, line, type, thresh,
78  query, Points, Cats)) {
79  Vect_list_append(List_query, line);
80  }
81  }
82  }
83  break;
84  }
85  case QUERY_DANGLE:{
86  struct ilist *List_dangle;
87 
88  List_dangle = Vect_new_list();
89  thresh_tmp = fabs(thresh);
90 
91  /* select dangles shorter than 'thresh_tmp' */
92  Vect_select_dangles(Map, type, thresh_tmp, List_dangle);
93 
94  if (thresh <= 0.0) { /* shorter than */
95  for (i = 0; i < List_dangle->n_values; i++) {
96  Vect_list_append(List_query, List_dangle->value[i]);
97  }
98  }
99  else { /* longer than */
100  for (i = 1; i <= Vect_get_num_lines(Map); i++) {
101  if (!Vect_val_in_list(List_dangle, i))
102  Vect_list_append(List_query, i);
103  }
104  }
105 
106  Vect_destroy_list(List_dangle);
107  break;
108  }
109  default:
110  break;
111  }
112 
113  if (List != List_query) {
114  merge_lists(List, List_query);
115  Vect_destroy_list(List_query);
116  }
117 
118  G_debug(3, "Vedit_select_by_query(): %d lines selected (by query %d)",
119  List->n_values, query);
120 
121  Vect_destroy_line_struct(Points);
123 
124  return List->n_values;
125 }
126 
134 int select_by_query(struct Map_info *Map, int line, int type, double thresh,
135  int query, struct line_pnts *Points,
136  struct line_cats *Cats)
137 {
138  int ltype;
139  double length;
140  int i, cat_curr;
141  int node1, node2, node; /* nodes */
142  int nnode1, nnode2; /* number of line in node */
143  double nx, ny, nz; /* node coordinates */
144  struct ilist *exclude, *found; /* line id of nearest lines */
145  struct line_cats *Cats_curr;
146 
147  if (!Vect_line_alive(Map, line))
148  return -1;
149 
150  ltype = Vect_read_line(Map, Points, Cats, line);
151 
152  if (!(ltype & type))
153  return -1;
154 
155  if (query == QUERY_LENGTH) {
156  length = Vect_line_length(Points);
157  if (thresh <= 0.0) { /* shorter then */
158  if (length <= fabs(thresh))
159  return 1;
160  }
161  else { /* longer then */
162  if (length > thresh)
163  return 1;
164  }
165  }
166  else if (query == QUERY_DANGLE) {
167  /*
168  this code is currently replaced by Vect_select_dangle()
169  not used by v.edit
170  */
171  int layer, cat;
172 
173  layer = 1;
174  Vect_cat_get(Cats, layer, &cat); /* get first category from layer */
175  if (!(type & GV_LINES))
176  return -1;
177  /* check if line is dangle */
178 
179  Vect_get_line_nodes(Map, line, &node1, &node2);
180 
181  node = -1;
182  nnode1 = Vect_get_node_n_lines(Map, node1);
183  nnode2 = Vect_get_node_n_lines(Map, node2);
184 
185  if ((nnode1 == 4 && nnode2 == 1) || (nnode1 == 1 && nnode2 == 4)) {
186  if (nnode1 == 4)
187  node = node1;
188  else
189  node = node2;
190  }
191 
192  /* no dangle ? */
193  if (node == -1)
194  return -1;
195 
196  length = Vect_line_length(Points);
197  if (thresh <= 0.0) { /* shorter then */
198  if (length > fabs(thresh))
199  return -1;
200  }
201  else { /* longer then */
202  if (length <= thresh)
203  return -1;
204  }
205 
206  /* at least one of the lines need to have same category number */
207  exclude = Vect_new_list();
208  found = Vect_new_list();
209 
210  Vect_get_node_coor(Map, node, &nx, &ny, &nz);
211 
212  Vect_list_append(exclude, line);
213  Vect_find_line_list(Map, nx, ny, nz,
214  GV_LINES, 0.0, WITHOUT_Z, exclude, found);
215 
216  Cats_curr = Vect_new_cats_struct();
217 
218  for (i = 0; i < found->n_values; i++) {
219  Vect_read_line(Map, NULL, Cats_curr, found->value[i]);
220  if (Vect_cat_get(Cats_curr, layer, &cat_curr) > -1) {
221  if (cat == cat_curr)
222  return 1;
223  }
224  }
225 
226  Vect_destroy_cats_struct(Cats_curr);
227  Vect_destroy_list(exclude);
228  Vect_destroy_list(found);
229  }
230  else {
231  /* this shouldn't happen */
232  G_fatal_error("Vedit_select_by_query(): %s", _("Unknown query tool"));
233  }
234 
235  return 0;
236 }
237 
246 int merge_lists(struct ilist *alist, struct ilist *blist)
247 {
248  int i;
249 
250  struct ilist *list_del;
251 
252  list_del = Vect_new_list();
253 
254  for (i = 0; i < alist->n_values; i++) {
255  if (!Vect_val_in_list(blist, alist->value[i]))
256  Vect_list_append(list_del, alist->value[i]);
257  }
258 
259  Vect_list_delete_list(alist, list_del);
260 
261  Vect_destroy_list(list_del);
262 
263  return alist->n_values;
264 }
int Vect_destroy_list(struct ilist *list)
Frees all memory associated with a struct ilist, including the struct itself.
int Vect_get_line_nodes(struct Map_info *Map, int line, int *n1, int *n2)
Get line nodes.
Definition: level_two.c:247
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.
int Vect_find_line_list(struct Map_info *map, double ux, double uy, double uz, int type, double maxdist, int with_z, struct ilist *exclude, struct ilist *found)
Find the nearest line(s).
long num
Definition: g3dcats.c:93
void Vect_select_dangles(struct Map_info *Map, int type, double maxlength, struct ilist *List)
Select dangles from vector map.
Definition: dangles.c:104
int GV_LINES
Definition: vdigit/main.py:24
int Vedit_select_by_query(struct Map_info *Map, int type, int layer, double thresh, int query, struct ilist *List)
Select primitives by query (based on geometry properties)
int Vect_destroy_cats_struct(struct line_cats *p)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_list_append(struct ilist *list, int val)
Append new item to the end of list if not yet present.
int Vect_line_alive(struct Map_info *Map, int line)
Check if feature is alive or dead.
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
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
int Vect_get_num_lines(struct Map_info *map)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:69
tuple Map
Definition: render.py:1310
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int Vect_list_delete_list(struct ilist *alist, struct ilist *blist)
Delete list from existing list.
CELL cat
Definition: g3dcats.c:90
int Vect_val_in_list(struct ilist *list, int val)
Find a given item in the list.
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 G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
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_cat_get(struct line_cats *Cats, int field, int *cat)
Get first found category of given field.
int Vect_get_node_n_lines(struct Map_info *Map, int node)
Get number of lines for node.
Definition: level_two.c:296