dangles.c

Go to the documentation of this file.
00001 /**************************************************************
00002  *
00003  * MODULE:       vector library
00004  *  
00005  * AUTHOR(S):    Radim Blazek
00006  *               
00007  * PURPOSE:      Clean lines
00008  *               
00009  * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00010  *
00011  *               This program is free software under the 
00012  *               GNU General Public License (>=v2). 
00013  *               Read the file COPYING that comes with GRASS
00014  *               for details.
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   Remove dangles of given type shorter than maxlength from vector map. 
00073   Line is considered to be a dangle if on at least one end node is no other line of given type(s).
00074   If a dangle is formed by more lines, such string of lines is taken as one dangle and 
00075   either deleted are all parts or nothing.
00076   Optionaly, if chtype is set to 1, only GV_BOUNDARY are checked for dangles, and if dangle is found
00077   lines are not deleted but rewritten with type GVLINE.
00078   Optionaly deleted dangles are written to error map. 
00079   Input map must be opened on level 2 for update at least on GV_BUILD_BASE.
00080 
00081   Parameters:
00082   Map input map where have to be deleted
00083   type type of dangles 
00084   chtype change boundaries to lines
00085   maxlength maxlength of dangles or -1 for all dangles
00086   Err vector map where deleted dangles are written or NULL
00087   msgout file pointer where messages will be written or NULL
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; /* number of removed dangles */
00099     int    lines_removed = 0; /* number of lines removed */
00100     struct ilist *List; /* List of lines in chain */
00101     char   *lmsg;
00102 
00103     type &= GV_LINES; /* to work only with lines and boundaries */
00104 
00105     if ( chtype ) {
00106         type = GV_BOUNDARY; /* process boundaries only */
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; /* number of lines of given type */
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                 /* Look at the next end of the line if just one another line of the type is connected */
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; /* number of lines of given type (except current next_line) */
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             /* Length of the chain */
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 ) { /* delete the chain */
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                     /* Write to Err deleted dangle */
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 

Generated on Sun Apr 6 17:32:44 2008 for GRASS by  doxygen 1.5.5