00001
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <unistd.h>
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <grass/glocale.h>
00027 #include <grass/gis.h>
00028 #include <grass/Vect.h>
00029
00030 #define MAX_OPEN_LEVEL 2
00031
00032 static int open_old_dummy()
00033 {
00034 return 0;
00035 }
00036
00037 #ifndef HAVE_OGR
00038 static int format()
00039 {
00040 G_fatal_error(_("Requested format is not compiled in this version"));
00041 return 0;
00042 }
00043 #endif
00044
00045 static int Open_level = 0;
00046
00047 static int (*Open_old_array[][2]) () = {
00048 {
00049 open_old_dummy, V1_open_old_nat}
00050 #ifdef HAVE_OGR
00051 , {
00052 open_old_dummy, V1_open_old_ogr}
00053 #else
00054 , {
00055 open_old_dummy, format}
00056 #endif
00057 };
00058
00059 static void 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
00096 int Vect_set_open_level(int level)
00097 {
00098 Open_level = level;
00099 if (Open_level < 1 || Open_level > MAX_OPEN_LEVEL) {
00100 G_warning(_("Programmer requested unknown open level %d"),
00101 Open_level);
00102 Open_level = 0;
00103 return 1;
00104 }
00105
00106 return 0;
00107 }
00108
00109
00124 int
00125 Vect__open_old(struct Map_info *Map, const char *name, const char *mapset,
00126 int update, int head_only)
00127 {
00128 char buf[GNAME_MAX + 10], buf2[GMAPSET_MAX + 10], xname[GNAME_MAX],
00129 xmapset[GMAPSET_MAX], errmsg[2000];
00130 FILE *fp;
00131 int level, level_request, ferror;
00132 int format, ret;
00133 char *fmapset;
00134
00135 G_debug(1, "Vect_open_old(): name = %s mapset= %s update = %d", name,
00136 mapset, update);
00137
00138
00139
00140 ferror = Vect_get_fatal_error();
00141 Vect_set_fatal_error(GV_FATAL_EXIT);
00142
00143 level_request = Open_level;
00144 Open_level = 0;
00145 Vect__init_head(Map);
00146 dig_init_plus(&(Map->plus));
00147
00148 if (G__name_is_fully_qualified(name, xname, xmapset)) {
00149 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, xname);
00150 sprintf(buf2, "%s@%s", GRASS_VECT_COOR_ELEMENT, xmapset);
00151
00152 Map->name = G_store(xname);
00153 Map->mapset = G_store(xmapset);
00154 }
00155 else {
00156 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, name);
00157 sprintf(buf2, "%s", GRASS_VECT_COOR_ELEMENT);
00158 Map->name = G_store(name);
00159
00160 if (mapset)
00161 Map->mapset = G_store(mapset);
00162 else
00163 Map->mapset = G_store("");
00164 }
00165
00166 fmapset = G_find_vector2(Map->name, Map->mapset);
00167 if (fmapset == NULL) {
00168 sprintf(errmsg, _("Vector map <%s> not found"),
00169 Vect_get_full_name(Map));
00170 fatal_error(ferror, errmsg);
00171 return -1;
00172 }
00173 Map->mapset = G_store(fmapset);
00174
00175 Map->location = G_store(G_location());
00176 Map->gisdbase = G_store(G_gisdbase());
00177
00178 if (update && (0 != strcmp(Map->mapset, G_mapset()))) {
00179 G_warning(_("Vector map which is not in the current mapset cannot be opened for update"));
00180 return -1;
00181 }
00182
00183
00184 format = 0;
00185 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00186 G_debug(1, "open format file: '%s/%s/%s'", Map->mapset, buf,
00187 GRASS_VECT_FRMT_ELEMENT);
00188 fp = G_fopen_old(buf, GRASS_VECT_FRMT_ELEMENT, Map->mapset);
00189 if (fp == NULL) {
00190 G_debug(1, "Vector format: %d (native)", format);
00191 format = GV_FORMAT_NATIVE;
00192 }
00193 else {
00194 format = dig_read_frmt_ascii(fp, &(Map->fInfo));
00195 fclose(fp);
00196
00197 G_debug(1, "Vector format: %d (non-native)", format);
00198 if (format < 0) {
00199 sprintf(errmsg, _("Unable to open vector map <%s>"),
00200 Vect_get_full_name(Map));
00201 fatal_error(ferror, errmsg);
00202 return -1;
00203 }
00204 }
00205
00206 Map->format = format;
00207
00208
00209 if (Vect__read_head(Map) != GRASS_OK) {
00210 sprintf(errmsg,
00211 _("Unable to open vector map <%s> on level %d. "
00212 "Try to rebuild vector topology by v.build."),
00213 Vect_get_full_name(Map), level_request);
00214 G_warning(_("Unable to read head file"));
00215 }
00216
00217 G_debug(1, "Level request = %d", level_request);
00218
00219
00220
00221
00222
00223
00224
00225
00226 if (level_request == 0 || level_request == 2) {
00227 level = 2;
00228
00229 ret = Vect_open_topo(Map, head_only);
00230 if (ret == 1) {
00231 G_debug(1, "Topo file for vector '%s' not available.",
00232 Vect_get_full_name(Map));
00233 level = 1;
00234 }
00235 else if (ret == -1) {
00236 G_fatal_error(_("Unable to open topology file for vector map <%s>"),
00237 Vect_get_full_name(Map));
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 if (level == 2) {
00252 ret = Vect_cidx_open(Map, head_only);
00253 if (ret == 1) {
00254 G_debug(1,
00255 "Category index file for vector '%s' not available.",
00256 Vect_get_full_name(Map));
00257 dig_free_plus(&(Map->plus));
00258 dig_spidx_free(&(Map->plus));
00259 level = 1;
00260 }
00261 else if (ret == -1) {
00262 G_fatal_error(_("Unable to open category index file for vector map <%s>"),
00263 Vect_get_full_name(Map));
00264 }
00265 }
00266 #ifdef HAVE_OGR
00267
00268 if (level == 2 && Map->format == GV_FORMAT_OGR) {
00269 if (V2_open_old_ogr(Map) < 0) {
00270 dig_free_plus(&(Map->plus));
00271 dig_spidx_free(&(Map->plus));
00272 dig_cidx_free(&(Map->plus));
00273 level = 1;
00274 }
00275 }
00276 #endif
00277 if (level_request == 2 && level < 2) {
00278 sprintf(errmsg,
00279 _("Unable to open vector map <%s> on level %d. "
00280 "Try to rebuild vector topology by v.build."),
00281 Vect_get_full_name(Map), level_request);
00282 fatal_error(ferror, errmsg);
00283 return -1;
00284 }
00285 }
00286 else {
00287 level = 1;
00288 }
00289
00290
00291 if (!head_only) {
00292 if (0 != (*Open_old_array[format][1]) (Map, update)) {
00293 if (level == 2) {
00294 dig_free_plus(&(Map->plus));
00295 dig_spidx_free(&(Map->plus));
00296 dig_cidx_free(&(Map->plus));
00297 }
00298 sprintf(errmsg,
00299 _("Unable to open vector map <%s> on level %d. "
00300 "Try to rebuild vector topology by v.build."),
00301 Vect_get_full_name(Map), level_request);
00302 fatal_error(ferror, errmsg);
00303 return -1;
00304 }
00305 }
00306 else {
00307 Map->head.with_z = Map->plus.with_z;
00308 }
00309
00310
00311 Map->open = VECT_OPEN_CODE;
00312 Map->level = level;
00313 Map->head_only = head_only;
00314 Map->support_updated = 0;
00315 if (update) {
00316 Map->mode = GV_MODE_RW;
00317 Map->plus.mode = GV_MODE_RW;
00318 }
00319 else {
00320 Map->mode = GV_MODE_READ;
00321 Map->plus.mode = GV_MODE_READ;
00322 }
00323 if (head_only) {
00324 Map->head_only = 1;
00325 }
00326 else {
00327 Map->head_only = 0;
00328 }
00329
00330 Map->Constraint_region_flag = 0;
00331 Map->Constraint_type_flag = 0;
00332 G_debug(1, "Vect_open_old(): vector opened on level %d", level);
00333
00334 if (level == 1) {
00335 Map->plus.built = GV_BUILD_NONE;
00336 }
00337 else {
00338 Map->plus.built = GV_BUILD_ALL;
00339 }
00340
00341 Map->plus.do_uplist = 0;
00342
00343 Map->dblnk = Vect_new_dblinks_struct();
00344 Vect_read_dblinks(Map);
00345
00346
00347 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00348
00349 if (update) {
00350 Map->hist_fp = G_fopen_modify(buf, GRASS_VECT_HIST_ELEMENT);
00351 if (Map->hist_fp == NULL) {
00352 sprintf(errmsg,
00353 _("Unable to open history file for vector map <%s>"),
00354 Vect_get_full_name(Map));
00355 fatal_error(ferror, errmsg);
00356 return (-1);
00357 }
00358 fseek(Map->hist_fp, (long)0, SEEK_END);
00359 Vect_hist_write(Map,
00360 "---------------------------------------------------------------------------------\n");
00361
00362 }
00363 else {
00364 if (Map->format == GV_FORMAT_NATIVE || Map->format == GV_FORMAT_OGR) {
00365 Map->hist_fp =
00366 G_fopen_old(buf, GRASS_VECT_HIST_ELEMENT, Map->mapset);
00367
00368 }
00369 else {
00370 Map->hist_fp = NULL;
00371 }
00372 }
00373
00374 if (!head_only) {
00375 Vect_rewind(Map);
00376 }
00377
00378
00379 if (update && !head_only) {
00380 char file_path[2000];
00381 struct stat info;
00382
00383 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, name);
00384
00385 G__file_name(file_path, buf, GV_TOPO_ELEMENT, G_mapset());
00386 if (stat(file_path, &info) == 0)
00387 unlink(file_path);
00388
00389 G__file_name(file_path, buf, GV_SIDX_ELEMENT, G_mapset());
00390 if (stat(file_path, &info) == 0)
00391 unlink(file_path);
00392
00393 G__file_name(file_path, buf, GV_CIDX_ELEMENT, G_mapset());
00394 if (stat(file_path, &info) == 0)
00395 unlink(file_path);
00396 }
00397
00398 return (level);
00399 }
00400
00413 int Vect_open_old(struct Map_info *Map, const char *name, const char *mapset)
00414 {
00415 return (Vect__open_old(Map, name, mapset, 0, 0));
00416 }
00417
00430 int
00431 Vect_open_update(struct Map_info *Map, const char *name, const char *mapset)
00432 {
00433 int ret;
00434
00435 ret = Vect__open_old(Map, name, mapset, 1, 0);
00436
00437 if (ret > 0) {
00438 Map->plus.do_uplist = 1;
00439
00440 Map->plus.uplines = NULL;
00441 Map->plus.n_uplines = 0;
00442 Map->plus.alloc_uplines = 0;
00443 Map->plus.upnodes = NULL;
00444 Map->plus.n_upnodes = 0;
00445 Map->plus.alloc_upnodes = 0;
00446
00447
00448 Vect_build_sidx_from_topo(Map);
00449 }
00450
00451 return ret;
00452 }
00453
00467 int
00468 Vect_open_old_head(struct Map_info *Map, const char *name, const char *mapset)
00469 {
00470 return (Vect__open_old(Map, name, mapset, 0, 1));
00471 }
00472
00485 int
00486 Vect_open_update_head(struct Map_info *Map, const char *name,
00487 const char *mapset)
00488 {
00489 int ret;
00490
00491 ret = Vect__open_old(Map, name, mapset, 1, 1);
00492
00493 if (ret > 0) {
00494 Map->plus.do_uplist = 1;
00495
00496 Map->plus.uplines = NULL;
00497 Map->plus.n_uplines = 0;
00498 Map->plus.alloc_uplines = 0;
00499 Map->plus.upnodes = NULL;
00500 Map->plus.n_upnodes = 0;
00501 Map->plus.alloc_upnodes = 0;
00502 }
00503
00504 return ret;
00505 }
00506
00517 int Vect_open_new(struct Map_info *Map, const char *name, int with_z)
00518 {
00519 int ret, ferror;
00520 char errmsg[2000], buf[200];
00521 char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
00522
00523 G_debug(2, "Vect_open_new(): name = %s", name);
00524
00525 Vect__init_head(Map);
00526 ferror = Vect_get_fatal_error();
00527 Vect_set_fatal_error(GV_FATAL_EXIT);
00528
00529 if (G__name_is_fully_qualified(name, xname, xmapset)) {
00530 if (strcmp(xmapset, G_mapset()) != 0) {
00531 sprintf(errmsg, _("%s is not in the current mapset (%s)"), name,
00532 G_mapset());
00533 fatal_error(ferror, errmsg);
00534 }
00535 name = xname;
00536 }
00537
00538
00539 if (Vect_legal_filename(name) < 0) {
00540 sprintf(errmsg, _("Vector map name is not SQL compliant"));
00541 fatal_error(ferror, errmsg);
00542 return (-1);
00543 }
00544
00545
00546 if (G_find_file2(GRASS_VECT_DIRECTORY, name, G_mapset()) != NULL) {
00547 G_warning(_("Vector map <%s> already exists and will be overwritten"),
00548 name);
00549
00550 ret = Vect_delete(name);
00551 if (ret == -1) {
00552 sprintf(errmsg, _("Unable to delete vector map <%s>"), name);
00553 fatal_error(ferror, errmsg);
00554 return (-1);
00555 }
00556 }
00557
00558 Map->name = G_store(name);
00559 Map->mapset = G_store(G_mapset());
00560 Map->location = G_store(G_location());
00561 Map->gisdbase = G_store(G_gisdbase());
00562
00563 Map->format = GV_FORMAT_NATIVE;
00564
00565 if (V1_open_new_nat(Map, name, with_z) < 0) {
00566 sprintf(errmsg, _("Unable to create vector map <%s>"),
00567 Vect_get_full_name(Map));
00568 fatal_error(ferror, errmsg);
00569 return (-1);
00570 }
00571
00572
00573 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00574 Map->hist_fp = G_fopen_new(buf, GRASS_VECT_HIST_ELEMENT);
00575 if (Map->hist_fp == NULL) {
00576 sprintf(errmsg, _("Unable to open history file for vector map <%s>"),
00577 Vect_get_full_name(Map));
00578 fatal_error(ferror, errmsg);
00579 return (-1);
00580 }
00581
00582 Open_level = 0;
00583
00584 dig_init_plus(&(Map->plus));
00585
00586 Map->open = VECT_OPEN_CODE;
00587 Map->level = 1;
00588 Map->head_only = 0;
00589 Map->support_updated = 0;
00590 Map->plus.built = GV_BUILD_NONE;
00591 Map->mode = GV_MODE_RW;
00592 Map->Constraint_region_flag = 0;
00593 Map->Constraint_type_flag = 0;
00594 Map->head.with_z = with_z;
00595 Map->plus.do_uplist = 0;
00596
00597 Map->dblnk = Vect_new_dblinks_struct();
00598
00599 return 1;
00600 }
00601
00611 int Vect_coor_info(struct Map_info *Map, struct Coor_info *Info)
00612 {
00613 char buf[2000], path[2000];
00614 struct stat stat_buf;
00615
00616 switch (Map->format) {
00617 case GV_FORMAT_NATIVE:
00618 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00619 G__file_name(path, buf, GRASS_VECT_COOR_ELEMENT, Map->mapset);
00620 G_debug(1, "get coor info: %s", path);
00621 if (0 != stat(path, &stat_buf)) {
00622 G_warning(_("Unable to stat file <%s>"), path);
00623 Info->size = -1L;
00624 Info->mtime = -1L;
00625 }
00626 else {
00627 Info->size = (long)stat_buf.st_size;
00628 Info->mtime = (long)stat_buf.st_mtime;
00629 }
00630
00631
00632 #ifdef __MINGW32__
00633 if (Map->open == VECT_OPEN_CODE) {
00634 dig_fseek(&(Map->dig_fp), 0L, SEEK_END);
00635 G_debug(2, "ftell = %d", dig_ftell(&(Map->dig_fp)));
00636 Info->size = dig_ftell(&(Map->dig_fp));
00637 }
00638 #endif
00639 break;
00640 case GV_FORMAT_OGR:
00641 Info->size = 0L;
00642 Info->mtime = 0L;
00643 break;
00644 }
00645 G_debug(1, "Info->size = %ld, Info->mtime = %ld", Info->size,
00646 Info->mtime);
00647
00648 return 1;
00649 }
00650
00659 const char *Vect_maptype_info(struct Map_info *Map)
00660 {
00661 char maptype[1000];
00662
00663 switch (Map->format) {
00664 case GV_FORMAT_NATIVE:
00665 sprintf(maptype, "native");
00666 break;
00667 case GV_FORMAT_OGR:
00668 sprintf(maptype, "ogr");
00669 break;
00670 default:
00671 sprintf(maptype, "unknown %d (update Vect_maptype_info)",
00672 Map->format);
00673 }
00674
00675 return G_store(maptype);
00676 }
00677
00678
00689 int Vect_open_topo(struct Map_info *Map, int head_only)
00690 {
00691 int err, ret;
00692 char buf[500], file_path[2000];
00693 GVFILE fp;
00694 struct Coor_info CInfo;
00695 struct Plus_head *Plus;
00696 struct stat info;
00697
00698 G_debug(1, "Vect_open_topo(): name = %s mapset= %s", Map->name,
00699 Map->mapset);
00700
00701 Plus = &(Map->plus);
00702
00703 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00704 G__file_name(file_path, buf, GV_TOPO_ELEMENT, Map->mapset);
00705
00706 if (stat(file_path, &info) != 0)
00707 return 1;
00708
00709 dig_file_init(&fp);
00710 fp.file = G_fopen_old(buf, GV_TOPO_ELEMENT, Map->mapset);
00711
00712 if (fp.file == NULL) {
00713 G_debug(1, "Cannot open topo file for vector '%s@%s'.",
00714 Map->name, Map->mapset);
00715 return -1;
00716 }
00717
00718
00719 Vect_coor_info(Map, &CInfo);
00720
00721
00722 if (dig_Rd_Plus_head(&fp, Plus) == -1)
00723 return -1;
00724
00725 G_debug(1, "Topo head: coor size = %ld, coor mtime = %ld",
00726 Plus->coor_size, Plus->coor_mtime);
00727
00728
00729 err = 0;
00730 if (CInfo.size != Plus->coor_size) {
00731 G_warning(_("Size of 'coor' file differs from value saved in topology file"));
00732 err = 1;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741 if (err) {
00742 G_warning(_("Please rebuild topology for vector map <%s@%s>"),
00743 Map->name, Map->mapset);
00744 return -1;
00745 }
00746
00747
00748
00749
00750
00751 ret = dig_load_plus(Plus, &fp, head_only);
00752
00753 fclose(fp.file);
00754
00755
00756 if (ret == 0)
00757 return -1;
00758
00759 return 0;
00760 }
00761
00770 int Vect_open_spatial_index(struct Map_info *Map)
00771 {
00772 char buf[500];
00773 GVFILE fp;
00774
00775
00776 struct Plus_head *Plus;
00777
00778 G_debug(1, "Vect_open_spatial_index(): name = %s mapset= %s", Map->name,
00779 Map->mapset);
00780
00781 Plus = &(Map->plus);
00782
00783 sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
00784 dig_file_init(&fp);
00785 fp.file = G_fopen_old(buf, GV_SIDX_ELEMENT, Map->mapset);
00786
00787 if (fp.file == NULL) {
00788 G_debug(1, "Cannot open spatial index file for vector '%s@%s'.",
00789 Map->name, Map->mapset);
00790 return -1;
00791 }
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828 dig_spidx_init(Plus);
00829 dig_read_spidx(&fp, Plus);
00830
00831 fclose(fp.file);
00832
00833
00834 return 0;
00835 }