GRASS Programmer's Manual  6.4.2(2012)
vector/vedit/select.c
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines