GRASS Programmer's Manual 6.4.1(2011)
|
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 /* Go through all lines in vector, for each select lines which overlap MBR of 00060 * this line and check if some of them is identical. If someone is identical 00061 * remove current line. (In each step just one line is deleted) 00062 */ 00063 00064 ndupl = 0; 00065 00066 for (i = 1; i <= nlines; i++) { 00067 G_percent(i, nlines, 1); 00068 if (!Vect_line_alive(Map, i)) 00069 continue; 00070 00071 atype = Vect_read_line(Map, APoints, ACats, i); 00072 if (!(atype & type)) 00073 continue; 00074 00075 Vect_line_box(APoints, &ABox); 00076 Vect_select_lines_by_box(Map, &ABox, type, List); 00077 G_debug(3, " %d lines selected by box", List->n_values); 00078 00079 for (j = 0; j < List->n_values; j++) { 00080 bline = List->value[j]; 00081 G_debug(3, " j = %d bline = %d", j, bline); 00082 if (i == bline) 00083 continue; 00084 00085 btype = Vect_read_line(Map, BPoints, BCats, bline); 00086 00087 /* check for duplicates */ 00088 if (!Vect_line_check_duplicate(APoints, BPoints, Vect_is_3d(Map))) 00089 continue; 00090 00091 /* Lines area identical -> remove current */ 00092 if (Err) { 00093 Vect_write_line(Err, atype, APoints, ACats); 00094 } 00095 00096 Vect_delete_line(Map, i); 00097 00098 /* Merge categories */ 00099 nbcats_orig = BCats->n_cats; 00100 00101 for (c = 0; c < ACats->n_cats; c++) 00102 Vect_cat_set(BCats, ACats->field[c], ACats->cat[c]); 00103 00104 if (BCats->n_cats > nbcats_orig) { 00105 G_debug(4, "cats merged: n_cats %d -> %d", nbcats_orig, 00106 BCats->n_cats); 00107 Vect_rewrite_line(Map, bline, btype, BPoints, BCats); 00108 } 00109 00110 ndupl++; 00111 00112 break; /* line was deleted -> take the next one */ 00113 } 00114 nlines = Vect_get_num_lines(Map); /* For future when lines with cats will be rewritten */ 00115 G_debug(3, "nlines = %d\n", nlines); 00116 } 00117 } 00118 00128 int Vect_line_check_duplicate(const struct line_pnts *APoints, 00129 const struct line_pnts *BPoints, int with_z) 00130 { 00131 int k; 00132 int npoints; 00133 int forw, backw; 00134 00135 if (APoints->n_points != BPoints->n_points) 00136 return 0; 00137 00138 npoints = APoints->n_points; 00139 00140 /* Forward */ 00141 forw = 1; 00142 for (k = 0; k < APoints->n_points; k++) { 00143 if (APoints->x[k] != BPoints->x[k] || 00144 APoints->y[k] != BPoints->y[k] || 00145 (with_z && APoints->z[k] != BPoints->z[k])) { 00146 forw = 0; 00147 break; 00148 } 00149 } 00150 00151 /* Backward */ 00152 backw = 1; 00153 for (k = 0; k < APoints->n_points; k++) { 00154 if (APoints->x[k] != BPoints->x[npoints - k - 1] || 00155 APoints->y[k] != BPoints->y[npoints - k - 1] || 00156 (with_z && APoints->z[k] != BPoints->z[npoints - k - 1])) { 00157 backw = 0; 00158 break; 00159 } 00160 } 00161 00162 if (!forw && !backw) 00163 return 0; 00164 00165 return 1; 00166 }