open.c

Go to the documentation of this file.
00001 /****************************************************************************
00002 *
00003 * MODULE:       Vector library 
00004 *               
00005 * AUTHOR(S):    Original author CERL, probably Dave Gerdes or Mike Higgins.
00006 *               Update to GRASS 5.7 Radim Blazek and David D. Gray.
00007 *
00008 * PURPOSE:      Higher level functions for reading/writing/manipulating vectors.
00009 *
00010 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00011 *
00012 *               This program is free software under the GNU General Public
00013 *               License (>=v2). Read the file COPYING that comes with GRASS
00014 *               for details.
00015 *
00016 *****************************************************************************/
00017 #include "stdlib.h"
00018 #include "stdio.h"
00019 #include "string.h"
00020 #include <unistd.h>
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023 #include "glocale.h"
00024 #include "gis.h"
00025 #include "Vect.h"
00026 /*
00027 
00028    Routines:    
00029    Vect_open_old (Map, name, mapset)
00030    Vect_open_new (Map, name)
00031    Vect_rewind (Map)
00032    Vect_close (Map)
00033 
00034    These routines all just call the V# equivalents to pass the function
00035    off to more level-specific code.
00036  */
00037 
00038 #define MAX_OPEN_LEVEL 2
00039 
00040 static int open_old_dummy () { return 0; }
00041 static int open_new_dummy () { return 0; }
00042 static int format () { G_fatal_error (_("Requested format is not compiled in this version")); return 0; }
00043 
00044 static int Open_level = 0;
00045 
00046 static int (*Open_old_array[][2]) () =
00047 {
00048     { open_old_dummy, V1_open_old_nat }
00049 #ifdef HAVE_OGR
00050    ,{ open_old_dummy, V1_open_old_ogr }
00051 #else   
00052    ,{ open_old_dummy, format }
00053 #endif
00054 };
00055 
00056 void 
00057 fatal_error ( int ferror, char *errmsg ) 
00058 {
00059       switch ( ferror ) {
00060           case GV_FATAL_EXIT:
00061               G_fatal_error ( errmsg ); 
00062               break;
00063           case GV_FATAL_PRINT:
00064               G_warning ( errmsg ); 
00065               break;
00066           case GV_FATAL_RETURN:
00067               break;
00068       }
00069 } 
00070 
00071 
00089 int 
00090 Vect_set_open_level (int level)
00091 {
00092   Open_level = level;
00093   if (Open_level < 1 || Open_level > MAX_OPEN_LEVEL)
00094     {
00095       fprintf (stderr, _("Warning, Programmer requested unknown open_level\n"));
00096       Open_level = 0;
00097     }
00098 
00099   return 0;
00100 }
00101 
00102 
00115 int
00116 Vect__open_old ( struct Map_info *Map, char *name, char *mapset, int update, int head_only ) 
00117 {
00118   char buf[200], buf2[200], xname[512], xmapset[512], errmsg[2000];
00119   FILE *fp;
00120   int level, level_request, ferror;
00121   int format, ret;
00122   char *fmapset;
00123 
00124   G_debug (1, "Vect_open_old(): name = %s mapset= %s update = %d", name, mapset, update);
00125   
00126   /* TODO: Open header for update ('dbln') */
00127       
00128   ferror = Vect_get_fatal_error ();
00129   Vect_set_fatal_error (GV_FATAL_EXIT);
00130 
00131   level_request = Open_level;
00132   Open_level = 0;
00133   Vect__init_head (Map);
00134   dig_init_plus ( &(Map->plus) );    
00135   
00136   if (G__name_is_fully_qualified (name, xname, xmapset)) {
00137       sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, xname);
00138       sprintf (buf2, "%s@%s", GRASS_VECT_COOR_ELEMENT, xmapset);
00139        
00140       Map->name = G_store (xname);
00141       Map->mapset = G_store (xmapset);
00142   } else {
00143       sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, name);
00144       sprintf (buf2, "%s", GRASS_VECT_COOR_ELEMENT);
00145       Map->name = G_store (name);
00146       
00147       if ( mapset )
00148           Map->mapset = G_store (mapset);
00149       else 
00150           Map->mapset = G_store ("");
00151   }
00152 
00153   fmapset = G_find_vector2 ( Map->name, Map->mapset );
00154   if ( fmapset == NULL ) {
00155       sprintf ( errmsg, _("Cannot find vector %s"), Vect_get_full_name(Map) ); 
00156       fatal_error (ferror, errmsg);
00157       return -1;
00158   }
00159   Map->mapset = G_store ( fmapset );
00160 
00161   Map->location = G_store ( G_location() );
00162   Map->gisdbase = G_store ( G_gisdbase() );
00163   
00164   if ( update && (0 != strcmp(Map->mapset, G_mapset()) ) ) {
00165       G_warning ( _("A map which is not in the current mapset cannot be opened for update.") );
00166       return -1;
00167   }
00168 
00169   /* Read vector format information */
00170   format = 0;
00171   sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00172   G_debug (1, "open format file: '%s/%s/%s'", Map->mapset, buf, GRASS_VECT_FRMT_ELEMENT);
00173   fp = G_fopen_old (buf, GRASS_VECT_FRMT_ELEMENT, Map->mapset);
00174   if ( fp == NULL) {
00175       G_debug ( 1, "Vector format: %d (native)", format);
00176       format = GV_FORMAT_NATIVE;
00177   } else {
00178       format = dig_read_frmt_ascii ( fp, &(Map->fInfo) );
00179       fclose (fp); 
00180       
00181       G_debug ( 1, "Vector format: %d (non-native)", format);
00182       if ( format < 0 ) {
00183           sprintf ( errmsg, _("Cannot open old vector %s"), Vect_get_full_name(Map) ); 
00184           fatal_error (ferror, errmsg);
00185           return -1;
00186       }
00187   }
00188           
00189   Map->format = format;
00190 
00191   /* Read vector head */
00192   if ( Vect__read_head (Map) != GRASS_OK ) {
00193       sprintf ( errmsg, _("Cannot open old vector %s on level %d"), Vect_get_full_name(Map), level_request ); 
00194       fatal_error (ferror, errmsg);
00195       return -1;
00196   }
00197   
00198   G_debug ( 1, "Level request = %d", level_request);
00199 
00200   /* There are only 2 possible open levels, 1 and 2. Try first to open 'support' files
00201    * (topo,sidx,cidx), these files are the same for all formats.
00202    * If it is not possible and requested level is 2, return error,
00203    * otherwise call Open_old_array[format][1], to open remaining files/sources (level 1)
00204    */
00205 
00206   /* Try to open support files if level was not requested or requested level is 2 (format independent) */
00207   if (level_request == 0 || level_request == 2 ) {
00208       level = 2; /* We expect success */
00209       /* open topo */
00210       ret = Vect_open_topo(Map, head_only);
00211       if ( ret == 1 ) { /* topo file is not available */
00212           G_debug( 1, "Topo file for vector '%s' not available.", Vect_get_full_name (Map));
00213           level = 1;
00214       } else if ( ret == -1 ) {
00215           G_fatal_error ( "Cannot open topo file for vector '%s'.", Vect_get_full_name (Map));
00216       }
00217       /* open spatial index, not needed for head_only */
00218       /* spatial index is not loaded anymore */
00219       /*
00220       if ( level == 2 && !head_only ) {
00221          if ( Vect_open_spatial_index(Map) == -1 ) {
00222              G_debug( 1, "Cannot open spatial index file for vector '%s'.", Vect_get_full_name (Map) );
00223              dig_free_plus ( &(Map->plus) );
00224              level = 1;
00225          }
00226       }
00227       */
00228       /* open category index */
00229       if ( level == 2 ) {
00230           ret = Vect_cidx_open(Map, head_only);
00231           if ( ret == 1 ) { /* category index is not available */
00232               G_debug( 1, "Category index file for vector '%s' not available.", Vect_get_full_name (Map) );
00233               dig_free_plus ( &(Map->plus) ); /* free topology */
00234               dig_spidx_free ( &(Map->plus) ); /* free spatial index */
00235               level = 1;
00236           } else if ( ret == -1 ) { /* file exists, but cannot be opened */
00237               G_fatal_error ( "Cannot open category index file for vector '%s'.", Vect_get_full_name (Map) );
00238           }
00239       }
00240 #ifdef HAVE_OGR
00241       /* Open OGR specific support files */
00242       if ( level == 2 && Map->format == GV_FORMAT_OGR ) {
00243           if ( V2_open_old_ogr ( Map ) < 0 ) {
00244               dig_free_plus ( &(Map->plus) );
00245               dig_spidx_free ( &(Map->plus) );
00246               dig_cidx_free ( &(Map->plus) );
00247               level = 1;
00248           }
00249       }
00250 #endif
00251       if (level_request == 2 && level < 2) {
00252           sprintf ( errmsg, _("Cannot open old vector %s on level %d"), Vect_get_full_name(Map), level_request ); 
00253           fatal_error (ferror, errmsg);
00254           return -1;
00255       }
00256   } else {
00257       level = 1; /* I.e. requested level is 1 */
00258   }
00259 
00260   /* Open level 1 files / sources (format specific) */ 
00261   if ( !head_only ) { /* No need to open coordinates */
00262       if (0 != (*Open_old_array[format][1]) (Map, update)) { /* Cannot open */
00263           if ( level == 2 ) { /* support files opened */
00264               dig_free_plus ( &(Map->plus) );
00265               dig_spidx_free ( &(Map->plus) );
00266               dig_cidx_free ( &(Map->plus) );
00267           }
00268           sprintf ( errmsg, _("Cannot open old vector %s on level %d"), Vect_get_full_name(Map), level_request ); 
00269           fatal_error (ferror, errmsg);
00270           return -1;
00271       }
00272   } else {
00273       Map->head.with_z = Map->plus.with_z; /* take dimension from topo */
00274   }
00275           
00276   /* Set status */
00277   Map->open = VECT_OPEN_CODE;
00278   Map->level = level;
00279   Map->head_only = head_only;
00280   Map->support_updated = 0;
00281   if ( update ) {
00282       Map->mode = GV_MODE_RW;
00283       Map->plus.mode = GV_MODE_RW;
00284   } else {
00285       Map->mode = GV_MODE_READ;
00286       Map->plus.mode = GV_MODE_READ;
00287   }
00288   if ( head_only ) {
00289       Map->head_only = 1;
00290   } else {
00291       Map->head_only = 0;
00292   }
00293   
00294   Map->Constraint_region_flag = 0;
00295   Map->Constraint_type_flag = 0;
00296   G_debug (1, "Vect_open_old(): vector opened on level %d", level);
00297 
00298   if ( level == 1 ) { /* without topology */
00299       Map->plus.built = GV_BUILD_NONE;  
00300   } else { /* level 2, with topology */
00301       Map->plus.built = GV_BUILD_ALL; /* Highest level of topology for level 2 */
00302   }
00303 
00304   Map->plus.do_uplist = 0;
00305 
00306   Map->dblnk = Vect_new_dblinks_struct ( );
00307   Vect_read_dblinks ( Map );
00308   
00309   /* Open history file */  
00310   sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00311 
00312   if ( update ) { /* native only */
00313       Map->hist_fp = G_fopen_modify (buf, GRASS_VECT_HIST_ELEMENT);
00314       if ( Map->hist_fp == NULL ) {
00315           sprintf ( errmsg, _("Cannot open history file for vector '%s'"), Vect_get_full_name(Map) ); 
00316           fatal_error (ferror, errmsg);
00317           return (-1);
00318       }
00319       fseek ( Map->hist_fp, 0, SEEK_END);
00320       Vect_hist_write ( Map, "---------------------------------------------------------------------------------\n");
00321       
00322   } else {
00323       if ( Map->format == GV_FORMAT_NATIVE ) {
00324           Map->hist_fp = G_fopen_old (buf, GRASS_VECT_HIST_ELEMENT, Map->mapset);
00325           /* If NULL (does not exist) then Vect_hist_read() handle that */
00326       } else { 
00327           Map->hist_fp = NULL;
00328       }
00329   }
00330 
00331   if ( !head_only ) { /* Cannot rewind if not fully opened */
00332       Vect_rewind ( Map );
00333   }
00334 
00335   /* Delete support files if native format was opened for update (not head_only) */
00336   if ( update && !head_only ) {
00337       char file_path[2000];
00338       struct stat info;
00339       
00340       sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, name);
00341 
00342       G__file_name ( file_path, buf, GV_TOPO_ELEMENT, G_mapset ());
00343       if (stat (file_path, &info) == 0)      /* file exists? */
00344           unlink (file_path);
00345 
00346       G__file_name ( file_path, buf, GV_SIDX_ELEMENT, G_mapset ());
00347       if (stat (file_path, &info) == 0)      /* file exists? */
00348           unlink (file_path);
00349 
00350       G__file_name ( file_path, buf, GV_CIDX_ELEMENT, G_mapset ());
00351       if (stat (file_path, &info) == 0)      /* file exists? */
00352           unlink (file_path);
00353   }
00354   
00355   return (level);
00356 }
00357 
00369 int
00370 Vect_open_old (
00371                 struct Map_info *Map,
00372                 char *name,
00373                 char *mapset)
00374 {
00375     return ( Vect__open_old (Map, name, mapset, 0, 0) );
00376 }
00377 
00389 int
00390 Vect_open_update (
00391                 struct Map_info *Map,
00392                 char *name,
00393                 char *mapset)
00394 {
00395     int ret;
00396 
00397     ret = Vect__open_old (Map, name, mapset, 1, 0);
00398 
00399     if ( ret > 0 ) {
00400         Map->plus.do_uplist = 1;
00401 
00402         Map->plus.uplines = NULL;
00403         Map->plus.n_uplines = 0;
00404         Map->plus.alloc_uplines = 0;
00405         Map->plus.upnodes = NULL;
00406         Map->plus.n_upnodes = 0;
00407         Map->plus.alloc_upnodes = 0;
00408 
00409         /* Build spatial index from topo */
00410         Vect_build_sidx_from_topo ( Map, NULL );
00411     }
00412         
00413     return ret;
00414 }
00415 
00425 int
00426 Vect_open_old_head (struct Map_info *Map, char *name, char *mapset)
00427 {
00428     return ( Vect__open_old (Map, name, mapset, 0, 1) );
00429 }
00430 
00440 int
00441 Vect_open_update_head ( struct Map_info *Map, char *name, char *mapset)
00442 {
00443     int ret;
00444 
00445     ret = Vect__open_old (Map, name, mapset, 1, 1);
00446 
00447     if ( ret > 0 ) { /* Probably not important */
00448         Map->plus.do_uplist = 1;
00449 
00450         Map->plus.uplines = NULL;
00451         Map->plus.n_uplines = 0;
00452         Map->plus.alloc_uplines = 0;
00453         Map->plus.upnodes = NULL;
00454         Map->plus.n_upnodes = 0;
00455         Map->plus.alloc_upnodes = 0;
00456     }
00457         
00458     return ret;
00459 }
00460 
00469 int 
00470 Vect_open_new (
00471                 struct Map_info *Map,
00472                 char *name,
00473                 int with_z)
00474 {
00475     int  ret, ferror;
00476     char errmsg[2000], buf[200];
00477 
00478     G_debug ( 2, "Vect_open_new(): name = %s", name);
00479     
00480     Vect__init_head (Map);
00481     ferror = Vect_get_fatal_error ();
00482     Vect_set_fatal_error (GV_FATAL_EXIT);
00483 
00484     /* check for [A-Za-z][A-Za-z0-9_]* in name */
00485     if (Vect_legal_filename(name) < 0 ) {
00486        sprintf ( errmsg, _("Map name is not SQL compliant.") );
00487        fatal_error (ferror , errmsg );
00488        return (-1);
00489     }
00490 
00491     /* Check if map already exists */
00492     if ( G_find_file(GRASS_VECT_DIRECTORY, name, G_mapset()) != NULL ) {
00493         G_warning (_("The vector '%s' already exists and will be overwritten."), name); 
00494         
00495         ret = Vect_delete ( name );
00496         if ( ret == -1 ) {
00497             sprintf ( errmsg, _("Cannot delete existing vector %s"), name ); 
00498             fatal_error (ferror , errmsg );
00499             return (-1);
00500         }
00501     }
00502     
00503     Map->name = G_store (name);
00504     Map->mapset = G_store ( G_mapset() );
00505     Map->location = G_store ( G_location() );
00506     Map->gisdbase = G_store ( G_gisdbase() );
00507     
00508     Map->format = GV_FORMAT_NATIVE;
00509 
00510     if ( V1_open_new_nat (Map, name, with_z) < 0 ) {
00511         sprintf ( errmsg, _("Cannot open new vector %s"), Vect_get_full_name(Map) ); 
00512         fatal_error (ferror , errmsg );
00513         return (-1);
00514     }
00515 
00516     /* Open history file */  
00517     sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00518     Map->hist_fp = G_fopen_new (buf, GRASS_VECT_HIST_ELEMENT);
00519     if ( Map->hist_fp == NULL ) {
00520         sprintf ( errmsg, _("Cannot open history file for vector '%s'"), Vect_get_full_name(Map) ); 
00521         fatal_error (ferror, errmsg);
00522         return (-1);
00523     }
00524 
00525     Open_level = 0;
00526 
00527     dig_init_plus ( &(Map->plus) );    
00528     
00529     Map->open = VECT_OPEN_CODE;
00530     Map->level = 1;
00531     Map->head_only = 0;
00532     Map->support_updated = 0;
00533     Map->plus.built = GV_BUILD_NONE;
00534     Map->mode = GV_MODE_RW;
00535     Map->Constraint_region_flag = 0;
00536     Map->Constraint_type_flag = 0;
00537     Map->head.with_z = with_z;
00538     Map->plus.do_uplist = 0;
00539     
00540     Map->dblnk = Vect_new_dblinks_struct ( );
00541   
00542     return 1;
00543 }
00544 
00551 int 
00552 Vect_coor_info ( struct Map_info *Map, struct Coor_info *Info )
00553 {
00554     char buf[2000], path[2000];
00555     struct stat stat_buf;
00556     
00557     switch (  Map->format ) {
00558         case GV_FORMAT_NATIVE :
00559             sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00560             G__file_name (path, buf, GRASS_VECT_COOR_ELEMENT, Map->mapset);
00561             G_debug ( 1, "get coor info: %s", path);
00562             if (0 != stat (path, &stat_buf)) {
00563                 G_warning ( _("Could not stat file '%s'"), path);
00564                 Info->size = -1L;
00565                 Info->mtime = -1L;
00566             } else {
00567                 Info->size = (long) stat_buf.st_size;      /* file size */
00568                 Info->mtime = (long) stat_buf.st_mtime;    /* last modified time */
00569             }
00570             break;
00571         case GV_FORMAT_OGR :
00572             Info->size = 0L;
00573             Info->mtime = 0L;
00574             break;
00575     }
00576     G_debug ( 1, "Info->size = %ld, Info->mtime = %ld", Info->size, Info->mtime);
00577         
00578     return 1;
00579 }
00580 
00587 char * 
00588 Vect_maptype_info ( struct Map_info *Map )
00589 {
00590     char *maptype;
00591 
00592     maptype = G_malloc ( 200 );
00593     switch (  Map->format ) {
00594         case GV_FORMAT_NATIVE :
00595             sprintf (maptype, "native");
00596             break;
00597         case GV_FORMAT_OGR :
00598             sprintf (maptype, "ogr");
00599             break;
00600         default :
00601             sprintf (maptype, "unknown %d (update Vect_maptype_info)", Map->format);
00602     }
00603         
00604     return maptype;
00605 }
00606 
00607 
00616 int 
00617 Vect_open_topo (struct Map_info *Map, int head_only)
00618 {
00619     int  err, ret;
00620     char buf[500], file_path[2000];
00621     GVFILE fp;
00622     struct Coor_info CInfo;
00623     struct Plus_head *Plus;
00624     struct stat info;
00625     
00626     G_debug (1, "Vect_open_topo(): name = %s mapset= %s", Map->name, Map->mapset);
00627 
00628     Plus = &(Map->plus);
00629     
00630     sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00631     G__file_name ( file_path, buf, GV_TOPO_ELEMENT, Map->mapset);
00632 
00633     if (stat (file_path, &info) != 0) /* does not exist */
00634         return 1;
00635 
00636     dig_file_init ( &fp );
00637     fp.file = G_fopen_old (buf, GV_TOPO_ELEMENT, Map->mapset);
00638 
00639     if ( fp.file == NULL ) { /* topo file is not available */
00640         G_debug( 1, "Cannot open topo file for vector '%s@%s'.", 
00641                       Map->name, Map->mapset);
00642         return -1;
00643     }
00644   
00645     /* get coor info */ 
00646     Vect_coor_info ( Map, &CInfo); 
00647 
00648     /* load head */
00649     if ( dig_Rd_Plus_head (&fp, Plus) == -1 ) return -1;
00650         
00651     G_debug ( 1, "Topo head: coor size = %ld, coor mtime = %ld", 
00652                                       Plus->coor_size, Plus->coor_mtime);
00653 
00654     /* do checks */
00655     err = 0;
00656     if ( CInfo.size != Plus->coor_size ) {
00657         G_warning ( _("Size of 'coor' file differs from value saved in topo file.") );
00658         err = 1;
00659     }
00660     /* Do not check mtime because mtime is changed by copy */
00661     /*
00662     if ( CInfo.mtime != Plus->coor_mtime ) {
00663         G_warning ( "Time of last modification for 'coor' file differs from value saved in topo file.\n");
00664         err = 1;
00665     }
00666     */
00667     if ( err ) {
00668         G_warning ( _("Please rebuild topology for vector '%s@%s'"), Map->name, Map->mapset );
00669         return -1;
00670     }
00671     
00672     /* load file to the memory */
00673     /* dig_file_load ( &fp); */
00674 
00675     /* load topo to memory */
00676     ret = dig_load_plus ( Plus, &fp, head_only );    
00677    
00678     fclose ( fp.file );  
00679     /* dig_file_free ( &fp); */
00680 
00681     if ( ret == 0 ) return -1;
00682 
00683     return 0;
00684 }
00685 
00692 int 
00693 Vect_open_spatial_index (struct Map_info *Map)
00694 {
00695     char buf[500];
00696     GVFILE fp;
00697     /* struct Coor_info CInfo; */
00698     struct Plus_head *Plus;
00699     
00700     G_debug (1, "Vect_open_spatial_index(): name = %s mapset= %s", Map->name, Map->mapset);
00701 
00702     Plus = &(Map->plus);
00703     
00704     sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00705     dig_file_init ( &fp );
00706     fp.file = G_fopen_old (buf, GV_SIDX_ELEMENT, Map->mapset);
00707 
00708     if ( fp.file == NULL ) { /* spatial index file is not available */
00709         G_debug( 1, "Cannot open spatial index file for vector '%s@%s'.", 
00710                       Map->name, Map->mapset);
00711         return -1;
00712     }
00713   
00714     /* TODO: checks */
00715     /* load head */
00716     /*
00717     dig_Rd_spindx_head (fp, Plus);
00718     G_debug ( 1, "Spindx head: coor size = %ld, coor mtime = %ld", 
00719                                       Plus->coor_size, Plus->coor_mtime);
00720 
00721     */
00722     /* do checks */
00723     /*
00724     err = 0;
00725     if ( CInfo.size != Plus->coor_size ) {
00726         G_warning ( "Size of 'coor' file differs from value saved in topo file.\n");
00727         err = 1;
00728     }
00729     */
00730     /* Do not check mtime because mtime is changed by copy */
00731     /*
00732     if ( CInfo.mtime != Plus->coor_mtime ) {
00733         G_warning ( "Time of last modification for 'coor' file differs from value saved in topo file.\n");
00734         err = 1;
00735     }
00736     */
00737     /*
00738     if ( err ) {
00739         G_warning ( "Please rebuild topology for vector '%s@%s'\n", Map->name,
00740                                   Map->mapset );
00741         return -1;
00742     }
00743     */
00744     
00745     /* load file to the memory */
00746     /* dig_file_load ( &fp); */
00747     
00748     /* load topo to memory */
00749     dig_spidx_init ( Plus);
00750     dig_read_spidx ( &fp, Plus );    
00751    
00752     fclose ( fp.file );  
00753     /* dig_file_free ( &fp); */
00754 
00755     return 0;
00756 }
00757 

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