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
00089 for (l = 0; l < seg; l++) {
00090 Vect_append_point(Points2, x[l], y[l], z[l]);
00091 }
00092
00093
00094 Vect_append_point(Points2, px, py, 0.0);
00095
00096
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
00106 Vect_append_point(Points2, px, py, 0.0);
00107
00108
00109 for (l = seg; l < Points->n_points; l++) {
00110 Vect_append_point(Points2, x[l], y[l], z[l]);
00111 }
00112
00113
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 }
00123 }
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
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
00187 Vect_get_node_coor(Map, node[j], &x, &y, &z);
00188
00189 do {
00190
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
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
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
00285
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
00298
00299
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
00310
00311
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
00321 line_new = Vect_write_line(Map, type_to,
00322 Points_final, Cats_to);
00323
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 }