GRASS Programmer's Manual
6.4.1(2011)
|
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 /* query all vector objects in vector map */ 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 /* select dangles shorter than 'thresh_tmp' */ 00093 Vect_select_dangles(Map, type, thresh_tmp, List_dangle); 00094 00095 if (thresh <= 0.0) { /* shorter than */ 00096 for (i = 0; i < List_dangle->n_values; i++) { 00097 Vect_list_append(List_query, List_dangle->value[i]); 00098 } 00099 } 00100 else { /* longer than */ 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; /* nodes */ 00143 int nnode1, nnode2; /* number of line in node */ 00144 double nx, ny, nz; /* node coordinates */ 00145 struct ilist *exclude, *found; /* line id of nearest lines */ 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) { /* shorter then */ 00159 if (length <= fabs(thresh)) 00160 return 1; 00161 } 00162 else { /* longer then */ 00163 if (length > thresh) 00164 return 1; 00165 } 00166 } 00167 else if (query == QUERY_DANGLE) { 00168 /* 00169 this code is currently replaced by Vect_select_dangle() 00170 not used by v.edit 00171 */ 00172 int layer, cat; 00173 00174 layer = 1; 00175 Vect_cat_get(Cats, layer, &cat); /* get first category from layer */ 00176 if (!(type & GV_LINES)) 00177 return -1; 00178 /* check if line is dangle */ 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 /* no dangle ? */ 00194 if (node == -1) 00195 return -1; 00196 00197 length = Vect_line_length(Points); 00198 if (thresh <= 0.0) { /* shorter then */ 00199 if (length > fabs(thresh)) 00200 return -1; 00201 } 00202 else { /* longer then */ 00203 if (length <= thresh) 00204 return -1; 00205 } 00206 00207 /* at least one of the lines need to have same category number */ 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 /* this shouldn't happen */ 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 }