697 struct pixelvalue *
pixval = NULL;
699 int dimpixval[2] = {1, 1};
700 int dimnoset[2] = {1, 1};
701 int hasnodata =
FALSE;
702 double nodataval = 0;
703 bool keepnodata =
FALSE;
704 bool hasnosetval =
FALSE;
705 bool nosetvalisnull =
FALSE;
720 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
725 PG_FREE_IF_COPY(pgraster, 0);
726 elog(ERROR,
"RASTER_setPixelValuesArray: Could not deserialize raster");
736 if (PG_ARGISNULL(1)) {
737 elog(NOTICE,
"Band index cannot be NULL. Value must be 1-based. Returning original raster");
739 PG_RETURN_POINTER(pgraster);
742 nband = PG_GETARG_INT32(1);
743 if (nband < 1 || nband > numbands) {
744 elog(NOTICE,
"Band index is invalid. Value must be 1-based. Returning original raster");
746 PG_RETURN_POINTER(pgraster);
750 for (i = 2, j = 0; i < 4; i++, j++) {
751 if (PG_ARGISNULL(i)) {
752 elog(NOTICE,
"%s cannot be NULL. Value must be 1-based. Returning original raster", j < 1 ?
"X" :
"Y");
754 PG_RETURN_POINTER(pgraster);
757 ul[j] = PG_GETARG_INT32(i);
760 (j < 1 && ul[j] > width) ||
761 (j > 0 && ul[j] > height)
764 elog(NOTICE,
"%s is invalid. Value must be 1-based. Returning original raster", j < 1 ?
"X" :
"Y");
766 PG_RETURN_POINTER(pgraster);
774 if (PG_ARGISNULL(4)) {
775 elog(NOTICE,
"No values to set. Returning original raster");
777 PG_RETURN_POINTER(pgraster);
780 array = PG_GETARG_ARRAYTYPE_P(4);
781 etype = ARR_ELEMTYPE(array);
782 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
790 PG_FREE_IF_COPY(pgraster, 0);
791 elog(ERROR,
"RASTER_setPixelValuesArray: Invalid data type for new values");
796 ndims = ARR_NDIM(array);
797 dims = ARR_DIMS(array);
800 if (ndims < 1 || ndims > 2) {
801 elog(NOTICE,
"New values array must be of 1 or 2 dimensions. Returning original raster");
803 PG_RETURN_POINTER(pgraster);
809 dimpixval[1] = dims[0];
811 dimpixval[0] = dims[0];
812 dimpixval[1] = dims[1];
819 typlen, typbyval, typalign,
820 &elements, &nulls, &num
824 if (num < 1 || num != (dimpixval[0] * dimpixval[1])) {
830 PG_FREE_IF_COPY(pgraster, 0);
831 elog(ERROR,
"RASTER_setPixelValuesArray: Could not deconstruct new values array");
837 pixval = palloc(
sizeof(
struct pixelvalue) * numpixval);
838 if (pixval == NULL) {
842 PG_FREE_IF_COPY(pgraster, 0);
843 elog(ERROR,
"RASTER_setPixelValuesArray: Could not allocate memory for new pixel values");
849 for (y = 0; y < dimpixval[0]; y++) {
850 for (x = 0; x < dimpixval[1]; x++) {
852 pixval[i].x = ul[0] +
x;
853 pixval[i].y = ul[1] +
y;
855 pixval[i].noset =
FALSE;
856 pixval[i].nodata =
FALSE;
860 pixval[i].nodata =
TRUE;
864 pixval[i].value = DatumGetFloat4(elements[i]);
867 pixval[i].value = DatumGetFloat8(elements[i]);
880 if (!PG_ARGISNULL(5)) {
881 array = PG_GETARG_ARRAYTYPE_P(5);
882 etype = ARR_ELEMTYPE(array);
883 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
891 PG_FREE_IF_COPY(pgraster, 0);
892 elog(ERROR,
"RASTER_setPixelValuesArray: Invalid data type for noset flags");
897 ndims = ARR_NDIM(array);
898 dims = ARR_DIMS(array);
901 if (ndims < 1 || ndims > 2) {
902 elog(NOTICE,
"Noset flags array must be of 1 or 2 dimensions. Returning original raster");
905 PG_RETURN_POINTER(pgraster);
911 dimnoset[1] = dims[0];
913 dimnoset[0] = dims[0];
914 dimnoset[1] = dims[1];
921 typlen, typbyval, typalign,
922 &elements, &nulls, &num
926 if (num < 1 || num != (dimnoset[0] * dimnoset[1])) {
933 PG_FREE_IF_COPY(pgraster, 0);
934 elog(ERROR,
"RASTER_setPixelValuesArray: Could not deconstruct noset flags array");
940 for (y = 0; y < dimnoset[0]; y++) {
941 if (y >= dimpixval[0])
break;
943 for (x = 0; x < dimnoset[1]; x++) {
945 if (x >= dimpixval[1]) {
946 i += (dimnoset[1] - dimpixval[1]);
950 if (!nulls[i] && DatumGetBool(elements[i]))
951 pixval[j].noset =
TRUE;
958 if (x < dimpixval[1])
959 j += (dimpixval[1] - dimnoset[1]);
966 else if (!PG_ARGISNULL(6) && PG_GETARG_BOOL(6)) {
969 nosetvalisnull =
TRUE;
971 nosetval = PG_GETARG_FLOAT8(7);
974 #if POSTGIS_DEBUG_LEVEL > 0 975 for (i = 0; i < numpixval; i++) {
976 POSTGIS_RT_DEBUGF(4,
"pixval[%d](x, y, noset, nodata, value) = (%d, %d, %d, %d, %f)",
988 if (!PG_ARGISNULL(8))
989 keepnodata = PG_GETARG_BOOL(8);
994 elog(NOTICE,
"Could not find band at index %d. Returning original raster", nband);
997 PG_RETURN_POINTER(pgraster);
1010 for (i = 0; i < numpixval; i++) {
1012 if (pixval[i].noset)
1015 else if (hasnosetval) {
1017 if (pixval[i].nodata && nosetvalisnull)
1020 else if (!pixval[i].nodata && !nosetvalisnull &&
FLT_EQ(pixval[i].
value, nosetval))
1026 (pixval[i].x < 0 || pixval[i].x >= width) ||
1027 (pixval[i].y < 0 || pixval[i].y >= height)
1029 elog(NOTICE,
"Cannot set value for pixel (%d, %d) outside raster bounds: %d x %d",
1030 pixval[i].x + 1, pixval[i].y + 1,
1037 if (hasnodata && keepnodata) {
1042 PG_FREE_IF_COPY(pgraster, 0);
1043 elog(ERROR,
"Cannot get value of pixel");
1053 if (pixval[i].nodata)
1064 PG_FREE_IF_COPY(pgraster, 0);
1068 SET_VARSIZE(pgrtn, pgrtn->
size);
1069 PG_RETURN_POINTER(pgrtn);
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
int rt_raster_get_num_bands(rt_raster raster)
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,...)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
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.
uint16_t rt_raster_get_width(rt_raster raster)
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_height(rt_raster raster)
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.