PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ rt_raster_from_gdal_dataset()

rt_raster rt_raster_from_gdal_dataset ( GDALDatasetH  ds)

Return a raster from a GDAL dataset.

Parameters
ds: the GDAL dataset to convert to a raster
Returns
raster or NULL

Definition at line 2177 of file rt_raster.c.

2177 {
2178 rt_raster rast = NULL;
2179 double gt[6] = {0};
2180 CPLErr cplerr;
2181 uint32_t width = 0;
2182 uint32_t height = 0;
2183 uint32_t numBands = 0;
2184 uint32_t i = 0;
2185 char *authname = NULL;
2186 char *authcode = NULL;
2187
2188 GDALRasterBandH gdband = NULL;
2189 GDALDataType gdpixtype = GDT_Unknown;
2190 rt_band band;
2191 int32_t idx;
2192 rt_pixtype pt = PT_END;
2193 uint32_t ptlen = 0;
2194 int hasnodata = 0;
2195 double nodataval;
2196
2197 int x;
2198 int y;
2199
2200 uint32_t nXBlocks, nYBlocks;
2201 int nXBlockSize, nYBlockSize;
2202 uint32_t iXBlock, iYBlock;
2203 uint32_t nXValid, nYValid;
2204 uint32_t iY;
2205
2206 uint8_t *values = NULL;
2207 uint32_t valueslen = 0;
2208 uint8_t *ptr = NULL;
2209
2210 assert(NULL != ds);
2211
2212 /* raster size */
2213 width = GDALGetRasterXSize(ds);
2214 height = GDALGetRasterYSize(ds);
2215 RASTER_DEBUGF(3, "Raster dimensions (width x height): %d x %d", width, height);
2216
2217 /* create new raster */
2218 RASTER_DEBUG(3, "Creating new raster");
2219 rast = rt_raster_new(width, height);
2220 if (NULL == rast) {
2221 rterror("rt_raster_from_gdal_dataset: Out of memory allocating new raster");
2222 return NULL;
2223 }
2224 RASTER_DEBUGF(3, "Created raster dimensions (width x height): %d x %d", rast->width, rast->height);
2225
2226 /* get raster attributes */
2227 cplerr = GDALGetGeoTransform(ds, gt);
2228 if (GDALGetGeoTransform(ds, gt) != CE_None) {
2229 RASTER_DEBUG(4, "Using default geotransform matrix (0, 1, 0, 0, 0, -1)");
2230 gt[0] = 0;
2231 gt[1] = 1;
2232 gt[2] = 0;
2233 gt[3] = 0;
2234 gt[4] = 0;
2235 gt[5] = -1;
2236 }
2237
2238 /* apply raster attributes */
2240
2241 RASTER_DEBUGF(3, "Raster geotransform (%f, %f, %f, %f, %f, %f)",
2242 gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]);
2243
2244 /* srid */
2245 if (rt_util_gdal_sr_auth_info(ds, &authname, &authcode) == ES_NONE) {
2246 if (
2247 authname != NULL &&
2248 strcmp(authname, "EPSG") == 0 &&
2249 authcode != NULL
2250 ) {
2251 rt_raster_set_srid(rast, atoi(authcode));
2252 RASTER_DEBUGF(3, "New raster's SRID = %d", rast->srid);
2253 }
2254
2255 if (authname != NULL)
2256 rtdealloc(authname);
2257 if (authcode != NULL)
2258 rtdealloc(authcode);
2259 }
2260
2261 numBands = GDALGetRasterCount(ds);
2262
2263#if POSTGIS_DEBUG_LEVEL > 3
2264 for (i = 1; i <= numBands; i++) {
2265 GDALRasterBandH _grb = NULL;
2266 double _min;
2267 double _max;
2268 double _mean;
2269 double _stddev;
2270
2271 _grb = GDALGetRasterBand(ds, i);
2272 GDALComputeRasterStatistics(_grb, FALSE, &_min, &_max, &_mean, &_stddev, NULL, NULL);
2273 RASTER_DEBUGF(4, "GDAL Band %d stats: %f, %f, %f, %f", i, _min, _max, _mean, _stddev);
2274 }
2275#endif
2276
2277 /* copy bands */
2278 for (i = 1; i <= numBands; i++) {
2279 RASTER_DEBUGF(3, "Processing band %d of %d", i, numBands);
2280 gdband = NULL;
2281 gdband = GDALGetRasterBand(ds, i);
2282 if (NULL == gdband) {
2283 rterror("rt_raster_from_gdal_dataset: Could not get GDAL band");
2284 rt_raster_destroy(rast);
2285 return NULL;
2286 }
2287 RASTER_DEBUGF(4, "gdband @ %p", gdband);
2288
2289 /* pixtype */
2290 gdpixtype = GDALGetRasterDataType(gdband);
2291 RASTER_DEBUGF(4, "gdpixtype, size = %s, %d", GDALGetDataTypeName(gdpixtype), GDALGetDataTypeSize(gdpixtype) / 8);
2292 pt = rt_util_gdal_datatype_to_pixtype(gdpixtype);
2293 if (pt == PT_END) {
2294 rterror("rt_raster_from_gdal_dataset: Unknown pixel type for GDAL band");
2295 rt_raster_destroy(rast);
2296 return NULL;
2297 }
2298 ptlen = rt_pixtype_size(pt);
2299
2300 /* size: width and height */
2301 width = GDALGetRasterBandXSize(gdband);
2302 height = GDALGetRasterBandYSize(gdband);
2303 RASTER_DEBUGF(3, "GDAL band dimensions (width x height): %d x %d", width, height);
2304
2305 /* nodata */
2306 nodataval = GDALGetRasterNoDataValue(gdband, &hasnodata);
2307 RASTER_DEBUGF(3, "(hasnodata, nodataval) = (%d, %f)", hasnodata, nodataval);
2308
2309 /* create band object */
2311 rast, pt,
2312 (hasnodata ? nodataval : 0),
2313 hasnodata, nodataval, rt_raster_get_num_bands(rast)
2314 );
2315 if (idx < 0) {
2316 rterror("rt_raster_from_gdal_dataset: Could not allocate memory for raster band");
2317 rt_raster_destroy(rast);
2318 return NULL;
2319 }
2320 band = rt_raster_get_band(rast, idx);
2321 RASTER_DEBUGF(3, "Created band of dimension (width x height): %d x %d", band->width, band->height);
2322
2323 /* this makes use of GDAL's "natural" blocks */
2324 GDALGetBlockSize(gdband, &nXBlockSize, &nYBlockSize);
2325 nXBlocks = (width + nXBlockSize - 1) / nXBlockSize;
2326 nYBlocks = (height + nYBlockSize - 1) / nYBlockSize;
2327 RASTER_DEBUGF(4, "(nXBlockSize, nYBlockSize) = (%d, %d)", nXBlockSize, nYBlockSize);
2328 RASTER_DEBUGF(4, "(nXBlocks, nYBlocks) = (%d, %d)", nXBlocks, nYBlocks);
2329
2330 /* allocate memory for values */
2331 valueslen = ptlen * nXBlockSize * nYBlockSize;
2332 values = rtalloc(valueslen);
2333 if (values == NULL) {
2334 rterror("rt_raster_from_gdal_dataset: Could not allocate memory for GDAL band pixel values");
2335 rt_raster_destroy(rast);
2336 return NULL;
2337 }
2338 RASTER_DEBUGF(3, "values @ %p of length = %d", values, valueslen);
2339
2340 for (iYBlock = 0; iYBlock < nYBlocks; iYBlock++) {
2341 for (iXBlock = 0; iXBlock < nXBlocks; iXBlock++) {
2342 x = iXBlock * nXBlockSize;
2343 y = iYBlock * nYBlockSize;
2344 RASTER_DEBUGF(4, "(iXBlock, iYBlock) = (%d, %d)", iXBlock, iYBlock);
2345 RASTER_DEBUGF(4, "(x, y) = (%d, %d)", x, y);
2346
2347 memset(values, 0, valueslen);
2348
2349 /* valid block width */
2350 if ((iXBlock + 1) * nXBlockSize > width)
2351 nXValid = width - (iXBlock * nXBlockSize);
2352 else
2353 nXValid = nXBlockSize;
2354
2355 /* valid block height */
2356 if ((iYBlock + 1) * nYBlockSize > height)
2357 nYValid = height - (iYBlock * nYBlockSize);
2358 else
2359 nYValid = nYBlockSize;
2360
2361 RASTER_DEBUGF(4, "(nXValid, nYValid) = (%d, %d)", nXValid, nYValid);
2362
2363 cplerr = GDALRasterIO(
2364 gdband, GF_Read,
2365 x, y,
2366 nXValid, nYValid,
2367 values, nXValid, nYValid,
2368 gdpixtype,
2369 0, 0
2370 );
2371 if (cplerr != CE_None) {
2372 rterror("rt_raster_from_gdal_dataset: Could not get data from GDAL raster");
2373 rtdealloc(values);
2374 rt_raster_destroy(rast);
2375 return NULL;
2376 }
2377
2378 /* if block width is same as raster width, shortcut */
2379 if (nXBlocks == 1 && nYBlockSize > 1 && nXValid == width) {
2380 x = 0;
2381 y = nYBlockSize * iYBlock;
2382
2383 RASTER_DEBUGF(4, "Setting set of pixel lines at (%d, %d) for %d pixels", x, y, nXValid * nYValid);
2384 rt_band_set_pixel_line(band, x, y, values, nXValid * nYValid);
2385 }
2386 else {
2387 ptr = values;
2388 x = nXBlockSize * iXBlock;
2389 for (iY = 0; iY < nYValid; iY++) {
2390 y = iY + (nYBlockSize * iYBlock);
2391
2392 RASTER_DEBUGF(4, "Setting pixel line at (%d, %d) for %d pixels", x, y, nXValid);
2393 rt_band_set_pixel_line(band, x, y, ptr, nXValid);
2394 ptr += (nXValid * ptlen);
2395 }
2396 }
2397 }
2398 }
2399
2400 /* free memory */
2401 rtdealloc(values);
2402 }
2403
2404 return rast;
2405}
#define FALSE
Definition dbfopen.c:168
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
Definition rt_context.c:199
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition rt_context.c:171
rt_pixtype rt_util_gdal_datatype_to_pixtype(GDALDataType gdt)
Convert GDALDataType to rt_pixtype.
Definition rt_util.c:155
#define RASTER_DEBUG(level, msg)
Definition librtcore.h:295
#define RASTER_DEBUGF(level, msg,...)
Definition librtcore.h:299
rt_pixtype
Definition librtcore.h:185
@ PT_END
Definition librtcore.h:197
@ ES_NONE
Definition librtcore.h:180
rt_errorstate rt_band_set_pixel_line(rt_band band, int x, int y, void *vals, uint32_t len)
Set values of multiple pixels.
Definition rt_band.c:853
void rtdealloc(void *mem)
Definition rt_context.c:186
rt_errorstate rt_util_gdal_sr_auth_info(GDALDatasetH hds, char **authname, char **authcode)
Get auth name and code.
Definition rt_util.c:272
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition rt_pixel.c:39
int rt_raster_generate_new_band(rt_raster raster, rt_pixtype pixtype, double initialvalue, uint32_t hasnodata, double nodatavalue, int index)
Generate a new inline band and add it to a raster.
Definition rt_raster.c:485
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
Definition rt_raster.c:727
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition rt_raster.c:82
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition rt_raster.c:48
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition rt_raster.c:372
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.
Definition rt_raster.c:381
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition rt_raster.c:363

References ES_NONE, FALSE, PT_END, RASTER_DEBUG, RASTER_DEBUGF, rt_band_set_pixel_line(), rt_pixtype_size(), rt_raster_destroy(), rt_raster_generate_new_band(), rt_raster_get_band(), rt_raster_get_num_bands(), rt_raster_new(), rt_raster_set_geotransform_matrix(), rt_raster_set_srid(), rt_util_gdal_datatype_to_pixtype(), rt_util_gdal_sr_auth_info(), rtalloc(), rtdealloc(), and rterror().

Referenced by build_overview(), convert_raster(), RASTER_fromGDALRaster(), rt_band_load_offline_data(), rt_raster_gdal_rasterize(), rt_raster_gdal_warp(), and test_gdal_to_raster().

Here is the call graph for this function:
Here is the caller graph for this function: