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 "glocale.h"
00022 #include "gis.h"
00023 #include "Vect.h"
00024 
00025 static int format () { G_fatal_error ("Requested format is not compiled in this version"); return 0; }
00026 
00027 static int (*Build_array[]) () =
00028 {
00029       Vect_build_nat
00030 #ifdef HAVE_OGR
00031     , Vect_build_ogr
00032 #else
00033     , format
00034 #endif
00035 };
00036 
00037 FILE *Msgout = NULL;
00038 
00039 int prnmsg ( char *msg, ...) {
00040     char buffer[1000]; 
00041     va_list ap; 
00042     
00043     if ( Msgout != NULL ) {
00044         va_start(ap,msg);
00045         vsprintf(buffer,msg,ap);
00046         va_end(ap);
00047         fprintf (Msgout, "%s", buffer);
00048         fflush (Msgout);
00049     }
00050         
00051     return 1;   
00052 }
00053 
00060 int
00061 Vect_build ( struct Map_info *Map, FILE *msgout ) 
00062 {
00063     return Vect_build_partial ( Map, GV_BUILD_ALL, msgout );
00064 }
00065 
00066 
00073 int
00074 Vect_get_built ( struct Map_info *Map ) 
00075 {
00076     return ( Map->plus.built );
00077 }
00078 
00112 int
00113 Vect_build_partial ( struct Map_info *Map, int build, FILE *msgout ) 
00114 {
00115     struct Plus_head *plus ;
00116     int    ret;
00117     
00118     G_debug (3, "Vect_build(): build = %d", build); 
00119     Msgout = msgout;
00120 
00121     /* If topology is already build (map on level2), set level to 1 so that lines will
00122     *  be read by V1_read_ (all lines) */
00123     Map->level = 1; /* may be not needed, because  V1_read is used directly by Vect_build_ */
00124     Map->support_updated = 1;
00125 
00126     Map->plus.Spidx_built = 1;
00127     
00128     plus = &(Map->plus);
00129     prnmsg ( _("Building topology ...\n") );
00130     plus->with_z = Map->head.with_z;
00131     plus->spidx_with_z = Map->head.with_z;
00132 
00133     if ( build == GV_BUILD_ALL ) {
00134         dig_cidx_free(plus); /* free old (if any) category index) */
00135         dig_cidx_init(plus);
00136     }
00137     
00138     ret = ( (*Build_array[Map->format]) (Map, build, msgout) );
00139 
00140     if ( ret == 0 ) { return 0; } 
00141 
00142     prnmsg (_("Topology was built.\n"));
00143     
00144     Map->level = LEVEL_2;
00145     plus->mode = GV_MODE_WRITE;
00146     
00147     if ( build == GV_BUILD_ALL ) {
00148         plus->cidx_up_to_date = 1; /* category index was build */
00149         dig_cidx_sort ( plus );
00150     }
00151     
00152     /* prnmsg ("Topology was built.\n") ; */
00153    
00154     prnmsg (_("Number of nodes     :   %d\n"), plus->n_nodes);
00155     prnmsg (_("Number of primitives:   %d\n"), plus->n_lines);
00156     prnmsg (_("Number of points    :   %d\n"), plus->n_plines);
00157     prnmsg (_("Number of lines     :   %d\n"), plus->n_llines);
00158     prnmsg (_("Number of boundaries:   %d\n"), plus->n_blines);
00159     prnmsg (_("Number of centroids :   %d\n"), plus->n_clines);
00160 
00161     if ( plus->n_flines > 0 )
00162         prnmsg (_("Number of faces     :   %d\n"), plus->n_flines);
00163 
00164     if ( plus->n_klines > 0 )
00165         prnmsg (_("Number of kernels   :   %d\n"), plus->n_klines);
00166 
00167     if ( plus->built >= GV_BUILD_AREAS ) {
00168         int line, nlines, area, nareas, err_boundaries, err_centr_out, err_centr_dupl, err_nocentr;
00169         P_LINE *Line;
00170         struct Plus_head *Plus;
00171         
00172         /* Count errors (it does not take much time comparing to build process) */
00173         Plus = &(Map->plus);
00174         nlines = Vect_get_num_lines (Map);
00175         err_boundaries = err_centr_out = err_centr_dupl = 0;
00176         for ( line = 1; line <= nlines; line++ ){
00177             Line = Plus->Line[line];
00178             if ( !Line ) continue;
00179             if ( Line->type == GV_BOUNDARY && ( Line->left == 0 || Line->right == 0 ) ) {
00180                 G_debug ( 3, "line = %d left = %d right = %d", line,  Line->left, Line->right);
00181                 err_boundaries++; 
00182             }
00183             if ( Line->type == GV_CENTROID ) {
00184                 if ( Line->left == 0 ) 
00185                     err_centr_out++;
00186                 else if ( Line->left < 0 )
00187                     err_centr_dupl++;
00188             }
00189         }
00190 
00191         err_nocentr = 0;
00192         nareas = Vect_get_num_areas (Map);
00193         for ( area = 1; area <= nareas; area++ ){
00194             if ( !Vect_area_alive(Map, area ) ) continue;
00195             line = Vect_get_area_centroid ( Map, area );
00196             if ( line == 0 ) 
00197                 err_nocentr++;
00198         }
00199             
00200         prnmsg (_("Number of areas     :   %d\n"), plus->n_areas);
00201         prnmsg (_("Number of isles     :   %d\n"), plus->n_isles);
00202 
00203         if ( err_boundaries )
00204             prnmsg (_("Number of incorrect boundaries   :   %d\n"), err_boundaries);
00205 
00206         if ( err_centr_out )
00207             prnmsg (_("Number of centroids outside area :   %d\n"), err_centr_out);
00208         
00209         if ( err_centr_dupl )
00210             prnmsg (_("Number of duplicate centroids    :   %d\n"), err_centr_dupl);
00211 
00212         if ( err_nocentr )
00213             prnmsg (_("Number of areas without centroid :   %d\n"), err_nocentr);
00214             
00215     } else {
00216         prnmsg (_("Number of areas     :   -\n"));
00217         prnmsg (_("Number of isles     :   -\n"));
00218     }
00219     return 1;
00220 }
00221 
00228 int
00229 Vect_save_topo ( struct Map_info *Map )
00230 {
00231     struct Plus_head *plus ;
00232     char   fname[1024], buf[1024];
00233     GVFILE  fp;
00234     
00235     G_debug (1, "Vect_save_topo()"); 
00236 
00237     plus = &(Map->plus);
00238     
00239     /*  write out all the accumulated info to the plus file  */
00240     sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00241     G__file_name (fname, buf, GV_TOPO_ELEMENT, Map->mapset);
00242     G_debug (1, "Open topo: %s", fname);
00243     dig_file_init ( &fp );
00244     fp.file = fopen( fname, "w");
00245     if ( fp.file ==  NULL) {
00246         G_warning(_("Can't open topo file for write: %s\n"), fname);
00247             return 0;
00248     }
00249 
00250     /* set portable info */
00251     dig_init_portable ( &(plus->port), dig__byte_order_out ());
00252     
00253     if ( 0 > dig_write_plus_file (&fp, plus) ) {
00254         G_warning (_("Error writing out topo file.\n"));
00255         return 0;
00256     }
00257     
00258     fclose( fp.file );
00259 
00260     return 1;
00261 }
00262 
00269 int
00270 Vect_topo_dump ( struct Map_info *Map, FILE *out )
00271 {
00272     int i, j, line, isle;
00273     P_NODE *Node;
00274     P_LINE *Line;
00275     P_AREA *Area;
00276     P_ISLE *Isle;
00277     BOUND_BOX box;
00278     struct Plus_head *plus;
00279 
00280     plus = &(Map->plus);
00281 
00282     fprintf (out, "---------- TOPOLOGY DUMP ----------\n" ); 
00283     
00284     /* box */
00285     Vect_box_copy ( &box, &(plus->box) );
00286     fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", box.N, box.S, 
00287                                  box.E, box.W, box.T, box.B);
00288     
00289     /* nodes */
00290     fprintf (out, "Nodes (%d nodes, alive + dead ):\n", plus->n_nodes ); 
00291     for (i = 1; i <= plus->n_nodes; i++) {
00292         if ( plus->Node[i] == NULL ) { continue; }
00293         Node = plus->Node[i];
00294         fprintf (out, "node = %d, n_lines = %d, xy = %f, %f\n", i, Node->n_lines,
00295                                     Node->x, Node->y ); 
00296         for (j = 0; j < Node->n_lines; j++) {
00297             line = Node->lines[j];
00298             Line = plus->Line[abs(line)];
00299             fprintf (out, "  line = %3d, type = %d, angle = %f\n", line, Line->type, Node->angles[j] ); 
00300         }
00301     }
00302     
00303     /* lines */
00304     fprintf (out, "Lines (%d lines, alive + dead ):\n", plus->n_lines ); 
00305     for (i = 1; i <= plus->n_lines; i++) {
00306         if ( plus->Line[i] == NULL ) { continue; }
00307         Line = plus->Line[i];
00308         fprintf (out, "line = %d, type = %d, offset = %ld n1 = %d, n2 = %d, "
00309                       "left/area = %d, right = %d\n",
00310                        i, Line->type, Line->offset, Line->N1, Line->N2,
00311                        Line->left, Line->right); 
00312         fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Line->N, Line->S,
00313                                Line->E, Line->W, Line->T, Line->B);     
00314     }
00315     
00316     /* areas */
00317     fprintf (out, "Areas (%d areas, alive + dead ):\n", plus->n_areas ); 
00318     for (i = 1; i <= plus->n_areas; i++) {
00319         if ( plus->Area[i] == NULL ) { continue; }
00320         Area = plus->Area[i];
00321         
00322         fprintf (out, "area = %d, n_lines = %d, n_isles = %d centroid = %d\n", 
00323                  i, Area->n_lines, Area->n_isles, Area->centroid ); 
00324         
00325         fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Area->N, Area->S,
00326                                Area->E, Area->W, Area->T, Area->B);     
00327                 
00328         for (j = 0; j < Area->n_lines; j++) {
00329             line = Area->lines[j];
00330             Line = plus->Line[abs(line)];
00331             fprintf (out, "  line = %3d\n", line ); 
00332         }
00333         for (j = 0; j < Area->n_isles; j++) {
00334             isle = Area->isles[j];
00335             fprintf (out, "  isle = %3d\n", isle ); 
00336         }
00337     }
00338     
00339     /* isles */
00340     fprintf (out, "Islands (%d islands, alive + dead ):\n", plus->n_isles ); 
00341     for (i = 1; i <= plus->n_isles; i++) {
00342         if ( plus->Isle[i] == NULL ) { continue; }
00343         Isle = plus->Isle[i];
00344         
00345         fprintf (out, "isle = %d, n_lines = %d area = %d\n", i, Isle->n_lines, 
00346                            Isle->area ); 
00347         
00348         fprintf (out, "N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", Isle->N, Isle->S,
00349                                Isle->E, Isle->W, Isle->T, Isle->B);     
00350         
00351         for (j = 0; j < Isle->n_lines; j++) {
00352             line = Isle->lines[j];
00353             Line = plus->Line[abs(line)];
00354             fprintf (out, "  line = %3d\n", line ); 
00355         }
00356     }
00357 
00358     return 1;
00359 }
00360 
00367 int
00368 Vect_save_spatial_index ( struct Map_info *Map )
00369 {
00370     struct Plus_head *plus ;
00371     char   fname[1024], buf[1024];
00372     GVFILE   fp;
00373     
00374     G_debug (1, "Vect_save_spatial_index()"); 
00375 
00376     plus = &(Map->plus);
00377     
00378     /*  write out rtrees to the sidx file  */
00379     sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00380     G__file_name (fname, buf, GV_SIDX_ELEMENT, Map->mapset);
00381     G_debug (1, "Open sidx: %s", fname);
00382     dig_file_init ( &fp );
00383     fp.file = fopen( fname, "w");
00384     if ( fp.file ==  NULL) {
00385         G_warning(_("Can't open spatial index file for write: %s\n"), fname);
00386             return 0;
00387     }
00388 
00389     /* set portable info */
00390     dig_init_portable ( &(plus->spidx_port), dig__byte_order_out ());
00391     
00392     if ( 0 > dig_write_spidx (&fp, plus) ) {
00393         G_warning (_("Error writing out spatial index file.\n"));
00394         return 0;
00395     }
00396     
00397     fclose( fp.file );
00398 
00399     return 1;
00400 }
00401 
00408 int
00409 Vect_spatial_index_dump ( struct Map_info *Map, FILE *out ) 
00410 {
00411     if ( !(Map->plus.Spidx_built) ) {
00412         Vect_build_sidx_from_topo ( Map, NULL );
00413     }
00414 
00415     fprintf (out, "---------- SPATIAL INDEX DUMP ----------\n" ); 
00416     
00417     dig_dump_spidx ( out, &(Map->plus) ); 
00418 
00419     return 1;
00420 }
00421 

Generated on Sat Jul 22 22:05:56 2006 for GRASS by  doxygen 1.4.7