33 #include <utils/builtins.h> 34 #include "utils/lsyscache.h" 35 #include "utils/array.h" 36 #include "catalog/pg_type.h" 57 uint16 width = 0, height = 0;
58 double ipx = 0, ipy = 0, scalex = 0, scaley = 0, skewx = 0, skewy = 0;
64 elog(ERROR,
"RASTER_makeEmpty: ST_MakeEmptyRaster requires 9 args");
69 width = PG_GETARG_UINT16(0);
72 height = PG_GETARG_UINT16(1);
75 ipx = PG_GETARG_FLOAT8(2);
78 ipy = PG_GETARG_FLOAT8(3);
81 scalex = PG_GETARG_FLOAT8(4);
84 scaley = PG_GETARG_FLOAT8(5);
87 skewx = PG_GETARG_FLOAT8(6);
90 skewy = PG_GETARG_FLOAT8(7);
93 srid = PG_GETARG_INT32(8);
96 width, height, ipx, ipy, scalex, scaley,
113 SET_VARSIZE(pgraster, pgraster->
size);
114 PG_RETURN_POINTER(pgraster);
127 int maxbandindex = 0;
129 int lastnumbands = 0;
131 text *text_pixtype = NULL;
132 char *char_pixtype = NULL;
142 struct addbandarg *arg = NULL;
162 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
167 PG_FREE_IF_COPY(pgraster, 0);
168 elog(ERROR,
"RASTER_addBand: Could not deserialize raster");
174 array = PG_GETARG_ARRAYTYPE_P(1);
175 etype = ARR_ELEMTYPE(array);
176 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
178 deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
182 PG_FREE_IF_COPY(pgraster, 0);
183 elog(ERROR,
"RASTER_addBand: Invalid argument for addbandargset");
188 arg = (
struct addbandarg *) palloc(
sizeof(
struct addbandarg) * n);
191 PG_FREE_IF_COPY(pgraster, 0);
192 elog(ERROR,
"RASTER_addBand: Could not allocate memory for addbandarg");
202 for (i = 0; i < n; i++) {
203 if (nulls[i])
continue;
208 tup = (HeapTupleHeader) DatumGetPointer(e[i]);
212 PG_FREE_IF_COPY(pgraster, 0);
213 elog(ERROR,
"RASTER_addBand: Invalid argument for addbandargset");
219 arg[i].append =
TRUE;
220 tupv = GetAttributeByName(tup,
"index", &isnull);
222 arg[i].index = DatumGetInt32(tupv);
223 arg[i].append =
FALSE;
227 if (!arg[i].append && arg[i].index < 1) {
230 PG_FREE_IF_COPY(pgraster, 0);
231 elog(ERROR,
"RASTER_addBand: Invalid argument for addbandargset. Invalid band index (must be 1-based) for addbandarg of index %d", i);
237 tupv = GetAttributeByName(tup,
"pixeltype", &isnull);
241 PG_FREE_IF_COPY(pgraster, 0);
242 elog(ERROR,
"RASTER_addBand: Invalid argument for addbandargset. Pixel type cannot be NULL for addbandarg of index %d", i);
245 text_pixtype = (text *) DatumGetPointer(tupv);
246 if (text_pixtype == NULL) {
249 PG_FREE_IF_COPY(pgraster, 0);
250 elog(ERROR,
"RASTER_addBand: Invalid argument for addbandargset. Pixel type cannot be NULL for addbandarg of index %d", i);
253 char_pixtype = text_to_cstring(text_pixtype);
257 if (arg[i].pixtype ==
PT_END) {
260 PG_FREE_IF_COPY(pgraster, 0);
261 elog(ERROR,
"RASTER_addBand: Invalid argument for addbandargset. Invalid pixel type for addbandarg of index %d", i);
266 arg[i].initialvalue = 0;
267 tupv = GetAttributeByName(tup,
"initialvalue", &isnull);
269 arg[i].initialvalue = DatumGetFloat8(tupv);
272 arg[i].hasnodata =
FALSE;
273 arg[i].nodatavalue = 0;
274 tupv = GetAttributeByName(tup,
"nodataval", &isnull);
276 arg[i].hasnodata =
TRUE;
277 arg[i].nodatavalue = DatumGetFloat8(tupv);
283 for (i = 0; i < n; i++) {
284 if (nulls[i])
continue;
287 maxbandindex = lastnumbands + 1;
290 if (!arg[i].append) {
291 if (arg[i].index > maxbandindex) {
292 elog(NOTICE,
"Band index for addbandarg of index %d exceeds possible value. Adding band at index %d", i, maxbandindex);
293 arg[i].index = maxbandindex;
298 arg[i].index = maxbandindex;
300 POSTGIS_RT_DEBUGF(4,
"new band (index, pixtype, initialvalue, hasnodata, nodatavalue) = (%d, %s, %f, %s, %f)",
304 arg[i].hasnodata ?
"TRUE" :
"FALSE",
310 arg[i].pixtype, arg[i].initialvalue,
311 arg[i].hasnodata, arg[i].nodatavalue,
316 if (numbands == lastnumbands || bandindex == -1) {
319 PG_FREE_IF_COPY(pgraster, 0);
320 elog(ERROR,
"RASTER_addBand: Could not add band defined by addbandarg of index %d to raster", i);
324 lastnumbands = numbands;
332 PG_FREE_IF_COPY(pgraster, 0);
336 SET_VARSIZE(pgrtn, pgrtn->
size);
337 PG_RETURN_POINTER(pgrtn);
354 bool appendband =
FALSE;
372 if (!PG_ARGISNULL(0)) {
373 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
378 PG_FREE_IF_COPY(pgraster, 0);
379 elog(ERROR,
"RASTER_addBandRasterArray: Could not deserialize destination raster");
387 if (!PG_ARGISNULL(2))
388 srcnband = PG_GETARG_INT32(2);
390 elog(NOTICE,
"Invalid band index for source rasters (must be 1-based). Returning original raster");
391 if (raster != NULL) {
393 PG_RETURN_POINTER(pgraster);
401 if (!PG_ARGISNULL(3)) {
402 dstnband = PG_GETARG_INT32(3);
406 elog(NOTICE,
"Invalid band index for destination raster (must be 1-based). Returning original raster");
407 if (raster != NULL) {
409 PG_RETURN_POINTER(pgraster);
419 if (raster != NULL) {
422 if (dstnumbands < 1) {
427 dstnband = dstnumbands + 1;
428 else if (dstnband > dstnumbands) {
429 elog(NOTICE,
"Band index provided for destination raster is greater than the number of bands in the raster. Bands will be appended");
431 dstnband = dstnumbands + 1;
439 array = PG_GETARG_ARRAYTYPE_P(1);
440 etype = ARR_ELEMTYPE(array);
441 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
443 deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
452 for (i = 0; i < n; i++) {
453 if (nulls[i])
continue;
463 if (pgraster != NULL)
464 PG_FREE_IF_COPY(pgraster, 0);
465 elog(ERROR,
"RASTER_addBandRasterArray: Could not deserialize source raster at index %d", i + 1);
473 if (srcnband > srcnumbands - 1) {
474 elog(NOTICE,
"Invalid band index for source raster at index %d. Returning original raster", i + 1);
478 if (raster != NULL) {
480 PG_RETURN_POINTER(pgraster);
487 if (raster == NULL) {
494 if (raster == NULL) {
497 if (pgraster != NULL)
498 PG_FREE_IF_COPY(pgraster, 0);
499 elog(ERROR,
"RASTER_addBandRasterArray: Could not create raster from source raster at index %d", i + 1);
512 elog(NOTICE,
"Could not add band from source raster at index %d to destination raster. Returning original raster", i + 1);
516 if (pgraster != NULL)
517 PG_RETURN_POINTER(pgraster);
527 if (raster != NULL) {
530 if (pgraster != NULL)
531 PG_FREE_IF_COPY(pgraster, 0);
535 SET_VARSIZE(pgrtn, pgrtn->
size);
536 PG_RETURN_POINTER(pgrtn);
555 int appendband =
FALSE;
556 char *outdbfile = NULL;
557 int *srcnband = NULL;
559 int allbands =
FALSE;
560 int hasnodata =
FALSE;
561 double nodataval = 0.;
564 char *authname = NULL;
565 char *authcode = NULL;
571 GDALRasterBandH hbandOut;
572 GDALDataType gdpixtype;
576 double ogt[6] = {0.};
582 if (!PG_ARGISNULL(0)) {
583 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
588 PG_FREE_IF_COPY(pgraster, 0);
589 elog(ERROR,
"RASTER_addBandOutDB: Could not deserialize destination raster");
597 if (!PG_ARGISNULL(1))
598 dstnband = PG_GETARG_INT32(1);
603 if (PG_ARGISNULL(2)) {
604 elog(NOTICE,
"Out-db raster file not provided. Returning original raster");
605 if (pgraster != NULL) {
607 PG_RETURN_POINTER(pgraster);
613 outdbfile = text_to_cstring(PG_GETARG_TEXT_P(2));
614 if (!strlen(outdbfile)) {
615 elog(NOTICE,
"Out-db raster file not provided. Returning original raster");
616 if (pgraster != NULL) {
618 PG_RETURN_POINTER(pgraster);
626 if (!PG_ARGISNULL(3)) {
638 array = PG_GETARG_ARRAYTYPE_P(3);
639 etype = ARR_ELEMTYPE(array);
640 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
647 if (pgraster != NULL) {
649 PG_FREE_IF_COPY(pgraster, 0);
651 elog(ERROR,
"RASTER_addBandOutDB: Invalid data type for band indexes");
656 deconstruct_array(array, etype, typlen, typbyval, typalign, &e, &nulls, &numsrcnband);
658 srcnband = palloc(
sizeof(
int) * numsrcnband);
659 if (srcnband == NULL) {
660 if (pgraster != NULL) {
662 PG_FREE_IF_COPY(pgraster, 0);
664 elog(ERROR,
"RASTER_addBandOutDB: Could not allocate memory for band indexes");
668 for (i = 0, j = 0; i < numsrcnband; i++) {
669 if (nulls[i])
continue;
673 srcnband[j] = DatumGetInt16(e[i]);
676 srcnband[j] = DatumGetInt32(e[i]);
682 if (j < numsrcnband) {
683 srcnband = repalloc(srcnband,
sizeof(
int) * j);
684 if (srcnband == NULL) {
685 if (pgraster != NULL) {
687 PG_FREE_IF_COPY(pgraster, 0);
689 elog(ERROR,
"RASTER_addBandOutDB: Could not reallocate memory for band indexes");
700 if (!PG_ARGISNULL(4)) {
702 nodataval = PG_GETARG_FLOAT8(4);
710 if (raster != NULL) {
714 elog(NOTICE,
"Invalid band index %d for adding bands. Using band index 1", dstnband);
717 else if (numbands > 0 && dstnband > numbands) {
718 elog(NOTICE,
"Invalid band index %d for adding bands. Using band index %d", dstnband, numbands);
719 dstnband = numbands + 1;
723 dstnband = numbands + 1;
729 if (hdsOut == NULL) {
730 if (pgraster != NULL) {
732 PG_FREE_IF_COPY(pgraster, 0);
734 elog(ERROR,
"RASTER_addBandOutDB: Could not open out-db file with GDAL");
739 if (GDALGetGeoTransform(hdsOut, ogt) != CE_None) {
749 if (raster == NULL) {
750 raster =
rt_raster_new(GDALGetRasterXSize(hdsOut), GDALGetRasterYSize(hdsOut));
752 elog(ERROR,
"RASTER_addBandOutDB: Could not create new raster");
761 strcmp(authname,
"EPSG") == 0 &&
767 elog(INFO,
"Unknown SRS auth name and code from out-db file. Defaulting SRID of new raster to %d",
SRID_UNKNOWN);
770 elog(INFO,
"Could not get SRS auth name and code from out-db file. Defaulting SRID of new raster to %d",
SRID_UNKNOWN);
788 if (pgraster != NULL)
789 PG_FREE_IF_COPY(pgraster, 0);
790 elog(ERROR,
"RASTER_addBandOutDB: Could not test alignment of out-db file");
794 elog(WARNING,
"The in-db representation of the out-db raster is not aligned. Band data may be incorrect");
796 numbands = GDALGetRasterCount(hdsOut);
800 numsrcnband = numbands;
801 srcnband = palloc(
sizeof(
int) * numsrcnband);
802 if (srcnband == NULL) {
806 if (pgraster != NULL)
807 PG_FREE_IF_COPY(pgraster, 0);
808 elog(ERROR,
"RASTER_addBandOutDB: Could not allocate memory for band indexes");
812 for (i = 0, j = 1; i < numsrcnband; i++, j++)
817 for (i = 0, j = dstnband - 1; i < numsrcnband; i++, j++) {
819 if (srcnband[i] < 1 || srcnband[i] > numbands) {
820 elog(NOTICE,
"Out-db file does not have a band at index %d. Returning original raster", srcnband[i]);
824 if (pgraster != NULL)
825 PG_RETURN_POINTER(pgraster);
832 hbandOut = GDALGetRasterBand(hdsOut, srcnband[i]);
833 if (NULL == hbandOut) {
837 if (pgraster != NULL)
838 PG_FREE_IF_COPY(pgraster, 0);
839 elog(ERROR,
"RASTER_addBandOutDB: Could not get band %d from GDAL dataset", srcnband[i]);
844 gdpixtype = GDALGetRasterDataType(hbandOut);
847 elog(NOTICE,
"Pixel type %s of band %d from GDAL dataset is not supported. Returning original raster", GDALGetDataTypeName(gdpixtype), srcnband[i]);
851 if (pgraster != NULL)
852 PG_RETURN_POINTER(pgraster);
859 nodataval = GDALGetRasterNoDataValue(hbandOut, &hasnodata);
865 hasnodata, nodataval,
866 srcnband[i] - 1, outdbfile
872 if (pgraster != NULL)
873 PG_FREE_IF_COPY(pgraster, 0);
874 elog(ERROR,
"RASTER_addBandOutDB: Could not create new out-db band");
882 if (pgraster != NULL)
883 PG_FREE_IF_COPY(pgraster, 0);
884 elog(ERROR,
"RASTER_addBandOutDB: Could not add new out-db band to raster");
891 if (pgraster != NULL)
892 PG_FREE_IF_COPY(pgraster, 0);
896 SET_VARSIZE(pgrtn, pgrtn->
size);
897 PG_RETURN_POINTER(pgrtn);
913 int oldtorastnumbands = 0;
914 int newtorastnumbands = 0;
915 int newbandindex = 0;
918 if (PG_ARGISNULL(0)) PG_RETURN_NULL();
919 pgto = (
rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
923 PG_FREE_IF_COPY(pgto, 0);
924 elog(ERROR,
"RASTER_copyBand: Could not deserialize first raster");
929 if (!PG_ARGISNULL(1)) {
930 pgfrom = (
rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
935 PG_FREE_IF_COPY(pgfrom, 1);
936 PG_FREE_IF_COPY(pgto, 0);
937 elog(ERROR,
"RASTER_copyBand: Could not deserialize second raster");
946 fromband = PG_GETARG_INT32(2);
949 toindex = oldtorastnumbands + 1;
951 toindex = PG_GETARG_INT32(3);
956 fromband - 1, toindex - 1
960 if (newtorastnumbands == oldtorastnumbands || newbandindex == -1) {
961 elog(NOTICE,
"RASTER_copyBand: Could not add band to raster. " 962 "Returning original raster." 967 PG_FREE_IF_COPY(pgfrom, 1);
973 PG_FREE_IF_COPY(pgto, 0);
974 if (!pgrtn) PG_RETURN_NULL();
976 SET_VARSIZE(pgrtn, pgrtn->
size);
977 PG_RETURN_POINTER(pgrtn);
986 FuncCallContext *funcctx;
1019 struct tile_arg_t *arg1 = NULL;
1020 struct tile_arg_t *arg2 = NULL;
1022 if (SRF_IS_FIRSTCALL()) {
1023 MemoryContext oldcontext;
1039 funcctx = SRF_FIRSTCALL_INIT();
1042 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1045 if (PG_ARGISNULL(0)) {
1046 MemoryContextSwitchTo(oldcontext);
1047 SRF_RETURN_DONE(funcctx);
1051 arg1 = palloc(
sizeof(
struct tile_arg_t));
1053 MemoryContextSwitchTo(oldcontext);
1054 elog(ERROR,
"RASTER_tile: Could not allocate memory for arguments");
1055 SRF_RETURN_DONE(funcctx);
1058 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
1060 if (!arg1->raster.raster) {
1062 errcode(ERRCODE_OUT_OF_MEMORY),
1063 errmsg(
"Could not deserialize raster")
1066 PG_FREE_IF_COPY(pgraster, 0);
1067 MemoryContextSwitchTo(oldcontext);
1068 SRF_RETURN_DONE(funcctx);
1085 if (PG_ARGISNULL(1)) {
1086 elog(NOTICE,
"Width cannot be NULL. Returning NULL");
1089 PG_FREE_IF_COPY(pgraster, 0);
1090 MemoryContextSwitchTo(oldcontext);
1091 SRF_RETURN_DONE(funcctx);
1093 arg1->tile.width = PG_GETARG_INT32(1);
1094 if (arg1->tile.width < 1) {
1095 elog(NOTICE,
"Width must be greater than zero. Returning NULL");
1098 PG_FREE_IF_COPY(pgraster, 0);
1099 MemoryContextSwitchTo(oldcontext);
1100 SRF_RETURN_DONE(funcctx);
1104 if (PG_ARGISNULL(2)) {
1105 elog(NOTICE,
"Height cannot be NULL. Returning NULL");
1108 PG_FREE_IF_COPY(pgraster, 0);
1109 MemoryContextSwitchTo(oldcontext);
1110 SRF_RETURN_DONE(funcctx);
1112 arg1->tile.height = PG_GETARG_INT32(2);
1113 if (arg1->tile.height < 1) {
1114 elog(NOTICE,
"Height must be greater than zero. Returning NULL");
1117 PG_FREE_IF_COPY(pgraster, 0);
1118 MemoryContextSwitchTo(oldcontext);
1119 SRF_RETURN_DONE(funcctx);
1123 if (numbands && !PG_ARGISNULL(3)) {
1124 array = PG_GETARG_ARRAYTYPE_P(3);
1125 etype = ARR_ELEMTYPE(array);
1126 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
1135 PG_FREE_IF_COPY(pgraster, 0);
1136 MemoryContextSwitchTo(oldcontext);
1137 elog(ERROR,
"RASTER_tile: Invalid data type for band indexes");
1138 SRF_RETURN_DONE(funcctx);
1142 deconstruct_array(array, etype, typlen, typbyval, typalign, &e, &nulls, &(arg1->numbands));
1144 arg1->nbands = palloc(
sizeof(
int) * arg1->numbands);
1145 if (arg1->nbands == NULL) {
1148 PG_FREE_IF_COPY(pgraster, 0);
1149 MemoryContextSwitchTo(oldcontext);
1150 elog(ERROR,
"RASTER_tile: Could not allocate memory for band indexes");
1151 SRF_RETURN_DONE(funcctx);
1154 for (i = 0, j = 0; i < arg1->numbands; i++) {
1155 if (nulls[i])
continue;
1159 arg1->nbands[j] = DatumGetInt16(e[i]) - 1;
1162 arg1->nbands[j] = DatumGetInt32(e[i]) - 1;
1169 if (j < arg1->numbands) {
1170 arg1->nbands = repalloc(arg1->nbands,
sizeof(
int) * j);
1171 if (arg1->nbands == NULL) {
1174 PG_FREE_IF_COPY(pgraster, 0);
1175 MemoryContextSwitchTo(oldcontext);
1176 elog(ERROR,
"RASTER_tile: Could not reallocate memory for band indexes");
1177 SRF_RETURN_DONE(funcctx);
1184 for (i = 0; i < arg1->numbands; i++) {
1186 elog(NOTICE,
"Band at index %d not found in raster", arg1->nbands[i] + 1);
1188 pfree(arg1->nbands);
1190 PG_FREE_IF_COPY(pgraster, 0);
1191 MemoryContextSwitchTo(oldcontext);
1192 SRF_RETURN_DONE(funcctx);
1197 arg1->numbands = numbands;
1200 arg1->nbands = palloc(
sizeof(
int) * arg1->numbands);
1202 if (arg1->nbands == NULL) {
1205 PG_FREE_IF_COPY(pgraster, 0);
1206 MemoryContextSwitchTo(oldcontext);
1207 elog(ERROR,
"RASTER_dumpValues: Could not allocate memory for pixel values");
1208 SRF_RETURN_DONE(funcctx);
1211 for (i = 0; i < arg1->numbands; i++) {
1212 arg1->nbands[i] = i;
1219 if (!PG_ARGISNULL(4)) {
1220 arg1->pad.pad = PG_GETARG_BOOL(4) ? 1 : 0;
1222 if (arg1->pad.pad && !PG_ARGISNULL(5)) {
1223 arg1->pad.hasnodata = 1;
1224 arg1->pad.nodataval = PG_GETARG_FLOAT8(5);
1227 arg1->pad.hasnodata = 0;
1228 arg1->pad.nodataval = 0;
1233 arg1->pad.hasnodata = 0;
1234 arg1->pad.nodataval = 0;
1244 arg1->tile.nx = ceil(arg1->raster.width / (
double) arg1->tile.width);
1245 arg1->tile.ny = ceil(arg1->raster.height / (
double) arg1->tile.height);
1246 POSTGIS_RT_DEBUGF(4,
"# of tiles (x, y) = (%d, %d)", arg1->tile.nx, arg1->tile.ny);
1249 funcctx->user_fctx = arg1;
1252 funcctx->max_calls = (arg1->tile.nx * arg1->tile.ny);
1254 MemoryContextSwitchTo(oldcontext);
1258 funcctx = SRF_PERCALL_SETUP();
1260 call_cntr = funcctx->call_cntr;
1261 max_calls = funcctx->max_calls;
1262 arg2 = funcctx->user_fctx;
1265 if (call_cntr < max_calls) {
1272 double nodataval = 0;
1298 ty = call_cntr / arg2->tile.nx;
1299 tx = call_cntr % arg2->tile.nx;
1303 if (!arg2->pad.pad) {
1304 if (ty + 1 == arg2->tile.ny)
1306 if (tx + 1 == arg2->tile.nx)
1311 rx = tx * arg2->tile.width;
1312 ry = ty * arg2->tile.height;
1317 width = arg2->tile.width;
1318 height = arg2->tile.height;
1324 width = arg2->raster.width - rx;
1327 height = arg2->raster.height - ry;
1339 if (arg2->numbands) pfree(arg2->nbands);
1341 elog(ERROR,
"RASTER_tile: Could not compute the coordinates of the upper-left corner of the output tile");
1342 SRF_RETURN_DONE(funcctx);
1348 len = arg2->tile.width;
1349 if (rx + arg2->tile.width >= arg2->raster.width)
1350 len = arg2->raster.width - rx;
1354 for (i = 0; i < arg2->numbands; i++) {
1358 if (_band == NULL) {
1359 int nband = arg2->nbands[i] + 1;
1362 if (arg2->numbands) pfree(arg2->nbands);
1364 elog(ERROR,
"RASTER_tile: Could not get band %d from source raster", nband);
1365 SRF_RETURN_DONE(funcctx);
1372 else if (arg2->pad.pad && arg2->pad.hasnodata) {
1374 nodataval = arg2->pad.nodataval;
1384 pfree(arg2->nbands);
1386 elog(ERROR,
"RASTER_tile: Could not add new band to output tile");
1387 SRF_RETURN_DONE(funcctx);
1393 if (arg2->numbands) pfree(arg2->nbands);
1395 elog(ERROR,
"RASTER_tile: Could not get newly added band from output tile");
1396 SRF_RETURN_DONE(funcctx);
1406 for (j = 0; j < arg2->tile.height; j++) {
1409 if (k >= arg2->raster.height) {
1418 if (arg2->numbands) pfree(arg2->nbands);
1420 elog(ERROR,
"RASTER_tile: Could not get pixel line from source raster");
1421 SRF_RETURN_DONE(funcctx);
1427 if (arg2->numbands) pfree(arg2->nbands);
1429 elog(ERROR,
"RASTER_tile: Could not set pixel line of output tile");
1430 SRF_RETURN_DONE(funcctx);
1442 hasnodata, nodataval,
1449 if (arg2->numbands) pfree(arg2->nbands);
1451 elog(ERROR,
"RASTER_tile: Could not create new offline band for output tile");
1452 SRF_RETURN_DONE(funcctx);
1459 if (arg2->numbands) pfree(arg2->nbands);
1461 elog(ERROR,
"RASTER_tile: Could not add new offline band to output tile");
1462 SRF_RETURN_DONE(funcctx);
1471 if (arg2->numbands) pfree(arg2->nbands);
1473 SRF_RETURN_DONE(funcctx);
1476 SET_VARSIZE(pgtile, pgtile->
size);
1477 SRF_RETURN_NEXT(funcctx, PointerGetDatum(pgtile));
1482 if (arg2->numbands) pfree(arg2->nbands);
1484 SRF_RETURN_DONE(funcctx);
1516 if (PG_ARGISNULL(0))
1518 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
1522 PG_FREE_IF_COPY(pgraster, 0);
1523 elog(ERROR,
"RASTER_band: Could not deserialize raster");
1528 if (PG_ARGISNULL(1)) {
1529 elog(NOTICE,
"Band number(s) not provided. Returning original raster");
1537 array = PG_GETARG_ARRAYTYPE_P(1);
1538 etype = ARR_ELEMTYPE(array);
1539 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
1547 PG_FREE_IF_COPY(pgraster, 0);
1548 elog(ERROR,
"RASTER_band: Invalid data type for band number(s)");
1553 deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
1556 bandNums = palloc(
sizeof(
uint32_t) * n);
1557 for (i = 0, j = 0; i < n; i++) {
1558 if (nulls[i])
continue;
1562 idx = (
uint32_t) DatumGetInt16(e[i]);
1565 idx = (
uint32_t) DatumGetInt32(e[i]);
1570 if (idx > numBands || idx < 1) {
1571 elog(NOTICE,
"Invalid band index (must use 1-based). Returning original raster");
1576 bandNums[j] = idx - 1;
1581 if (skip || j < 1) {
1592 PG_FREE_IF_COPY(pgraster, 0);
1594 elog(ERROR,
"RASTER_band: Could not create new raster");
1604 SET_VARSIZE(pgrast, pgrast->
size);
1605 PG_RETURN_POINTER(pgrast);
1608 PG_RETURN_POINTER(pgraster);
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
int rt_util_gdal_register_all(int force_register_all)
int rt_raster_get_num_bands(rt_raster raster)
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
rt_raster rt_raster_from_band(rt_raster raster, uint32_t *bandNums, int count)
Construct a new rt_raster from an existing rt_raster and an array of band numbers.
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
void rt_raster_set_skews(rt_raster raster, double skewX, double skewY)
Set skews about the X and Y axis.
int rt_band_is_offline(rt_band band)
Return non-zero if the given band data is on the filesystem.
void rt_band_destroy(rt_band band)
Destroy a raster band.
Datum RASTER_addBandRasterArray(PG_FUNCTION_ARGS)
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Datum RASTER_band(PG_FUNCTION_ARGS)
#define POSTGIS_RT_DEBUGF(level, msg,...)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
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).
rt_errorstate rt_raster_cell_to_geopoint(rt_raster raster, double xr, double yr, double *xw, double *yw, double *gt)
Convert an xr, yr raster point to an xw, yw point on map.
Datum RASTER_copyBand(PG_FUNCTION_ARGS)
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
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.
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
rt_errorstate rt_band_get_pixel_line(rt_band band, int x, int y, uint16_t len, void **vals, uint16_t *nvals)
Get values of multiple pixels.
void rt_raster_set_offsets(rt_raster raster, double x, double y)
Set insertion points in projection units.
#define SRID_UNKNOWN
Unknown SRID value.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Datum RASTER_addBand(PG_FUNCTION_ARGS)
int rt_raster_copy_band(rt_raster torast, rt_raster fromrast, int fromindex, int toindex)
Copy one band from one raster to another.
rt_pixtype rt_util_gdal_datatype_to_pixtype(GDALDataType gdt)
Convert GDALDataType to rt_pixtype.
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
Datum RASTER_makeEmpty(PG_FUNCTION_ARGS)
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
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).
Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
uint16_t rt_raster_get_width(rt_raster raster)
rt_errorstate rt_band_set_isnodata_flag(rt_band band, int flag)
Set isnodata flag value.
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
const char * rt_pixtype_name(rt_pixtype pixtype)
Datum RASTER_tile(PG_FUNCTION_ARGS)
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
rt_errorstate rt_band_set_pixel_line(rt_band band, int x, int y, void *vals, uint32_t len)
Set values of multiple pixels.
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
rt_errorstate rt_util_gdal_sr_auth_info(GDALDatasetH hds, char **authname, char **authcode)
Get auth name and code.
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
uint16_t rt_raster_get_height(rt_raster raster)
PG_FUNCTION_INFO_V1(RASTER_makeEmpty)
Make a new raster with no bands.
#define POSTGIS_RT_DEBUG(level, msg)
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
GDALDatasetH rt_util_gdal_open(const char *fn, GDALAccess fn_access, int shared)
rt_band rt_band_new_offline(uint16_t width, uint16_t height, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, uint8_t bandNum, const char *path)
Create an out-db rt_band.