open.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. /*!
  2. * \file open.c
  3. *
  4. * \brief Vector library - Open vector map
  5. *
  6. * Higher level functions for reading/writing/manipulating vectors.
  7. *
  8. * (C) 2001-2008 by the GRASS Development Team
  9. *
  10. * This program is free software under the
  11. * GNU General Public License (>=v2).
  12. * Read the file COPYING that comes with GRASS
  13. * for details.
  14. *
  15. * \author Original author CERL, probably Dave Gerdes or Mike
  16. * Higgins. Update to GRASS 5.7 Radim Blazek and David D. Gray.
  17. *
  18. * \date 2001-2008
  19. */
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #include <grass/glocale.h>
  27. #include <grass/gis.h>
  28. #include <grass/Vect.h>
  29. #define MAX_OPEN_LEVEL 2
  30. static int open_old_dummy () { return 0; }
  31. #ifndef HAVE_OGR
  32. static int format () { G_fatal_error (_("Requested format is not compiled in this version")); return 0; }
  33. #endif
  34. static int Open_level = 0;
  35. static int (*Open_old_array[][2]) () =
  36. {
  37. { open_old_dummy, V1_open_old_nat }
  38. #ifdef HAVE_OGR
  39. ,{ open_old_dummy, V1_open_old_ogr }
  40. #else
  41. ,{ open_old_dummy, format }
  42. #endif
  43. };
  44. static void
  45. fatal_error ( int ferror, char *errmsg )
  46. {
  47. switch ( ferror ) {
  48. case GV_FATAL_EXIT:
  49. G_fatal_error ( errmsg );
  50. break;
  51. case GV_FATAL_PRINT:
  52. G_warning ( errmsg );
  53. break;
  54. case GV_FATAL_RETURN:
  55. break;
  56. }
  57. }
  58. /*!
  59. * \brief Predetermine level at which a map will be opened for
  60. * reading.
  61. *
  62. * If it can't open that level, the open will fail. The specified
  63. * level must be set before any call to open. The default is to try
  64. * to open the highest level possible, and keep stepping down until
  65. * success.
  66. *
  67. * NOTE!! This should only be used to set when you wish to force
  68. * a lower level open. If you require a higher level, then just
  69. * check the return to verify the level instead of forcing it.
  70. * This is because future releases will have higher levels which
  71. * will be downward compatible and which your programs should
  72. * support by default.
  73. *
  74. * \param[in] level vector (topo) level
  75. *
  76. * \return 0 on success
  77. * \return 1 on error
  78. */
  79. int
  80. Vect_set_open_level (int level)
  81. {
  82. Open_level = level;
  83. if (Open_level < 1 || Open_level > MAX_OPEN_LEVEL)
  84. {
  85. G_warning (_("Programmer requested unknown open level %d"), Open_level);
  86. Open_level = 0;
  87. return 1;
  88. }
  89. return 0;
  90. }
  91. /*!
  92. * \brief Open old vector for reading.
  93. *
  94. * In case of error, the functions respect fatal error settings.
  95. *
  96. * \param[out] Map vector map
  97. * \param[in] name name of vector map to open
  98. * \param[in] mapset mapset name
  99. * \param[in] update open for update
  100. * \param[in] head_only read only header info from 'head', 'dbln', 'topo', 'cidx' is not opened. The header may be opened on level 2 only.
  101. *
  102. * \return level of openness (1, 2)
  103. * \return -1 in error
  104. */
  105. int
  106. Vect__open_old ( struct Map_info *Map, const char *name, const char *mapset, int update, int head_only )
  107. {
  108. char buf[GNAME_MAX+10], buf2[GMAPSET_MAX+10], xname[GNAME_MAX], xmapset[GMAPSET_MAX], errmsg[2000];
  109. FILE *fp;
  110. int level, level_request, ferror;
  111. int format, ret;
  112. char *fmapset;
  113. G_debug (1, "Vect_open_old(): name = %s mapset= %s update = %d", name, mapset, update);
  114. /* TODO: Open header for update ('dbln') */
  115. ferror = Vect_get_fatal_error ();
  116. Vect_set_fatal_error (GV_FATAL_EXIT);
  117. level_request = Open_level;
  118. Open_level = 0;
  119. Vect__init_head (Map);
  120. dig_init_plus ( &(Map->plus) );
  121. if (G__name_is_fully_qualified (name, xname, xmapset)) {
  122. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, xname);
  123. sprintf (buf2, "%s@%s", GRASS_VECT_COOR_ELEMENT, xmapset);
  124. Map->name = G_store (xname);
  125. Map->mapset = G_store (xmapset);
  126. } else {
  127. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, name);
  128. sprintf (buf2, "%s", GRASS_VECT_COOR_ELEMENT);
  129. Map->name = G_store (name);
  130. if ( mapset )
  131. Map->mapset = G_store (mapset);
  132. else
  133. Map->mapset = G_store ("");
  134. }
  135. fmapset = G_find_vector2 ( Map->name, Map->mapset );
  136. if ( fmapset == NULL ) {
  137. sprintf ( errmsg, _("Vector map <%s> not found"), Vect_get_full_name(Map) );
  138. fatal_error (ferror, errmsg);
  139. return -1;
  140. }
  141. Map->mapset = G_store ( fmapset );
  142. Map->location = G_store ( G_location() );
  143. Map->gisdbase = G_store ( G_gisdbase() );
  144. if ( update && (0 != strcmp(Map->mapset, G_mapset()) ) ) {
  145. G_warning ( _("Vector map which is not in the current mapset cannot be opened for update") );
  146. return -1;
  147. }
  148. /* Read vector format information */
  149. format = 0;
  150. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
  151. G_debug (1, "open format file: '%s/%s/%s'", Map->mapset, buf, GRASS_VECT_FRMT_ELEMENT);
  152. fp = G_fopen_old (buf, GRASS_VECT_FRMT_ELEMENT, Map->mapset);
  153. if ( fp == NULL) {
  154. G_debug ( 1, "Vector format: %d (native)", format);
  155. format = GV_FORMAT_NATIVE;
  156. } else {
  157. format = dig_read_frmt_ascii ( fp, &(Map->fInfo) );
  158. fclose (fp);
  159. G_debug ( 1, "Vector format: %d (non-native)", format);
  160. if ( format < 0 ) {
  161. sprintf ( errmsg, _("Unable to open vector map <%s>"), Vect_get_full_name(Map) );
  162. fatal_error (ferror, errmsg);
  163. return -1;
  164. }
  165. }
  166. Map->format = format;
  167. /* Read vector head */
  168. if ( Vect__read_head (Map) != GRASS_OK ) {
  169. sprintf ( errmsg, _("Unable to open vector map <%s> on topology level %d"), Vect_get_full_name(Map), level_request );
  170. G_warning (_("Unable to read head file"));
  171. }
  172. G_debug ( 1, "Level request = %d", level_request);
  173. /* There are only 2 possible open levels, 1 and 2. Try first to open 'support' files
  174. * (topo,sidx,cidx), these files are the same for all formats.
  175. * If it is not possible and requested level is 2, return error,
  176. * otherwise call Open_old_array[format][1], to open remaining files/sources (level 1)
  177. */
  178. /* Try to open support files if level was not requested or requested level is 2 (format independent) */
  179. if (level_request == 0 || level_request == 2 ) {
  180. level = 2; /* We expect success */
  181. /* open topo */
  182. ret = Vect_open_topo(Map, head_only);
  183. if ( ret == 1 ) { /* topo file is not available */
  184. G_debug( 1, "Topo file for vector '%s' not available.", Vect_get_full_name (Map));
  185. level = 1;
  186. } else if ( ret == -1 ) {
  187. G_fatal_error (_("Unable to open topology file for vector map <%s>"),
  188. Vect_get_full_name (Map));
  189. }
  190. /* open spatial index, not needed for head_only */
  191. /* spatial index is not loaded anymore */
  192. /*
  193. if ( level == 2 && !head_only ) {
  194. if ( Vect_open_spatial_index(Map) == -1 ) {
  195. G_debug( 1, "Cannot open spatial index file for vector '%s'.", Vect_get_full_name (Map) );
  196. dig_free_plus ( &(Map->plus) );
  197. level = 1;
  198. }
  199. }
  200. */
  201. /* open category index */
  202. if ( level == 2 ) {
  203. ret = Vect_cidx_open(Map, head_only);
  204. if ( ret == 1 ) { /* category index is not available */
  205. G_debug( 1, "Category index file for vector '%s' not available.", Vect_get_full_name (Map) );
  206. dig_free_plus ( &(Map->plus) ); /* free topology */
  207. dig_spidx_free ( &(Map->plus) ); /* free spatial index */
  208. level = 1;
  209. } else if ( ret == -1 ) { /* file exists, but cannot be opened */
  210. G_fatal_error (_("Unable to open category index file for vector map <%s>"),
  211. Vect_get_full_name (Map) );
  212. }
  213. }
  214. #ifdef HAVE_OGR
  215. /* Open OGR specific support files */
  216. if ( level == 2 && Map->format == GV_FORMAT_OGR ) {
  217. if ( V2_open_old_ogr ( Map ) < 0 ) {
  218. dig_free_plus ( &(Map->plus) );
  219. dig_spidx_free ( &(Map->plus) );
  220. dig_cidx_free ( &(Map->plus) );
  221. level = 1;
  222. }
  223. }
  224. #endif
  225. if (level_request == 2 && level < 2) {
  226. sprintf ( errmsg, _("Unable to open vector map <%s> on topology level %d"),
  227. Vect_get_full_name(Map), level_request );
  228. fatal_error (ferror, errmsg);
  229. return -1;
  230. }
  231. } else {
  232. level = 1; /* I.e. requested level is 1 */
  233. }
  234. /* Open level 1 files / sources (format specific) */
  235. if ( !head_only ) { /* No need to open coordinates */
  236. if (0 != (*Open_old_array[format][1]) (Map, update)) { /* Cannot open */
  237. if ( level == 2 ) { /* support files opened */
  238. dig_free_plus ( &(Map->plus) );
  239. dig_spidx_free ( &(Map->plus) );
  240. dig_cidx_free ( &(Map->plus) );
  241. }
  242. sprintf ( errmsg, _("Unable to open vector map <%s> on topology level %d"),
  243. Vect_get_full_name(Map), level_request );
  244. fatal_error (ferror, errmsg);
  245. return -1;
  246. }
  247. } else {
  248. Map->head.with_z = Map->plus.with_z; /* take dimension from topo */
  249. }
  250. /* Set status */
  251. Map->open = VECT_OPEN_CODE;
  252. Map->level = level;
  253. Map->head_only = head_only;
  254. Map->support_updated = 0;
  255. if ( update ) {
  256. Map->mode = GV_MODE_RW;
  257. Map->plus.mode = GV_MODE_RW;
  258. } else {
  259. Map->mode = GV_MODE_READ;
  260. Map->plus.mode = GV_MODE_READ;
  261. }
  262. if ( head_only ) {
  263. Map->head_only = 1;
  264. } else {
  265. Map->head_only = 0;
  266. }
  267. Map->Constraint_region_flag = 0;
  268. Map->Constraint_type_flag = 0;
  269. G_debug (1, "Vect_open_old(): vector opened on level %d", level);
  270. if ( level == 1 ) { /* without topology */
  271. Map->plus.built = GV_BUILD_NONE;
  272. } else { /* level 2, with topology */
  273. Map->plus.built = GV_BUILD_ALL; /* Highest level of topology for level 2 */
  274. }
  275. Map->plus.do_uplist = 0;
  276. Map->dblnk = Vect_new_dblinks_struct ( );
  277. Vect_read_dblinks ( Map );
  278. /* Open history file */
  279. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
  280. if ( update ) { /* native only */
  281. Map->hist_fp = G_fopen_modify (buf, GRASS_VECT_HIST_ELEMENT);
  282. if ( Map->hist_fp == NULL ) {
  283. sprintf ( errmsg, _("Unable to open history file for vector map <%s>"),
  284. Vect_get_full_name(Map) );
  285. fatal_error (ferror, errmsg);
  286. return (-1);
  287. }
  288. fseek ( Map->hist_fp, (long)0, SEEK_END);
  289. Vect_hist_write ( Map, "---------------------------------------------------------------------------------\n");
  290. } else {
  291. if ( Map->format == GV_FORMAT_NATIVE || Map->format == GV_FORMAT_OGR ) {
  292. Map->hist_fp = G_fopen_old (buf, GRASS_VECT_HIST_ELEMENT, Map->mapset);
  293. /* If NULL (does not exist) then Vect_hist_read() handle that */
  294. } else {
  295. Map->hist_fp = NULL;
  296. }
  297. }
  298. if ( !head_only ) { /* Cannot rewind if not fully opened */
  299. Vect_rewind ( Map );
  300. }
  301. /* Delete support files if native format was opened for update (not head_only) */
  302. if ( update && !head_only ) {
  303. char file_path[2000];
  304. struct stat info;
  305. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, name);
  306. G__file_name ( file_path, buf, GV_TOPO_ELEMENT, G_mapset ());
  307. if (stat (file_path, &info) == 0) /* file exists? */
  308. unlink (file_path);
  309. G__file_name ( file_path, buf, GV_SIDX_ELEMENT, G_mapset ());
  310. if (stat (file_path, &info) == 0) /* file exists? */
  311. unlink (file_path);
  312. G__file_name ( file_path, buf, GV_CIDX_ELEMENT, G_mapset ());
  313. if (stat (file_path, &info) == 0) /* file exists? */
  314. unlink (file_path);
  315. }
  316. return (level);
  317. }
  318. /*!
  319. * \brief Open existing vector for reading
  320. *
  321. * In case of error, the functions respect fatal error settings.
  322. *
  323. * \param[out] Map vector map
  324. * \param[in] name name of vector map
  325. * \param[in] mapset mapset name
  326. *
  327. * \return level of openness [1, 2, (3)]
  328. * \return -1 on error
  329. */
  330. int
  331. Vect_open_old (struct Map_info *Map, const char *name, const char *mapset)
  332. {
  333. return ( Vect__open_old (Map, name, mapset, 0, 0) );
  334. }
  335. /*!
  336. * \brief Open existing vector for reading/writing
  337. *
  338. * In case of error, the functions respect fatal error settings.
  339. *
  340. * \param[out] Map vector map
  341. * \param[in] name name of vector map to update
  342. * \param[in] mapset mapset name
  343. *
  344. * \return level of openness [1, 2, (3)]
  345. * \return -1 on error
  346. */
  347. int
  348. Vect_open_update (struct Map_info *Map, const char *name, const char *mapset)
  349. {
  350. int ret;
  351. ret = Vect__open_old (Map, name, mapset, 1, 0);
  352. if ( ret > 0 ) {
  353. Map->plus.do_uplist = 1;
  354. Map->plus.uplines = NULL;
  355. Map->plus.n_uplines = 0;
  356. Map->plus.alloc_uplines = 0;
  357. Map->plus.upnodes = NULL;
  358. Map->plus.n_upnodes = 0;
  359. Map->plus.alloc_upnodes = 0;
  360. /* Build spatial index from topo */
  361. Vect_build_sidx_from_topo ( Map, NULL );
  362. }
  363. return ret;
  364. }
  365. /*!
  366. * \brief Reads only info about vector from headers of 'head', 'dbln',
  367. * 'topo' and 'cidx' file.
  368. *
  369. * In case of error, the functions respect fatal error settings.
  370. *
  371. * \param[out] Map vector map
  372. * \param[in] name name of vector map to read
  373. * \param[in] mapset mapset name
  374. *
  375. * \return level of openness [1, 2, (3)]
  376. * \return -1 on error
  377. */
  378. int
  379. Vect_open_old_head (struct Map_info *Map, const char *name, const char *mapset)
  380. {
  381. return ( Vect__open_old (Map, name, mapset, 0, 1) );
  382. }
  383. /*!
  384. * \brief Open old vector head for updating (mostly for database link updates)
  385. *
  386. * In case of error, the functions respect fatal error settings.
  387. *
  388. * \param[out] Map vector map
  389. * \param[in] name name of vector map to update
  390. * \param[in] mapset mapset name
  391. *
  392. * \return level of openness [1, 2, (3)]
  393. * \return -1 on error
  394. */
  395. int
  396. Vect_open_update_head ( struct Map_info *Map, const char *name, const char *mapset)
  397. {
  398. int ret;
  399. ret = Vect__open_old (Map, name, mapset, 1, 1);
  400. if ( ret > 0 ) { /* Probably not important */
  401. Map->plus.do_uplist = 1;
  402. Map->plus.uplines = NULL;
  403. Map->plus.n_uplines = 0;
  404. Map->plus.alloc_uplines = 0;
  405. Map->plus.upnodes = NULL;
  406. Map->plus.n_upnodes = 0;
  407. Map->plus.alloc_upnodes = 0;
  408. }
  409. return ret;
  410. }
  411. /*!
  412. * \brief Open new vector for reading/writing
  413. *
  414. * \param[out] Map vector map
  415. * \param[in] name name of vector map
  416. * \param[in] with_z 2D/3D vector map
  417. *
  418. * \return 1 on success
  419. * \return -1 on error
  420. */
  421. int
  422. Vect_open_new (struct Map_info *Map, const char *name, int with_z)
  423. {
  424. int ret, ferror;
  425. char errmsg[2000], buf[200];
  426. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  427. G_debug ( 2, "Vect_open_new(): name = %s", name);
  428. Vect__init_head (Map);
  429. ferror = Vect_get_fatal_error ();
  430. Vect_set_fatal_error (GV_FATAL_EXIT);
  431. if (G__name_is_fully_qualified(name, xname, xmapset))
  432. {
  433. if (strcmp(xmapset, G_mapset()) != 0)
  434. {
  435. sprintf ( errmsg, _("%s is not in the current mapset (%s)"), name, G_mapset());
  436. fatal_error (ferror , errmsg );
  437. }
  438. name = xname;
  439. }
  440. /* check for [A-Za-z][A-Za-z0-9_]* in name */
  441. if (Vect_legal_filename(name) < 0 ) {
  442. sprintf ( errmsg, _("Vector map name is not SQL compliant") );
  443. fatal_error (ferror , errmsg );
  444. return (-1);
  445. }
  446. /* Check if map already exists */
  447. if ( G_find_file2(GRASS_VECT_DIRECTORY, name, G_mapset()) != NULL ) {
  448. G_warning (_("Vector map <%s> already exists and will be overwritten"), name);
  449. ret = Vect_delete ( name );
  450. if ( ret == -1 ) {
  451. sprintf ( errmsg, _("Unable to delete vector map <%s>"), name );
  452. fatal_error (ferror , errmsg );
  453. return (-1);
  454. }
  455. }
  456. Map->name = G_store (name);
  457. Map->mapset = G_store ( G_mapset() );
  458. Map->location = G_store ( G_location() );
  459. Map->gisdbase = G_store ( G_gisdbase() );
  460. Map->format = GV_FORMAT_NATIVE;
  461. if ( V1_open_new_nat (Map, name, with_z) < 0 ) {
  462. sprintf ( errmsg, _("Unable to create vector map <%s>"), Vect_get_full_name(Map) );
  463. fatal_error (ferror , errmsg );
  464. return (-1);
  465. }
  466. /* Open history file */
  467. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
  468. Map->hist_fp = G_fopen_new (buf, GRASS_VECT_HIST_ELEMENT);
  469. if ( Map->hist_fp == NULL ) {
  470. sprintf ( errmsg, _("Unable to open history file for vector map <%s>"), Vect_get_full_name(Map) );
  471. fatal_error (ferror, errmsg);
  472. return (-1);
  473. }
  474. Open_level = 0;
  475. dig_init_plus ( &(Map->plus) );
  476. Map->open = VECT_OPEN_CODE;
  477. Map->level = 1;
  478. Map->head_only = 0;
  479. Map->support_updated = 0;
  480. Map->plus.built = GV_BUILD_NONE;
  481. Map->mode = GV_MODE_RW;
  482. Map->Constraint_region_flag = 0;
  483. Map->Constraint_type_flag = 0;
  484. Map->head.with_z = with_z;
  485. Map->plus.do_uplist = 0;
  486. Map->dblnk = Vect_new_dblinks_struct ( );
  487. return 1;
  488. }
  489. /*!
  490. * \brief Update Coor_info structure
  491. *
  492. * \param[in] Map vector map
  493. * \param[out] Info Coor_info structure
  494. *
  495. * \return 1 on success
  496. * \return 0 on error
  497. */
  498. int
  499. Vect_coor_info ( struct Map_info *Map, struct Coor_info *Info )
  500. {
  501. char buf[2000], path[2000];
  502. struct stat stat_buf;
  503. switch ( Map->format ) {
  504. case GV_FORMAT_NATIVE :
  505. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
  506. G__file_name (path, buf, GRASS_VECT_COOR_ELEMENT, Map->mapset);
  507. G_debug ( 1, "get coor info: %s", path);
  508. if (0 != stat (path, &stat_buf)) {
  509. G_warning ( _("Unable to stat file <%s>"), path);
  510. Info->size = -1L;
  511. Info->mtime = -1L;
  512. } else {
  513. Info->size = (long) stat_buf.st_size; /* file size */
  514. Info->mtime = (long) stat_buf.st_mtime; /* last modified time */
  515. }
  516. /* stat does not give correct size on MINGW
  517. * if the file is opened */
  518. #ifdef __MINGW32__
  519. if ( Map->open == VECT_OPEN_CODE ) {
  520. dig_fseek ( &(Map->dig_fp), 0L, SEEK_END);
  521. G_debug ( 2, "ftell = %d", dig_ftell ( &(Map->dig_fp) ) );
  522. Info->size = dig_ftell ( &(Map->dig_fp) );
  523. }
  524. #endif
  525. break;
  526. case GV_FORMAT_OGR :
  527. Info->size = 0L;
  528. Info->mtime = 0L;
  529. break;
  530. }
  531. G_debug ( 1, "Info->size = %ld, Info->mtime = %ld", Info->size, Info->mtime);
  532. return 1;
  533. }
  534. /*!
  535. * \brief Gets maptype (native, shape, postgis)
  536. *
  537. * \param[in] Map vector map
  538. *
  539. * \return maptype string on success
  540. * \return error message on error
  541. */
  542. const char *
  543. Vect_maptype_info ( struct Map_info *Map )
  544. {
  545. char maptype[1000];
  546. switch ( Map->format ) {
  547. case GV_FORMAT_NATIVE :
  548. sprintf (maptype, "native");
  549. break;
  550. case GV_FORMAT_OGR :
  551. sprintf (maptype, "ogr");
  552. break;
  553. default :
  554. sprintf (maptype, "unknown %d (update Vect_maptype_info)", Map->format);
  555. }
  556. return G_store(maptype);
  557. }
  558. /*!
  559. * \brief Open topo file
  560. *
  561. * \param[in,out] Map vector map
  562. * \param[in] head_only open only head
  563. *
  564. * \return 0 on success
  565. * \return 1 file does not exist
  566. * \return -1 on error
  567. */
  568. int
  569. Vect_open_topo (struct Map_info *Map, int head_only)
  570. {
  571. int err, ret;
  572. char buf[500], file_path[2000];
  573. GVFILE fp;
  574. struct Coor_info CInfo;
  575. struct Plus_head *Plus;
  576. struct stat info;
  577. G_debug (1, "Vect_open_topo(): name = %s mapset= %s", Map->name, Map->mapset);
  578. Plus = &(Map->plus);
  579. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
  580. G__file_name ( file_path, buf, GV_TOPO_ELEMENT, Map->mapset);
  581. if (stat (file_path, &info) != 0) /* does not exist */
  582. return 1;
  583. dig_file_init ( &fp );
  584. fp.file = G_fopen_old (buf, GV_TOPO_ELEMENT, Map->mapset);
  585. if ( fp.file == NULL ) { /* topo file is not available */
  586. G_debug( 1, "Cannot open topo file for vector '%s@%s'.",
  587. Map->name, Map->mapset);
  588. return -1;
  589. }
  590. /* get coor info */
  591. Vect_coor_info ( Map, &CInfo);
  592. /* load head */
  593. if ( dig_Rd_Plus_head (&fp, Plus) == -1 ) return -1;
  594. G_debug ( 1, "Topo head: coor size = %ld, coor mtime = %ld",
  595. Plus->coor_size, Plus->coor_mtime);
  596. /* do checks */
  597. err = 0;
  598. if ( CInfo.size != Plus->coor_size ) {
  599. G_warning ( _("Size of 'coor' file differs from value saved in topology file") );
  600. err = 1;
  601. }
  602. /* Do not check mtime because mtime is changed by copy */
  603. /*
  604. if ( CInfo.mtime != Plus->coor_mtime ) {
  605. G_warning ( "Time of last modification for 'coor' file differs from value saved in topo file.\n");
  606. err = 1;
  607. }
  608. */
  609. if ( err ) {
  610. G_warning ( _("Please rebuild topology for vector map <%s@%s>"), Map->name, Map->mapset );
  611. return -1;
  612. }
  613. /* load file to the memory */
  614. /* dig_file_load ( &fp); */
  615. /* load topo to memory */
  616. ret = dig_load_plus ( Plus, &fp, head_only );
  617. fclose ( fp.file );
  618. /* dig_file_free ( &fp); */
  619. if ( ret == 0 ) return -1;
  620. return 0;
  621. }
  622. /*!
  623. * \brief Open spatial index file
  624. *
  625. * \param[in,out] Map vector map
  626. *
  627. * \return 0 on success
  628. * \return -1 on error
  629. */
  630. int
  631. Vect_open_spatial_index (struct Map_info *Map)
  632. {
  633. char buf[500];
  634. GVFILE fp;
  635. /* struct Coor_info CInfo; */
  636. struct Plus_head *Plus;
  637. G_debug (1, "Vect_open_spatial_index(): name = %s mapset= %s", Map->name, Map->mapset);
  638. Plus = &(Map->plus);
  639. sprintf (buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);
  640. dig_file_init ( &fp );
  641. fp.file = G_fopen_old (buf, GV_SIDX_ELEMENT, Map->mapset);
  642. if ( fp.file == NULL ) { /* spatial index file is not available */
  643. G_debug( 1, "Cannot open spatial index file for vector '%s@%s'.",
  644. Map->name, Map->mapset);
  645. return -1;
  646. }
  647. /* TODO: checks */
  648. /* load head */
  649. /*
  650. dig_Rd_spindx_head (fp, Plus);
  651. G_debug ( 1, "Spindx head: coor size = %ld, coor mtime = %ld",
  652. Plus->coor_size, Plus->coor_mtime);
  653. */
  654. /* do checks */
  655. /*
  656. err = 0;
  657. if ( CInfo.size != Plus->coor_size ) {
  658. G_warning ( "Size of 'coor' file differs from value saved in topo file.\n");
  659. err = 1;
  660. }
  661. */
  662. /* Do not check mtime because mtime is changed by copy */
  663. /*
  664. if ( CInfo.mtime != Plus->coor_mtime ) {
  665. G_warning ( "Time of last modification for 'coor' file differs from value saved in topo file.\n");
  666. err = 1;
  667. }
  668. */
  669. /*
  670. if ( err ) {
  671. G_warning ( "Please rebuild topology for vector '%s@%s'\n", Map->name,
  672. Map->mapset );
  673. return -1;
  674. }
  675. */
  676. /* load file to the memory */
  677. /* dig_file_load ( &fp); */
  678. /* load topo to memory */
  679. dig_spidx_init ( Plus);
  680. dig_read_spidx ( &fp, Plus );
  681. fclose ( fp.file );
  682. /* dig_file_free ( &fp); */
  683. return 0;
  684. }