break.c

Go to the documentation of this file.
00001 
00016 #include <math.h>
00017 #include <grass/vedit.h>
00018 
00019 static int connect_lines(struct Map_info *, int, int, int,
00020                          double, struct ilist *);
00021 
00033 int Vedit_split_lines(struct Map_info *Map, struct ilist *List,
00034                       struct line_pnts *coord, double thresh,
00035                       struct ilist *List_updated)
00036 {
00037     int i, j, l;
00038     int type, line, seg, newline;
00039     int nlines_modified;
00040     double px, py, spdist, lpdist, dist;
00041     double *x, *y, *z;
00042 
00043     struct line_pnts *Points, *Points2;
00044     struct line_cats *Cats;
00045     struct ilist *List_in_box;
00046 
00047     nlines_modified = 0;
00048 
00049     Points = Vect_new_line_struct();
00050     Points2 = Vect_new_line_struct();
00051     Cats = Vect_new_cats_struct();
00052     List_in_box = Vect_new_list();
00053 
00054     for (i = 0; i < List->n_values; i++) {
00055         line = List->value[i];
00056 
00057         if (!Vect_line_alive(Map, line))
00058             continue;
00059 
00060         type = Vect_read_line(Map, Points, Cats, line);
00061 
00062         if (!(type & GV_LINES))
00063             continue;
00064 
00065         x = Points->x;
00066         y = Points->y;
00067         z = Points->z;
00068 
00069         for (j = 0; j < coord->n_points; j++) {
00070             seg =
00071                 Vect_line_distance(Points, coord->x[j], coord->y[j],
00072                                    coord->z[j], WITHOUT_Z, &px, &py, NULL,
00073                                    &dist, &spdist, &lpdist);
00074 
00075             if (dist > thresh) {
00076                 continue;
00077             }
00078 
00079             G_debug(3, "Vedit_split_lines(): line=%d, x=%f, y=%f, px=%f, py=%f, seg=%d, "
00080                     "dist=%f, spdist=%f, lpdist=%f", line, coord->x[j],
00081                     coord->y[j], px, py, seg, dist, spdist, lpdist);
00082             
00083             if (spdist <= 0.0 || spdist >= Vect_line_length(Points))
00084                 continue;
00085 
00086             G_debug(3, "Vedit_split_lines(): line=%d", line);
00087 
00088             /* copy first line part */
00089             for (l = 0; l < seg; l++) {
00090                 Vect_append_point(Points2, x[l], y[l], z[l]);
00091             }
00092 
00093             /* add last vertex */
00094             Vect_append_point(Points2, px, py, 0.0);
00095 
00096             /* rewrite the line */
00097             newline = Vect_rewrite_line(Map, line, type, Points2, Cats);
00098             if (newline < 0) {
00099                 return -1;
00100             }
00101             if (List_updated)
00102                 Vect_list_append(List_updated, newline);
00103             Vect_reset_line(Points2);
00104 
00105             /* add given vertex */
00106             Vect_append_point(Points2, px, py, 0.0);
00107 
00108             /* copy second line part */
00109             for (l = seg; l < Points->n_points; l++) {
00110                 Vect_append_point(Points2, x[l], y[l], z[l]);
00111             }
00112 
00113             /* rewrite the line */
00114             newline = Vect_write_line(Map, type, Points2, Cats);
00115             if (newline < 0) {
00116                 return -1;
00117             }
00118             if (List_updated)
00119                 Vect_list_append(List_updated, newline);
00120 
00121             nlines_modified++;
00122         }                       /* for each bounding box */
00123     }                           /* for each selected line */
00124 
00125     Vect_destroy_line_struct(Points);
00126     Vect_destroy_line_struct(Points2);
00127     Vect_destroy_cats_struct(Cats);
00128     Vect_destroy_list(List_in_box);
00129 
00130     return nlines_modified;
00131 }
00132 
00153 int Vedit_connect_lines(struct Map_info *Map, struct ilist *List,
00154                         double thresh)
00155 {
00156     int nlines_modified, connected;
00157     int i, j, node[2], n_nodes;
00158     int line, found;
00159     double x, y, z;
00160 
00161     struct ilist *List_exclude, *List_found;
00162 
00163     nlines_modified = 0;
00164 
00165     List_exclude = Vect_new_list();
00166     List_found = Vect_new_list();
00167 
00168     n_nodes = 2;
00169 
00170     /* collect lines to be modified */
00171     for (i = 0; i < List->n_values; i++) {
00172         line = List->value[i];
00173 
00174         if (!Vect_line_alive(Map, line))
00175             continue;
00176 
00177         node[0] = node[1] = -1;
00178         Vect_get_line_nodes(Map, line, &(node[0]), &(node[1]));
00179         if (node[0] < 0 || node[1] < 0)
00180             continue;
00181 
00182         connected = 0;
00183         Vect_reset_list(List_exclude);
00184         Vect_list_append(List_exclude, line);
00185         for (j = 0; j < n_nodes && !connected; j++) {
00186             /* for each line node find lines in threshold */
00187             Vect_get_node_coor(Map, node[j], &x, &y, &z);
00188 
00189             do {
00190                 /* find first nearest line */
00191                 found = Vect_find_line_list(Map, x, y, z,
00192                                             GV_LINES, thresh, WITHOUT_Z,
00193                                             List_exclude, List_found);
00194                 
00195                 if (found > 0 && Vect_line_alive(Map, found)) {
00196                     /* try to connect lines (given node) */
00197                     G_debug(3, "Vedit_connect_lines(): lines=%d,%d", line, found);
00198                     if (connect_lines(Map, !j, line, found, thresh, List)) {
00199                         G_debug(3, "Vedit_connect_lines(): lines=%d,%d -> connected",
00200                                 line, found);
00201                         nlines_modified += 2;
00202                         connected = 1;
00203                     }
00204                 }
00205                 
00206                 Vect_list_append(List_exclude, found);
00207             } while(List_found->n_values > 0 && !connected);
00208         }
00209     }
00210     
00211     Vect_destroy_list(List_exclude);
00212     Vect_destroy_list(List_found);
00213 
00214     return nlines_modified;
00215 }
00216 
00217 int connect_lines(struct Map_info *Map, int first, int line_from, int line_to,
00218                   double thresh, struct ilist *List)
00219 {
00220     int line_new;
00221     int type_from, type_to;
00222     int n_points, seg, is;
00223     double x, y, px, py, x1, y1;
00224     double dist, spdist, lpdist, length, dist_p;
00225     double angle_t, angle_f, angle;
00226 
00227     struct line_pnts *Points_from, *Points_to, *Points_final;
00228     struct line_cats *Cats_from, *Cats_to;
00229 
00230     Points_from = Vect_new_line_struct();
00231     Points_to = Vect_new_line_struct();
00232     Points_final = Vect_new_line_struct();
00233     Cats_from = Vect_new_cats_struct();
00234     Cats_to = Vect_new_cats_struct();
00235 
00236     type_from = Vect_read_line(Map, Points_from, Cats_from, line_from);
00237     type_to = Vect_read_line(Map, Points_to, Cats_to, line_to);
00238 
00239     line_new = 0;
00240     if (!(type_from & GV_LINES) || !(type_to & GV_LINES))
00241         line_new = -1;
00242 
00243     if (line_new > -1) {
00244         if (first) {
00245             x = Points_from->x[0];
00246             y = Points_from->y[0];
00247         }
00248         else {
00249             n_points = Points_from->n_points - 1;
00250             x = Points_from->x[n_points];
00251             y = Points_from->y[n_points];
00252         }
00253         seg = Vect_line_distance(Points_to, x, y, 0.0, WITHOUT_Z,
00254                                  &px, &py, NULL, &dist, &spdist, &lpdist);
00255         
00256         if (seg > 0 && dist > 0.0 && (thresh < 0. || dist <= thresh)) {
00257             /* lines in threshold */
00258             if (first)
00259                 length = 0;
00260             else
00261                 length = Vect_line_length(Points_from);
00262 
00263             if (Vect_point_on_line(Points_from, length,
00264                                    NULL, NULL, NULL, &angle_f, NULL) > 0) {
00265                 if (Vect_point_on_line(Points_to, lpdist,
00266                                        NULL, NULL, NULL, &angle_t,
00267                                        NULL) > 0) {
00268                     angle = angle_t - angle_f;
00269                     dist_p = fabs(dist / sin(angle));
00270                     
00271                     if (first) {
00272                         if (angle_f < 0)
00273                             angle_f -= M_PI;
00274                         else
00275                             angle_f += M_PI;
00276                     }
00277 
00278                     x1 = x + dist_p * cos(angle_f);
00279                     y1 = y + dist_p * sin(angle_f);
00280 
00281                     length = Vect_line_length(Points_to);
00282                     Vect_line_insert_point(Points_to, seg, x1, y1, 0.);
00283                     if (fabs(Vect_line_length(Points_to) - length) < length * 1e-3) {
00284                         /* lines connected -> split line_to */
00285                         /* update line_from */
00286                         if (first) {
00287                             Points_from->x[0] = x1;
00288                             Points_from->y[0] = y1;
00289                         }
00290                         else {
00291                             Points_from->x[n_points] = x1;
00292                             Points_from->y[n_points] = y1;
00293                         }
00294                         
00295                         line_new = Vect_rewrite_line(Map, line_from, type_from,
00296                                                      Points_from, Cats_from);
00297                         /* Vect_list_append(List, line_new); */
00298                         
00299                         /* update line_to  -- first part */
00300                         Vect_reset_line(Points_final);
00301                         for (is = 0; is < seg; is++) {
00302                             Vect_append_point(Points_final, Points_to->x[is],
00303                                           Points_to->y[is],
00304                                               Points_to->z[is]);
00305                         }
00306                         Vect_append_point(Points_final, x1, y1, 0.0);
00307                         line_new = Vect_rewrite_line(Map, line_to, type_to,
00308                                                      Points_final, Cats_to);
00309                         /* Vect_list_append(List, line_new); */
00310                         
00311                         /* write second part */
00312                         Vect_reset_line(Points_final);
00313                         Vect_append_point(Points_final, x1, y1, 0.0);
00314                         for (is = seg; is < Points_to->n_points; is++) {
00315                             Vect_append_point(Points_final, Points_to->x[is],
00316                                               Points_to->y[is],
00317                                               Points_to->z[is]);
00318                         }
00319                         
00320                         /* rewrite first part */
00321                         line_new = Vect_write_line(Map, type_to,
00322                                                    Points_final, Cats_to);
00323                         /* Vect_list_append(List, line_new); */
00324                     }
00325                 }
00326             }
00327         }
00328     }
00329 
00330     Vect_destroy_line_struct(Points_from);
00331     Vect_destroy_line_struct(Points_to);
00332     Vect_destroy_line_struct(Points_final);
00333     Vect_destroy_cats_struct(Cats_from);
00334     Vect_destroy_cats_struct(Cats_to);
00335 
00336     return line_new > 0 ? 1 : 0;
00337 }
Generated on Tue Apr 6 13:28:09 2010 for GRASS Programmer's Manual by  doxygen 1.6.3