00001
00017 #include <grass/glocale.h>
00018 #include <grass/vedit.h>
00019
00020 static int select_by_query(struct Map_info *, int, int, double,
00021 int, struct line_pnts *, struct line_cats *);
00022
00023 static int merge_lists(struct ilist *alist, struct ilist *blist);
00024
00044 int Vedit_select_by_query(struct Map_info *Map,
00045 int type, int layer, double thresh, int query,
00046 struct ilist *List)
00047 {
00048 int num, line, i;
00049 double thresh_tmp;
00050 struct line_pnts *Points;
00051 struct line_cats *Cats;
00052 struct ilist *List_query;
00053
00054 Points = Vect_new_line_struct();
00055 Cats = Vect_new_cats_struct();
00056
00057 if (List->n_values == 0) {
00058 List_query = List;
00059 }
00060 else {
00061 List_query = Vect_new_list();
00062 }
00063
00064 switch (query) {
00065 case QUERY_LENGTH:{
00066 if (List->n_values == 0) {
00067
00068 num = Vect_get_num_lines(Map);
00069 for (line = 1; line <= num; line++) {
00070 if (select_by_query(Map, line, type, thresh,
00071 query, Points, Cats))
00072 Vect_list_append(List_query, line);
00073 }
00074 }
00075 else {
00076 for (i = 0; i < List->n_values; i++) {
00077 line = List->value[i];
00078 if (select_by_query(Map, line, type, thresh,
00079 query, Points, Cats)) {
00080 Vect_list_append(List_query, line);
00081 }
00082 }
00083 }
00084 break;
00085 }
00086 case QUERY_DANGLE:{
00087 struct ilist *List_dangle;
00088
00089 List_dangle = Vect_new_list();
00090 thresh_tmp = fabs(thresh);
00091
00092
00093 Vect_select_dangles(Map, type, thresh_tmp, List_dangle);
00094
00095 if (thresh <= 0.0) {
00096 for (i = 0; i < List_dangle->n_values; i++) {
00097 Vect_list_append(List_query, List_dangle->value[i]);
00098 }
00099 }
00100 else {
00101 for (i = 1; i <= Vect_get_num_lines(Map); i++) {
00102 if (!Vect_val_in_list(List_dangle, i))
00103 Vect_list_append(List_query, i);
00104 }
00105 }
00106
00107 Vect_destroy_list(List_dangle);
00108 break;
00109 }
00110 default:
00111 break;
00112 }
00113
00114 if (List != List_query) {
00115 merge_lists(List, List_query);
00116 Vect_destroy_list(List_query);
00117 }
00118
00119 G_debug(3, "Vedit_select_by_query(): %d lines selected (by query %d)",
00120 List->n_values, query);
00121
00122 Vect_destroy_line_struct(Points);
00123 Vect_destroy_cats_struct(Cats);
00124
00125 return List->n_values;
00126 }
00127
00135 int select_by_query(struct Map_info *Map, int line, int type, double thresh,
00136 int query, struct line_pnts *Points,
00137 struct line_cats *Cats)
00138 {
00139 int ltype;
00140 double length;
00141 int i, cat_curr;
00142 int node1, node2, node;
00143 int nnode1, nnode2;
00144 double nx, ny, nz;
00145 struct ilist *exclude, *found;
00146 struct line_cats *Cats_curr;
00147
00148 if (!Vect_line_alive(Map, line))
00149 return -1;
00150
00151 ltype = Vect_read_line(Map, Points, Cats, line);
00152
00153 if (!(ltype & type))
00154 return -1;
00155
00156 if (query == QUERY_LENGTH) {
00157 length = Vect_line_length(Points);
00158 if (thresh <= 0.0) {
00159 if (length <= fabs(thresh))
00160 return 1;
00161 }
00162 else {
00163 if (length > thresh)
00164 return 1;
00165 }
00166 }
00167 else if (query == QUERY_DANGLE) {
00168
00169
00170
00171
00172 int layer, cat;
00173
00174 layer = 1;
00175 Vect_cat_get(Cats, layer, &cat);
00176 if (!(type & GV_LINES))
00177 return -1;
00178
00179
00180 Vect_get_line_nodes(Map, line, &node1, &node2);
00181
00182 node = -1;
00183 nnode1 = Vect_get_node_n_lines(Map, node1);
00184 nnode2 = Vect_get_node_n_lines(Map, node2);
00185
00186 if ((nnode1 == 4 && nnode2 == 1) || (nnode1 == 1 && nnode2 == 4)) {
00187 if (nnode1 == 4)
00188 node = node1;
00189 else
00190 node = node2;
00191 }
00192
00193
00194 if (node == -1)
00195 return -1;
00196
00197 length = Vect_line_length(Points);
00198 if (thresh <= 0.0) {
00199 if (length > fabs(thresh))
00200 return -1;
00201 }
00202 else {
00203 if (length <= thresh)
00204 return -1;
00205 }
00206
00207
00208 exclude = Vect_new_list();
00209 found = Vect_new_list();
00210
00211 Vect_get_node_coor(Map, node, &nx, &ny, &nz);
00212
00213 Vect_list_append(exclude, line);
00214 Vect_find_line_list(Map, nx, ny, nz,
00215 GV_LINES, 0.0, WITHOUT_Z, exclude, found);
00216
00217 Cats_curr = Vect_new_cats_struct();
00218
00219 for (i = 0; i < found->n_values; i++) {
00220 Vect_read_line(Map, NULL, Cats_curr, found->value[i]);
00221 if (Vect_cat_get(Cats_curr, layer, &cat_curr) > -1) {
00222 if (cat == cat_curr)
00223 return 1;
00224 }
00225 }
00226
00227 Vect_destroy_cats_struct(Cats_curr);
00228 Vect_destroy_list(exclude);
00229 Vect_destroy_list(found);
00230 }
00231 else {
00232
00233 G_fatal_error("Vedit_select_by_query(): %s", _("Unknown query tool"));
00234 }
00235
00236 return 0;
00237 }
00238
00247 int merge_lists(struct ilist *alist, struct ilist *blist)
00248 {
00249 int i;
00250
00251 struct ilist *list_del;
00252
00253 list_del = Vect_new_list();
00254
00255 for (i = 0; i < alist->n_values; i++) {
00256 if (!Vect_val_in_list(blist, alist->value[i]))
00257 Vect_list_append(list_del, alist->value[i]);
00258 }
00259
00260 Vect_list_delete_list(alist, list_del);
00261
00262 Vect_destroy_list(list_del);
00263
00264 return alist->n_values;
00265 }