00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <grass/glocale.h>
00025 #include <grass/gis.h>
00026 #include <grass/Vect.h>
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define MAX_OPEN_LEVEL 2
00040
00041 static int open_old_dummy () { return 0; }
00042 #ifndef HAVE_OGR
00043 static int format () { G_fatal_error (_("Requested format is not compiled in this version")); return 0; }
00044 #endif
00045
00046 static int Open_level = 0;
00047
00048 static int (*Open_old_array[][2]) () =
00049 {
00050 { open_old_dummy, V1_open_old_nat }
00051 #ifdef HAVE_OGR
00052 ,{ open_old_dummy, V1_open_old_ogr }
00053 #else
00054 ,{ open_old_dummy, format }
00055 #endif
00056 };
00057
00058 void
00059 fatal_error ( int ferror, char *errmsg )
00060 {
00061 switch ( ferror ) {
00062 case GV_FATAL_EXIT:
00063 G_fatal_error ( errmsg );
00064 break;
00065 case GV_FATAL_PRINT:
00066 G_warning ( errmsg );
00067 break;
00068 case GV_FATAL_RETURN:
00069 break;
00070 }
00071 }
00072
00073
00091 int
00092 Vect_set_open_level (int level)
00093 {
00094 Open_level = level;
00095 if (Open_level < 1 || Open_level > MAX_OPEN_LEVEL)
00096 {
00097 fprintf (stderr, _("Warning, Programmer requested unknown open_level\n"));
00098 Open_level = 0;
00099 }
00100
00101 return 0;
00102 }
00103
00104
00117 int
00118 Vect__open_old ( struct Map_info *Map, char *name, char *mapset, int update, int head_only )
00119 {
00120 char buf[200], buf2[200], xname[512], xmapset[512], errmsg[2000];
00121 FILE *fp;
00122 int level, level_request, ferror;
00123 int format, ret;
00124 char *fmapset;
00125
00126 G_debug (1, "Vect_open_old(): name = %s mapset= %s update = %d", name, mapset, update);
00127
00128
00129
00130 ferror = Vect_get_fatal_error ();
00131 Vect_set_fatal_error (GV_FATAL_EXIT);
00132
00133 level_request = Open_level;
00134 Open_level = 0;
00135 Vect__init_head (Map);
00136 dig_init_plus ( &(Map->plus) );
00137
00138 if (G__name_is_fully_qualified (name, xname, xmapset)) {
00139 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, xname);
00140 sprintf (buf2, "%s@%s", GRASS_VECT_COOR_ELEMENT, xmapset);
00141
00142 Map->name = G_store (xname);
00143 Map->mapset = G_store (xmapset);
00144 } else {
00145 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, name);
00146 sprintf (buf2, "%s", GRASS_VECT_COOR_ELEMENT);
00147 Map->name = G_store (name);
00148
00149 if ( mapset )
00150 Map->mapset = G_store (mapset);
00151 else
00152 Map->mapset = G_store ("");
00153 }
00154
00155 fmapset = G_find_vector2 ( Map->name, Map->mapset );
00156 if ( fmapset == NULL ) {
00157 sprintf ( errmsg, _("Cannot find vector %s"), Vect_get_full_name(Map) );
00158 fatal_error (ferror, errmsg);
00159 return -1;
00160 }
00161 Map->mapset = G_store ( fmapset );
00162
00163 Map->location = G_store ( G_location() );
00164 Map->gisdbase = G_store ( G_gisdbase() );
00165
00166 if ( update && (0 != strcmp(Map->mapset, G_mapset()) ) ) {
00167 G_warning ( _("A map which is not in the current mapset cannot be opened for update.") );
00168 return -1;
00169 }
00170
00171
00172 format = 0;
00173 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00174 G_debug (1, "open format file: '%s/%s/%s'", Map->mapset, buf, GRASS_VECT_FRMT_ELEMENT);
00175 fp = G_fopen_old (buf, GRASS_VECT_FRMT_ELEMENT, Map->mapset);
00176 if ( fp == NULL) {
00177 G_debug ( 1, "Vector format: %d (native)", format);
00178 format = GV_FORMAT_NATIVE;
00179 } else {
00180 format = dig_read_frmt_ascii ( fp, &(Map->fInfo) );
00181 fclose (fp);
00182
00183 G_debug ( 1, "Vector format: %d (non-native)", format);
00184 if ( format < 0 ) {
00185 sprintf ( errmsg, _("Cannot open old vector %s"), Vect_get_full_name(Map) );
00186 fatal_error (ferror, errmsg);
00187 return -1;
00188 }
00189 }
00190
00191 Map->format = format;
00192
00193
00194 if ( Vect__read_head (Map) != GRASS_OK ) {
00195 sprintf ( errmsg, _("Cannot open old vector %s on level %d"), Vect_get_full_name(Map), level_request );
00196 G_warning ( "Cannot read head file." );
00197 }
00198
00199 G_debug ( 1, "Level request = %d", level_request);
00200
00201
00202
00203
00204
00205
00206
00207
00208 if (level_request == 0 || level_request == 2 ) {
00209 level = 2;
00210
00211 ret = Vect_open_topo(Map, head_only);
00212 if ( ret == 1 ) {
00213 G_debug( 1, "Topo file for vector '%s' not available.", Vect_get_full_name (Map));
00214 level = 1;
00215 } else if ( ret == -1 ) {
00216 G_fatal_error ( "Cannot open topo file for vector '%s'.", Vect_get_full_name (Map));
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 if ( level == 2 ) {
00231 ret = Vect_cidx_open(Map, head_only);
00232 if ( ret == 1 ) {
00233 G_debug( 1, "Category index file for vector '%s' not available.", Vect_get_full_name (Map) );
00234 dig_free_plus ( &(Map->plus) );
00235 dig_spidx_free ( &(Map->plus) );
00236 level = 1;
00237 } else if ( ret == -1 ) {
00238 G_fatal_error ( "Cannot open category index file for vector '%s'.", Vect_get_full_name (Map) );
00239 }
00240 }
00241 #ifdef HAVE_OGR
00242
00243 if ( level == 2 && Map->format == GV_FORMAT_OGR ) {
00244 if ( V2_open_old_ogr ( Map ) < 0 ) {
00245 dig_free_plus ( &(Map->plus) );
00246 dig_spidx_free ( &(Map->plus) );
00247 dig_cidx_free ( &(Map->plus) );
00248 level = 1;
00249 }
00250 }
00251 #endif
00252 if (level_request == 2 && level < 2) {
00253 sprintf ( errmsg, _("Cannot open old vector %s on level %d"), Vect_get_full_name(Map), level_request );
00254 fatal_error (ferror, errmsg);
00255 return -1;
00256 }
00257 } else {
00258 level = 1;
00259 }
00260
00261
00262 if ( !head_only ) {
00263 if (0 != (*Open_old_array[format][1]) (Map, update)) {
00264 if ( level == 2 ) {
00265 dig_free_plus ( &(Map->plus) );
00266 dig_spidx_free ( &(Map->plus) );
00267 dig_cidx_free ( &(Map->plus) );
00268 }
00269 sprintf ( errmsg, _("Cannot open old vector %s on level %d"), Vect_get_full_name(Map), level_request );
00270 fatal_error (ferror, errmsg);
00271 return -1;
00272 }
00273 } else {
00274 Map->head.with_z = Map->plus.with_z;
00275 }
00276
00277
00278 Map->open = VECT_OPEN_CODE;
00279 Map->level = level;
00280 Map->head_only = head_only;
00281 Map->support_updated = 0;
00282 if ( update ) {
00283 Map->mode = GV_MODE_RW;
00284 Map->plus.mode = GV_MODE_RW;
00285 } else {
00286 Map->mode = GV_MODE_READ;
00287 Map->plus.mode = GV_MODE_READ;
00288 }
00289 if ( head_only ) {
00290 Map->head_only = 1;
00291 } else {
00292 Map->head_only = 0;
00293 }
00294
00295 Map->Constraint_region_flag = 0;
00296 Map->Constraint_type_flag = 0;
00297 G_debug (1, "Vect_open_old(): vector opened on level %d", level);
00298
00299 if ( level == 1 ) {
00300 Map->plus.built = GV_BUILD_NONE;
00301 } else {
00302 Map->plus.built = GV_BUILD_ALL;
00303 }
00304
00305 Map->plus.do_uplist = 0;
00306
00307 Map->dblnk = Vect_new_dblinks_struct ( );
00308 Vect_read_dblinks ( Map );
00309
00310
00311 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00312
00313 if ( update ) {
00314 Map->hist_fp = G_fopen_modify (buf, GRASS_VECT_HIST_ELEMENT);
00315 if ( Map->hist_fp == NULL ) {
00316 sprintf ( errmsg, _("Cannot open history file for vector '%s'"), Vect_get_full_name(Map) );
00317 fatal_error (ferror, errmsg);
00318 return (-1);
00319 }
00320 fseek ( Map->hist_fp, (long)0, SEEK_END);
00321 Vect_hist_write ( Map, "---------------------------------------------------------------------------------\n");
00322
00323 } else {
00324 if ( Map->format == GV_FORMAT_NATIVE || Map->format == GV_FORMAT_OGR ) {
00325 Map->hist_fp = G_fopen_old (buf, GRASS_VECT_HIST_ELEMENT, Map->mapset);
00326
00327 } else {
00328 Map->hist_fp = NULL;
00329 }
00330 }
00331
00332 if ( !head_only ) {
00333 Vect_rewind ( Map );
00334 }
00335
00336
00337 if ( update && !head_only ) {
00338 char file_path[2000];
00339 struct stat info;
00340
00341 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, name);
00342
00343 G__file_name ( file_path, buf, GV_TOPO_ELEMENT, G_mapset ());
00344 if (stat (file_path, &info) == 0)
00345 unlink (file_path);
00346
00347 G__file_name ( file_path, buf, GV_SIDX_ELEMENT, G_mapset ());
00348 if (stat (file_path, &info) == 0)
00349 unlink (file_path);
00350
00351 G__file_name ( file_path, buf, GV_CIDX_ELEMENT, G_mapset ());
00352 if (stat (file_path, &info) == 0)
00353 unlink (file_path);
00354 }
00355
00356 return (level);
00357 }
00358
00370 int
00371 Vect_open_old (
00372 struct Map_info *Map,
00373 char *name,
00374 char *mapset)
00375 {
00376 return ( Vect__open_old (Map, name, mapset, 0, 0) );
00377 }
00378
00390 int
00391 Vect_open_update (
00392 struct Map_info *Map,
00393 char *name,
00394 char *mapset)
00395 {
00396 int ret;
00397
00398 ret = Vect__open_old (Map, name, mapset, 1, 0);
00399
00400 if ( ret > 0 ) {
00401 Map->plus.do_uplist = 1;
00402
00403 Map->plus.uplines = NULL;
00404 Map->plus.n_uplines = 0;
00405 Map->plus.alloc_uplines = 0;
00406 Map->plus.upnodes = NULL;
00407 Map->plus.n_upnodes = 0;
00408 Map->plus.alloc_upnodes = 0;
00409
00410
00411 Vect_build_sidx_from_topo ( Map, NULL );
00412 }
00413
00414 return ret;
00415 }
00416
00426 int
00427 Vect_open_old_head (struct Map_info *Map, char *name, char *mapset)
00428 {
00429 return ( Vect__open_old (Map, name, mapset, 0, 1) );
00430 }
00431
00441 int
00442 Vect_open_update_head ( struct Map_info *Map, char *name, char *mapset)
00443 {
00444 int ret;
00445
00446 ret = Vect__open_old (Map, name, mapset, 1, 1);
00447
00448 if ( ret > 0 ) {
00449 Map->plus.do_uplist = 1;
00450
00451 Map->plus.uplines = NULL;
00452 Map->plus.n_uplines = 0;
00453 Map->plus.alloc_uplines = 0;
00454 Map->plus.upnodes = NULL;
00455 Map->plus.n_upnodes = 0;
00456 Map->plus.alloc_upnodes = 0;
00457 }
00458
00459 return ret;
00460 }
00461
00470 int
00471 Vect_open_new (
00472 struct Map_info *Map,
00473 char *name,
00474 int with_z)
00475 {
00476 int ret, ferror;
00477 char errmsg[2000], buf[200];
00478
00479 G_debug ( 2, "Vect_open_new(): name = %s", name);
00480
00481 Vect__init_head (Map);
00482 ferror = Vect_get_fatal_error ();
00483 Vect_set_fatal_error (GV_FATAL_EXIT);
00484
00485
00486 if (Vect_legal_filename(name) < 0 ) {
00487 sprintf ( errmsg, _("Map name is not SQL compliant.") );
00488 fatal_error (ferror , errmsg );
00489 return (-1);
00490 }
00491
00492
00493 if ( G_find_file(GRASS_VECT_DIRECTORY, name, G_mapset()) != NULL ) {
00494 G_warning (_("The vector '%s' already exists and will be overwritten."), name);
00495
00496 ret = Vect_delete ( name );
00497 if ( ret == -1 ) {
00498 sprintf ( errmsg, _("Cannot delete existing vector %s"), name );
00499 fatal_error (ferror , errmsg );
00500 return (-1);
00501 }
00502 }
00503
00504 Map->name = G_store (name);
00505 Map->mapset = G_store ( G_mapset() );
00506 Map->location = G_store ( G_location() );
00507 Map->gisdbase = G_store ( G_gisdbase() );
00508
00509 Map->format = GV_FORMAT_NATIVE;
00510
00511 if ( V1_open_new_nat (Map, name, with_z) < 0 ) {
00512 sprintf ( errmsg, _("Cannot open new vector %s"), Vect_get_full_name(Map) );
00513 fatal_error (ferror , errmsg );
00514 return (-1);
00515 }
00516
00517
00518 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00519 Map->hist_fp = G_fopen_new (buf, GRASS_VECT_HIST_ELEMENT);
00520 if ( Map->hist_fp == NULL ) {
00521 sprintf ( errmsg, _("Cannot open history file for vector '%s'"), Vect_get_full_name(Map) );
00522 fatal_error (ferror, errmsg);
00523 return (-1);
00524 }
00525
00526 Open_level = 0;
00527
00528 dig_init_plus ( &(Map->plus) );
00529
00530 Map->open = VECT_OPEN_CODE;
00531 Map->level = 1;
00532 Map->head_only = 0;
00533 Map->support_updated = 0;
00534 Map->plus.built = GV_BUILD_NONE;
00535 Map->mode = GV_MODE_RW;
00536 Map->Constraint_region_flag = 0;
00537 Map->Constraint_type_flag = 0;
00538 Map->head.with_z = with_z;
00539 Map->plus.do_uplist = 0;
00540
00541 Map->dblnk = Vect_new_dblinks_struct ( );
00542
00543 return 1;
00544 }
00545
00552 int
00553 Vect_coor_info ( struct Map_info *Map, struct Coor_info *Info )
00554 {
00555 char buf[2000], path[2000];
00556 struct stat stat_buf;
00557
00558 switch ( Map->format ) {
00559 case GV_FORMAT_NATIVE :
00560 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00561 G__file_name (path, buf, GRASS_VECT_COOR_ELEMENT, Map->mapset);
00562 G_debug ( 1, "get coor info: %s", path);
00563 if (0 != stat (path, &stat_buf)) {
00564 G_warning ( _("Could not stat file '%s'"), path);
00565 Info->size = -1L;
00566 Info->mtime = -1L;
00567 } else {
00568 Info->size = (long) stat_buf.st_size;
00569 Info->mtime = (long) stat_buf.st_mtime;
00570 }
00571
00572
00573 #ifdef __MINGW32__
00574 if ( Map->open == VECT_OPEN_CODE ) {
00575 dig_fseek ( &(Map->dig_fp), 0L, SEEK_END);
00576 G_debug ( 2, "ftell = %d", dig_ftell ( &(Map->dig_fp) ) );
00577 Info->size = dig_ftell ( &(Map->dig_fp) );
00578 }
00579 #endif
00580 break;
00581 case GV_FORMAT_OGR :
00582 Info->size = 0L;
00583 Info->mtime = 0L;
00584 break;
00585 }
00586 G_debug ( 1, "Info->size = %ld, Info->mtime = %ld", Info->size, Info->mtime);
00587
00588 return 1;
00589 }
00590
00597 char *
00598 Vect_maptype_info ( struct Map_info *Map )
00599 {
00600 char *maptype;
00601
00602 maptype = G_malloc(sizeof(char) * 200);
00603 switch ( Map->format ) {
00604 case GV_FORMAT_NATIVE :
00605 sprintf (maptype, "native");
00606 break;
00607 case GV_FORMAT_OGR :
00608 sprintf (maptype, "ogr");
00609 break;
00610 default :
00611 sprintf (maptype, "unknown %d (update Vect_maptype_info)", Map->format);
00612 }
00613
00614 return maptype;
00615 }
00616
00617
00626 int
00627 Vect_open_topo (struct Map_info *Map, int head_only)
00628 {
00629 int err, ret;
00630 char buf[500], file_path[2000];
00631 GVFILE fp;
00632 struct Coor_info CInfo;
00633 struct Plus_head *Plus;
00634 struct stat info;
00635
00636 G_debug (1, "Vect_open_topo(): name = %s mapset= %s", Map->name, Map->mapset);
00637
00638 Plus = &(Map->plus);
00639
00640 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00641 G__file_name ( file_path, buf, GV_TOPO_ELEMENT, Map->mapset);
00642
00643 if (stat (file_path, &info) != 0)
00644 return 1;
00645
00646 dig_file_init ( &fp );
00647 fp.file = G_fopen_old (buf, GV_TOPO_ELEMENT, Map->mapset);
00648
00649 if ( fp.file == NULL ) {
00650 G_debug( 1, "Cannot open topo file for vector '%s@%s'.",
00651 Map->name, Map->mapset);
00652 return -1;
00653 }
00654
00655
00656 Vect_coor_info ( Map, &CInfo);
00657
00658
00659 if ( dig_Rd_Plus_head (&fp, Plus) == -1 ) return -1;
00660
00661 G_debug ( 1, "Topo head: coor size = %ld, coor mtime = %ld",
00662 Plus->coor_size, Plus->coor_mtime);
00663
00664
00665 err = 0;
00666 if ( CInfo.size != Plus->coor_size ) {
00667 G_warning ( _("Size of 'coor' file differs from value saved in topo file.") );
00668 err = 1;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677 if ( err ) {
00678 G_warning ( _("Please rebuild topology for vector '%s@%s'"), Map->name, Map->mapset );
00679 return -1;
00680 }
00681
00682
00683
00684
00685
00686 ret = dig_load_plus ( Plus, &fp, head_only );
00687
00688 fclose ( fp.file );
00689
00690
00691 if ( ret == 0 ) return -1;
00692
00693 return 0;
00694 }
00695
00702 int
00703 Vect_open_spatial_index (struct Map_info *Map)
00704 {
00705 char buf[500];
00706 GVFILE fp;
00707
00708 struct Plus_head *Plus;
00709
00710 G_debug (1, "Vect_open_spatial_index(): name = %s mapset= %s", Map->name, Map->mapset);
00711
00712 Plus = &(Map->plus);
00713
00714 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00715 dig_file_init ( &fp );
00716 fp.file = G_fopen_old (buf, GV_SIDX_ELEMENT, Map->mapset);
00717
00718 if ( fp.file == NULL ) {
00719 G_debug( 1, "Cannot open spatial index file for vector '%s@%s'.",
00720 Map->name, Map->mapset);
00721 return -1;
00722 }
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 dig_spidx_init ( Plus);
00760 dig_read_spidx ( &fp, Plus );
00761
00762 fclose ( fp.file );
00763
00764
00765 return 0;
00766 }
00767