896 struct pixelvalue *
pixval = NULL;
898 int dimpixval[2] = {1, 1};
899 int dimnoset[2] = {1, 1};
900 int hasnodata =
FALSE;
901 double nodataval = 0;
902 bool keepnodata =
FALSE;
903 bool hasnosetval =
FALSE;
904 bool nosetvalisnull =
FALSE;
919 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
924 PG_FREE_IF_COPY(pgraster, 0);
925 elog(ERROR,
"RASTER_setPixelValuesArray: Could not deserialize raster");
935 if (PG_ARGISNULL(1)) {
936 elog(NOTICE,
"Band index cannot be NULL. Value must be 1-based. Returning original raster");
938 PG_RETURN_POINTER(pgraster);
941 nband = PG_GETARG_INT32(1);
942 if (nband < 1 || nband > numbands) {
943 elog(NOTICE,
"Band index is invalid. Value must be 1-based. Returning original raster");
945 PG_RETURN_POINTER(pgraster);
949 for (i = 2, j = 0; i < 4; i++, j++) {
950 if (PG_ARGISNULL(i)) {
951 elog(NOTICE,
"%s cannot be NULL. Value must be 1-based. Returning original raster", j < 1 ?
"X" :
"Y");
953 PG_RETURN_POINTER(pgraster);
956 ul[j] = PG_GETARG_INT32(i);
959 (j < 1 && ul[j] > width) ||
960 (j > 0 && ul[j] > height)
963 elog(NOTICE,
"%s is invalid. Value must be 1-based. Returning original raster", j < 1 ?
"X" :
"Y");
965 PG_RETURN_POINTER(pgraster);
973 if (PG_ARGISNULL(4)) {
974 elog(NOTICE,
"No values to set. Returning original raster");
976 PG_RETURN_POINTER(pgraster);
979 array = PG_GETARG_ARRAYTYPE_P(4);
980 etype = ARR_ELEMTYPE(array);
981 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
989 PG_FREE_IF_COPY(pgraster, 0);
990 elog(ERROR,
"RASTER_setPixelValuesArray: Invalid data type for new values");
995 ndims = ARR_NDIM(array);
996 dims = ARR_DIMS(array);
999 if (ndims < 1 || ndims > 2) {
1000 elog(NOTICE,
"New values array must be of 1 or 2 dimensions. Returning original raster");
1002 PG_RETURN_POINTER(pgraster);
1008 dimpixval[1] = dims[0];
1010 dimpixval[0] = dims[0];
1011 dimpixval[1] = dims[1];
1018 typlen, typbyval, typalign,
1019 &elements, &nulls, &num
1023 if (num < 1 || num != (dimpixval[0] * dimpixval[1])) {
1029 PG_FREE_IF_COPY(pgraster, 0);
1030 elog(ERROR,
"RASTER_setPixelValuesArray: Could not deconstruct new values array");
1036 pixval = palloc(
sizeof(
struct pixelvalue) * numpixval);
1041 PG_FREE_IF_COPY(pgraster, 0);
1042 elog(ERROR,
"RASTER_setPixelValuesArray: Could not allocate memory for new pixel values");
1048 for (
y = 0;
y < dimpixval[0];
y++) {
1049 for (
x = 0;
x < dimpixval[1];
x++) {
1063 pixval[i].value = DatumGetFloat4(elements[i]);
1066 pixval[i].value = DatumGetFloat8(elements[i]);
1079 if (!PG_ARGISNULL(5)) {
1080 array = PG_GETARG_ARRAYTYPE_P(5);
1081 etype = ARR_ELEMTYPE(array);
1082 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
1090 PG_FREE_IF_COPY(pgraster, 0);
1091 elog(ERROR,
"RASTER_setPixelValuesArray: Invalid data type for noset flags");
1096 ndims = ARR_NDIM(array);
1097 dims = ARR_DIMS(array);
1100 if (ndims < 1 || ndims > 2) {
1101 elog(NOTICE,
"Noset flags array must be of 1 or 2 dimensions. Returning original raster");
1104 PG_RETURN_POINTER(pgraster);
1110 dimnoset[1] = dims[0];
1112 dimnoset[0] = dims[0];
1113 dimnoset[1] = dims[1];
1120 typlen, typbyval, typalign,
1121 &elements, &nulls, &num
1125 if (num < 1 || num != (dimnoset[0] * dimnoset[1])) {
1132 PG_FREE_IF_COPY(pgraster, 0);
1133 elog(ERROR,
"RASTER_setPixelValuesArray: Could not deconstruct noset flags array");
1139 for (
y = 0;
y < dimnoset[0];
y++) {
1140 if (
y >= dimpixval[0])
break;
1142 for (
x = 0;
x < dimnoset[1];
x++) {
1144 if (
x >= dimpixval[1]) {
1145 i += (dimnoset[1] - dimpixval[1]);
1149 if (!nulls[i] && DatumGetBool(elements[i]))
1157 if (
x < dimpixval[1])
1158 j += (dimpixval[1] - dimnoset[1]);
1165 else if (!PG_ARGISNULL(6) && PG_GETARG_BOOL(6)) {
1167 if (PG_ARGISNULL(7))
1168 nosetvalisnull =
TRUE;
1170 nosetval = PG_GETARG_FLOAT8(7);
1173 #if POSTGIS_DEBUG_LEVEL > 0
1174 for (i = 0; i < numpixval; i++) {
1175 POSTGIS_RT_DEBUGF(4,
"pixval[%d](x, y, noset, nodata, value) = (%d, %d, %d, %d, %f)",
1187 if (!PG_ARGISNULL(8))
1188 keepnodata = PG_GETARG_BOOL(8);
1193 elog(NOTICE,
"Could not find band at index %d. Returning original raster",
nband);
1196 PG_RETURN_POINTER(pgraster);
1209 for (i = 0; i < numpixval; i++) {
1214 else if (hasnosetval) {
1216 if (
pixval[i].nodata && nosetvalisnull)
1228 elog(NOTICE,
"Cannot set value for pixel (%d, %d) outside raster bounds: %d x %d",
1236 if (hasnodata && keepnodata) {
1241 PG_FREE_IF_COPY(pgraster, 0);
1242 elog(ERROR,
"Cannot get value of pixel");
1263 PG_FREE_IF_COPY(pgraster, 0);
1267 SET_VARSIZE(pgrtn, pgrtn->
size);
1268 PG_RETURN_POINTER(pgrtn);
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
uint16_t rt_raster_get_num_bands(rt_raster raster)
uint16_t rt_raster_get_height(rt_raster raster)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
uint16_t rt_raster_get_width(rt_raster raster)
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): ...
#define POSTGIS_RT_DEBUGF(level, msg,...)