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