GRASS Programmer's Manual
6.4.1(2011)
|
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 }