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