plus_line.c

Go to the documentation of this file.
00001 /*
00002 * $Id: plus_line.c,v 1.12 2006/02/09 03:08:58 glynn Exp $
00003 *
00004 ****************************************************************************
00005 *
00006 * MODULE:       Vector library 
00007 *               
00008 * AUTHOR(S):    Original author CERL, probably Dave Gerdes.
00009 *               Update to GRASS 5.7 Radim Blazek.
00010 *
00011 * PURPOSE:      Lower level functions for reading/writing/manipulating vectors.
00012 *
00013 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00014 *
00015 *               This program is free software under the GNU General Public
00016 *               License (>=v2). Read the file COPYING that comes with GRASS
00017 *               for details.
00018 *
00019 *****************************************************************************/
00020 #include <stdlib.h>
00021 #include <grass/Vect.h>
00022 
00023 /* dig_add_line ()
00024 ** Add new line to plus structure.
00025 ** 
00026 **
00027 ** Returns -1 on error      
00028 **          number of line
00029 */
00030 int 
00031 dig_add_line (struct Plus_head *plus, int type, struct line_pnts *Points, long offset){
00032     int  lineid, node, lp;
00033     P_LINE *line;
00034     BOUND_BOX box;
00035    
00036     /* First look if we have space in array of pointers to lines
00037     *  and reallocate if necessary */
00038     if ( plus->n_lines >= plus->alloc_lines ) { /* array is full */
00039         if ( dig_alloc_lines(plus,1000) == -1 )
00040             return -1;
00041     }
00042     
00043     /* allocate line structure */
00044     lineid = plus->n_lines + 1;
00045     plus->Line[lineid] = dig_alloc_line();
00046     line = plus->Line[lineid];
00047     
00048     /* Add nodes */
00049     G_debug ( 3, "Register node: type = %d,  %f,%f", type, Points->x[0], Points->y[0]);
00050 
00051     node = dig_find_node ( plus, Points->x[0], Points->y[0], Points->z[0]);
00052     G_debug ( 3, "node = %d", node);
00053     if ( node == 0 ) {
00054         node = dig_add_node ( plus, Points->x[0], Points->y[0], Points->z[0] );
00055         G_debug ( 3, "Add new node: %d", node);
00056     } else {
00057         G_debug ( 3, "Old node found: %d", node);
00058     }   
00059     line->N1 = node;
00060     dig_node_add_line (plus, node, lineid, Points, type );
00061     if ( plus->do_uplist ) dig_node_add_updated ( plus, node );
00062      
00063     if ( type & GV_LINES ) {
00064         lp = Points->n_points - 1;
00065         G_debug ( 3, "Register node %f,%f", Points->x[lp], Points->y[lp]);
00066         node = dig_find_node ( plus, Points->x[lp], Points->y[lp], Points->z[lp]);
00067         G_debug ( 3, "node = %d", node);
00068         if ( node == 0 ) {
00069             node = dig_add_node ( plus, Points->x[lp], Points->y[lp], Points->z[lp]);
00070             G_debug ( 3, "Add new node: %d", node);
00071         } else {
00072             G_debug ( 3, "Old node found: %d", node);
00073         }
00074         line->N2 = node;
00075         dig_node_add_line (plus, node, -lineid, Points, type );
00076         if ( plus->do_uplist ) dig_node_add_updated ( plus, node );
00077     } else {
00078         line->N2 = 0;
00079     }
00080 
00081     line->type = type;
00082     line->offset = offset;
00083     line->left = 0;
00084     line->right = 0;
00085     line->N = 0;
00086     line->S = 0;
00087     line->E = 0;
00088     line->W = 0;
00089     plus->n_lines++;
00090 
00091     switch ( type ) {
00092         case GV_POINT:
00093             plus->n_plines++;
00094             break;
00095         case GV_LINE:
00096             plus->n_llines++;
00097             break;
00098         case GV_BOUNDARY:
00099             plus->n_blines++;
00100             break;
00101         case GV_CENTROID:
00102             plus->n_clines++;
00103             break;
00104         case GV_FACE:
00105             plus->n_flines++;
00106             break;
00107         case GV_KERNEL:
00108             plus->n_klines++;
00109             break;
00110     }
00111          
00112     dig_line_box ( Points, &box );
00113     dig_line_set_box (plus, lineid, &box);
00114     dig_spidx_add_line ( plus, lineid, &box );    
00115     if ( plus->do_uplist ) dig_line_add_updated ( plus, lineid );
00116     
00117     return ( lineid );
00118 }
00119 
00120 /* dig_del_line ()
00121 ** Delete line from topology. Doesn't update area/isle references
00122 ** (dig_del_area/isle() must be run before the line is deleted if the
00123 **  line is part of such structure).
00124 ** Updateis info about line in nodes. If this line is last in node then node is deleted.
00125 **
00126 ** Returns -1 on error      
00127 **          0 OK
00128 */
00129 int 
00130 dig_del_line (struct Plus_head *plus, int line)
00131 {
00132     int    i, mv;
00133     P_LINE *Line;
00134     P_NODE *Node;
00135   
00136     /* TODO: free structures */
00137     G_debug (3, "dig_del_line() line =  %d", line);
00138     
00139     Line = plus->Line[line]; 
00140     dig_spidx_del_line ( plus, line );
00141     
00142     /* Delete from nodes (and nodes) */
00143     Node = plus->Node[Line->N1];
00144     mv = 0;
00145     for ( i = 0; i < Node->n_lines; i++ ) {
00146         if ( mv ) {
00147             Node->lines[i-1] = Node->lines[i]; 
00148             Node->angles[i-1] = Node->angles[i]; 
00149         } else {
00150             if ( abs(Node->lines[i]) == line ) mv = 1;
00151         }
00152     }
00153     Node->n_lines--;
00154     if ( Node->n_lines == 0 ) {
00155         G_debug (3, "    node %d has 0 lines -> delete", Line->N1);
00156         dig_spidx_del_node ( plus, Line->N1 );
00157         plus->Node[Line->N1] = NULL;    
00158     } else {
00159         if ( plus->do_uplist ) dig_node_add_updated ( plus, Line->N1 );
00160     }
00161     
00162     if ( Line->type & GV_LINES ) {
00163         Node = plus->Node[Line->N2];
00164         mv = 0;
00165         for ( i = 0; i < Node->n_lines; i++ ) {
00166             if ( mv ) {
00167                 Node->lines[i-1] = Node->lines[i]; 
00168                 Node->angles[i-1] = Node->angles[i]; 
00169             } else {
00170                 if ( abs(Node->lines[i]) == line ) mv = 1;
00171             }
00172         }
00173         Node->n_lines--;
00174         if ( Node->n_lines == 0 ) {
00175             G_debug (3, "    node %d has 0 lines -> delete", Line->N2);
00176             dig_spidx_del_node ( plus, Line->N2 );
00177             plus->Node[Line->N2] = NULL;        
00178         } else {
00179             if ( plus->do_uplist ) dig_node_add_updated ( plus, Line->N2 );
00180         }
00181     }
00182      
00183     /* Delete line */ 
00184     plus->Line[line] = NULL; 
00185     
00186     return 0;
00187 }
00188 
00189 /* dig_line_get_area ()
00190 ** Get area number on line side
00191 ** 
00192 ** Returns area number 
00193 **         0 no area
00194 **         -1 error
00195 */
00196 plus_t
00197 dig_line_get_area (struct Plus_head *plus, plus_t line, int side) {
00198     P_LINE *Line;
00199     
00200     Line = plus->Line[line];
00201     if ( side == GV_LEFT  ) { 
00202         G_debug ( 3, "dig_line_get_area(): line = %d, side = %d (left), area = %d", 
00203                       line, side, Line->left ); 
00204         return (Line->left );
00205     }
00206     if ( side == GV_RIGHT ) {
00207         G_debug ( 3, "dig_line_get_area(): line = %d, side = %d (right), area = %d", 
00208                       line, side, Line->right );
00209        
00210         return (Line->right); 
00211     }
00212 
00213     return (-1);
00214 }
00215 
00216 /* dig_line_set_area ()
00217 ** Set area number on line side
00218 ** 
00219 */
00220 int
00221 dig_line_set_area (struct Plus_head *plus, plus_t line, int side, plus_t area ) {
00222     P_LINE *Line;
00223     
00224     Line = plus->Line[line];
00225     if ( side == GV_LEFT  ) { Line->left = area; }
00226     else if ( side == GV_RIGHT ) { Line->right = area; }
00227 
00228     return (1);
00229 }
00230 
00231 /* dig_line_set_box ()
00232 ** Set line bound box
00233 ** 
00234 */
00235 int
00236 dig_line_set_box (struct Plus_head *plus, plus_t line, BOUND_BOX *Box ) {
00237     P_LINE *Line;
00238     
00239     Line = plus->Line[line];
00240     
00241     Line->N = Box->N;
00242     Line->S = Box->S;
00243     Line->E = Box->E;
00244     Line->W = Box->W;
00245     Line->T = Box->T;
00246     Line->B = Box->B;
00247 
00248     return (1);
00249 }
00250 
00251 /* dig_line_get_box ()
00252 ** Get line bound box saved in topo
00253 ** 
00254 */
00255 int
00256 dig_line_get_box (struct Plus_head *plus, plus_t line, BOUND_BOX *Box ) {
00257     P_LINE *Line;
00258     
00259     Line = plus->Line[line];
00260     
00261     Box->N = Line->N;
00262     Box->S = Line->S;
00263     Box->E = Line->E;
00264     Box->W = Line->W;
00265     Box->T = Line->T;
00266     Box->B = Line->B;
00267 
00268     return (1);
00269 }
00270 

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