00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00029
00030
00031
00032
00033
00034
00035
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
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
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
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
00201
00202
00203
00204
00205
00206
00207 if (level_request == 0 || level_request == 2 ) {
00208 level = 2;
00209
00210 ret = Vect_open_topo(Map, head_only);
00211 if ( ret == 1 ) {
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
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 if ( level == 2 ) {
00230 ret = Vect_cidx_open(Map, head_only);
00231 if ( ret == 1 ) {
00232 G_debug( 1, "Category index file for vector '%s' not available.", Vect_get_full_name (Map) );
00233 dig_free_plus ( &(Map->plus) );
00234 dig_spidx_free ( &(Map->plus) );
00235 level = 1;
00236 } else if ( ret == -1 ) {
00237 G_fatal_error ( "Cannot open category index file for vector '%s'.", Vect_get_full_name (Map) );
00238 }
00239 }
00240 #ifdef HAVE_OGR
00241
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;
00258 }
00259
00260
00261 if ( !head_only ) {
00262 if (0 != (*Open_old_array[format][1]) (Map, update)) {
00263 if ( level == 2 ) {
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;
00274 }
00275
00276
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 ) {
00299 Map->plus.built = GV_BUILD_NONE;
00300 } else {
00301 Map->plus.built = GV_BUILD_ALL;
00302 }
00303
00304 Map->plus.do_uplist = 0;
00305
00306 Map->dblnk = Vect_new_dblinks_struct ( );
00307 Vect_read_dblinks ( Map );
00308
00309
00310 sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00311
00312 if ( update ) {
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
00326 } else {
00327 Map->hist_fp = NULL;
00328 }
00329 }
00330
00331 if ( !head_only ) {
00332 Vect_rewind ( Map );
00333 }
00334
00335
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)
00344 unlink (file_path);
00345
00346 G__file_name ( file_path, buf, GV_SIDX_ELEMENT, G_mapset ());
00347 if (stat (file_path, &info) == 0)
00348 unlink (file_path);
00349
00350 G__file_name ( file_path, buf, GV_CIDX_ELEMENT, G_mapset ());
00351 if (stat (file_path, &info) == 0)
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
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 ) {
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
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
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
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;
00568 Info->mtime = (long) stat_buf.st_mtime;
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)
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 ) {
00640 G_debug( 1, "Cannot open topo file for vector '%s@%s'.",
00641 Map->name, Map->mapset);
00642 return -1;
00643 }
00644
00645
00646 Vect_coor_info ( Map, &CInfo);
00647
00648
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
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
00661
00662
00663
00664
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
00673
00674
00675
00676 ret = dig_load_plus ( Plus, &fp, head_only );
00677
00678 fclose ( fp.file );
00679
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
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 ) {
00709 G_debug( 1, "Cannot open spatial index file for vector '%s@%s'.",
00710 Map->name, Map->mapset);
00711 return -1;
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
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 dig_spidx_init ( Plus);
00750 dig_read_spidx ( &fp, Plus );
00751
00752 fclose ( fp.file );
00753
00754
00755 return 0;
00756 }
00757