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