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
00032 int
00033 Vect_clean_small_angles_at_nodes ( struct Map_info *Map, int otype, struct Map_info *Err, FILE *msgout)
00034 {
00035 int node;
00036 int nmodif = 0;
00037 struct line_pnts *Points;
00038 struct line_cats *SCats, *LCats, *OCats;
00039
00040 Points = Vect_new_line_struct ();
00041 SCats = Vect_new_cats_struct ();
00042 LCats = Vect_new_cats_struct ();
00043 OCats = Vect_new_cats_struct ();
00044
00045 if ( msgout ) fprintf (msgout, "Modifications: %5d", nmodif );
00046
00047 for ( node = 1; node <= Vect_get_num_nodes(Map); node++ ){
00048 int i, nlines;
00049
00050 G_debug (3, "node = %d", node );
00051 if ( !Vect_node_alive ( Map, node ) ) continue;
00052
00053 while ( 1 ) {
00054 float angle1 = -100;
00055 int line1 = -999;
00056 int clean = 1;
00057
00058
00059 nlines = Vect_get_node_n_lines ( Map, node );
00060 G_debug (3, "nlines = %d", nlines );
00061
00062 for ( i = 0; i < nlines; i++ ) {
00063 P_LINE *Line;
00064 int line2;
00065 float angle2;
00066
00067 line2 = Vect_get_node_line ( Map, node, i );
00068 Line = Map->plus.Line[abs(line2)];
00069 if ( !Line ) continue;
00070 G_debug (4, " type = %d", Line->type );
00071 if ( !(Line->type & (otype & GV_LINES)) ) continue;
00072
00073 angle2 = Vect_get_node_line_angle ( Map, node, i );
00074 if ( angle2 == -9.0 ) continue;
00075
00076 G_debug (4, " line1 = %d angle1 = %e line2 = %d angle2 = %e", line1, angle1, line2, angle2 );
00077
00078 if ( angle2 == angle1 ) {
00079 int j;
00080 double length1, length2;
00081 int short_line;
00082 int long_line;
00083 int new_short_line=0;
00084 int short_type, long_type, type;
00085 double x, y, z, nx, ny, nz;
00086
00087 G_debug (4, " identical angles -> clean" );
00088
00089
00090 Vect_read_line ( Map, Points, NULL, abs(line1) );
00091 if ( line1 > 0 ) {
00092 length1 = Vect_points_distance ( Points->x[0], Points->y[0], 0.0,
00093 Points->x[1], Points->y[1], 0.0, 0 );
00094 } else {
00095 int np;
00096 np = Points->n_points;
00097 length1 = Vect_points_distance ( Points->x[np-1], Points->y[np-1], 0.0,
00098 Points->x[np-2], Points->y[np-2], 0.0, 0 );
00099 }
00100
00101 Vect_read_line ( Map, Points, NULL, abs(line2) );
00102 if ( line2 > 0 ) {
00103 length2 = Vect_points_distance ( Points->x[0], Points->y[0], 0.0,
00104 Points->x[1], Points->y[1], 0.0, 0 );
00105 } else {
00106 int np;
00107 np = Points->n_points;
00108 length2 = Vect_points_distance ( Points->x[np-1], Points->y[np-1], 0.0,
00109 Points->x[np-2], Points->y[np-2], 0.0, 0 );
00110 }
00111
00112 G_debug (4, " length1 = %f length2 = %f", length1, length2 );
00113
00114 if ( length1 < length2 ) {
00115 short_line = line1;
00116 long_line = line2;
00117 } else {
00118 short_line = line2;
00119 long_line = line1;
00120 }
00121
00122
00123 short_type = Vect_read_line ( Map, Points, SCats, abs(short_line) );
00124
00125 if ( short_line > 0 ) {
00126 x = Points->x[1];
00127 y = Points->y[1];
00128 z = Points->z[1];
00129 Vect_line_delete_point ( Points, 0 );
00130 } else {
00131 x = Points->x[Points->n_points-2];
00132 y = Points->y[Points->n_points-2];
00133 z = Points->z[Points->n_points-2];
00134 Vect_line_delete_point ( Points, Points->n_points-1 );
00135 }
00136
00137 if ( Points->n_points > 1 ) {
00138 new_short_line = Vect_rewrite_line ( Map, abs(short_line), short_type, Points, SCats );
00139 } else {
00140 Vect_delete_line ( Map, abs(short_line) );
00141 }
00142
00143
00144
00145 if ( abs(line1) == abs(line2) ) {
00146 if ( long_line > 0 )
00147 long_line = new_short_line;
00148 else
00149 long_line = -new_short_line;
00150 }
00151
00152
00153
00154 long_type = Vect_read_line ( Map, NULL, LCats, abs(long_line) );
00155
00156 Vect_reset_cats ( OCats );
00157 for ( j = 0; j < SCats->n_cats; j++ ) {
00158 Vect_cat_set ( OCats, SCats->field[j], SCats->cat[j] );
00159 }
00160 for ( j = 0; j < LCats->n_cats; j++ ) {
00161 Vect_cat_set ( OCats, LCats->field[j], LCats->cat[j] );
00162 }
00163
00164 if ( long_type == GV_BOUNDARY || short_type == GV_BOUNDARY ) {
00165 type = GV_BOUNDARY;
00166 } else {
00167 type = GV_LINE;
00168 }
00169
00170 Vect_get_node_coor ( Map, node, &nx, &ny, &nz );
00171 Vect_reset_line ( Points );
00172 Vect_append_point ( Points, nx, ny, nz );
00173 Vect_append_point ( Points, x, y, z );
00174 Vect_write_line ( Map, type, Points, OCats );
00175
00176 if ( Err ) {
00177 Vect_write_line ( Err, type, Points, OCats );
00178 }
00179
00180
00181 long_type = Vect_read_line ( Map, Points, LCats, abs(long_line) );
00182 if ( long_line > 0 ) {
00183 Points->x[0] = x;
00184 Points->y[0] = y;
00185 Points->z[0] = z;
00186 } else {
00187 Points->x[Points->n_points-1] = x;
00188 Points->y[Points->n_points-1] = y;
00189 Points->z[Points->n_points-1] = z;
00190 }
00191 Vect_line_prune ( Points );
00192 if ( Points->n_points > 1 ) {
00193 Vect_rewrite_line ( Map, abs(long_line), long_type, Points, LCats );
00194 } else {
00195 Vect_delete_line ( Map, abs(long_line) );
00196 }
00197
00198 nmodif += 3;
00199 clean = 0;
00200
00201 break;
00202 }
00203
00204 line1 = line2;
00205 angle1 = angle2;
00206 }
00207
00208 if ( msgout ) {
00209 fprintf (msgout, "\rModifications: %5d", nmodif );
00210 fflush ( msgout );
00211 }
00212
00213 if ( clean )
00214 break;
00215
00216 }
00217
00218 }
00219 if ( msgout ) fprintf (stderr, "\n" );
00220
00221 return (nmodif);
00222 }
00223