open.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114
  1. /*!
  2. * \file lib/vector/Vlib/open.c
  3. *
  4. * \brief Vector library - Open vector map (native or OGR format)
  5. *
  6. * Higher level functions for reading/writing/manipulating vectors.
  7. *
  8. * (C) 2001-2009 by the GRASS Development Team
  9. *
  10. * This program is free software under the GNU General Public License
  11. * (>=v2). Read the file COPYING that comes with GRASS for details.
  12. *
  13. * \author Original author CERL, probably Dave Gerdes or Mike
  14. * Higgins.
  15. * \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
  16. */
  17. #include <grass/config.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <grass/gis.h>
  25. #include <grass/vector.h>
  26. #include <grass/glocale.h>
  27. /*
  28. \brief Number of levels - without and with topology
  29. */
  30. #define MAX_OPEN_LEVEL 2
  31. static int open_old_dummy()
  32. {
  33. return 0;
  34. }
  35. static int open_new_dummy()
  36. {
  37. return 0;
  38. }
  39. #ifndef HAVE_OGR
  40. static int format()
  41. {
  42. G_fatal_error(_("Requested format is not compiled in this version"));
  43. return 0;
  44. }
  45. #endif
  46. static int Open_level = 0;
  47. static int (*Open_old_array[][2]) () = {
  48. {
  49. open_old_dummy, V1_open_old_nat}
  50. #ifdef HAVE_OGR
  51. , {
  52. open_old_dummy, V1_open_old_ogr}
  53. , {
  54. open_old_dummy, V1_open_old_ogr}
  55. #else
  56. , {
  57. open_old_dummy, format}
  58. , {
  59. open_old_dummy, format}
  60. #endif
  61. };
  62. static int (*Open_new_array[][2]) () = {
  63. {
  64. open_new_dummy, V1_open_new_nat}
  65. #ifdef HAVE_OGR
  66. , {
  67. open_new_dummy, V1_open_new_ogr}
  68. , {
  69. open_new_dummy, V1_open_new_ogr}
  70. #else
  71. , {
  72. open_new_dummy, format}
  73. , {
  74. open_new_dummy, format}
  75. #endif
  76. };
  77. static void fatal_error(int ferror, char *errmsg)
  78. {
  79. switch (ferror) {
  80. case GV_FATAL_EXIT:
  81. G_fatal_error(errmsg);
  82. break;
  83. case GV_FATAL_PRINT:
  84. G_warning(errmsg);
  85. break;
  86. case GV_FATAL_RETURN:
  87. break;
  88. }
  89. }
  90. /*!
  91. * \brief Predetermine level at which a vector map will be opened for
  92. * reading.
  93. *
  94. * If it can't open that level, the open will fail. The specified
  95. * level must be set before any call to open. The default is to try to
  96. * open the highest level possible, and keep stepping down until
  97. * success.
  98. *
  99. * NOTE: This should only be used to set when you wish to force a
  100. * lower level open. If you require a higher level, then just check
  101. * the return to verify the level instead of forcing it. This is
  102. * because future releases will have higher levels which will be
  103. * downward compatible and which your programs should support by
  104. * default.
  105. *
  106. * \param level vector access level
  107. *
  108. * \return 0 on success
  109. * \return 1 on error
  110. */
  111. int Vect_set_open_level(int level)
  112. {
  113. Open_level = level;
  114. if (Open_level < 1 || Open_level > MAX_OPEN_LEVEL) {
  115. G_warning(_("Programmer requested unknown access level %d"),
  116. Open_level);
  117. Open_level = 0;
  118. return 1;
  119. }
  120. return 0;
  121. }
  122. /*!
  123. * \brief Open existing vector map for reading (internal use only)
  124. *
  125. * In case of error, the functions respect fatal error settings.
  126. *
  127. * \param[out] Map pointer to Map_info structure
  128. * \param name name of vector map to open
  129. * \param mapset mapset name ("" for search path)
  130. * \param layer layer name (OGR format only)
  131. * \param update non-zero to open for update otherwise read-only mode
  132. * \param head_only read only header info from 'head', 'dbln', 'topo',
  133. * 'cidx' is not opened. The header may be opened on level 2 only.
  134. *
  135. * \return level of openness (1, 2)
  136. * \return -1 in error
  137. */
  138. int Vect__open_old(struct Map_info *Map, const char *name, const char *mapset, const char *layer,
  139. int update, int head_only)
  140. {
  141. char buf[GNAME_MAX + 10], buf2[GMAPSET_MAX + 10], xname[GNAME_MAX],
  142. xmapset[GMAPSET_MAX], errmsg[2000];
  143. FILE *fp;
  144. int level, level_request, ferror;
  145. int format, ret;
  146. int ogr_mapset;
  147. const char *fmapset;
  148. G_debug(1, "Vect__open_old(): name = %s mapset = %s layer= %s update = %d", name,
  149. mapset, layer, update);
  150. /* zero Map_info structure */
  151. G_zero(Map, sizeof(struct Map_info));
  152. /* TODO: Open header for update ('dbln') */
  153. ferror = Vect_get_fatal_error();
  154. Vect_set_fatal_error(GV_FATAL_EXIT);
  155. level_request = Open_level;
  156. Open_level = 0;
  157. /* initialize Map->head */
  158. Vect__init_head(Map);
  159. /* initialize support structures for 2D, update to 3D when reading support files */
  160. Map->plus.spidx_with_z = Map->plus.with_z = Map->head.with_z = WITHOUT_Z;
  161. /* initialize Map->plus */
  162. Map->plus.Spidx_file = 0;
  163. dig_init_plus(&(Map->plus));
  164. /* check OGR mapset */
  165. ogr_mapset = FALSE;
  166. if (G_name_is_fully_qualified(name, xname, xmapset)) {
  167. if (strcasecmp(xmapset, "ogr") == 0) {
  168. /* unique OGR mapset detected */
  169. G_debug(1, "OGR mapset detected");
  170. ogr_mapset = TRUE;
  171. Map->fInfo.ogr.dsn = G_store(xname);
  172. if (layer) {
  173. Map->fInfo.ogr.layer_name = G_store(layer); /* no layer to be open */
  174. }
  175. }
  176. else {
  177. sprintf(buf, "%s/%s", GV_DIRECTORY, xname);
  178. sprintf(buf2, "%s@%s", GV_COOR_ELEMENT, xmapset);
  179. }
  180. Map->name = G_store(xname);
  181. Map->mapset = G_store(xmapset);
  182. }
  183. else {
  184. sprintf(buf, "%s/%s", GV_DIRECTORY, name);
  185. sprintf(buf2, "%s", GV_COOR_ELEMENT);
  186. Map->name = G_store(name);
  187. if (mapset)
  188. Map->mapset = G_store(mapset);
  189. else
  190. Map->mapset = G_store("");
  191. }
  192. if (!ogr_mapset) {
  193. /* try to find vector map (not for OGR mapset) */
  194. fmapset = G_find_vector2(Map->name, Map->mapset);
  195. if (fmapset == NULL) {
  196. sprintf(errmsg, _("Vector map <%s> not found"),
  197. Vect_get_full_name(Map));
  198. fatal_error(ferror, errmsg);
  199. return -1;
  200. }
  201. Map->mapset = G_store(fmapset);
  202. }
  203. Map->location = G_store(G_location());
  204. Map->gisdbase = G_store(G_gisdbase());
  205. if (update && !ogr_mapset && (0 != strcmp(Map->mapset, G_mapset()))) {
  206. G_warning(_("Vector map which is not in the current mapset cannot be opened for update"));
  207. return -1;
  208. }
  209. G_debug(1, "Map name: %s", Map->name);
  210. G_debug(1, "Map mapset: %s", Map->mapset);
  211. /* Read vector format information */
  212. if (ogr_mapset) {
  213. format = GV_FORMAT_OGR_DIRECT;
  214. }
  215. else {
  216. format = 0;
  217. sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
  218. G_debug(1, "open format file: '%s/%s/%s'", Map->mapset, buf,
  219. GV_FRMT_ELEMENT);
  220. fp = G_fopen_old(buf, GV_FRMT_ELEMENT, Map->mapset);
  221. if (fp == NULL) {
  222. G_debug(1, "Vector format: %d (native)", format);
  223. format = GV_FORMAT_NATIVE;
  224. }
  225. else {
  226. format = dig_read_frmt_ascii(fp, &(Map->fInfo));
  227. fclose(fp);
  228. G_debug(1, "Vector format: %d (non-native)", format);
  229. if (format < 0) {
  230. sprintf(errmsg, _("Unable to open vector map <%s>"),
  231. Vect_get_full_name(Map));
  232. fatal_error(ferror, errmsg);
  233. return -1;
  234. }
  235. }
  236. }
  237. Map->format = format;
  238. /* projection info */
  239. Vect_set_proj(Map, G_projection());
  240. Vect_set_zone(Map, G_zone());
  241. /* read vector head (ignored for OGR mapset) */
  242. if (!ogr_mapset && Vect__read_head(Map) != 0) {
  243. sprintf(errmsg,
  244. _("Unable to open vector map <%s> on level %d. "
  245. "Try to rebuild vector topology by v.build."),
  246. Vect_get_full_name(Map), level_request);
  247. G_warning(_("Unable to read header file of vector map <%s>"),
  248. Vect_get_full_name(Map));
  249. }
  250. /* zone not set */
  251. if (Vect_get_zone(Map) == -1)
  252. Vect_set_zone(Map, G_zone());
  253. Vect_set_proj(Map, G_projection());
  254. G_debug(1, "Level request = %d", level_request);
  255. /* There are only 2 possible open levels, 1 and 2. Try first to
  256. * open 'support' files (topo,sidx,cidx), these files are the same
  257. * for all formats. If it is not possible and requested level is
  258. * 2, return error, otherwise call Open_old_array[format][1], to
  259. * open remaining files/sources (level 1)
  260. */
  261. /* Try to open support files if level was not requested or
  262. * requested level is 2 (format independent) */
  263. if (level_request == 0 || level_request == 2) {
  264. level = 2; /* we expect success */
  265. /* open topo */
  266. ret = Vect_open_topo(Map, head_only);
  267. if (ret == 1) { /* topo file is not available */
  268. G_debug(1, "topo file for vector '%s' not available.",
  269. Vect_get_full_name(Map));
  270. level = 1;
  271. }
  272. else if (ret == -1) {
  273. G_fatal_error(_("Unable to open topology file for vector map <%s>"),
  274. Vect_get_full_name(Map));
  275. }
  276. /* open spatial index */
  277. if (level == 2) {
  278. ret = Vect_open_sidx(Map, (update != 0));
  279. if (ret == 1) { /* sidx file is not available */
  280. G_debug(1, "sidx file for vector '%s' not available.",
  281. Vect_get_full_name(Map));
  282. level = 1;
  283. }
  284. else if (ret == -1) {
  285. G_fatal_error(_("Unable to open spatial index file for vector map <%s>"),
  286. Vect_get_full_name(Map));
  287. }
  288. /* check with_z consistency */
  289. if ((Map->plus.with_z != 0 && Map->plus.spidx_with_z == 0) ||
  290. (Map->plus.with_z == 0 && Map->plus.spidx_with_z != 0)) {
  291. G_warning("Vector map <%s>: topology is %s, but spatial index is %s",
  292. Vect_get_full_name(Map), (Map->plus.with_z != 0 ? "3D" : "2D"),
  293. (Map->plus.spidx_with_z != 0 ? "3D" : "2D"));
  294. level = 1;
  295. }
  296. }
  297. /* open category index */
  298. if (level == 2) {
  299. ret = Vect_cidx_open(Map, head_only);
  300. if (ret == 1) { /* category index is not available */
  301. G_debug(1,
  302. "cidx file for vector '%s' not available.",
  303. Vect_get_full_name(Map));
  304. dig_free_plus(&(Map->plus)); /* free topology */
  305. dig_spidx_free(&(Map->plus)); /* free spatial index */
  306. level = 1;
  307. }
  308. else if (ret == -1) { /* file exists, but cannot be opened */
  309. G_fatal_error(_("Unable to open category index file for vector map <%s>"),
  310. Vect_get_full_name(Map));
  311. }
  312. }
  313. #ifdef HAVE_OGR
  314. /* Open OGR specific support files */
  315. if (level == 2 && Map->format == GV_FORMAT_OGR) {
  316. if (V2_open_old_ogr(Map) < 0) {
  317. dig_free_plus(&(Map->plus));
  318. dig_spidx_free(&(Map->plus));
  319. dig_cidx_free(&(Map->plus));
  320. level = 1;
  321. }
  322. }
  323. #endif
  324. if (level_request == 2 && level < 2) {
  325. if (!ogr_mapset) {
  326. /* for direct OGR read access is built pseudo-topology on the fly */
  327. sprintf(errmsg,
  328. _("Unable to open vector map <%s> on level %d. "
  329. "Try to rebuild vector topology by v.build."),
  330. Vect_get_full_name(Map), level_request);
  331. fatal_error(ferror, errmsg);
  332. return -1;
  333. }
  334. }
  335. }
  336. else {
  337. level = 1; /* i.e. requested level is 1 */
  338. }
  339. /* open level 1 files / sources (format specific) */
  340. if (!head_only || ogr_mapset) { /* no need to open coordinates */
  341. if (0 != (*Open_old_array[format][1]) (Map, update)) { /* cannot open */
  342. if (level == 2) { /* support files opened */
  343. dig_free_plus(&(Map->plus));
  344. dig_spidx_free(&(Map->plus));
  345. dig_cidx_free(&(Map->plus));
  346. }
  347. sprintf(errmsg,
  348. _("Unable to open vector map <%s> on level %d. "
  349. "Try to rebuild vector topology by v.build."),
  350. Vect_get_full_name(Map), level_request);
  351. fatal_error(ferror, errmsg);
  352. return -1;
  353. }
  354. if (ogr_mapset && !head_only && level_request != 1) {
  355. /* build pseudo-topology on the fly */
  356. int verbose;
  357. verbose = G_verbose();
  358. G_message(_("Building topology for OGR layer <%s> from datasource '%s'..."),
  359. Map->fInfo.ogr.layer_name, Map->fInfo.ogr.dsn);
  360. G_set_verbose(0);
  361. if (Vect_build(Map)) {
  362. level = 2;
  363. }
  364. G_set_verbose(verbose);
  365. if (level < level_request)
  366. G_fatal_error(_("Unable to open vector map <%s> on level %d"),
  367. Map->fInfo.ogr.layer_name, level_request);
  368. }
  369. }
  370. else {
  371. Map->head.with_z = Map->plus.with_z; /* take dimension from topo */
  372. }
  373. /* set status */
  374. Map->open = VECT_OPEN_CODE;
  375. Map->level = level;
  376. Map->head_only = head_only;
  377. Map->support_updated = 0;
  378. if (update) {
  379. Map->mode = GV_MODE_RW;
  380. Map->plus.mode = GV_MODE_RW;
  381. }
  382. else {
  383. Map->mode = GV_MODE_READ;
  384. Map->plus.mode = GV_MODE_READ;
  385. }
  386. if (head_only) {
  387. Map->head_only = 1;
  388. }
  389. else {
  390. Map->head_only = 0;
  391. }
  392. Map->Constraint_region_flag = 0;
  393. Map->Constraint_type_flag = 0;
  394. G_debug(1, "Vect_open_old(): vector opened on level %d", level);
  395. if (level == 1) { /* without topology */
  396. Map->plus.built = GV_BUILD_NONE;
  397. }
  398. else { /* level 2, with topology */
  399. Map->plus.built = GV_BUILD_ALL; /* highest level of topology for level 2 */
  400. }
  401. Map->plus.do_uplist = 0;
  402. /* read db links */
  403. Map->dblnk = Vect_new_dblinks_struct();
  404. Vect_read_dblinks(Map);
  405. /* open history file */
  406. sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
  407. if (update && !ogr_mapset) { /* native only */
  408. Map->hist_fp = G_fopen_modify(buf, GV_HIST_ELEMENT);
  409. if (Map->hist_fp == NULL) {
  410. sprintf(errmsg,
  411. _("Unable to open history file for vector map <%s>"),
  412. Vect_get_full_name(Map));
  413. fatal_error(ferror, errmsg);
  414. return (-1);
  415. }
  416. G_fseek(Map->hist_fp, (off_t) 0, SEEK_END);
  417. Vect_hist_write(Map,
  418. "---------------------------------------------------------------------------------\n");
  419. }
  420. else {
  421. if (Map->format == GV_FORMAT_NATIVE || Map->format == GV_FORMAT_OGR) {
  422. Map->hist_fp =
  423. G_fopen_old(buf, GV_HIST_ELEMENT, Map->mapset);
  424. /* If NULL (does not exist) then Vect_hist_read() handle that */
  425. }
  426. else {
  427. Map->hist_fp = NULL;
  428. }
  429. }
  430. if (!head_only) { /* cannot rewind if not fully opened */
  431. Vect_rewind(Map);
  432. }
  433. /* delete support files if native format was opened for update (not head_only) */
  434. if (update && !head_only) {
  435. char file_path[2000];
  436. sprintf(buf, "%s/%s", GV_DIRECTORY, name);
  437. G__file_name(file_path, buf, GV_TOPO_ELEMENT, G_mapset());
  438. if (access(file_path, F_OK) == 0) /* file exists? */
  439. unlink(file_path);
  440. G__file_name(file_path, buf, GV_SIDX_ELEMENT, G_mapset());
  441. if (access(file_path, F_OK) == 0) /* file exists? */
  442. unlink(file_path);
  443. G__file_name(file_path, buf, GV_CIDX_ELEMENT, G_mapset());
  444. if (access(file_path, F_OK) == 0) /* file exists? */
  445. unlink(file_path);
  446. }
  447. return level;
  448. }
  449. /*!
  450. * \brief Open existing vector map for reading (native or OGR format
  451. * via v.external)
  452. *
  453. * This function is replaced by Vect_open_old2() to handle also direct
  454. * OGR support.
  455. *
  456. * In case of error, the functions respect fatal error settings.
  457. *
  458. * \param[out] Map pointer to Map_info structure
  459. * \param name name of vector map to open
  460. * \param mapset mapset name
  461. *
  462. * \return level of openness [1, 2, (3)]
  463. * \return -1 on error
  464. */
  465. int Vect_open_old(struct Map_info *Map, const char *name, const char *mapset)
  466. {
  467. return (Vect__open_old(Map, name, mapset, NULL, 0, 0));
  468. }
  469. /*!
  470. * \brief Open existing vector map for reading (native and OGR format)
  471. *
  472. * In case of error, the functions respect fatal error settings.
  473. *
  474. * \param[out] Map pointer to Map_info structure
  475. * \param name name of vector map to open
  476. * \param mapset mapset name
  477. * \param layer layer name (OGR format)
  478. *
  479. * \return level of openness [1, 2, (3)]
  480. * \return -1 on error
  481. */
  482. int Vect_open_old2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
  483. {
  484. return (Vect__open_old(Map, name, mapset, layer, 0, 0));
  485. }
  486. /*!
  487. * \brief Open existing vector map for reading/writing (native or OGR
  488. * format via v.external)
  489. *
  490. * This function is replaced by Vect_open_update2() to handle also
  491. * direct OGR support.
  492. *
  493. * In case of error, the functions respect fatal error settings.
  494. *
  495. * \param[out] Map pointer to Map_info structure
  496. * \param name name of vector map to update
  497. * \param mapset mapset name
  498. *
  499. * \return level of openness [1, 2, (3)]
  500. * \return -1 on error
  501. */
  502. int Vect_open_update(struct Map_info *Map, const char *name, const char *mapset)
  503. {
  504. int ret;
  505. ret = Vect__open_old(Map, name, mapset, NULL, 1, 0);
  506. /* the update lists are unused, a waste of time and memory */
  507. /*
  508. if (ret > 0) {
  509. Map->plus.do_uplist = 1;
  510. Map->plus.uplines = NULL;
  511. Map->plus.n_uplines = 0;
  512. Map->plus.alloc_uplines = 0;
  513. Map->plus.upnodes = NULL;
  514. Map->plus.n_upnodes = 0;
  515. Map->plus.alloc_upnodes = 0;
  516. }
  517. */
  518. return ret;
  519. }
  520. /*!
  521. * \brief Open existing vector map for reading/writing (native or OGR
  522. * format)
  523. *
  524. * In case of error, the functions respect fatal error settings.
  525. *
  526. * \param[out] Map pointer to Map_info structure
  527. * \param name name of vector map to update
  528. * \param mapset mapset name
  529. * \param layer layer name (OGR format)
  530. *
  531. * \return level of openness [1, 2, (3)]
  532. * \return -1 on error
  533. */
  534. int Vect_open_update2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
  535. {
  536. int ret;
  537. ret = Vect__open_old(Map, name, mapset, layer, 1, 0);
  538. return ret;
  539. }
  540. /*!
  541. * \brief Reads only info about vector map from headers of 'head',
  542. * 'dbln', 'topo' and 'cidx' file (native or OGR format via
  543. * v.external)
  544. *
  545. * This function is replaced by Vect_open_old_head2() to handle also
  546. * direct OGR support.
  547. *
  548. * In case of error, the functions respect fatal error settings.
  549. *
  550. * \param[out] Map pointer to Map_info structure
  551. * \param name name of vector map to read (dsn for OGR)
  552. * \param mapset mapset name ("" for search path)
  553. *
  554. * \return level of openness [1, 2, (3)]
  555. * \return -1 on error
  556. */
  557. int Vect_open_old_head(struct Map_info *Map, const char *name, const char *mapset)
  558. {
  559. return (Vect__open_old(Map, name, mapset, NULL, 0, 1));
  560. }
  561. /*!
  562. * \brief Reads only info about vector map from headers of 'head',
  563. * 'dbln', 'topo' and 'cidx' file (native or OGR format)
  564. *
  565. * In case of error, the functions respect fatal error settings.
  566. *
  567. * \param[out] Map pointer to Map_info structure
  568. * \param name name of vector map to read (dsn for OGR)
  569. * \param mapset mapset name ("" for search path)
  570. * \param layer layer name (OGR format)
  571. *
  572. * \return level of openness [1, 2, (3)]
  573. * \return -1 on error
  574. */
  575. int Vect_open_old_head2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
  576. {
  577. return (Vect__open_old(Map, name, mapset, layer, 0, 1));
  578. }
  579. /*!
  580. * \brief Open header file of existing vector map for updating (mostly
  581. * for database link updates)
  582. *
  583. * In case of error, the functions respect fatal error settings.
  584. *
  585. * \param[out] Map pointer to Map_info structure
  586. * \param name name of vector map to update
  587. * \param mapset mapset name
  588. *
  589. * \return level of openness [1, 2, (3)]
  590. * \return -1 on error
  591. */
  592. int Vect_open_update_head(struct Map_info *Map, const char *name,
  593. const char *mapset)
  594. {
  595. int ret;
  596. ret = Vect__open_old(Map, name, mapset, NULL, 1, 1);
  597. /* the update lists are unused, a waste of time and memory */
  598. /*
  599. if (ret > 0) {
  600. Map->plus.do_uplist = 1;
  601. Map->plus.uplines = NULL;
  602. Map->plus.n_uplines = 0;
  603. Map->plus.alloc_uplines = 0;
  604. Map->plus.upnodes = NULL;
  605. Map->plus.n_upnodes = 0;
  606. Map->plus.alloc_upnodes = 0;
  607. }
  608. */
  609. return ret;
  610. }
  611. /*!
  612. * \brief Create new vector map for reading/writing
  613. *
  614. * \param[in,out] Map pointer to Map_info structure
  615. * \param name name of vector map
  616. * \param with_z non-zero value for 3D vector data
  617. *
  618. * \return 1 on success
  619. * \return -1 on error
  620. */
  621. int Vect_open_new(struct Map_info *Map, const char *name, int with_z)
  622. {
  623. int ret, ferror;
  624. char errmsg[2000], buf[500];
  625. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  626. G_debug(2, "Vect_open_new(): name = %s", name);
  627. G_zero(Map, sizeof(struct Map_info));
  628. /* init header */
  629. Vect__init_head(Map);
  630. /* error handling */
  631. ferror = Vect_get_fatal_error();
  632. Vect_set_fatal_error(GV_FATAL_EXIT);
  633. if (G_name_is_fully_qualified(name, xname, xmapset)) {
  634. if (strcmp(xmapset, G_mapset()) != 0) {
  635. sprintf(errmsg, _("%s is not in the current mapset (%s)"), name,
  636. G_mapset());
  637. fatal_error(ferror, errmsg);
  638. }
  639. name = xname;
  640. }
  641. /* check for [A-Za-z][A-Za-z0-9_]* in name */
  642. if (Vect_legal_filename(name) < 0) {
  643. sprintf(errmsg, _("Vector map name is not SQL compliant"));
  644. fatal_error(ferror, errmsg);
  645. return -1;
  646. }
  647. /* determine output format native or ogr */
  648. if (G_find_file2("", "OGR", G_mapset())) {
  649. /* OGR */
  650. FILE *fp;
  651. struct Key_Value *key_val;
  652. const char *p;
  653. G_debug(2, " using OGR format");
  654. Map->format = GV_FORMAT_OGR_DIRECT;
  655. fp = G_fopen_old("", "OGR", G_mapset());
  656. if (!fp) {
  657. sprintf(errmsg, _("Unable to open OGR file"));
  658. fatal_error(ferror, errmsg);
  659. }
  660. key_val = G_fread_key_value(fp);
  661. fclose(fp);
  662. p = G_find_key_value("format", key_val);
  663. if (p)
  664. Map->fInfo.ogr.driver_name = G_store(p);
  665. p = G_find_key_value("dsn", key_val);
  666. if (p)
  667. Map->fInfo.ogr.dsn = G_store(p);
  668. Map->fInfo.ogr.layer_name = G_store(name);
  669. }
  670. else {
  671. /* native */
  672. G_debug(2, " using native format");
  673. Map->format = GV_FORMAT_NATIVE;
  674. /* check if map already exists */
  675. if (G_find_vector2(name, G_mapset()) != NULL) {
  676. G_warning(_("Vector map <%s> already exists and will be overwritten"),
  677. name);
  678. ret = Vect_delete(name);
  679. if (ret == -1) {
  680. sprintf(errmsg, _("Unable to delete vector map <%s>"), name);
  681. fatal_error(ferror, errmsg);
  682. return -1;
  683. }
  684. }
  685. }
  686. Map->name = G_store(name);
  687. Map->mapset = G_store(G_mapset());
  688. Map->location = G_store(G_location());
  689. Map->gisdbase = G_store(G_gisdbase());
  690. /* set 2D/3D */
  691. Map->plus.spidx_with_z = Map->plus.with_z = Map->head.with_z = (with_z != 0);
  692. if ((*Open_new_array[Map->format][1]) (Map, name, with_z) < 0) {
  693. sprintf(errmsg, _("Unable to create vector map <%s>"),
  694. Vect_get_full_name(Map));
  695. fatal_error(ferror, errmsg);
  696. return -1;
  697. }
  698. if (Map->format == GV_FORMAT_NATIVE) {
  699. /* Open history file */
  700. sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
  701. Map->hist_fp = G_fopen_new(buf, GV_HIST_ELEMENT);
  702. if (Map->hist_fp == NULL) {
  703. sprintf(errmsg, _("Unable to open history file of vector map <%s>"),
  704. Vect_get_full_name(Map));
  705. fatal_error(ferror, errmsg);
  706. return -1;
  707. }
  708. }
  709. Open_level = 0;
  710. /* initialize topo */
  711. Map->plus.Spidx_file = 0;
  712. dig_init_plus(&(Map->plus));
  713. /* open new spatial index */
  714. Vect_open_sidx(Map, 2);
  715. Map->open = VECT_OPEN_CODE;
  716. Map->level = 1;
  717. Map->head_only = 0;
  718. Map->support_updated = 0;
  719. Map->plus.built = GV_BUILD_NONE;
  720. Map->mode = GV_MODE_RW;
  721. Map->Constraint_region_flag = 0;
  722. Map->Constraint_type_flag = 0;
  723. Map->plus.do_uplist = 0;
  724. Vect_set_proj(Map, G_projection());
  725. Vect_set_zone(Map, G_zone());
  726. Map->dblnk = Vect_new_dblinks_struct();
  727. return 1;
  728. }
  729. /*!
  730. * \brief Update Coor_info structure
  731. *
  732. * \param Map pointer to Map_info structure
  733. * \param[out] Info pointer to Coor_info structure
  734. *
  735. * \return 1 on success
  736. * \return 0 on error
  737. */
  738. int Vect_coor_info(const struct Map_info *Map, struct Coor_info *Info)
  739. {
  740. char buf[2000], path[2000];
  741. STRUCT_STAT stat_buf;
  742. switch (Map->format) {
  743. case GV_FORMAT_NATIVE:
  744. sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
  745. G__file_name(path, buf, GV_COOR_ELEMENT, Map->mapset);
  746. G_debug(1, "get coor info: %s", path);
  747. if (0 != stat(path, &stat_buf)) {
  748. G_warning(_("Unable to stat file <%s>"), path);
  749. Info->size = -1L;
  750. Info->mtime = -1L;
  751. }
  752. else {
  753. Info->size = (off_t)stat_buf.st_size; /* file size */
  754. Info->mtime = (long)stat_buf.st_mtime; /* last modified time */
  755. }
  756. /* stat does not give correct size on MINGW
  757. * if the file is opened */
  758. #ifdef __MINGW32__
  759. if (Map->open == VECT_OPEN_CODE) {
  760. dig_fseek(&(Map->dig_fp), 0L, SEEK_END);
  761. G_debug(2, "dig_ftell = %d", dig_ftell(&(Map->dig_fp)));
  762. Info->size = dig_ftell(&(Map->dig_fp));
  763. }
  764. #endif
  765. break;
  766. case GV_FORMAT_OGR:
  767. case GV_FORMAT_OGR_DIRECT:
  768. Info->size = 0L;
  769. Info->mtime = 0L;
  770. break;
  771. }
  772. G_debug(1, "Info->size = %lu, Info->mtime = %ld",
  773. (unsigned long)Info->size, Info->mtime);
  774. return 1;
  775. }
  776. /*!
  777. * \brief Gets vector map format (as string)
  778. *
  779. * Note: string is allocated by G_store(). Free allocated memory with
  780. * G_free().
  781. *
  782. * Currently are implemeted:
  783. * - Native format (native)
  784. * - OGR format (ogr)
  785. *
  786. * \param Map pointer to Map_info structure
  787. *
  788. * \return maptype string on success
  789. * \return error message on error
  790. */
  791. const char *Vect_maptype_info(const struct Map_info *Map)
  792. {
  793. char maptype[1000];
  794. switch (Map->format) {
  795. case GV_FORMAT_NATIVE:
  796. sprintf(maptype, "native");
  797. break;
  798. case GV_FORMAT_OGR:
  799. case GV_FORMAT_OGR_DIRECT:
  800. sprintf(maptype, "ogr");
  801. break;
  802. default:
  803. sprintf(maptype, _("unknown %d (update Vect_maptype_info)"),
  804. Map->format);
  805. }
  806. return G_store(maptype);
  807. }
  808. /*!
  809. \brief Gets vector map format
  810. Currently are implemeted:
  811. - Native format (GV_FORMAT_NATIVE)
  812. - OGR format linked via v.external (GV_FORMAT_OGR)
  813. - OGR format (GV_FORMAT_DIRECT)
  814. \param Map pointer to Map_info structure
  815. \return maptype code
  816. */
  817. int Vect_maptype(const struct Map_info *Map)
  818. {
  819. return Map->format;
  820. }
  821. /*!
  822. * \brief Open topology file ('topo')
  823. *
  824. * \param[in,out] Map pointer to Map_info structure
  825. * \param head_only TRUE to read only header
  826. *
  827. * \return 0 on success
  828. * \return 1 file does not exist
  829. * \return -1 on error
  830. */
  831. int Vect_open_topo(struct Map_info *Map, int head_only)
  832. {
  833. int err, ret;
  834. char buf[500], file_path[2000];
  835. struct gvfile fp;
  836. struct Coor_info CInfo;
  837. struct Plus_head *Plus;
  838. G_debug(1, "Vect_open_topo(): name = %s mapset= %s", Map->name,
  839. Map->mapset);
  840. Plus = &(Map->plus);
  841. sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
  842. G__file_name(file_path, buf, GV_TOPO_ELEMENT, Map->mapset);
  843. if (access(file_path, F_OK) != 0) /* does not exist */
  844. return 1;
  845. dig_file_init(&fp);
  846. fp.file = G_fopen_old(buf, GV_TOPO_ELEMENT, Map->mapset);
  847. if (fp.file == NULL) { /* topo file is not available */
  848. G_debug(1, "Cannot open topo file for vector '%s@%s'.",
  849. Map->name, Map->mapset);
  850. return -1;
  851. }
  852. /* get coor info */
  853. /* NOTE: coor file not yet opened */
  854. Vect_coor_info(Map, &CInfo);
  855. /* load head */
  856. if (dig_Rd_Plus_head(&fp, Plus) == -1)
  857. return -1;
  858. G_debug(1, "Topo head: coor size = %lu, coor mtime = %ld",
  859. (unsigned long)Plus->coor_size, Plus->coor_mtime);
  860. /* do checks */
  861. err = 0;
  862. if (CInfo.size != Plus->coor_size) {
  863. G_warning(_("Size of 'coor' file differs from value saved in topology file"));
  864. err = 1;
  865. }
  866. /* Do not check mtime because mtime is changed by copy */
  867. /*
  868. if ( CInfo.mtime != Plus->coor_mtime ) {
  869. G_warning ( "Time of last modification for 'coor' file differs from value saved in topo file.\n");
  870. err = 1;
  871. }
  872. */
  873. if (err) {
  874. G_warning(_("Please rebuild topology for vector map <%s@%s>"),
  875. Map->name, Map->mapset);
  876. return -1;
  877. }
  878. /* load file to the memory */
  879. /* dig_file_load ( &fp); */
  880. /* load topo to memory */
  881. ret = dig_load_plus(Plus, &fp, head_only);
  882. fclose(fp.file);
  883. /* dig_file_free ( &fp); */
  884. if (ret == 0)
  885. return -1;
  886. return 0;
  887. }
  888. /*!
  889. * \brief Open spatial index file ('sidx')
  890. *
  891. * \param[in,out] Map pointer to Map_info
  892. * \param mode 0 old, 1 update, 2 new
  893. *
  894. * \return 0 on success
  895. * \return -1 on error
  896. */
  897. int Vect_open_sidx(struct Map_info *Map, int mode)
  898. {
  899. char buf[500], file_path[2000];
  900. int err;
  901. struct Coor_info CInfo;
  902. struct Plus_head *Plus;
  903. G_debug(1, "Vect_open_sidx(): name = %s mapset= %s mode = %s", Map->name,
  904. Map->mapset, mode == 0 ? "old" : (mode == 1 ? "update" : "new"));
  905. if (Map->plus.Spidx_built == 1) {
  906. G_warning("Spatial index already opened");
  907. return 0;
  908. }
  909. Plus = &(Map->plus);
  910. dig_file_init(&(Map->plus.spidx_fp));
  911. if (mode < 2) {
  912. sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
  913. G__file_name(file_path, buf, GV_SIDX_ELEMENT, Map->mapset);
  914. if (access(file_path, F_OK) != 0) /* does not exist */
  915. return 1;
  916. Map->plus.spidx_fp.file =
  917. G_fopen_old(buf, GV_SIDX_ELEMENT, Map->mapset);
  918. if (Map->plus.spidx_fp.file == NULL) { /* sidx file is not available */
  919. G_debug(1, "Cannot open spatial index file for vector '%s@%s'.",
  920. Map->name, Map->mapset);
  921. return -1;
  922. }
  923. /* get coor info */
  924. /* NOTE: coor file not yet opened */
  925. Vect_coor_info(Map, &CInfo);
  926. /* initialize spatial index */
  927. Map->plus.Spidx_new = 0;
  928. /* load head */
  929. if (dig_Rd_spidx_head(&(Map->plus.spidx_fp), Plus) == -1) {
  930. fclose(Map->plus.spidx_fp.file);
  931. return -1;
  932. }
  933. G_debug(1, "Sidx head: coor size = %lu, coor mtime = %ld",
  934. (unsigned long)Plus->coor_size, Plus->coor_mtime);
  935. /* do checks */
  936. err = 0;
  937. if (CInfo.size != Plus->coor_size) {
  938. G_warning(_("Size of 'coor' file differs from value saved in sidx file"));
  939. err = 1;
  940. }
  941. /* Do not check mtime because mtime is changed by copy */
  942. /*
  943. if ( CInfo.mtime != Plus->coor_mtime ) {
  944. G_warning ( "Time of last modification for 'coor' file differs from value saved in topo file.\n");
  945. err = 1;
  946. }
  947. */
  948. if (err) {
  949. G_warning(_("Please rebuild topology for vector map <%s@%s>"),
  950. Map->name, Map->mapset);
  951. fclose(Map->plus.spidx_fp.file);
  952. return -1;
  953. }
  954. }
  955. if (mode) {
  956. /* open new spatial index */
  957. Map->plus.Spidx_new = 1;
  958. /* file based or memory based */
  959. if (getenv("GRASS_VECTOR_LOWMEM")) {
  960. /* free old indices */
  961. dig_spidx_free(Plus);
  962. /* initialize file based indices */
  963. Map->plus.Spidx_file = 1;
  964. dig_spidx_init(Plus);
  965. }
  966. G_debug(1, "%s based spatial index",
  967. Map->plus.Spidx_file == 0 ? "Memory" : "File");
  968. if (mode == 1) {
  969. /* load spatial index for update */
  970. if (dig_Rd_spidx(&(Map->plus.spidx_fp), Plus) == -1) {
  971. fclose(Map->plus.spidx_fp.file);
  972. return -1;
  973. }
  974. }
  975. }
  976. Map->plus.Spidx_built = 1;
  977. return 0;
  978. }