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 <dirent.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include "glocale.h"
00025 #include "gis.h"
00026 #include "Vect.h"
00027 #include "dbmi.h"
00028
00035 int
00036 Vect_copy_map_lines ( struct Map_info *In, struct Map_info *Out )
00037 {
00038 int i, type, nlines, ret;
00039 struct line_pnts *Points;
00040 struct line_cats *Cats;
00041
00042 Points = Vect_new_line_struct ();
00043 Cats = Vect_new_cats_struct ();
00044
00045 if ( Vect_level ( In ) < 1 )
00046 G_fatal_error ("Vect_copy_map_lines(): input vector is not open");
00047
00048 ret = 0;
00049
00050
00051 if ( Vect_level ( In ) >= 2 ) {
00052 nlines = Vect_get_num_lines ( In );
00053 for ( i = 1; i <= nlines; i++ ) {
00054 type = Vect_read_line (In, Points, Cats, i);
00055 if ( type == -1 ) {
00056 G_warning ("Cannot read vector file\n" );
00057 ret = 1;
00058 break;
00059 }
00060 if ( type == 0 ) continue;
00061
00062 Vect_write_line ( Out, type, Points, Cats );
00063 }
00064 } else {
00065 Vect_rewind ( In );
00066 while ( 1 ) {
00067 type = Vect_read_next_line (In, Points, Cats);
00068 if ( type == -1 ) {
00069 G_warning ("Cannot read vector file\n" );
00070 ret = 1;
00071 break;
00072 } else if ( type == -2 ) {
00073 break;
00074 } else if ( type == 0 ) {
00075 continue;
00076 }
00077 Vect_write_line ( Out, type, Points, Cats );
00078 }
00079 }
00080 Vect_destroy_line_struct (Points);
00081 Vect_destroy_cats_struct (Cats);
00082
00083 return ret;
00084 }
00085
00095 int
00096 Vect_copy ( char *in, char *mapset, char *out, FILE *msgout )
00097 {
00098 int i, n, ret, type;
00099 struct Map_info In, Out;
00100 struct field_info *Fi, *Fin;
00101 char old_path[1000], new_path[1000], cmd[2000];
00102 struct stat info;
00103 dbDriver *driver;
00104
00105 G_debug (3, "Copy vector '%s' in '%s' to '%s'", in, mapset, out );
00106
00107
00108 if ( G_find_vector2(out, G_mapset()) ) {
00109 G_warning (_("The vector '%s' already exists and will be overwritten."), out);
00110 ret = Vect_delete ( out );
00111 if ( ret != 0 ) {
00112 G_warning ( "Cannot copy vector" );
00113 return -1;
00114 }
00115 }
00116
00117
00118 G__make_mapset_element ( GRASS_VECT_DIRECTORY );
00119 G__file_name (old_path, GRASS_VECT_DIRECTORY, in, mapset );
00120 G__file_name (new_path, GRASS_VECT_DIRECTORY, out, G_mapset() );
00121 sprintf ( cmd, "cp -r '%s' '%s'", old_path, new_path );
00122 G_debug (2, "system: %s", cmd );
00123 ret = system ( cmd );
00124
00125 if (ret != 0 ) {
00126 G_warning ( "Cannot copy vector" );
00127 return -1;
00128 }
00129
00130
00131 sprintf (old_path, "%s/%s", GRASS_VECT_DIRECTORY, out);
00132 G__file_name ( new_path, old_path, GRASS_VECT_DBLN_ELEMENT, G_mapset ());
00133
00134 if (stat (new_path, &info) == 0)
00135 unlink (new_path);
00136
00137
00138 Vect_set_open_level (1);
00139 Vect_open_old_head (&In, in, mapset);
00140
00141 if ( In.format != GV_FORMAT_NATIVE ) {
00142 Vect_close ( &In );
00143 return 0;
00144 }
00145
00146
00147 Vect_open_update_head ( &Out, out, G_mapset() );
00148
00149
00150 n = Vect_get_num_dblinks ( &In );
00151 type = GV_1TABLE;
00152 if ( n > 1 ) type = GV_MTABLE;
00153 for ( i = 0; i < n; i++ ) {
00154 Fi = Vect_get_dblink ( &In, i );
00155 if ( Fi == NULL ) {
00156 G_warning ( "Cannot get db link info" );
00157 Vect_close ( &In );
00158 Vect_close ( &Out );
00159 return -1;
00160 }
00161 Fin = Vect_default_field_info ( &Out, Fi->number, Fi->name, type );
00162 G_debug (3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
00163 Fi->driver, Fi->database, Fi->table, Fin->driver, Fin->database, Fin->table );
00164 Vect_map_add_dblink ( &Out, Fi->number, Fi->name, Fin->table, Fi->key, Fin->database, Fin->driver);
00165
00166 ret = db_copy_table ( Fi->driver, Fi->database, Fi->table,
00167 Fin->driver, Vect_subst_var(Fin->database,&Out), Fin->table );
00168 if ( ret == DB_FAILED ) {
00169 G_warning ( "Cannot copy table" );
00170 Vect_close ( &In );
00171 Vect_close ( &Out );
00172 return -1;
00173 }
00174
00175 driver = db_start_driver_open_database ( Fin->driver, Vect_subst_var(Fin->database,&Out) );
00176 if ( driver == NULL ) {
00177 G_warning ( "Cannot open database -> create index" );
00178 } else {
00179 if ( db_create_index2(driver, Fin->table, Fi->key ) != DB_OK )
00180 G_warning ( "Cannot create index" );
00181
00182 db_close_database_shutdown_driver ( driver );
00183 }
00184 }
00185
00186 Vect_close ( &In );
00187 Vect_close ( &Out );
00188
00189 return 0;
00190 }
00191
00202 int
00203 Vect_rename ( char *in, char *out, FILE *msgout )
00204 {
00205 int i, n, ret, type;
00206 struct Map_info Map;
00207 struct field_info *Fin, *Fout;
00208 int *fields;
00209 dbDriver *driver;
00210
00211 G_debug (2, "Rename vector '%s' to '%s'", in, out );
00212
00213
00214 if ( G_find_vector2(out, G_mapset()) ) {
00215 G_warning (_("The vector '%s' already exists and will be overwritten."), out);
00216 Vect_delete ( out );
00217 }
00218
00219
00220 ret = G_rename ( GRASS_VECT_DIRECTORY, in, out );
00221
00222 if ( ret == 0 ) {
00223 G_warning (_("Input vector '%s' not found"), in );
00224 return -1;
00225 } else if ( ret == -1 ) {
00226 G_warning (_("Cannot copy vector '%s' to '%s'"), in, out );
00227 return -1;
00228 }
00229
00230
00231 Vect_set_open_level (1);
00232 Vect_open_update_head ( &Map, out, G_mapset() );
00233
00234 if ( Map.format != GV_FORMAT_NATIVE ) {
00235 Vect_close ( &Map );
00236 return 0;
00237 }
00238
00239
00240 n = Vect_get_num_dblinks ( &Map );
00241 type = GV_1TABLE;
00242 if ( n > 1 ) type = GV_MTABLE;
00243
00244
00245 fields = (int *) G_malloc ( n * sizeof(int) );
00246
00247 for ( i = 0; i < n; i++ ) {
00248 Fin = Vect_get_dblink ( &Map, i );
00249
00250 fields[i] = Fin->number;
00251 }
00252
00253 for ( i = 0; i < n; i++ ) {
00254 G_debug (3, "field[%d] = %d", i, fields[i] );
00255
00256 Fin = Vect_get_field ( &Map, fields[i] );
00257 if ( Fin == NULL ) {
00258 G_warning ( "Cannot get db link info" );
00259 Vect_close ( &Map );
00260 return -1;
00261 }
00262
00263 Fout = Vect_default_field_info ( &Map, Fin->number, Fin->name, type );
00264 G_debug (3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
00265 Fin->driver, Fin->database, Fin->table, Fout->driver, Fout->database, Fout->table );
00266
00267
00268 ret = db_copy_table ( Fin->driver, Fin->database, Fin->table,
00269 Fout->driver, Vect_subst_var(Fout->database,&Map), Fout->table );
00270
00271 if ( ret == DB_FAILED ) {
00272 G_warning ( "Cannot copy table" );
00273 Vect_close ( &Map );
00274 return -1;
00275 }
00276
00277
00278 Vect_map_del_dblink ( &Map, Fin->number );
00279
00280 Vect_map_add_dblink ( &Map, Fout->number, Fout->name, Fout->table, Fin->key,
00281 Fout->database, Fout->driver);
00282
00283
00284 ret = db_delete_table ( Fin->driver, Fin->database, Fin->table );
00285 if ( ret == DB_FAILED ) {
00286 G_warning ( "Cannot delete table" );
00287 Vect_close ( &Map );
00288 return -1;
00289 }
00290
00291 driver = db_start_driver_open_database ( Fout->driver, Vect_subst_var(Fout->database, &Map) );
00292 if ( driver == NULL ) {
00293 G_warning ( "Cannot open database -> create index" );
00294 } else {
00295 if ( db_create_index2(driver, Fout->table, Fin->key ) != DB_OK )
00296 G_warning ( "Cannot create index" );
00297
00298 db_close_database_shutdown_driver ( driver );
00299 }
00300 }
00301
00302 Vect_close ( &Map );
00303 free ( fields );
00304
00305 return 0;
00306 }
00307
00314 int
00315 Vect_delete ( char *map )
00316 {
00317 int i, n, ret;
00318 struct Map_info Map;
00319 struct field_info *Fi;
00320 char buf[5000];
00321 DIR *dir;
00322 struct dirent *ent;
00323
00324 G_debug (3, "Delete vector '%s'", map );
00325
00326 G_chop ( map );
00327
00328 if ( map == NULL || strlen ( map ) == 0 ) {
00329 G_warning ( "Wrong map name '%s'", map );
00330 return -1;
00331 }
00332
00333
00334 Vect_set_open_level (1);
00335 ret = Vect_open_old_head (&Map, map, G_mapset());
00336 if ( ret < 1 ) {
00337 G_warning ( "Cannot open vector %s", map );
00338 return -1;
00339 }
00340
00341
00342 if ( Map.format == GV_FORMAT_NATIVE ) {
00343
00344 n = Vect_get_num_dblinks ( &Map );
00345 for ( i = 0; i < n; i++ ) {
00346 Fi = Vect_get_dblink ( &Map, i );
00347 if ( Fi == NULL ) {
00348 G_warning ( "Cannot get db link info" );
00349 Vect_close ( &Map );
00350 return -1;
00351 }
00352 G_debug (3, "Delete drv:db:table '%s:%s:%s'", Fi->driver, Fi->database, Fi->table);
00353
00354 ret = db_table_exists ( Fi->driver, Fi->database, Fi->table );
00355 if ( ret == -1 ) {
00356 G_warning ( "Cannot get info if table '%s' linked to vector exists.", Fi->table );
00357 Vect_close ( &Map );
00358 return -1;
00359 }
00360
00361 if ( ret == 1 ) {
00362 ret = db_delete_table ( Fi->driver, Fi->database, Fi->table );
00363 if ( ret == DB_FAILED ) {
00364 G_warning ( "Cannot delete table" );
00365 Vect_close ( &Map );
00366 return -1;
00367 }
00368 } else {
00369 G_warning ( "Table '%s' linked to vector did not exist.", Fi->table );
00370 }
00371 }
00372 }
00373
00374 Vect_close ( &Map );
00375
00376
00377 sprintf ( buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map );
00378 G_debug (3, "opendir '%s'", buf );
00379 dir = opendir( buf );
00380 if (dir == NULL) {
00381 G_warning ( "Cannot open directory '%s'", buf );
00382 return -1;
00383 }
00384
00385 while ( (ent = readdir (dir)) ) {
00386 G_debug (3, "file = '%s'", ent->d_name );
00387 if ( (strcmp (ent->d_name, ".") == 0) || (strcmp (ent->d_name, "..") == 0) ) continue;
00388 sprintf ( buf, "%s/%s/vector/%s/%s", G_location_path(), G_mapset(), map, ent->d_name );
00389 G_debug (3, "delete file '%s'", buf );
00390 ret = unlink ( buf );
00391 if ( ret == -1 ) {
00392 G_warning ( "Cannot delete file '%s'", buf );
00393 closedir (dir);
00394 return -1;
00395 }
00396 }
00397 closedir (dir);
00398
00399
00400 sprintf ( buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map );
00401 G_debug (3, "opendir '%s'", buf );
00402 dir = opendir( buf );
00403 if (dir == NULL) {
00404 G_warning ( "Cannot open directory '%s'", buf );
00405 return -1;
00406 }
00407 while ( (ent = readdir (dir)) ) {
00408 G_debug (3, "file = '%s'", ent->d_name );
00409 if ( (strcmp (ent->d_name, ".") == 0) || (strcmp (ent->d_name, "..") == 0) ) continue;
00410 sprintf ( buf, "%s/%s/vector/%s/%s", G_location_path(), G_mapset(), map, ent->d_name );
00411 G_debug (3, "delete file '%s'", buf );
00412 ret = unlink ( buf );
00413 if ( ret == -1 ) {
00414 G_warning ( "Cannot delete file '%s'", buf );
00415 closedir (dir);
00416 return -1;
00417 }
00418 }
00419 closedir (dir);
00420
00421 sprintf ( buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map );
00422 G_debug (3, "delete directory '%s'", buf );
00423 ret = rmdir ( buf );
00424 if ( ret == -1 ) {
00425 G_warning ( "Cannot delete directory '%s'", buf );
00426 return -1;
00427 }
00428
00429 return 0;
00430 }
00431
00438 int
00439 Vect_copy_tables ( struct Map_info *In, struct Map_info *Out, int field )
00440 {
00441 int i, n, ret, type;
00442 struct field_info *Fi, *Fin;
00443 dbDriver *driver;
00444
00445 G_debug (2, "Vect_copy_tables()");
00446
00447 n = Vect_get_num_dblinks ( In );
00448 type = GV_1TABLE;
00449 if ( n > 1 ) type = GV_MTABLE;
00450
00451 for ( i = 0; i < n; i++ ) {
00452 Fi = Vect_get_dblink ( In, i );
00453 if ( Fi == NULL ) {
00454 G_warning ( "Cannot get db link info" );
00455 return -1;
00456 }
00457 if ( field > 0 && Fi->number != field ) continue;
00458
00459 Fin = Vect_default_field_info ( Out, Fi->number, Fi->name, type );
00460 G_debug (2, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
00461 Fi->driver, Fi->database, Fi->table, Fin->driver, Fin->database, Fin->table );
00462
00463 ret = Vect_map_add_dblink ( Out, Fi->number, Fi->name, Fin->table, Fi->key, Fin->database, Fin->driver);
00464 if ( ret == -1 ) {
00465 G_warning ( "Cannot add database link" );
00466 return -1;
00467 }
00468
00469 ret = db_copy_table ( Fi->driver, Fi->database, Fi->table,
00470 Fin->driver, Vect_subst_var(Fin->database,Out), Fin->table );
00471 if ( ret == DB_FAILED ) {
00472 G_warning ( "Cannot copy table" );
00473 return -1;
00474 }
00475
00476 driver = db_start_driver_open_database ( Fin->driver, Vect_subst_var(Fin->database,Out) );
00477 if ( driver == NULL ) {
00478 G_warning ( "Cannot open database -> create index" );
00479 } else {
00480 if ( db_create_index2(driver, Fin->table, Fi->key ) != DB_OK )
00481 G_warning ( "Cannot create index" );
00482
00483 db_close_database_shutdown_driver ( driver );
00484 }
00485 }
00486
00487 return 0;
00488 }
00489
00502 int
00503 Vect_copy_table ( struct Map_info *In, struct Map_info *Out, int field_in,
00504 int field_out, char *field_name, int type )
00505 {
00506 return Vect_copy_table_by_cats ( In, Out, field_in, field_out, field_name, type, NULL, 0);
00507 }
00508
00523 int
00524 Vect_copy_table_by_cats ( struct Map_info *In, struct Map_info *Out, int field_in,
00525 int field_out, char *field_name, int type, int *cats, int ncats )
00526 {
00527 int ret;
00528 struct field_info *Fi, *Fin;
00529 char *name, *key;
00530
00531 G_debug (2, "Vect_copy_table(): field_in = %d field_out = %d", field_in, field_out);
00532
00533 Fi = Vect_get_field ( In, field_in );
00534 if ( Fi == NULL ) {
00535 G_warning ( "Cannot get db link info" );
00536 return -1;
00537 }
00538
00539 if ( field_name != NULL ) name = field_name;
00540 else name = Fi->name;
00541
00542 Fin = Vect_default_field_info ( Out, field_out, name, type );
00543 G_debug (3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
00544 Fi->driver, Fi->database, Fi->table, Fin->driver, Fin->database, Fin->table );
00545
00546 ret = Vect_map_add_dblink ( Out, Fin->number, Fin->name, Fin->table, Fi->key, Fin->database, Fin->driver);
00547 if ( ret == -1 ) {
00548 G_warning ( "Cannot add database link" );
00549 return -1;
00550 }
00551
00552 if ( cats )
00553 key = Fi->key;
00554 else
00555 key = NULL;
00556
00557 ret = db_copy_table_by_ints ( Fi->driver, Fi->database, Fi->table,
00558 Fin->driver, Vect_subst_var(Fin->database,Out), Fin->table, key, cats, ncats );
00559 if ( ret == DB_FAILED ) {
00560 G_warning ( "Cannot copy table" );
00561 return -1;
00562 }
00563
00564 return 0;
00565 }
00566
00572 void
00573 Vect_set_release_support ( struct Map_info * Map )
00574 {
00575 Map->plus.release_support = 1;
00576 }
00577
00585 void
00586 Vect_set_category_index_update ( struct Map_info * Map )
00587 {
00588 Map->plus.update_cidx = 1;
00589 }
00590