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

◆ build_overview()

static int build_overview ( int  idx,
RTLOADERCFG config,
RASTERINFO info,
uint32_t  ovx,
STRINGBUFFER tileset,
STRINGBUFFER buffer 
)
static

Definition at line 1328 of file raster2pgsql.c.

1328 {
1329 GDALDatasetH hdsSrc;
1330 VRTDatasetH hdsOv;
1331 VRTSourcedRasterBandH hbandOv;
1332 double gtOv[6] = {0.};
1333 int dimOv[2] = {0};
1334
1335 uint32_t j = 0;
1336 int factor;
1337 const char *ovtable = NULL;
1338
1339 VRTDatasetH hdsDst;
1340 VRTSourcedRasterBandH hbandDst;
1341 int tile_size[2] = {0};
1342 int _tile_size[2] = {0};
1343 int ntiles[2] = {1, 1};
1344 int xtile = 0;
1345 int ytile = 0;
1346 double gt[6] = {0.};
1347
1348 rt_raster rast = NULL;
1349 char *hex;
1350 uint32_t hexlen = 0;
1351
1352 hdsSrc = GDALOpenShared(config->rt_file[idx], GA_ReadOnly);
1353 if (hdsSrc == NULL) {
1354 rterror(_("build_overview: Could not open raster: %s"), config->rt_file[idx]);
1355 return 0;
1356 }
1357
1358 /* working copy of geotransform matrix */
1359 memcpy(gtOv, info->gt, sizeof(double) * 6);
1360
1361 if (ovx >= config->overview_count) {
1362 rterror(_("build_overview: Invalid overview index: %d"), ovx);
1363 return 0;
1364 }
1365 factor = config->overview[ovx];
1366 ovtable = (const char *) config->overview_table[ovx];
1367
1368 /* factor must be within valid range */
1369 if (factor < MINOVFACTOR || factor > MAXOVFACTOR) {
1370 rterror(_("build_overview: Overview factor %d is not between %d and %d"), factor, MINOVFACTOR, MAXOVFACTOR);
1371 return 0;
1372 }
1373
1374 dimOv[0] = (int) (info->dim[0] + (factor / 2)) / factor;
1375 dimOv[1] = (int) (info->dim[1] + (factor / 2)) / factor;
1376
1377 /* create VRT dataset */
1378 hdsOv = VRTCreate(dimOv[0], dimOv[1]);
1379 /*
1380 GDALSetDescription(hdsOv, "/tmp/ov.vrt");
1381 */
1382 GDALSetProjection(hdsOv, info->srs);
1383
1384 /* adjust scale */
1385 gtOv[1] *= factor;
1386 gtOv[5] *= factor;
1387
1388 GDALSetGeoTransform(hdsOv, gtOv);
1389
1390 /* add bands as simple sources */
1391 for (j = 0; j < info->nband_count; j++) {
1392 GDALAddBand(hdsOv, info->gdalbandtype[j], NULL);
1393 hbandOv = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsOv, j + 1);
1394
1395 if (info->hasnodata[j])
1396 GDALSetRasterNoDataValue(hbandOv, info->nodataval[j]);
1397
1398 VRTAddSimpleSource(
1399 hbandOv, GDALGetRasterBand(hdsSrc, info->nband[j]),
1400 0, 0,
1401 info->dim[0], info->dim[1],
1402 0, 0,
1403 dimOv[0], dimOv[1],
1404 "near", VRT_NODATA_UNSET
1405 );
1406 }
1407
1408 /* make sure VRT reflects all changes */
1409 VRTFlushCache(hdsOv);
1410
1411 /* decide on tile size */
1412 if (!config->tile_size[0])
1413 tile_size[0] = dimOv[0];
1414 else
1415 tile_size[0] = config->tile_size[0];
1416 if (!config->tile_size[1])
1417 tile_size[1] = dimOv[1];
1418 else
1419 tile_size[1] = config->tile_size[1];
1420
1421 /* number of tiles */
1422 if (
1423 tile_size[0] != dimOv[0] &&
1424 tile_size[1] != dimOv[1]
1425 ) {
1426 ntiles[0] = (dimOv[0] + tile_size[0] - 1) / tile_size[0];
1427 ntiles[1] = (dimOv[1] + tile_size[1] - 1) / tile_size[1];
1428 }
1429
1430 /* working copy of geotransform matrix */
1431 memcpy(gt, gtOv, sizeof(double) * 6);
1432
1433 /* tile overview */
1434 /* each tile is a VRT with constraints set for just the data required for the tile */
1435 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1436
1437 /* edge y tile */
1438 if (!config->pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1439 _tile_size[1] = dimOv[1] - (ytile * tile_size[1]);
1440 else
1441 _tile_size[1] = tile_size[1];
1442
1443 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1444 /*
1445 char fn[100];
1446 sprintf(fn, "/tmp/ovtile%d.vrt", (ytile * ntiles[0]) + xtile);
1447 */
1448
1449 /* edge x tile */
1450 if (!config->pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1451 _tile_size[0] = dimOv[0] - (xtile * tile_size[0]);
1452 else
1453 _tile_size[0] = tile_size[0];
1454
1455 /* compute tile's upper-left corner */
1456 GDALApplyGeoTransform(
1457 gtOv,
1458 xtile * tile_size[0], ytile * tile_size[1],
1459 &(gt[0]), &(gt[3])
1460 );
1461
1462 /* create VRT dataset */
1463 hdsDst = VRTCreate(_tile_size[0], _tile_size[1]);
1464 /*
1465 GDALSetDescription(hdsDst, fn);
1466 */
1467 GDALSetProjection(hdsDst, info->srs);
1468 GDALSetGeoTransform(hdsDst, gt);
1469
1470 /* add bands as simple sources */
1471 for (j = 0; j < info->nband_count; j++) {
1472 GDALAddBand(hdsDst, info->gdalbandtype[j], NULL);
1473 hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, j + 1);
1474
1475 if (info->hasnodata[j])
1476 GDALSetRasterNoDataValue(hbandDst, info->nodataval[j]);
1477
1478 VRTAddSimpleSource(
1479 hbandDst, GDALGetRasterBand(hdsOv, j + 1),
1480 xtile * tile_size[0], ytile * tile_size[1],
1481 _tile_size[0], _tile_size[1],
1482 0, 0,
1483 _tile_size[0], _tile_size[1],
1484 "near", VRT_NODATA_UNSET
1485 );
1486 }
1487
1488 /* make sure VRT reflects all changes */
1489 VRTFlushCache(hdsDst);
1490
1491 /* convert VRT dataset to rt_raster */
1493 if (rast == NULL) {
1494 rterror(_("build_overview: Could not convert VRT dataset to PostGIS raster"));
1495 GDALClose(hdsDst);
1496 return 0;
1497 }
1498
1499 /* set srid if provided */
1500 rt_raster_set_srid(rast, info->srid);
1501
1502 /* convert rt_raster to hexwkb */
1503 hex = rt_raster_to_hexwkb(rast, FALSE, &hexlen);
1504 raster_destroy(rast);
1505
1506 if (hex == NULL) {
1507 rterror(_("build_overview: Could not convert PostGIS raster to hex WKB"));
1508 GDALClose(hdsDst);
1509 return 0;
1510 }
1511
1512 /* add hexwkb to tileset */
1513 append_stringbuffer(tileset, hex);
1514
1515 GDALClose(hdsDst);
1516
1517 /* flush if tileset gets too big */
1518 if (tileset->length > 10) {
1519 if (!insert_records(
1520 config->schema, ovtable, config->raster_column,
1521 (config->file_column ? config->rt_filename[idx] : NULL), config->file_column_name,
1522 config->copy_statements, config->out_srid,
1523 tileset, buffer
1524 )) {
1525 rterror(_("build_overview: Could not convert raster tiles into INSERT or COPY statements"));
1526 GDALClose(hdsSrc);
1527 return 0;
1528 }
1529
1530 rtdealloc_stringbuffer(tileset, 0);
1531 }
1532 }
1533 }
1534
1535 GDALClose(hdsOv);
1536 GDALClose(hdsSrc);
1537 return 1;
1538}
#define FALSE
Definition dbfopen.c:168
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
Definition rt_context.c:199
rt_raster rt_raster_from_gdal_dataset(GDALDatasetH ds)
Return a raster from a GDAL dataset.
Definition rt_raster.c:2177
char * rt_raster_to_hexwkb(rt_raster raster, int outasin, uint32_t *hexwkbsize)
Return this raster in HEXWKB form (null-terminated hex)
Definition rt_wkb.c:679
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition rt_raster.c:363
Datum buffer(PG_FUNCTION_ARGS)
static int append_stringbuffer(STRINGBUFFER *buffer, const char *str)
static void rtdealloc_stringbuffer(STRINGBUFFER *buffer, int freebuffer)
static int insert_records(const char *schema, const char *table, const char *column, const char *filename, const char *file_column_name, int copy_statements, int out_srid, STRINGBUFFER *tileset, STRINGBUFFER *buffer)
static void raster_destroy(rt_raster raster)
#define MAXOVFACTOR
#define MINOVFACTOR
#define _(String)
Definition shpcommon.h:24
double * nodataval
double gt[6]
uint32_t nband_count
GDALDataType * gdalbandtype
uint32_t dim[2]

References _, append_stringbuffer(), buffer(), raster_loader_config::copy_statements, rasterinfo_t::dim, FALSE, raster_loader_config::file_column, raster_loader_config::file_column_name, rasterinfo_t::gdalbandtype, rasterinfo_t::gt, rasterinfo_t::hasnodata, insert_records(), stringbuffer_t::length, MAXOVFACTOR, MINOVFACTOR, rasterinfo_t::nband, rasterinfo_t::nband_count, rasterinfo_t::nodataval, raster_loader_config::out_srid, raster_loader_config::overview, raster_loader_config::overview_count, raster_loader_config::overview_table, raster_loader_config::pad_tile, raster_loader_config::raster_column, raster_destroy(), raster_loader_config::rt_file, raster_loader_config::rt_filename, rt_raster_from_gdal_dataset(), rt_raster_set_srid(), rt_raster_to_hexwkb(), rtdealloc_stringbuffer(), rterror(), raster_loader_config::schema, rasterinfo_t::srid, rasterinfo_t::srs, and raster_loader_config::tile_size.

Referenced by process_rasters().

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