vedit/select.c

Go to the documentation of this file.
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 }
Generated on Tue Apr 6 13:28:10 2010 for GRASS Programmer's Manual by  doxygen 1.6.3