GRASS Programmer's Manual  6.4.2(2012)
 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 <grass/glocale.h>
15 #include <grass/vedit.h>
16 
17 static int select_by_query(struct Map_info *, int, int, double,
18  int, struct line_pnts *, struct line_cats *);
19 
20 static int merge_lists(struct ilist *alist, struct ilist *blist);
21 
41 int Vedit_select_by_query(struct Map_info *Map,
42  int type, int layer, double thresh, int query,
43  struct ilist *List)
44 {
45  int num, line, i;
46  double thresh_tmp;
47  struct line_pnts *Points;
48  struct line_cats *Cats;
49  struct ilist *List_query;
50 
51  Points = Vect_new_line_struct();
52  Cats = Vect_new_cats_struct();
53 
54  if (List->n_values == 0) {
55  List_query = List;
56  }
57  else {
58  List_query = Vect_new_list();
59  }
60 
61  switch (query) {
62  case QUERY_LENGTH:{
63  if (List->n_values == 0) {
64  /* query all vector objects in vector map */
65  num = Vect_get_num_lines(Map);
66  for (line = 1; line <= num; line++) {
67  if (select_by_query(Map, line, type, thresh,
68  query, Points, Cats))
69  Vect_list_append(List_query, line);
70  }
71  }
72  else {
73  for (i = 0; i < List->n_values; i++) {
74  line = List->value[i];
75  if (select_by_query(Map, line, type, thresh,
76  query, Points, Cats)) {
77  Vect_list_append(List_query, line);
78  }
79  }
80  }
81  break;
82  }
83  case QUERY_DANGLE:{
84  struct ilist *List_dangle;
85 
86  List_dangle = Vect_new_list();
87  thresh_tmp = fabs(thresh);
88 
89  /* select dangles shorter than 'thresh_tmp' */
90  Vect_select_dangles(Map, type, thresh_tmp, List_dangle);
91 
92  if (thresh <= 0.0) { /* shorter than */
93  for (i = 0; i < List_dangle->n_values; i++) {
94  Vect_list_append(List_query, List_dangle->value[i]);
95  }
96  }
97  else { /* longer than */
98  for (i = 1; i <= Vect_get_num_lines(Map); i++) {
99  if (!Vect_val_in_list(List_dangle, i))
100  Vect_list_append(List_query, i);
101  }
102  }
103 
104  Vect_destroy_list(List_dangle);
105  break;
106  }
107  default:
108  break;
109  }
110 
111  if (List != List_query) {
112  merge_lists(List, List_query);
113  Vect_destroy_list(List_query);
114  }
115 
116  G_debug(3, "Vedit_select_by_query(): %d lines selected (by query %d)",
117  List->n_values, query);
118 
119  Vect_destroy_line_struct(Points);
121 
122  return List->n_values;
123 }
124 
132 int select_by_query(struct Map_info *Map, int line, int type, double thresh,
133  int query, struct line_pnts *Points,
134  struct line_cats *Cats)
135 {
136  int ltype;
137  double length;
138  int i, cat_curr;
139  int node1, node2, node; /* nodes */
140  int nnode1, nnode2; /* number of line in node */
141  double nx, ny, nz; /* node coordinates */
142  struct ilist *exclude, *found; /* line id of nearest lines */
143  struct line_cats *Cats_curr;
144 
145  if (!Vect_line_alive(Map, line))
146  return -1;
147 
148  ltype = Vect_read_line(Map, Points, Cats, line);
149 
150  if (!(ltype & type))
151  return -1;
152 
153  if (query == QUERY_LENGTH) {
154  length = Vect_line_length(Points);
155  if (thresh <= 0.0) { /* shorter then */
156  if (length <= fabs(thresh))
157  return 1;
158  }
159  else { /* longer then */
160  if (length > thresh)
161  return 1;
162  }
163  }
164  else if (query == QUERY_DANGLE) {
165  /*
166  this code is currently replaced by Vect_select_dangle()
167  not used by v.edit
168  */
169  int layer, cat;
170 
171  layer = 1;
172  Vect_cat_get(Cats, layer, &cat); /* get first category from layer */
173  if (!(type & GV_LINES))
174  return -1;
175  /* check if line is dangle */
176 
177  Vect_get_line_nodes(Map, line, &node1, &node2);
178 
179  node = -1;
180  nnode1 = Vect_get_node_n_lines(Map, node1);
181  nnode2 = Vect_get_node_n_lines(Map, node2);
182 
183  if ((nnode1 == 4 && nnode2 == 1) || (nnode1 == 1 && nnode2 == 4)) {
184  if (nnode1 == 4)
185  node = node1;
186  else
187  node = node2;
188  }
189 
190  /* no dangle ? */
191  if (node == -1)
192  return -1;
193 
194  length = Vect_line_length(Points);
195  if (thresh <= 0.0) { /* shorter then */
196  if (length > fabs(thresh))
197  return -1;
198  }
199  else { /* longer then */
200  if (length <= thresh)
201  return -1;
202  }
203 
204  /* at least one of the lines need to have same category number */
205  exclude = Vect_new_list();
206  found = Vect_new_list();
207 
208  Vect_get_node_coor(Map, node, &nx, &ny, &nz);
209 
210  Vect_list_append(exclude, line);
211  Vect_find_line_list(Map, nx, ny, nz,
212  GV_LINES, 0.0, WITHOUT_Z, exclude, found);
213 
214  Cats_curr = Vect_new_cats_struct();
215 
216  for (i = 0; i < found->n_values; i++) {
217  Vect_read_line(Map, NULL, Cats_curr, found->value[i]);
218  if (Vect_cat_get(Cats_curr, layer, &cat_curr) > -1) {
219  if (cat == cat_curr)
220  return 1;
221  }
222  }
223 
224  Vect_destroy_cats_struct(Cats_curr);
225  Vect_destroy_list(exclude);
226  Vect_destroy_list(found);
227  }
228  else {
229  /* this shouldn't happen */
230  G_fatal_error("Vedit_select_by_query(): %s", _("Unknown query tool"));
231  }
232 
233  return 0;
234 }
235 
244 int merge_lists(struct ilist *alist, struct ilist *blist)
245 {
246  int i;
247 
248  struct ilist *list_del;
249 
250  list_del = Vect_new_list();
251 
252  for (i = 0; i < alist->n_values; i++) {
253  if (!Vect_val_in_list(blist, alist->value[i]))
254  Vect_list_append(list_del, alist->value[i]);
255  }
256 
257  Vect_list_delete_list(alist, list_del);
258 
259  Vect_destroy_list(list_del);
260 
261  return alist->n_values;
262 }