00001
00017 #include <grass/vedit.h>
00018
00031 int Vedit_snap_point(struct Map_info *Map,
00032 int line, double *x, double *y, double *z, double thresh,
00033 int vertex)
00034 {
00035 struct line_pnts *Points;
00036
00037 int i, snapped;
00038 int line2snap, mindist_idx;
00039 double dist, mindist;
00040
00041 snapped = 0;
00042 mindist_idx = -1;
00043 mindist = thresh;
00044
00045 Points = Vect_new_line_struct();
00046
00047 line2snap = Vect_find_line(Map, *x, *y, *z, -1, thresh, WITHOUT_Z, line);
00048
00049 if (line2snap > 0) {
00050 Vect_read_line(Map, Points, NULL, line2snap);
00051
00052 if (!Vect_line_alive(Map, line2snap)) {
00053 Vect_destroy_line_struct(Points);
00054 return snapped;
00055 }
00056
00057 for (i = 0; i < Points->n_points; i++) {
00058 if (i > 0 && i < Points->n_points - 1)
00059 if (!vertex)
00060 continue;
00061 dist = Vect_points_distance(*x, *y, *z,
00062 Points->x[i], Points->y[i],
00063 Points->z[i], WITHOUT_Z);
00064
00065 if (mindist >= dist) {
00066 mindist = dist;
00067 mindist_idx = i;
00068 }
00069 }
00070
00071 if (mindist_idx > -1) {
00072 *x = Points->x[mindist_idx];
00073 *y = Points->y[mindist_idx];
00074 *z = Points->z[mindist_idx];
00075 snapped = 1;
00076 }
00077 }
00078
00079 G_debug(3, "Vedit_snap_point(): map=%s, line2snap=%d, snapped=%d",
00080 Map->name, line2snap, snapped);
00081
00082 Vect_destroy_line_struct(Points);
00083
00084 return snapped;
00085 }
00086
00102 int Vedit_snap_line(struct Map_info *Map, struct Map_info **BgMap,
00103 int nbgmaps, int line, struct line_pnts *Points,
00104 double thresh, int to_vertex)
00105 {
00106 int i, npoints, node, rewrite;
00107 double *x, *y, *z;
00108
00109 struct line_cats *Cats;
00110
00111 Cats = Vect_new_cats_struct();
00112
00113 G_debug(3, "Vedit_snap_line(): thresh=%g, to_vertex=%d", thresh,
00114 to_vertex);
00115
00116 if (line > 0 && !Vect_line_alive(Map, line))
00117 return -1;
00118
00119 npoints = Points->n_points;
00120 x = Points->x;
00121 y = Points->y;
00122 z = Points->z;
00123
00124 rewrite = 0;
00125 for (node = 0; node < npoints; node++) {
00126 if ((node > 0 && node < npoints - 1) && !to_vertex)
00127 continue;
00128
00129 if (Vedit_snap_point(Map, line, &x[node], &y[node], &z[node], thresh,
00130 to_vertex)) {
00131 rewrite = 1;
00132 }
00133 else {
00134
00135 for (i = 0; i < nbgmaps; i++) {
00136 if (Vedit_snap_point
00137 (BgMap[i], -1, &x[node], &y[node], &z[node], thresh,
00138 to_vertex)) {
00139 rewrite = 1;
00140 break;
00141 }
00142 }
00143 }
00144 }
00145
00146
00147 if (!rewrite &&
00148 Vect_points_distance(x[0], y[0], z[0],
00149 x[npoints - 1], y[npoints - 1], z[npoints - 1],
00150 WITHOUT_Z) <= thresh) {
00151 x[npoints - 1] = x[0];
00152 y[npoints - 1] = y[0];
00153 z[npoints - 1] = z[0];
00154
00155 rewrite = 1;
00156 }
00157
00158 G_debug(3, "Vedit_snap_line(): line=%d, snapped=%d", line, rewrite);
00159
00160 Vect_destroy_cats_struct(Cats);
00161
00162 return rewrite;
00163 }
00164
00178 int Vedit_snap_lines(struct Map_info *Map, struct Map_info **BgMap,
00179 int nbgmaps, struct ilist *List, double thresh,
00180 int to_vertex)
00181 {
00182 int i, line, type;
00183 int nlines_modified = 0;
00184
00185 struct line_pnts *Points;
00186 struct line_cats *Cats;
00187
00188 Points = Vect_new_line_struct();
00189 Cats = Vect_new_cats_struct();
00190
00191 for (i = 0; i < List->n_values; i++) {
00192 line = List->value[i];
00193 type = Vect_read_line(Map, Points, Cats, line);
00194
00195 if (!(type & (GV_POINT | GV_LINES))) {
00196 continue;
00197 }
00198
00199 if (Vedit_snap_line(Map, BgMap, nbgmaps,
00200 line, Points, thresh, to_vertex) == 1) {
00201 if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
00202 return -1;
00203 }
00204
00205 nlines_modified++;
00206 }
00207 }
00208
00209 Vect_destroy_line_struct(Points);
00210 Vect_destroy_cats_struct(Cats);
00211
00212 return nlines_modified;
00213 }