main.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /****************************************************************************
  2. *
  3. * MODULE: r.external
  4. *
  5. * AUTHOR(S): Glynn Clements, based on r.in.gdal
  6. * List GDAL layers by Martin Landa <landa.martin gmail.com> 8/2011
  7. *
  8. * PURPOSE: Link raster map into GRASS utilizing the GDAL library.
  9. *
  10. * COPYRIGHT: (C) 2008-2015 by Glynn Clements and the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <math.h>
  20. #include <string.h>
  21. #include <grass/gis.h>
  22. #include <grass/raster.h>
  23. #include <grass/imagery.h>
  24. #include <grass/glocale.h>
  25. #include <gdal.h>
  26. #include <ogr_srs_api.h>
  27. #include <cpl_conv.h>
  28. #include "proto.h"
  29. int main(int argc, char *argv[])
  30. {
  31. const char *input, *source, *output;
  32. char *title;
  33. struct Cell_head cellhd;
  34. GDALDatasetH hDS;
  35. GDALRasterBandH hBand;
  36. struct GModule *module;
  37. struct {
  38. struct Option *input, *source, *output, *band, *title;
  39. } parm;
  40. struct {
  41. struct Flag *o, *j, *f, *e, *h, *v, *t, *a;
  42. } flag;
  43. int min_band, max_band, band;
  44. struct band_info info;
  45. int flip;
  46. struct Ref reference;
  47. G_gisinit(argv[0]);
  48. module = G_define_module();
  49. G_add_keyword(_("raster"));
  50. G_add_keyword(_("import"));
  51. G_add_keyword(_("external"));
  52. module->description =
  53. _("Links GDAL supported raster data as a pseudo GRASS raster map.");
  54. parm.input = G_define_standard_option(G_OPT_F_INPUT);
  55. parm.input->description = _("Name of raster file to be linked");
  56. parm.input->required = NO;
  57. parm.input->guisection = _("Input");
  58. parm.source = G_define_option();
  59. parm.source->key = "source";
  60. parm.source->description = _("Name of non-file GDAL data source");
  61. parm.source->required = NO;
  62. parm.source->type = TYPE_STRING;
  63. parm.source->key_desc = "name";
  64. parm.source->guisection = _("Input");
  65. parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
  66. parm.band = G_define_option();
  67. parm.band->key = "band";
  68. parm.band->type = TYPE_INTEGER;
  69. parm.band->required = NO;
  70. parm.band->description = _("Band to select (default is all bands)");
  71. parm.band->guisection = _("Input");
  72. parm.title = G_define_option();
  73. parm.title->key = "title";
  74. parm.title->key_desc = "phrase";
  75. parm.title->type = TYPE_STRING;
  76. parm.title->required = NO;
  77. parm.title->description = _("Title for resultant raster map");
  78. parm.title->guisection = _("Metadata");
  79. flag.f = G_define_flag();
  80. flag.f->key = 'f';
  81. flag.f->description = _("List supported formats and exit");
  82. flag.f->guisection = _("Print");
  83. flag.f->suppress_required = YES;
  84. flag.o = G_define_flag();
  85. flag.o->key = 'o';
  86. flag.o->label =
  87. _("Override projection check (use current location's projection)");
  88. flag.o->description =
  89. _("Assume that the dataset has same projection as the current location");
  90. flag.j = G_define_flag();
  91. flag.j->key = 'j';
  92. flag.j->description =
  93. _("Perform projection check only and exit");
  94. flag.j->suppress_required = YES;
  95. flag.e = G_define_flag();
  96. flag.e->key = 'e';
  97. flag.e->label = _("Extend region extents based on new dataset");
  98. flag.e->description = _("Also updates the default region if in the PERMANENT mapset");
  99. flag.a = G_define_flag();
  100. flag.a->key = 'a';
  101. flag.a->label = _("Auto-adjustment for lat/lon");
  102. flag.a->description = _("Attempt to fix small precision errors in resolution and extents");
  103. flag.h = G_define_flag();
  104. flag.h->key = 'h';
  105. flag.h->description = _("Flip horizontally");
  106. flag.v = G_define_flag();
  107. flag.v->key = 'v';
  108. flag.v->description = _("Flip vertically");
  109. flag.t = G_define_flag();
  110. flag.t->key = 't';
  111. flag.t->label =
  112. _("List available bands including band type in dataset and exit");
  113. flag.t->description = _("Format: band number,type,projection check");
  114. flag.t->guisection = _("Print");
  115. flag.t->suppress_required = YES;
  116. if (G_parser(argc, argv))
  117. exit(EXIT_FAILURE);
  118. GDALAllRegister();
  119. if (flag.f->answer) {
  120. list_formats();
  121. exit(EXIT_SUCCESS);
  122. }
  123. input = parm.input->answer;
  124. source = parm.source->answer;
  125. output = parm.output->answer;
  126. flip = 0;
  127. if (flag.h->answer)
  128. flip |= FLIP_H;
  129. if (flag.v->answer)
  130. flip |= FLIP_V;
  131. if (parm.title->answer) {
  132. title = G_store(parm.title->answer);
  133. G_strip(title);
  134. }
  135. else
  136. title = NULL;
  137. if (!input && !source)
  138. G_fatal_error(_("%s= or %s= must be given"),
  139. parm.input->key, parm.source->key);
  140. if (input && source)
  141. G_fatal_error(_("%s= and %s= are mutually exclusive"),
  142. parm.input->key, parm.source->key);
  143. if (input && !G_is_absolute_path(input)) {
  144. char path[GPATH_MAX], *cwd;
  145. cwd = CPLGetCurrentDir();
  146. if (!cwd)
  147. G_fatal_error(_("Unable to get current working directory"));
  148. G_snprintf(path, GPATH_MAX, "%s%c%s", cwd, HOST_DIRSEP, input);
  149. input = G_store(path);
  150. CPLFree(cwd);
  151. }
  152. if (!input)
  153. input = source;
  154. hDS = GDALOpen(input, GA_ReadOnly);
  155. if (hDS == NULL)
  156. return 1;
  157. setup_window(&cellhd, hDS, &flip);
  158. if (flag.t->answer) {
  159. list_bands(&cellhd, hDS);
  160. /* close the GDALDataset to avoid segfault in libgdal */
  161. GDALClose(hDS);
  162. exit(EXIT_SUCCESS);
  163. }
  164. check_projection(&cellhd, hDS, NULL, 0, flag.o->answer, flag.j->answer);
  165. if (flag.a->answer && cellhd.proj == PROJECTION_LL) {
  166. G_adjust_Cell_head(&cellhd, 1, 1);
  167. G_adjust_window_ll(&cellhd);
  168. }
  169. Rast_set_window(&cellhd);
  170. if (parm.band->answer)
  171. min_band = max_band = atoi(parm.band->answer);
  172. else
  173. min_band = 1, max_band = GDALGetRasterCount(hDS);
  174. G_verbose_message(_("Proceeding with import..."));
  175. if (max_band > min_band) {
  176. if (I_find_group(output) == 1)
  177. G_warning(_("Imagery group <%s> already exists and will be overwritten."), output);
  178. I_init_group_ref(&reference);
  179. }
  180. for (band = min_band; band <= max_band; band++) {
  181. char *output2, *title2 = NULL;
  182. G_message(_("Reading band %d of %d..."),
  183. band, GDALGetRasterCount( hDS ));
  184. hBand = GDALGetRasterBand(hDS, band);
  185. if (!hBand)
  186. G_fatal_error(_("Selected band (%d) does not exist"), band);
  187. if (max_band > min_band) {
  188. G_asprintf(&output2, "%s.%d", output, band);
  189. if (title)
  190. G_asprintf(&title2, "%s (band %d)", title, band);
  191. G_debug(1, "Adding raster map <%s> to group <%s>", output2, output);
  192. I_add_file_to_group_ref(output2, G_mapset(), &reference);
  193. }
  194. else {
  195. output2 = G_store(output);
  196. if (title)
  197. title2 = G_store(title);
  198. }
  199. query_band(hBand, output2, &cellhd, &info);
  200. create_map(input, band, output2, &cellhd, &info, title, flip);
  201. G_free(output2);
  202. G_free(title2);
  203. }
  204. /* close the GDALDataset to avoid segfault in libgdal */
  205. GDALClose(hDS);
  206. if (flag.e->answer)
  207. update_default_window(&cellhd);
  208. /* Create the imagery group if multiple bands are imported */
  209. if (max_band > min_band) {
  210. I_put_group_ref(output, &reference);
  211. I_put_group(output);
  212. G_message(_("Imagery group <%s> created"), output);
  213. }
  214. exit(EXIT_SUCCESS);
  215. }