main.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /****************************************************************
  2. *
  3. * MODULE: v.external
  4. *
  5. * AUTHOR(S): Radim Blazek
  6. * Updated to GRASS 7 by Martin Landa <landa.martin gmail.com>
  7. *
  8. * PURPOSE: Create a new vector as a link to OGR layer
  9. *
  10. * COPYRIGHT: (C) 2003-2017 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General
  13. * Public License (>=v2). Read the file COPYING that
  14. * comes with GRASS for details.
  15. *
  16. **************************************************************/
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <unistd.h>
  20. #include <grass/gis.h>
  21. #include <grass/dbmi.h>
  22. #include <grass/vector.h>
  23. #include <grass/glocale.h>
  24. #ifdef HAVE_OGR
  25. #include <ogr_api.h>
  26. #endif
  27. #include "local_proto.h"
  28. int main(int argc, char *argv[])
  29. {
  30. struct GModule *module;
  31. struct _options options;
  32. struct _flags flags;
  33. struct Map_info Map;
  34. FILE *fd;
  35. int ilayer, use_ogr;
  36. char buf[GPATH_MAX], *dsn, *layer;
  37. const char *output;
  38. struct Cell_head cellhd;
  39. ds_t Ogr_ds;
  40. G_gisinit(argv[0]);
  41. module = G_define_module();
  42. G_add_keyword(_("vector"));
  43. G_add_keyword(_("import"));
  44. G_add_keyword(_("external"));
  45. G_add_keyword("OGR");
  46. G_add_keyword("PostGIS");
  47. G_add_keyword(_("level1"));
  48. module->description = _("Creates a new pseudo-vector map as a link to an OGR-supported layer "
  49. "or a PostGIS feature table.");
  50. parse_args(argc, argv,
  51. &options, &flags);
  52. use_ogr = TRUE;
  53. G_debug(1, "GRASS_VECTOR_OGR defined? %s",
  54. getenv("GRASS_VECTOR_OGR") ? "yes" : "no");
  55. if (options.dsn->answer &&
  56. G_strncasecmp(options.dsn->answer, "PG:", 3) == 0) {
  57. /* -> PostgreSQL */
  58. #if defined HAVE_OGR && defined HAVE_POSTGRES
  59. if (getenv("GRASS_VECTOR_OGR"))
  60. use_ogr = TRUE;
  61. else
  62. use_ogr = FALSE;
  63. #else
  64. #ifdef HAVE_POSTGRES
  65. if (getenv("GRASS_VECTOR_OGR"))
  66. G_warning(_("Environment variable GRASS_VECTOR_OGR defined, "
  67. "but GRASS is compiled with OGR support. "
  68. "Using GRASS-PostGIS data driver instead."));
  69. use_ogr = FALSE;
  70. #else /* -> force using OGR */
  71. G_warning(_("GRASS is not compiled with PostgreSQL support. "
  72. "Using OGR-PostgreSQL driver instead of native "
  73. "GRASS-PostGIS data driver."));
  74. use_ogr = TRUE;
  75. #endif /* HAVE_POSTRES */
  76. #endif /* HAVE_OGR && HAVE_POSTGRES */
  77. }
  78. #ifdef HAVE_OGR
  79. /* GDAL drivers must be registered since check_projection()
  80. * depends on it (even use_ogr is false)*/
  81. OGRRegisterAll();
  82. #endif
  83. if (flags.format->answer) {
  84. /* list formats */
  85. list_formats(stdout);
  86. exit(EXIT_SUCCESS);
  87. }
  88. dsn = NULL;
  89. /* disabling GRASS-PostGIS driver:
  90. * TODO: a new fn that converts OGR dsn to PQ connection info,
  91. * ignoring current GRASS db connection */
  92. use_ogr = TRUE;
  93. if (options.dsn->answer)
  94. dsn = G_store(options.dsn->answer);
  95. if (flags.list->answer || flags.tlist->answer) {
  96. /* list layers */
  97. if (!dsn)
  98. G_fatal_error(_("Required parameter <%s> not set"), options.dsn->key);
  99. list_layers(stdout, dsn, NULL,
  100. flags.tlist->answer ? TRUE : FALSE, use_ogr);
  101. exit(EXIT_SUCCESS);
  102. }
  103. /* get layer index/name */
  104. layer = NULL;
  105. if (options.layer->answer)
  106. layer = G_store(options.layer->answer);
  107. ilayer = list_layers(NULL, dsn, &layer,
  108. FALSE, use_ogr);
  109. if (ilayer == -1) {
  110. if (options.layer->answer)
  111. G_fatal_error(_("Layer <%s> not available"), options.layer->answer);
  112. else
  113. G_fatal_error(_("No layer defined"));
  114. }
  115. G_debug(2, "layer '%s' was found", layer);
  116. /* define name for output */
  117. if (!options.output->answer)
  118. output = layer;
  119. else
  120. output = options.output->answer;
  121. if (G_find_vector2(output, G_mapset()) && !G_check_overwrite(argc, argv)) {
  122. G_fatal_error(_("option <%s>: <%s> exists. To overwrite, use the --overwrite flag"),
  123. options.output->key, output);
  124. }
  125. /* open OGR DSN */
  126. Ogr_ds = NULL;
  127. if (strlen(options.dsn->answer) > 0) {
  128. #if GDAL_VERSION_NUM >= 2020000
  129. Ogr_ds = GDALOpenEx(options.dsn->answer, GDAL_OF_VECTOR, NULL, NULL, NULL);
  130. #else
  131. Ogr_ds = OGROpen(dsn, FALSE, NULL);
  132. #endif
  133. }
  134. if (Ogr_ds == NULL)
  135. G_fatal_error(_("Unable to open data source <%s>"), dsn);
  136. G_get_window(&cellhd);
  137. cellhd.north = 1.;
  138. cellhd.south = 0.;
  139. cellhd.west = 0.;
  140. cellhd.east = 1.;
  141. cellhd.top = 1.;
  142. cellhd.bottom = 0.;
  143. cellhd.rows = 1;
  144. cellhd.rows3 = 1;
  145. cellhd.cols = 1;
  146. cellhd.cols3 = 1;
  147. cellhd.depths = 1;
  148. cellhd.ns_res = 1.;
  149. cellhd.ns_res3 = 1.;
  150. cellhd.ew_res = 1.;
  151. cellhd.ew_res3 = 1.;
  152. cellhd.tb_res = 1.;
  153. /* check projection match */
  154. check_projection(&cellhd, Ogr_ds, ilayer, NULL, NULL, 0,
  155. flags.override->answer, flags.proj->answer);
  156. ds_close(Ogr_ds);
  157. /* create new vector map */
  158. putenv("GRASS_VECTOR_EXTERNAL_IGNORE=1");
  159. if (Vect_open_new(&Map, output, WITHOUT_Z) < 0) /* dimension is set later from data source */
  160. G_fatal_error(_("Unable to create vector map <%s>"), output);
  161. Vect_set_error_handler_io(NULL, &Map);
  162. Vect_hist_command(&Map);
  163. Vect_close(&Map);
  164. /* Vect_open_new created 'head', 'coor', 'hist'
  165. -> delete 'coor' and create 'frmt' */
  166. sprintf(buf, "%s/%s/%s/%s/coor", G_location_path(), G_mapset(),
  167. GV_DIRECTORY, output);
  168. G_debug(2, "Delete '%s'", buf);
  169. if (unlink(buf) == -1) {
  170. G_fatal_error(_("Unable to delete '%s'"), buf);
  171. }
  172. /* create frmt file */
  173. sprintf(buf, "%s/%s", GV_DIRECTORY, output);
  174. fd = G_fopen_new(buf, GV_FRMT_ELEMENT);
  175. if (fd == NULL)
  176. G_fatal_error(_("Unable to create file '%s/%s'"), buf, GV_FRMT_ELEMENT);
  177. if (!use_ogr) {
  178. char *table_name, *schema_name;
  179. get_table_name(layer, &table_name, &schema_name);
  180. fprintf(fd, "format: postgis\n");
  181. fprintf(fd, "conninfo: %s\n", dsn);
  182. if (schema_name)
  183. fprintf(fd, "schema: %s\n", schema_name);
  184. fprintf(fd, "table: %s\n", table_name);
  185. G_free(table_name);
  186. G_free(schema_name);
  187. }
  188. else {
  189. fprintf(fd, "format: ogr\n");
  190. fprintf(fd, "dsn: %s\n", dsn);
  191. fprintf(fd, "layer: %s\n", layer);
  192. }
  193. if (options.where->answer)
  194. fprintf(fd, "where: %s\n", options.where->answer);
  195. fclose(fd);
  196. if (!flags.topo->answer) {
  197. Vect_set_open_level(1);
  198. if (Vect_open_old(&Map, output, G_mapset()) < 0)
  199. G_fatal_error(_("Unable to open vector map <%s>"), output);
  200. Vect_build(&Map);
  201. Vect_close(&Map);
  202. }
  203. G_done_msg(_("Link to vector map <%s> created."), output);
  204. exit(EXIT_SUCCESS);
  205. }