build.c

Go to the documentation of this file.
00001 /*
00002 ****************************************************************************
00003 *
00004 * MODULE:       Vector library 
00005 *               
00006 * AUTHOR(S):    Original author CERL, probably Dave Gerdes or Mike Higgins.
00007 *               Update to GRASS 5.7 Radim Blazek and David D. Gray.
00008 *
00009 * PURPOSE:      Higher level functions for reading/writing/manipulating vectors.
00010 *
00011 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00012 *
00013 *               This program is free software under the GNU General Public
00014 *               License (>=v2). Read the file COPYING that comes with GRASS
00015 *               for details.
00016 *
00017 *****************************************************************************/
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <stdarg.h>
00021 #include <grass/glocale.h>
00022 #include <grass/gis.h>
00023 #include <grass/Vect.h>
00024 
00025 
00026 #ifndef HAVE_OGR
00027 static int format () { G_fatal_error ("Requested format is not compiled in this version"); return 0; }
00028 #endif
00029 
00030 static int (*Build_array[]) () =
00031 {
00032       Vect_build_nat
00033 #ifdef HAVE_OGR
00034     , Vect_build_ogr
00035 #else
00036     , format
00037 #endif
00038 };
00039 
00040 FILE *Msgout = NULL;
00041 
00042 
00043 int prnmsg ( char *msg, ...) {
00044     char buffer[1000]; 
00045     va_list ap; 
00046     
00047     if ( Msgout != NULL ) {
00048         va_start(ap,msg);
00049         vsprintf(buffer,msg,ap);
00050         va_end(ap);
00051         fprintf (Msgout, "%s", buffer);
00052         fflush (Msgout);
00053     }
00054         
00055     return 1;   
00056 }
00057 
00064 int
00065 Vect_build ( struct Map_info *Map, FILE *msgout ) 
00066 {
00067     return Vect_build_partial ( Map, GV_BUILD_ALL, msgout );
00068 }
00069 
00070 
00077 int
00078 Vect_get_built ( struct Map_info *Map ) 
00079 {
00080     return ( Map->plus.built );
00081 }
00082 
00117 int
00118 Vect_build_partial ( struct Map_info *Map, int build, FILE *msgout ) 
00119 {
00120     struct Plus_head *plus ;
00121     int    ret;
00122     
00123     G_debug (3, "Vect_build(): build = %d", build); 
00124     Msgout = msgout;
00125 
00126     /* If topology is already build (map on level2), set level to 1 so that lines will
00127     *  be read by V1_read_ (all lines) */
00128     Map->level = 1; /* may be not needed, because  V1_read is used directly by Vect_build_ */
00129     Map->support_updated = 1;
00130 
00131     Map->plus.Spidx_built = 1;
00132     
00133     plus = &(Map->plus);
00134     prnmsg ( _("Building topology ...\n") );
00135     plus->with_z = Map->head.with_z;
00136     plus->spidx_with_z = Map->head.with_z;
00137 
00138     if ( build == GV_BUILD_ALL ) {
00139         dig_cidx_free(plus); /* free old (if any) category index) */
00140         dig_cidx_init(plus);
00141     }
00142     
00143     ret = ( (*Build_array[Map->format]) (Map, build, msgout) );
00144 
00145     if ( ret == 0 ) { return 0; } 
00146 
00147     prnmsg (_("Topology was built.\n"));
00148     
00149     Map->level = LEVEL_2;
00150     plus->mode = GV_MODE_WRITE;
00151     
00152     if ( build == GV_BUILD_ALL ) {
00153         plus->cidx_up_to_date = 1; /* category index was build */
00154         dig_cidx_sort ( plus );
00155     }
00156     
00157     /* prnmsg ("Topology was built.\n") ; */
00158    
00159     prnmsg (_("Number of nodes     :   %d\n"), plus->n_nodes);
00160     prnmsg (_("Number of primitives:   %d\n"), plus->n_lines);
00161     prnmsg (_("Number of points    :   %d\n"), plus->n_plines);
00162     prnmsg (_("Number of lines     :   %d\n"), plus->n_llines);
00163     prnmsg (_("Number of boundaries:   %d\n"), plus->n_blines);
00164     prnmsg (_("Number of centroids :   %d\n"), plus->n_clines);
00165 
00166     if ( plus->n_flines > 0 )
00167         prnmsg (_("Number of faces     :   %d\n"), plus->n_flines);
00168 
00169     if ( plus->n_klines > 0 )
00170         prnmsg (_("Number of kernels   :   %d\n"), plus->n_klines);
00171 
00172     if ( plus->built >= GV_BUILD_AREAS ) {
00173         int line, nlines, area, nareas, err_boundaries, err_centr_out, err_centr_dupl, err_nocentr;
00174         P_LINE *Line;
00175         struct Plus_head *Plus;
00176         
00177         /* Count errors (it does not take much time comparing to build process) */
00178         Plus = &(Map->plus);
00179         nlines = Vect_get_num_lines (Map);
00180         err_boundaries = err_centr_out = err_centr_dupl = 0;
00181         for ( line = 1; line <= nlines; line++ ){
00182             Line = Plus->Line[line];
00183             if ( !Line ) continue;
00184             if ( Line->type == GV_BOUNDARY && ( Line->left == 0 || Line->right == 0 ) ) {
00185                 G_debug ( 3, "line = %d left = %d right = %d", line,  Line->left, Line->right);
00186                 err_boundaries++; 
00187             }
00188             if ( Line->type == GV_CENTROID ) {
00189                 if ( Line->left == 0 ) 
00190                     err_centr_out++;
00191                 else if ( Line->left < 0 )
00192                     err_centr_dupl++;
00193             }
00194         }
00195 
00196         err_nocentr = 0;
00197         nareas = Vect_get_num_areas (Map);
00198         for ( area = 1; area <= nareas; area++ ){
00199             if ( !Vect_area_alive(Map, area ) ) continue;
00200             line = Vect_get_area_centroid ( Map, area );
00201             if ( line == 0 ) 
00202                 err_nocentr++;
00203         }
00204             
00205         prnmsg (_("Number of areas     :   %d\n"), plus->n_areas);
00206         prnmsg (_("Number of isles     :   %d\n"), plus->n_isles);
00207 
00208         if ( err_boundaries )
00209             prnmsg (_("Number of incorrect boundaries   :   %d\n"), err_boundaries);
00210 
00211         if ( err_centr_out )
00212             prnmsg (_("Number of centroids outside area :   %d\n"), err_centr_out);
00213         
00214         if ( err_centr_dupl )
00215             prnmsg (_("Number of duplicate centroids    :   %d\n"), err_centr_dupl);
00216 
00217         if ( err_nocentr )
00218             prnmsg (_("Number of areas without centroid :   %d\n"), err_nocentr);
00219             
00220     } else {
00221         prnmsg (_("Number of areas     :   -\n"));
00222         prnmsg (_("Number of isles     :   -\n"));
00223     }
00224     return 1;
00225 }
00226 
00233 int
00234 Vect_save_topo ( struct Map_info *Map )
00235 {
00236     struct Plus_head *plus ;
00237     char   fname[1024], buf[1024];
00238     GVFILE  fp;
00239     
00240     G_debug (1, "Vect_save_topo()"); 
00241 
00242     plus = &(Map->plus);
00243     
00244     /*  write out all the accumulated info to the plus file  */
00245     sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00246     G__file_name (fname, buf, GV_TOPO_ELEMENT, Map->mapset);
00247     G_debug (1, "Open topo: %s", fname);
00248     dig_file_init ( &fp );
00249     fp.file = fopen( fname, "w");
00250     if ( fp.file ==  NULL) {
00251         G_warning(_("Can't open topo file for write: %s\n"), fname);
00252             return 0;
00253     }
00254 
00255     /* set portable info */
00256     dig_init_portable ( &(plus->port), dig__byte_order_out ());
00257     
00258     if ( 0 > dig_write_plus_file (&fp, plus) ) {
00259         G_warning (_("Error writing out topo file.\n"));
00260         return 0;
00261     }
00262     
00263     fclose( fp.file );
00264 
00265     return 1;
00266 }
00267 
00274 int
00275 Vect_topo_dump ( struct Map_info *Map, FILE *out )
00276 {
00277     int i, j, line, isle;
00278     P_NODE *Node;
00279     P_LINE *Line;
00280     P_AREA *Area;
00281     P_ISLE *Isle;
00282     BOUND_BOX box;
00283     struct Plus_head *plus;
00284 
00285     plus = &(Map->plus);
00286 
00287     fprintf (out, "---------- TOPOLOGY DUMP ----------\n" ); 
00288     
00289     /* box */
00290     Vect_box_copy ( &box, &(plus->box) );
00291     fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", box.N, box.S, 
00292                                  box.E, box.W, box.T, box.B);
00293     
00294     /* nodes */
00295     fprintf (out, "Nodes (%d nodes, alive + dead ):\n", plus->n_nodes ); 
00296     for (i = 1; i <= plus->n_nodes; i++) {
00297         if ( plus->Node[i] == NULL ) { continue; }
00298         Node = plus->Node[i];
00299         fprintf (out, "node = %d, n_lines = %d, xy = %f, %f\n", i, Node->n_lines,
00300                                     Node->x, Node->y ); 
00301         for (j = 0; j < Node->n_lines; j++) {
00302             line = Node->lines[j];
00303             Line = plus->Line[abs(line)];
00304             fprintf (out, "  line = %3d, type = %d, angle = %f\n", line, Line->type, Node->angles[j] ); 
00305         }
00306     }
00307     
00308     /* lines */
00309     fprintf (out, "Lines (%d lines, alive + dead ):\n", plus->n_lines ); 
00310     for (i = 1; i <= plus->n_lines; i++) {
00311         if ( plus->Line[i] == NULL ) { continue; }
00312         Line = plus->Line[i];
00313         fprintf (out, "line = %d, type = %d, offset = %ld n1 = %d, n2 = %d, "
00314                       "left/area = %d, right = %d\n",
00315                        i, Line->type, Line->offset, Line->N1, Line->N2,
00316                        Line->left, Line->right); 
00317         fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Line->N, Line->S,
00318                                Line->E, Line->W, Line->T, Line->B);     
00319     }
00320     
00321     /* areas */
00322     fprintf (out, "Areas (%d areas, alive + dead ):\n", plus->n_areas ); 
00323     for (i = 1; i <= plus->n_areas; i++) {
00324         if ( plus->Area[i] == NULL ) { continue; }
00325         Area = plus->Area[i];
00326         
00327         fprintf (out, "area = %d, n_lines = %d, n_isles = %d centroid = %d\n", 
00328                  i, Area->n_lines, Area->n_isles, Area->centroid ); 
00329         
00330         fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Area->N, Area->S,
00331                                Area->E, Area->W, Area->T, Area->B);     
00332                 
00333         for (j = 0; j < Area->n_lines; j++) {
00334             line = Area->lines[j];
00335             Line = plus->Line[abs(line)];
00336             fprintf (out, "  line = %3d\n", line ); 
00337         }
00338         for (j = 0; j < Area->n_isles; j++) {
00339             isle = Area->isles[j];
00340             fprintf (out, "  isle = %3d\n", isle ); 
00341         }
00342     }
00343     
00344     /* isles */
00345     fprintf (out, "Islands (%d islands, alive + dead ):\n", plus->n_isles ); 
00346     for (i = 1; i <= plus->n_isles; i++) {
00347         if ( plus->Isle[i] == NULL ) { continue; }
00348         Isle = plus->Isle[i];
00349         
00350         fprintf (out, "isle = %d, n_lines = %d area = %d\n", i, Isle->n_lines, 
00351                            Isle->area ); 
00352         
00353         fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Isle->N, Isle->S,
00354                                Isle->E, Isle->W, Isle->T, Isle->B);     
00355         
00356         for (j = 0; j < Isle->n_lines; j++) {
00357             line = Isle->lines[j];
00358             Line = plus->Line[abs(line)];
00359             fprintf (out, "  line = %3d\n", line ); 
00360         }
00361     }
00362 
00363     return 1;
00364 }
00365 
00372 int
00373 Vect_save_spatial_index ( struct Map_info *Map )
00374 {
00375     struct Plus_head *plus ;
00376     char   fname[1024], buf[1024];
00377     GVFILE   fp;
00378     
00379     G_debug (1, "Vect_save_spatial_index()"); 
00380 
00381     plus = &(Map->plus);
00382     
00383     /*  write out rtrees to the sidx file  */
00384     sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00385     G__file_name (fname, buf, GV_SIDX_ELEMENT, Map->mapset);
00386     G_debug (1, "Open sidx: %s", fname);
00387     dig_file_init ( &fp );
00388     fp.file = fopen( fname, "w");
00389     if ( fp.file ==  NULL) {
00390         G_warning(_("Can't open spatial index file for write: %s\n"), fname);
00391             return 0;
00392     }
00393 
00394     /* set portable info */
00395     dig_init_portable ( &(plus->spidx_port), dig__byte_order_out ());
00396     
00397     if ( 0 > dig_write_spidx (&fp, plus) ) {
00398         G_warning (_("Error writing out spatial index file.\n"));
00399         return 0;
00400     }
00401     
00402     fclose( fp.file );
00403 
00404     return 1;
00405 }
00406 
00413 int
00414 Vect_spatial_index_dump ( struct Map_info *Map, FILE *out ) 
00415 {
00416     if ( !(Map->plus.Spidx_built) ) {
00417         Vect_build_sidx_from_topo ( Map, NULL );
00418     }
00419 
00420     fprintf (out, "---------- SPATIAL INDEX DUMP ----------\n" ); 
00421     
00422     dig_dump_spidx ( out, &(Map->plus) ); 
00423 
00424     return 1;
00425 }
00426 

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