00001
00020 #include <stdlib.h>
00021 #include <grass/gis.h>
00022 #include <grass/Vect.h>
00023 #include <grass/glocale.h>
00024
00037 void
00038 Vect_remove_duplicates(struct Map_info *Map, int type, struct Map_info *Err)
00039 {
00040 struct line_pnts *APoints, *BPoints;
00041 struct line_cats *ACats, *BCats, *Cats;
00042 int i, j, c, atype, btype, bline;
00043 int nlines, nbcats_orig;
00044 BOUND_BOX ABox;
00045 struct ilist *List;
00046 int ndupl;
00047
00048
00049 APoints = Vect_new_line_struct();
00050 BPoints = Vect_new_line_struct();
00051 ACats = Vect_new_cats_struct();
00052 BCats = Vect_new_cats_struct();
00053 Cats = Vect_new_cats_struct();
00054 List = Vect_new_list();
00055
00056 nlines = Vect_get_num_lines(Map);
00057
00058 G_debug(1, "nlines = %d", nlines);
00059
00060
00061
00062
00063
00064 ndupl = 0;
00065
00066 for (i = 1; i <= nlines; i++) {
00067 if (!Vect_line_alive(Map, i))
00068 continue;
00069
00070 atype = Vect_read_line(Map, APoints, ACats, i);
00071 if (!(atype & type))
00072 continue;
00073
00074 Vect_line_box(APoints, &ABox);
00075 Vect_select_lines_by_box(Map, &ABox, type, List);
00076 G_debug(3, " %d lines selected by box", List->n_values);
00077
00078 for (j = 0; j < List->n_values; j++) {
00079 bline = List->value[j];
00080 G_debug(3, " j = %d bline = %d", j, bline);
00081 if (i == bline)
00082 continue;
00083
00084 btype = Vect_read_line(Map, BPoints, BCats, bline);
00085
00086
00087 if (!Vect_line_check_duplicate(APoints, BPoints, Vect_is_3d(Map)))
00088 continue;
00089
00090
00091 if (Err) {
00092 Vect_write_line(Err, atype, APoints, ACats);
00093 }
00094
00095 Vect_delete_line(Map, i);
00096
00097
00098 nbcats_orig = BCats->n_cats;
00099
00100 for (c = 0; c < ACats->n_cats; c++)
00101 Vect_cat_set(BCats, ACats->field[c], ACats->cat[c]);
00102
00103 if (BCats->n_cats > nbcats_orig) {
00104 G_debug(4, "cats merged: n_cats %d -> %d", nbcats_orig,
00105 BCats->n_cats);
00106 Vect_rewrite_line(Map, bline, btype, BPoints, BCats);
00107 }
00108
00109 ndupl++;
00110
00111 break;
00112 }
00113 nlines = Vect_get_num_lines(Map);
00114 G_debug(3, "nlines = %d\n", nlines);
00115 }
00116 }
00117
00127 int Vect_line_check_duplicate(const struct line_pnts *APoints,
00128 const struct line_pnts *BPoints, int with_z)
00129 {
00130 int k;
00131 int npoints;
00132 int forw, backw;
00133
00134 if (APoints->n_points != BPoints->n_points)
00135 return 0;
00136
00137 npoints = APoints->n_points;
00138
00139
00140 forw = 1;
00141 for (k = 0; k < APoints->n_points; k++) {
00142 if (APoints->x[k] != BPoints->x[k] ||
00143 APoints->y[k] != BPoints->y[k] ||
00144 (with_z && APoints->z[k] != BPoints->z[k])) {
00145 forw = 0;
00146 break;
00147 }
00148 }
00149
00150
00151 backw = 1;
00152 for (k = 0; k < APoints->n_points; k++) {
00153 if (APoints->x[k] != BPoints->x[npoints - k - 1] ||
00154 APoints->y[k] != BPoints->y[npoints - k - 1] ||
00155 (with_z && APoints->z[k] != BPoints->z[npoints - k - 1])) {
00156 backw = 0;
00157 break;
00158 }
00159 }
00160
00161 if (!forw && !backw)
00162 return 0;
00163
00164 return 1;
00165 }