build_pg.c 3.7 KB

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