build_pg.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*!
  2. \file lib/vector/Vlib/build_pg.c
  3. \brief Vector library - Building topology for PostGIS layers
  4. Higher level functions for reading/writing/manipulating vectors.
  5. Line offset is
  6. - centroids : FID
  7. - other types : index of the first record (which is FID) in offset array.
  8. (C) 2012 by the GRASS Development Team
  9. This program is free software under the GNU General Public License
  10. (>=v2). Read the file COPYING that comes with GRASS for details.
  11. \author Martin Landa <landa.martin gmail.com>
  12. */
  13. #include <grass/vector.h>
  14. #include <grass/glocale.h>
  15. #ifdef HAVE_POSTGRES
  16. #include "pg_local_proto.h"
  17. static int build_topo(struct Map_info *, int);
  18. #endif
  19. /*!
  20. \brief Build topology for PostGIS layer
  21. Build levels:
  22. - GV_BUILD_NONE
  23. - GV_BUILD_BASE
  24. - GV_BUILD_ATTACH_ISLES
  25. - GV_BUILD_CENTROIDS
  26. - GV_BUILD_ALL
  27. \param Map pointer to Map_info structure
  28. \param build build level
  29. \return 1 on success
  30. \return 0 on error
  31. */
  32. int Vect_build_pg(struct Map_info *Map, int build)
  33. {
  34. #ifdef HAVE_POSTGRES
  35. struct Plus_head *plus;
  36. struct Format_info_pg *pg_info;
  37. plus = &(Map->plus);
  38. pg_info = &(Map->fInfo.pg);
  39. G_debug(1, "Vect_build_pg(): db='%s' table='%s', build=%d",
  40. pg_info->db_name, pg_info->table_name, build);
  41. if (build == plus->built)
  42. return 1; /* do nothing */
  43. /* TODO move this init to better place (Vect_open_ ?), because in
  44. theory build may be reused on level2 */
  45. if (build >= plus->built && build > GV_BUILD_BASE) {
  46. G_free((void *)pg_info->offset.array);
  47. G_zero(&(pg_info->offset), sizeof(struct Format_info_offset));
  48. }
  49. if (!pg_info->conn) {
  50. G_warning(_("No DB connection"));
  51. return 0;
  52. }
  53. if (!pg_info->fid_column) {
  54. G_warning(_("Feature table <%s> has no primary key defined"),
  55. pg_info->table_name);
  56. G_warning(_("Random read is not supported for this layer. "
  57. "Unable to build topology."));
  58. return 0;
  59. }
  60. /* commit transaction block (update mode only) */
  61. if (pg_info->inTransaction && execute(pg_info->conn, "COMMIT") == -1)
  62. return -1;
  63. pg_info->inTransaction = FALSE;
  64. if (build > GV_BUILD_NONE) {
  65. G_message(_("Using external data format '%s' (feature type '%s')"),
  66. Vect_get_finfo_format_info(Map),
  67. Vect_get_finfo_geometry_type(Map));
  68. if (!pg_info->toposchema_name)
  69. G_message(_("Building pseudo-topology over simple features..."));
  70. else
  71. G_message(_("Building topology from PostGIS topology schema <%s>..."),
  72. pg_info->toposchema_name);
  73. }
  74. if (!pg_info->toposchema_name)
  75. return Vect__build_sfa(Map, build);
  76. return build_topo(Map, build);
  77. #else
  78. G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
  79. return 0;
  80. #endif
  81. }
  82. #ifdef HAVE_POSTGRES
  83. /*!
  84. \brief Build from PostGIS topology schema
  85. Currently only GV_BUILD_ALL is supported
  86. \param Map pointer to Map_info struct
  87. \param build build level
  88. \return 1 on success
  89. \return 0 on error
  90. */
  91. int build_topo(struct Map_info *Map, int build)
  92. {
  93. struct Plus_head *plus;
  94. plus = &(Map->plus);
  95. /* check if upgrade or downgrade */
  96. if (build < plus->built) {
  97. /* -> downgrade */
  98. Vect__build_downgrade(Map, build);
  99. return 1;
  100. }
  101. if (build != GV_BUILD_ALL) {
  102. G_warning(_("Only %s is supported for PostGIS topology"),
  103. "GV_BUILD_ALL");
  104. return 0;
  105. }
  106. if (plus->built < GV_BUILD_BASE) {
  107. if (load_plus(Map, FALSE) != 0)
  108. return 0;
  109. }
  110. plus->built = build;
  111. return 1;
  112. }
  113. #endif