build_ogr.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*!
  2. \file lib/vector/Vlib/build_ogr.c
  3. \brief Vector library - Building topology for OGR
  4. Higher level functions for reading/writing/manipulating vectors.
  5. Category: FID, not all layer have FID, OGRNullFID is defined
  6. (5/2004) as -1, so FID should be only >= 0
  7. (C) 2001-2010, 2012 by the GRASS Development Team
  8. This program is free software under the GNU General Public License
  9. (>=v2). Read the file COPYING that comes with GRASS for details.
  10. \author Radim Blazek, Piero Cavalieri
  11. \author Various updates for GRASS 7 by Martin Landa <landa.martin gmail.com>
  12. */
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <grass/vector.h>
  17. #include <grass/glocale.h>
  18. #ifdef HAVE_OGR
  19. #include <ogr_api.h>
  20. #include <cpl_error.h>
  21. #endif
  22. #include "local_proto.h"
  23. /*!
  24. \brief Build pseudo-topology (simple features) for OGR layer
  25. Build levels:
  26. - GV_BUILD_NONE
  27. - GV_BUILD_BASE
  28. - GV_BUILD_ATTACH_ISLES
  29. - GV_BUILD_CENTROIDS
  30. - GV_BUILD_ALL
  31. \param Map pointer to Map_info structure
  32. \param build build level
  33. \return 1 on success
  34. \return 0 on error
  35. */
  36. int Vect_build_ogr(struct Map_info *Map, int build)
  37. {
  38. #ifdef HAVE_OGR
  39. struct Plus_head *plus;
  40. struct Format_info_ogr *ogr_info;
  41. plus = &(Map->plus);
  42. ogr_info = &(Map->fInfo.ogr);
  43. G_debug(1, "Vect_build_ogr(): dsn='%s' layer='%s', build=%d",
  44. ogr_info->dsn, ogr_info->layer_name, build);
  45. if (build == plus->built)
  46. return 1; /* do nothing */
  47. /* TODO move this init to better place (Vect_open_ ?), because in
  48. theory build may be reused on level2 */
  49. if (build >= plus->built && build > GV_BUILD_BASE) {
  50. G_free((void *) ogr_info->offset.array);
  51. G_zero(&(ogr_info->offset), sizeof(struct Format_info_offset));
  52. }
  53. if (!ogr_info->layer) {
  54. G_warning(_("Empty OGR layer, nothing to build"));
  55. return 0;
  56. }
  57. if (OGR_L_TestCapability(ogr_info->layer, OLCTransactions)) {
  58. CPLPushErrorHandler(CPLQuietErrorHandler);
  59. if (OGR_L_CommitTransaction(ogr_info->layer) != OGRERR_NONE)
  60. G_debug(1, "Unable to commit transaction");
  61. CPLPushErrorHandler(CPLDefaultErrorHandler);
  62. }
  63. /* test layer capabilities */
  64. if (!OGR_L_TestCapability(ogr_info->layer, OLCRandomRead)) {
  65. if (strcmp(OGR_Dr_GetName(OGR_DS_GetDriver(Map->fInfo.ogr.ds)),
  66. "PostgreSQL") == 0)
  67. G_warning(_("Feature table <%s> has no primary key defined"),
  68. ogr_info->layer_name);
  69. G_warning(_("Random read is not supported by OGR for this layer. "
  70. "Unable to build topology."));
  71. return 0;
  72. }
  73. if (build > GV_BUILD_NONE)
  74. G_message(_("Using external data format '%s' (feature type '%s')"),
  75. Vect_get_finfo_format_info(Map),
  76. Vect_get_finfo_geometry_type(Map));
  77. return Vect__build_sfa(Map, build);
  78. #else
  79. G_fatal_error(_("GRASS is not compiled with OGR support"));
  80. return 0;
  81. #endif
  82. }
  83. /*!
  84. \brief Save feature index file for vector map
  85. \param Map pointer to Map_info structure
  86. \param offset pointer to Format_info_offset struct
  87. (see Format_info_ogr and Format_info_pg struct for implementation issues)
  88. \return 1 on success
  89. \return 0 on error
  90. */
  91. int Vect_save_fidx(struct Map_info *Map,
  92. struct Format_info_offset *offset)
  93. {
  94. #ifdef HAVE_OGR
  95. char fname[GPATH_MAX], elem[GPATH_MAX];
  96. char buf[5];
  97. long length;
  98. struct gvfile fp;
  99. struct Port_info port;
  100. if (strcmp(Map->mapset, G_mapset()) != 0 ||
  101. Map->support_updated == FALSE ||
  102. Map->plus.built != GV_BUILD_ALL)
  103. return 1;
  104. length = 9;
  105. sprintf(elem, "%s/%s", GV_DIRECTORY, Map->name);
  106. Vect__get_element_path(fname, Map, GV_FIDX_ELEMENT);
  107. G_debug(4, "Open fidx: %s", fname);
  108. dig_file_init(&fp);
  109. fp.file = fopen(fname, "w");
  110. if (fp.file == NULL) {
  111. G_warning(_("Unable to open fidx file for write <%s>"), fname);
  112. return 0;
  113. }
  114. dig_init_portable(&port, dig__byte_order_out());
  115. dig_set_cur_port(&port);
  116. /* Header */
  117. /* bytes 1 - 5 */
  118. buf[0] = 5;
  119. buf[1] = 0;
  120. buf[2] = 5;
  121. buf[3] = 0;
  122. buf[4] = (char)dig__byte_order_out();
  123. if (0 >= dig__fwrite_port_C(buf, 5, &fp))
  124. return 0;
  125. /* bytes 6 - 9 : header size */
  126. if (0 >= dig__fwrite_port_L(&length, 1, &fp))
  127. return 0;
  128. /* Body */
  129. /* number of records */
  130. if (0 >= dig__fwrite_port_I(&(offset->array_num), 1, &fp))
  131. return 0;
  132. /* offsets */
  133. if (0 >= dig__fwrite_port_I(offset->array,
  134. offset->array_num, &fp))
  135. return 0;
  136. G_debug(3, "Vect_save_fidx(): offset_num = %d", offset->array_num);
  137. fclose(fp.file);
  138. return 1;
  139. #else
  140. G_fatal_error(_("GRASS is not compiled with OGR support"));
  141. return 0;
  142. #endif
  143. }