475 FuncCallContext *funcctx;
480 struct bandmetadata {
492 struct bandmetadata *bmd = NULL;
493 struct bandmetadata *bmd2 = NULL;
498 if (SRF_IS_FIRSTCALL()) {
499 MemoryContext oldcontext;
518 uint32_t *bandNums = NULL;
519 const char *chartmp = NULL;
526 funcctx = SRF_FIRSTCALL_INIT();
529 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
532 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
533 MemoryContextSwitchTo(oldcontext);
535 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
537 "function returning record called in context "
538 "that cannot accept type record"
543 BlessTupleDesc(tupdesc);
544 funcctx->tuple_desc = tupdesc;
547 if (PG_ARGISNULL(0)) {
548 bmd = (
struct bandmetadata *) palloc(
sizeof(
struct bandmetadata));
549 bmd->isnullband =
TRUE;
550 funcctx->user_fctx = bmd;
551 funcctx->max_calls = 1;
552 MemoryContextSwitchTo(oldcontext);
555 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
560 PG_FREE_IF_COPY(pgraster, 0);
561 MemoryContextSwitchTo(oldcontext);
562 elog(ERROR,
"RASTER_bandmetadata: Could not deserialize raster");
563 SRF_RETURN_DONE(funcctx);
569 elog(NOTICE,
"Raster provided has no bands");
571 PG_FREE_IF_COPY(pgraster, 0);
572 bmd = (
struct bandmetadata *) palloc(
sizeof(
struct bandmetadata));
573 bmd->isnullband =
TRUE;
574 funcctx->user_fctx = bmd;
575 funcctx->max_calls = 1;
576 MemoryContextSwitchTo(oldcontext);
581 array = PG_GETARG_ARRAYTYPE_P(1);
582 etype = ARR_ELEMTYPE(array);
583 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
591 PG_FREE_IF_COPY(pgraster, 0);
592 MemoryContextSwitchTo(oldcontext);
593 elog(ERROR,
"RASTER_bandmetadata: Invalid data type for band number(s)");
594 SRF_RETURN_DONE(funcctx);
598 deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
601 bandNums = palloc(
sizeof(uint32_t) * n);
602 for (i = 0, j = 0; i < n; i++) {
603 if (nulls[i])
continue;
607 idx = (uint32_t) DatumGetInt16(e[i]);
610 idx = (uint32_t) DatumGetInt32(e[i]);
615 if (idx > numBands || idx < 1) {
616 elog(NOTICE,
"Invalid band index: %d. Indices must be 1-based. Returning NULL", idx);
619 PG_FREE_IF_COPY(pgraster, 0);
620 bmd = (
struct bandmetadata *) palloc(
sizeof(
struct bandmetadata));
621 bmd->isnullband =
TRUE;
622 funcctx->user_fctx = bmd;
623 funcctx->max_calls = 1;
624 MemoryContextSwitchTo(oldcontext);
635 bandNums = repalloc(bandNums,
sizeof(uint32_t) * j);
636 for (i = 0; i < j; i++)
640 bandNums = repalloc(bandNums,
sizeof(uint32_t) * j);
642 bmd = (
struct bandmetadata *) palloc0(
sizeof(
struct bandmetadata) * j);
644 for (i = 0; i < j; i++) {
647 elog(NOTICE,
"Could not get raster band at index %d", bandNums[i]);
649 PG_FREE_IF_COPY(pgraster, 0);
650 bmd[0].isnullband =
TRUE;
651 funcctx->user_fctx = bmd;
652 funcctx->max_calls = 1;
653 MemoryContextSwitchTo(oldcontext);
658 bmd[i].bandnum = bandNums[i];
662 charlen = strlen(chartmp) + 1;
663 bmd[i].pixeltype = palloc(
sizeof(
char) * charlen);
664 strncpy(bmd[i].pixeltype, chartmp, charlen);
668 bmd[i].hasnodata =
TRUE;
670 bmd[i].hasnodata =
FALSE;
673 if (bmd[i].hasnodata)
676 bmd[i].nodataval = 0;
681 charlen = strlen(chartmp) + 1;
682 bmd[i].bandpath = palloc(
sizeof(
char) * charlen);
683 strncpy(bmd[i].bandpath, chartmp, charlen);
686 bmd[i].bandpath = NULL;
689 bmd[i].isoutdb = bmd[i].bandpath ?
TRUE :
FALSE;
693 bmd[i].extbandnum = extbandnum + 1;
695 bmd[i].extbandnum = 0;
698 bmd[i].timestamp = 0;
701 if( VSIStatL(bmd[i].bandpath, &sStat) == 0 ) {
702 bmd[i].filesize = sStat.st_size;
703 bmd[i].timestamp = sStat.st_mtime;
711 PG_FREE_IF_COPY(pgraster, 0);
714 funcctx->user_fctx = bmd;
717 funcctx->max_calls = j;
719 MemoryContextSwitchTo(oldcontext);
725 funcctx = SRF_PERCALL_SETUP();
727 call_cntr = funcctx->call_cntr;
728 max_calls = funcctx->max_calls;
729 tupdesc = funcctx->tuple_desc;
730 bmd2 = funcctx->user_fctx;
733 if (call_cntr < max_calls) {
737 if (bmd2[0].isnullband) {
741 result = HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls));
742 SRF_RETURN_NEXT(funcctx,
result);
747 values[0] = UInt32GetDatum(bmd2[call_cntr].bandnum);
748 values[1] = CStringGetTextDatum(bmd2[call_cntr].pixeltype);
750 if (bmd2[call_cntr].hasnodata)
751 values[2] = Float8GetDatum(bmd2[call_cntr].nodataval);
755 values[3] = BoolGetDatum(bmd2[call_cntr].isoutdb);
756 if (bmd2[call_cntr].bandpath && strlen(bmd2[call_cntr].bandpath)) {
757 values[4] = CStringGetTextDatum(bmd2[call_cntr].bandpath);
758 values[5] = UInt32GetDatum(bmd2[call_cntr].extbandnum);
765 if (bmd2[call_cntr].filesize)
767 values[6] = UInt64GetDatum(bmd2[call_cntr].filesize);
768 values[7] = UInt64GetDatum(bmd2[call_cntr].timestamp);
777 tuple = heap_form_tuple(tupdesc, values, nulls);
780 result = HeapTupleGetDatum(tuple);
783 pfree(bmd2[call_cntr].pixeltype);
784 if (bmd2[call_cntr].bandpath) pfree(bmd2[call_cntr].bandpath);
786 SRF_RETURN_NEXT(funcctx,
result);
791 SRF_RETURN_DONE(funcctx);
char result[OUT_DOUBLE_BUFFER_SIZE]
const char * rt_band_get_ext_path(rt_band band)
Return band's external path (only valid when rt_band_is_offline returns non-zero).
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
void rt_band_destroy(rt_band band)
Destroy a raster band.
uint16_t rt_raster_get_num_bands(rt_raster raster)
rt_errorstate rt_band_get_ext_band_num(rt_band band, uint8_t *bandnum)
Return bands' external band number (only valid when rt_band_is_offline returns non-zero).
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
const char * rt_pixtype_name(rt_pixtype pixtype)
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
bool enable_outdb_rasters
#define POSTGIS_RT_DEBUG(level, msg)
#define POSTGIS_RT_DEBUGF(level, msg,...)