00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdlib.h>
00018 #include <grass/gis.h>
00019 #include <grass/Vect.h>
00020
00021 void remove_dangles ( struct Map_info *Map, int type, int chtype, double maxlength,
00022 struct Map_info *Err, FILE *msgout );
00023
00042 void
00043 Vect_remove_dangles ( struct Map_info *Map, int type, double maxlength, struct Map_info *Err, FILE *msgout )
00044 {
00045 remove_dangles ( Map, type, 0, maxlength, Err, msgout );
00046 }
00047
00066 void
00067 Vect_chtype_dangles ( struct Map_info *Map, double maxlength, struct Map_info *Err, FILE *msgout )
00068 {
00069 remove_dangles ( Map, 0, 1, maxlength, Err, msgout );
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 void
00090 remove_dangles ( struct Map_info *Map, int type, int chtype, double maxlength, struct Map_info *Err, FILE *msgout )
00091 {
00092 struct line_pnts *Points;
00093 struct line_cats *Cats;
00094 int i, line, ltype, next_line=0, nnodelines;
00095 int nnodes, node, node1, node2, next_node;
00096 int lcount, tmp_next_line=0;
00097 double length;
00098 int dangles_removed = 0;
00099 int lines_removed = 0;
00100 struct ilist *List;
00101 char *lmsg;
00102
00103 type &= GV_LINES;
00104
00105 if ( chtype ) {
00106 type = GV_BOUNDARY;
00107 lmsg = "changed lines";
00108 } else {
00109 lmsg = "removed lines";
00110 }
00111
00112 Points = Vect_new_line_struct ();
00113 Cats = Vect_new_cats_struct ();
00114 List = Vect_new_list ();
00115
00116 if ( msgout ) fprintf (msgout, "Removed dangles: %5d %s: %5d",
00117 dangles_removed, lmsg, lines_removed );
00118
00119 nnodes = Vect_get_num_nodes (Map);
00120 G_debug (2, "nnodes = %d", nnodes );
00121
00122 for ( node = 1; node <= nnodes; node++ ){
00123 G_debug (3, "node = %d", node);
00124 if ( !Vect_node_alive (Map, node) ) continue;
00125
00126 nnodelines = Vect_get_node_n_lines ( Map, node );
00127
00128 lcount = 0;
00129 for ( i = 0; i < nnodelines; i++) {
00130 line = Vect_get_node_line (Map, node, i);
00131 G_debug (3, " node line %d = %d", i, line);
00132
00133 ltype = Vect_read_line (Map, NULL, NULL, abs(line));
00134
00135 if ( ltype & type ) {
00136 lcount++;
00137 next_line = line;
00138 }
00139 }
00140
00141 Vect_reset_list ( List );
00142 if ( lcount == 1 ) {
00143 G_debug (3, " node %d is dangle -> follow the line %d", node, next_line);
00144
00145 while ( next_line != 0 ) {
00146 Vect_list_append ( List, abs(next_line) );
00147
00148
00149 Vect_get_line_nodes ( Map, abs(next_line), &node1, &node2 );
00150 next_node = next_line > 0 ? node2 : node1;
00151
00152 G_debug (3, " next_node = %d", next_node);
00153
00154 nnodelines = Vect_get_node_n_lines ( Map, next_node );
00155
00156 lcount = 0;
00157 for ( i = 0; i < nnodelines; i++) {
00158 line = Vect_get_node_line (Map, next_node, i);
00159 G_debug (3, " node line %d = %d", i, line);
00160
00161 ltype = Vect_read_line (Map, NULL, NULL, abs(line));
00162
00163 if ( ltype & type && abs(line) != abs(next_line) ) {
00164 lcount++;
00165 tmp_next_line = line;
00166 }
00167 }
00168 if ( lcount == 1 )
00169 next_line = tmp_next_line;
00170 else
00171 next_line = 0;
00172
00173 }
00174
00175
00176 length = 0;
00177 for ( i = 0; i < List->n_values; i++) {
00178 G_debug (3, " chain line %d = %d", i, List->value[i]);
00179 ltype = Vect_read_line (Map, Points, NULL, List->value[i]);
00180 length += Vect_line_length ( Points );
00181 }
00182
00183 if ( maxlength < 0 || length < maxlength ) {
00184 G_debug (3, " delete the chain" );
00185
00186 for ( i = 0; i < List->n_values; i++) {
00187 ltype = Vect_read_line (Map, Points, Cats, List->value[i]);
00188
00189
00190 if ( Err ) {
00191 Vect_write_line ( Err, ltype, Points, Cats );
00192 }
00193
00194 if ( !chtype ) {
00195 Vect_delete_line (Map, List->value[i]);
00196 } else {
00197 G_debug (3, " rewrite line %d", List->value[i] );
00198 Vect_rewrite_line ( Map, List->value[i], GV_LINE, Points, Cats);
00199 }
00200
00201 lines_removed++;
00202 }
00203 }
00204 if ( msgout ) {
00205 if ( msgout ) fprintf (msgout, "\rRemoved dangles: %5d %s: %5d",
00206 dangles_removed, lmsg, lines_removed );
00207 fflush ( msgout );
00208 }
00209 dangles_removed++;
00210 }
00211 }
00212 if ( msgout ) {
00213 if ( msgout ) fprintf (msgout, "\rRemoved dangles: %5d %s: %5d",
00214 dangles_removed, lmsg, lines_removed );
00215 fprintf (msgout, "\n" );
00216 }
00217 }
00218