gdal.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /*!
  2. \file lib/raster/gdal.c
  3. \brief Raster Library - Utilization of GDAL library.
  4. (C) 2010 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Glynn Clements
  8. */
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <unistd.h>
  12. #include <grass/config.h>
  13. #include <grass/gis.h>
  14. #include <grass/raster.h>
  15. #include <grass/gprojects.h>
  16. #include <grass/glocale.h>
  17. #include "R.h"
  18. #ifndef HAVE_GDAL
  19. #undef GDAL_LINK
  20. #endif
  21. #ifdef GDAL_LINK
  22. #ifdef GDAL_DYNAMIC
  23. # if defined(__unix) || defined(__unix__)
  24. # include <dlfcn.h>
  25. # endif
  26. # ifdef _WIN32
  27. # include <windows.h>
  28. # endif
  29. #endif
  30. static void CPL_STDCALL(*pGDALAllRegister) (void);
  31. static void CPL_STDCALL(*pGDALClose) (GDALDatasetH);
  32. static GDALRasterBandH CPL_STDCALL(*pGDALGetRasterBand) (GDALDatasetH, int);
  33. static GDALDatasetH CPL_STDCALL(*pGDALOpen) (const char *pszFilename,
  34. GDALAccess eAccess);
  35. static CPLErr CPL_STDCALL(*pGDALRasterIO) (GDALRasterBandH hRBand,
  36. GDALRWFlag eRWFlag, int nDSXOff,
  37. int nDSYOff, int nDSXSize,
  38. int nDSYSize, void *pBuffer,
  39. int nBXSize, int nBYSize,
  40. GDALDataType eBDataType,
  41. int nPixelSpace, int nLineSpace);
  42. static GDALDriverH CPL_STDCALL(*pGDALGetDriverByName) (const char *);
  43. static const char *CPL_STDCALL(*pGDALGetMetadataItem) (GDALMajorObjectH,
  44. const char *,
  45. const char *);
  46. static GDALDatasetH CPL_STDCALL(*pGDALCreate) (GDALDriverH hDriver,
  47. const char *, int, int, int,
  48. GDALDataType, char **);
  49. static GDALDatasetH CPL_STDCALL(*pGDALCreateCopy) (GDALDriverH, const char *,
  50. GDALDatasetH, int, char **,
  51. GDALProgressFunc, void *);
  52. static CPLErr CPL_STDCALL(*pGDALSetRasterNoDataValue) (GDALRasterBandH,
  53. double);
  54. static CPLErr CPL_STDCALL(*pGDALSetGeoTransform) (GDALDatasetH, double *);
  55. static CPLErr CPL_STDCALL(*pGDALSetProjection) (GDALDatasetH, const char *);
  56. static const char *CPL_STDCALL(*pGDALGetDriverShortName) (GDALDriverH);
  57. static GDALDriverH CPL_STDCALL(*pGDALGetDatasetDriver) (GDALDatasetH);
  58. #if GDAL_DYNAMIC
  59. # if defined(__unix) && !defined(__unix__)
  60. # define __unix__ __unix
  61. # endif
  62. static void *library_h;
  63. static void *get_symbol(const char *name)
  64. {
  65. void *sym;
  66. # ifdef __unix__
  67. sym = dlsym(library_h, name);
  68. # endif
  69. # ifdef _WIN32
  70. sym = GetProcAddress((HINSTANCE) library_h, name);
  71. # endif
  72. if (!sym)
  73. G_fatal_error(_("Unable to locate symbol <%s>"), name);
  74. return sym;
  75. }
  76. static void try_load_library(const char *name)
  77. {
  78. # ifdef __unix__
  79. library_h = dlopen(name, RTLD_NOW);
  80. # endif
  81. # ifdef _WIN32
  82. library_h = LoadLibrary(name);
  83. # endif
  84. }
  85. static void load_library(void)
  86. {
  87. static const char *const candidates[] = {
  88. # ifdef __unix__
  89. "libgdal.so.26", /* GDAL 3.0 */
  90. "libgdal.so.20",
  91. "libgdal.so.1",
  92. "libgdal.1.1.so",
  93. "gdal.1.0.so",
  94. "gdal.so.1.0",
  95. "libgdal.so",
  96. "libgdal1.6.0.so",
  97. "libgdal1.7.0.so",
  98. # endif
  99. # ifdef _WIN32
  100. "gdal303.dll",
  101. "gdal302.dll",
  102. "gdal301.dll",
  103. "gdal300.dll",
  104. "gdal204.dll",
  105. "gdal203.dll",
  106. "gdal202.dll",
  107. "gdal201.dll",
  108. "gdal200.dll",
  109. "gdal111.dll",
  110. "gdal110.dll",
  111. "gdal19.dll",
  112. "gdal18.dll",
  113. "gdal17.dll",
  114. "gdal16.dll",
  115. "gdal15.dll",
  116. "gdal11.dll",
  117. "gdal.1.0.dll",
  118. "libgdal-1.dll",
  119. "gdal.dll",
  120. # endif
  121. NULL
  122. };
  123. int i;
  124. for (i = 0; candidates[i]; i++) {
  125. try_load_library(candidates[i]);
  126. if (library_h) {
  127. G_debug(3, "found %s", candidates[i]);
  128. return;
  129. }
  130. }
  131. G_fatal_error(_("Unable to load GDAL library"));
  132. }
  133. static void init_gdal(void)
  134. {
  135. load_library();
  136. # if defined(_WIN32) && !defined(_WIN64)
  137. pGDALAllRegister = get_symbol("_GDALAllRegister@0");
  138. pGDALOpen = get_symbol("_GDALOpen@8");
  139. pGDALClose = get_symbol("_GDALClose@4");
  140. pGDALGetRasterBand = get_symbol("_GDALGetRasterBand@8");
  141. pGDALRasterIO = get_symbol("_GDALRasterIO@48");
  142. pGDALGetDriverByName = get_symbol("_GDALGetDriverByName@4");
  143. pGDALGetMetadataItem = get_symbol("_GDALGetMetadataItem@12");
  144. pGDALCreate = get_symbol("_GDALCreate@28");
  145. pGDALCreateCopy = get_symbol("_GDALCreateCopy@28");
  146. pGDALSetRasterNoDataValue = get_symbol("_GDALSetRasterNoDataValue@12");
  147. pGDALSetGeoTransform = get_symbol("_GDALSetGeoTransform@8");
  148. pGDALSetProjection = get_symbol("_GDALSetProjection@8");
  149. pGDALGetDriverShortName = get_symbol("_GDALGetDriverShortName@4");
  150. pGDALGetDatasetDriver = get_symbol("_GDALGetDatasetDriver@4");
  151. #else
  152. pGDALAllRegister = get_symbol("GDALAllRegister");
  153. pGDALOpen = get_symbol("GDALOpen");
  154. pGDALClose = get_symbol("GDALClose");
  155. pGDALGetRasterBand = get_symbol("GDALGetRasterBand");
  156. pGDALRasterIO = get_symbol("GDALRasterIO");
  157. pGDALGetDriverByName = get_symbol("GDALGetDriverByName");
  158. pGDALGetMetadataItem = get_symbol("GDALGetMetadataItem");
  159. pGDALCreate = get_symbol("GDALCreate");
  160. pGDALCreateCopy = get_symbol("GDALCreateCopy");
  161. pGDALSetRasterNoDataValue = get_symbol("GDALSetRasterNoDataValue");
  162. pGDALSetGeoTransform = get_symbol("GDALSetGeoTransform");
  163. pGDALSetProjection = get_symbol("GDALSetProjection");
  164. pGDALGetDriverShortName = get_symbol("GDALGetDriverShortName");
  165. pGDALGetDatasetDriver = get_symbol("GDALGetDatasetDriver");
  166. #endif
  167. }
  168. #else /* GDAL_DYNAMIC */
  169. static void init_gdal(void)
  170. {
  171. pGDALAllRegister = &GDALAllRegister;
  172. pGDALOpen = &GDALOpen;
  173. pGDALClose = &GDALClose;
  174. pGDALGetRasterBand = &GDALGetRasterBand;
  175. pGDALRasterIO = &GDALRasterIO;
  176. pGDALGetDriverByName = &GDALGetDriverByName;
  177. pGDALGetMetadataItem = &GDALGetMetadataItem;
  178. pGDALCreate = &GDALCreate;
  179. pGDALCreateCopy = &GDALCreateCopy;
  180. pGDALSetRasterNoDataValue = &GDALSetRasterNoDataValue;
  181. pGDALSetGeoTransform = &GDALSetGeoTransform;
  182. pGDALSetProjection = &GDALSetProjection;
  183. pGDALGetDriverShortName = &GDALGetDriverShortName;
  184. pGDALGetDatasetDriver = &GDALGetDatasetDriver;
  185. }
  186. #endif /* GDAL_DYNAMIC */
  187. #endif /* GDAL_LINK */
  188. /*!
  189. \brief Initialization
  190. Register all GDAL drivers.
  191. */
  192. void Rast_init_gdal(void)
  193. {
  194. #ifdef GDAL_LINK
  195. static int initialized;
  196. if (G_is_initialized(&initialized))
  197. return;
  198. init_gdal();
  199. (*pGDALAllRegister) ();
  200. G_initialize_done(&initialized);
  201. #endif
  202. }
  203. /*!
  204. \brief Get GDAL link settings for given raster map
  205. \param name map name
  206. \param mapset name of mapset
  207. \return pointer to GDAL_link structure
  208. \return NULL if link not found
  209. */
  210. struct GDAL_link *Rast_get_gdal_link(const char *name, const char *mapset)
  211. {
  212. #ifdef GDAL_LINK
  213. GDALDatasetH data;
  214. GDALRasterBandH band;
  215. GDALDataType type;
  216. RASTER_MAP_TYPE req_type;
  217. #endif
  218. const char *filename;
  219. int band_num;
  220. struct GDAL_link *gdal;
  221. RASTER_MAP_TYPE map_type;
  222. FILE *fp;
  223. struct Key_Value *key_val;
  224. const char *p;
  225. DCELL null_val;
  226. int hflip, vflip;
  227. if (!G_find_raster2(name, mapset))
  228. return NULL;
  229. map_type = Rast_map_type(name, mapset);
  230. if (map_type < 0)
  231. return NULL;
  232. fp = G_fopen_old_misc("cell_misc", "gdal", name, mapset);
  233. if (!fp)
  234. return NULL;
  235. key_val = G_fread_key_value(fp);
  236. fclose(fp);
  237. if (!key_val)
  238. return NULL;
  239. filename = G_find_key_value("file", key_val);
  240. if (!filename)
  241. return NULL;
  242. p = G_find_key_value("band", key_val);
  243. if (!p)
  244. return NULL;
  245. band_num = atoi(p);
  246. if (!band_num)
  247. return NULL;
  248. p = G_find_key_value("null", key_val);
  249. if (!p)
  250. return NULL;
  251. /* atof on windows can not read "nan" and returns 0 instead */
  252. if (strcmp(p, "none") == 0 ||
  253. G_strcasecmp(p, "nan") == 0 || G_strcasecmp(p, "-nan") == 0) {
  254. Rast_set_d_null_value(&null_val, 1);
  255. }
  256. else
  257. null_val = atof(p);
  258. hflip = G_find_key_value("hflip", key_val) ? 1 : 0;
  259. vflip = G_find_key_value("vflip", key_val) ? 1 : 0;
  260. #ifdef GDAL_LINK
  261. p = G_find_key_value("type", key_val);
  262. if (!p)
  263. return NULL;
  264. type = atoi(p);
  265. switch (type) {
  266. case GDT_Byte:
  267. case GDT_Int16:
  268. case GDT_UInt16:
  269. case GDT_Int32:
  270. case GDT_UInt32:
  271. req_type = CELL_TYPE;
  272. break;
  273. case GDT_Float32:
  274. req_type = FCELL_TYPE;
  275. break;
  276. case GDT_Float64:
  277. req_type = DCELL_TYPE;
  278. break;
  279. default:
  280. return NULL;
  281. }
  282. if (req_type != map_type)
  283. return NULL;
  284. Rast_init_gdal();
  285. data = (*pGDALOpen) (filename, GA_ReadOnly);
  286. if (!data)
  287. return NULL;
  288. band = (*pGDALGetRasterBand) (data, band_num);
  289. if (!band) {
  290. (*pGDALClose) (data);
  291. return NULL;
  292. }
  293. #endif
  294. gdal = G_calloc(1, sizeof(struct GDAL_link));
  295. gdal->filename = G_store(filename);
  296. gdal->band_num = band_num;
  297. gdal->null_val = null_val;
  298. gdal->hflip = hflip;
  299. gdal->vflip = vflip;
  300. #ifdef GDAL_LINK
  301. gdal->data = data;
  302. gdal->band = band;
  303. gdal->type = type;
  304. #endif
  305. return gdal;
  306. }
  307. struct GDAL_Options
  308. {
  309. const char *dir;
  310. const char *ext;
  311. const char *format;
  312. char **options;
  313. };
  314. static struct state
  315. {
  316. int initialized;
  317. struct GDAL_Options opts;
  318. struct Key_Value *projinfo, *projunits, *projepsg;
  319. char *srswkt;
  320. } state;
  321. static struct state *st = &state;
  322. static void read_gdal_options(void)
  323. {
  324. FILE *fp;
  325. struct Key_Value *key_val;
  326. const char *p;
  327. fp = G_fopen_old("", "GDAL", G_mapset());
  328. if (!fp)
  329. G_fatal_error(_("Unable to open GDAL file"));
  330. key_val = G_fread_key_value(fp);
  331. fclose(fp);
  332. p = G_find_key_value("directory", key_val);
  333. if (!p)
  334. p = "gdal";
  335. if (*p == '/') {
  336. st->opts.dir = G_store(p);
  337. }
  338. else {
  339. char path[GPATH_MAX];
  340. G_file_name(path, p, "", G_mapset());
  341. st->opts.dir = G_store(path);
  342. if (access(path, 0) != 0)
  343. G_make_mapset_object_group(p);
  344. }
  345. p = G_find_key_value("extension", key_val);
  346. st->opts.ext = G_store(p ? p : "");
  347. p = G_find_key_value("format", key_val);
  348. st->opts.format = G_store(p ? p : "GTiff");
  349. p = G_find_key_value("options", key_val);
  350. st->opts.options = p ? G_tokenize(p, ",") : NULL;
  351. G_free_key_value(key_val);
  352. }
  353. /*!
  354. \brief Create GDAL settings for given raster map
  355. \param name map name
  356. \param map_type map type (CELL, FCELL, DCELL)
  357. \return pointer to allocated GDAL_link structure
  358. \return NULL on error
  359. */
  360. struct GDAL_link *Rast_create_gdal_link(const char *name,
  361. RASTER_MAP_TYPE map_type)
  362. {
  363. #ifdef GDAL_LINK
  364. char path[GPATH_MAX];
  365. GDALDriverH driver;
  366. double transform[6];
  367. struct GDAL_link *gdal;
  368. FILE *fp;
  369. struct Key_Value *key_val;
  370. char buf[32];
  371. Rast__init_window();
  372. Rast_init_gdal();
  373. if (!G_is_initialized(&st->initialized)) {
  374. read_gdal_options();
  375. st->projinfo = G_get_projinfo();
  376. st->projunits = G_get_projunits();
  377. st->projepsg = G_get_projepsg();
  378. if (st->projinfo && st->projunits)
  379. st->srswkt = GPJ_grass_to_wkt2(st->projinfo, st->projunits,
  380. st->projepsg, 0, 0);
  381. G_initialize_done(&st->initialized);
  382. }
  383. gdal = G_calloc(1, sizeof(struct GDAL_link));
  384. sprintf(path, "%s/%s%s", st->opts.dir, name, st->opts.ext);
  385. gdal->filename = G_store(path);
  386. gdal->band_num = 1;
  387. gdal->hflip = 0;
  388. gdal->vflip = 0;
  389. switch (map_type) {
  390. case CELL_TYPE:
  391. switch (R__.nbytes) {
  392. case 1:
  393. gdal->type = GDT_Byte;
  394. gdal->null_val = (DCELL) 0xFF;
  395. break;
  396. case 2:
  397. gdal->type = GDT_UInt16;
  398. gdal->null_val = (DCELL) 0xFFFF;
  399. break;
  400. case 3:
  401. case 4:
  402. gdal->type = GDT_Int32;
  403. gdal->null_val = (DCELL) 0x80000000U;
  404. break;
  405. }
  406. break;
  407. case FCELL_TYPE:
  408. gdal->type = GDT_Float32;
  409. Rast_set_d_null_value(&gdal->null_val, 1);
  410. break;
  411. case DCELL_TYPE:
  412. gdal->type = GDT_Float64;
  413. Rast_set_d_null_value(&gdal->null_val, 1);
  414. break;
  415. default:
  416. G_fatal_error(_("Invalid map type <%d>"), map_type);
  417. break;
  418. }
  419. driver = (*pGDALGetDriverByName) (st->opts.format);
  420. if (!driver)
  421. G_fatal_error(_("Unable to get <%s> driver"), st->opts.format);
  422. /* Does driver support GDALCreate ? */
  423. if ((*pGDALGetMetadataItem) (driver, GDAL_DCAP_CREATE, NULL)) {
  424. gdal->data =
  425. (*pGDALCreate)(driver, gdal->filename,
  426. R__.wr_window.cols, R__.wr_window.rows,
  427. 1, gdal->type, st->opts.options);
  428. if (!gdal->data)
  429. G_fatal_error(_("Unable to create <%s> dataset using <%s> driver"),
  430. name, st->opts.format);
  431. }
  432. /* If not - create MEM driver for intermediate dataset.
  433. * Check if raster can be created at all (with GDALCreateCopy) */
  434. else if ((*pGDALGetMetadataItem) (driver, GDAL_DCAP_CREATECOPY, NULL)) {
  435. GDALDriverH mem_driver;
  436. G_message(_("Driver <%s> does not support direct writing. "
  437. "Using MEM driver for intermediate dataset."),
  438. st->opts.format);
  439. mem_driver = (*pGDALGetDriverByName) ("MEM");
  440. if (!mem_driver)
  441. G_fatal_error(_("Unable to get in-memory raster driver"));
  442. gdal->data =
  443. (*pGDALCreate)(mem_driver, "",
  444. R__.wr_window.cols, R__.wr_window.rows,
  445. 1, gdal->type, st->opts.options);
  446. if (!gdal->data)
  447. G_fatal_error(_("Unable to create <%s> dataset using memory driver"),
  448. name);
  449. }
  450. else
  451. G_fatal_error(_("Driver <%s> does not support creating rasters"),
  452. st->opts.format);
  453. gdal->band = (*pGDALGetRasterBand) (gdal->data, gdal->band_num);
  454. (*pGDALSetRasterNoDataValue) (gdal->band, gdal->null_val);
  455. /* Set Geo Transform */
  456. transform[0] = R__.wr_window.west;
  457. transform[1] = R__.wr_window.ew_res;
  458. transform[2] = 0.0;
  459. transform[3] = R__.wr_window.north;
  460. transform[4] = 0.0;
  461. transform[5] = -R__.wr_window.ns_res;
  462. if ((*pGDALSetGeoTransform) (gdal->data, transform) >= CE_Failure)
  463. G_warning(_("Unable to set geo transform"));
  464. if (st->srswkt)
  465. if ((*pGDALSetProjection) (gdal->data, st->srswkt) == CE_Failure)
  466. G_warning(_("Unable to set projection"));
  467. fp = G_fopen_new_misc("cell_misc", "gdal", name);
  468. if (!fp)
  469. G_fatal_error(_("Unable to create cell_misc/%s/gdal file"), name);
  470. key_val = G_create_key_value();
  471. G_set_key_value("file", gdal->filename, key_val);
  472. sprintf(buf, "%d", gdal->band_num);
  473. G_set_key_value("band", buf, key_val);
  474. sprintf(buf, "%.22g", gdal->null_val);
  475. G_set_key_value("null", buf, key_val);
  476. sprintf(buf, "%d", gdal->type);
  477. G_set_key_value("type", buf, key_val);
  478. if (G_fwrite_key_value(fp, key_val) < 0)
  479. G_fatal_error(_("Error writing cell_misc/%s/gdal file"), name);
  480. G_free_key_value(key_val);
  481. fclose(fp);
  482. return gdal;
  483. #else
  484. return NULL;
  485. #endif
  486. }
  487. /*!
  488. \brief Close existing GDAL link
  489. \param gdal pointer to GDAL_link to be closed
  490. */
  491. void Rast_close_gdal_link(struct GDAL_link *gdal)
  492. {
  493. #ifdef GDAL_LINK
  494. (*pGDALClose) (gdal->data);
  495. #endif
  496. G_free(gdal->filename);
  497. G_free(gdal);
  498. }
  499. /*!
  500. \brief Close existing GDAL link and write out data
  501. \param gdal pointer to GDAL_link to be closed
  502. \return 1 on success
  503. \return -1 on failure
  504. */
  505. int Rast_close_gdal_write_link(struct GDAL_link *gdal)
  506. {
  507. int stat = 1;
  508. #ifdef GDAL_LINK
  509. GDALDriverH src_drv = (*pGDALGetDatasetDriver) (gdal->data);
  510. if (G_strcasecmp((*pGDALGetDriverShortName) (src_drv), "MEM") == 0) {
  511. GDALDriverH dst_drv = (*pGDALGetDriverByName) (st->opts.format);
  512. GDALDatasetH dst =
  513. (*pGDALCreateCopy) (dst_drv, gdal->filename, gdal->data, FALSE,
  514. st->opts.options, NULL, NULL);
  515. if (!dst) {
  516. G_warning(_("Unable to create output file <%s> using driver <%s>"),
  517. gdal->filename, st->opts.format);
  518. stat = -1;
  519. }
  520. (*pGDALClose) (dst);
  521. }
  522. (*pGDALClose) (gdal->data);
  523. #endif
  524. G_free(gdal->filename);
  525. G_free(gdal);
  526. return stat;
  527. }
  528. #ifdef GDAL_LINK
  529. /*!
  530. \brief Input/output function for GDAL links
  531. See GDAL's RasterIO for details.
  532. */
  533. CPLErr Rast_gdal_raster_IO(GDALRasterBandH band, GDALRWFlag rw_flag,
  534. int x_off, int y_off, int x_size, int y_size,
  535. void *buffer, int buf_x_size, int buf_y_size,
  536. GDALDataType buf_type, int pixel_size,
  537. int line_size)
  538. {
  539. return (*pGDALRasterIO) (band, rw_flag, x_off, y_off, x_size, y_size,
  540. buffer, buf_x_size, buf_y_size, buf_type,
  541. pixel_size, line_size);
  542. }
  543. #endif