/*! \brief Create GDAL settings for given raster map \param name map name \param map_type map type (CELL, FCELL, DCELL) \return pointer to allocated GDAL_link structure \return NULL on error */ struct GDAL_link *Rast_create_gdal_link(const char *name, RASTER_MAP_TYPE map_type) { #ifdef GDAL_LINK char path[GPATH_MAX]; GDALDriverH driver; double transform[6]; struct GDAL_link *gdal; FILE *fp; struct Key_Value *key_val; char buf[32]; Rast__init_window(); Rast_init_gdal(); if (!G_is_initialized(&st->initialized)) { read_gdal_options(); st->projinfo = G_get_projinfo(); st->projunits = G_get_projunits(); #if 0 /* We cannot use GPJ_grass_to_wkt() here because that would create a circular dependency between libgis and libgproj */ if (st->projinfo && st->projunits) st->srswkt = GPJ_grass_to_wkt(st->projinfo, st->projunits); #endif G_initialize_done(&st->initialized); } gdal = G_calloc(1, sizeof(struct GDAL_link)); sprintf(path, "%s/%s%s", st->opts.dir, name, st->opts.ext); gdal->filename = G_store(path); gdal->band_num = 1; gdal->hflip = 0; gdal->vflip = 0; switch (map_type) { case CELL_TYPE: switch (R__.nbytes) { case 1: gdal->type = GDT_Byte; gdal->null_val = (DCELL) 0xFF; break; case 2: gdal->type = GDT_UInt16; gdal->null_val = (DCELL) 0xFFFF; break; case 3: case 4: gdal->type = GDT_Int32; gdal->null_val = (DCELL) 0x80000000U; break; } break; case FCELL_TYPE: gdal->type = GDT_Float32; Rast_set_d_null_value(&gdal->null_val, 1); break; case DCELL_TYPE: gdal->type = GDT_Float64; Rast_set_d_null_value(&gdal->null_val, 1); break; default: G_fatal_error(_("Invalid map type <%d>"), map_type); break; } driver = (*pGDALGetDriverByName) (st->opts.format); if (!driver) G_fatal_error(_("Unable to get <%s> driver"), st->opts.format); /* Does driver support GDALCreate ? */ if ((*pGDALGetMetadataItem) (driver, GDAL_DCAP_CREATE, NULL)) { gdal->data = (*pGDALCreate)(driver, gdal->filename, R__.wr_window.cols, R__.wr_window.rows, 1, gdal->type, st->opts.options); if (!gdal->data) G_fatal_error(_("Unable to create <%s> dataset using <%s> driver"), name, st->opts.format); } /* If not - create MEM driver for intermediate dataset. * Check if raster can be created at all (with GDALCreateCopy) */ else if ((*pGDALGetMetadataItem) (driver, GDAL_DCAP_CREATECOPY, NULL)) { GDALDriverH mem_driver; G_message(_("Driver <%s> does not support direct writing. " "Using MEM driver for intermediate dataset."), st->opts.format); mem_driver = (*pGDALGetDriverByName) ("MEM"); if (!mem_driver) G_fatal_error(_("Unable to get in-memory raster driver")); gdal->data = (*pGDALCreate)(mem_driver, "", R__.wr_window.cols, R__.wr_window.rows, 1, gdal->type, st->opts.options); if (!gdal->data) G_fatal_error(_("Unable to create <%s> dataset using memory driver"), name); } else G_fatal_error(_("Driver <%s> does not support creating rasters"), st->opts.format); gdal->band = (*pGDALGetRasterBand) (gdal->data, gdal->band_num); (*pGDALSetRasterNoDataValue) (gdal->band, gdal->null_val); /* Set Geo Transform */ transform[0] = R__.wr_window.west; transform[1] = R__.wr_window.ew_res; transform[2] = 0.0; transform[3] = R__.wr_window.north; transform[4] = 0.0; transform[5] = -R__.wr_window.ns_res; if ((*pGDALSetGeoTransform) (gdal->data, transform) >= CE_Failure) G_warning(_("Unable to set geo transform")); if (st->srswkt) if ((*pGDALSetProjection) (gdal->data, st->srswkt) == CE_Failure) G_warning(_("Unable to set projection")); fp = G_fopen_new_misc("cell_misc", "gdal", name); if (!fp) G_fatal_error(_("Unable to create cell_misc/%s/gdal file"), name); key_val = G_create_key_value(); G_set_key_value("file", gdal->filename, key_val); sprintf(buf, "%d", gdal->band_num); G_set_key_value("band", buf, key_val); sprintf(buf, "%.22g", gdal->null_val); G_set_key_value("null", buf, key_val); sprintf(buf, "%d", gdal->type); G_set_key_value("type", buf, key_val); if (G_fwrite_key_value(fp, key_val) < 0) G_fatal_error(_("Error writing cell_misc/%s/gdal file"), name); G_free_key_value(key_val); fclose(fp); return gdal; #else return NULL; #endif }
void Rast_init_all(void) { Rast__init(); Rast__check_for_auto_masking(); Rast_init_gdal(); }
/*! \brief Get GDAL link settings for given raster map \param name map name \param mapset name of mapset \return pointer to GDAL_link structure \return NULL if link not found */ struct GDAL_link *Rast_get_gdal_link(const char *name, const char *mapset) { #ifdef GDAL_LINK GDALDatasetH data; GDALRasterBandH band; GDALDataType type; RASTER_MAP_TYPE req_type; #endif const char *filename; int band_num; struct GDAL_link *gdal; RASTER_MAP_TYPE map_type; FILE *fp; struct Key_Value *key_val; const char *p; DCELL null_val; int hflip, vflip; if (!G_find_raster2(name, mapset)) return NULL; map_type = Rast_map_type(name, mapset); if (map_type < 0) return NULL; fp = G_fopen_old_misc("cell_misc", "gdal", name, mapset); if (!fp) return NULL; key_val = G_fread_key_value(fp); fclose(fp); if (!key_val) return NULL; filename = G_find_key_value("file", key_val); if (!filename) return NULL; p = G_find_key_value("band", key_val); if (!p) return NULL; band_num = atoi(p); if (!band_num) return NULL; p = G_find_key_value("null", key_val); if (!p) return NULL; if (strcmp(p, "none") == 0) Rast_set_d_null_value(&null_val, 1); else null_val = atof(p); hflip = G_find_key_value("hflip", key_val) ? 1 : 0; vflip = G_find_key_value("vflip", key_val) ? 1 : 0; #ifdef GDAL_LINK p = G_find_key_value("type", key_val); if (!p) return NULL; type = atoi(p); switch (type) { case GDT_Byte: case GDT_Int16: case GDT_UInt16: case GDT_Int32: case GDT_UInt32: req_type = CELL_TYPE; break; case GDT_Float32: req_type = FCELL_TYPE; break; case GDT_Float64: req_type = DCELL_TYPE; break; default: return NULL; } if (req_type != map_type) return NULL; Rast_init_gdal(); data = (*pGDALOpen) (filename, GA_ReadOnly); if (!data) return NULL; band = (*pGDALGetRasterBand) (data, band_num); if (!band) { (*pGDALClose) (data); return NULL; } #endif gdal = G_calloc(1, sizeof(struct GDAL_link)); gdal->filename = G_store(filename); gdal->band_num = band_num; gdal->null_val = null_val; gdal->hflip = hflip; gdal->vflip = vflip; #ifdef GDAL_LINK gdal->data = data; gdal->band = band; gdal->type = type; #endif return gdal; }