swap_char(d + 4, d + 3);
}
+uint8_t
+rt_util_clamp_to_1BB(double value) {
+ return (uint8_t)fmin(fmax((value), 0), POSTGIS_RT_1BBMAX);
+}
+
+uint8_t
+rt_util_clamp_to_2BUI(double value) {
+ return (uint8_t)fmin(fmax((value), 0), POSTGIS_RT_2BUIMAX);
+}
+
+uint8_t
+rt_util_clamp_to_4BUI(double value) {
+ return (uint8_t)fmin(fmax((value), 0), POSTGIS_RT_4BUIMAX);
+}
+
+int8_t
+rt_util_clamp_to_8BSI(double value) {
+ return (int8_t)fmin(fmax((value), SCHAR_MIN), SCHAR_MAX);
+}
+
+uint8_t
+rt_util_clamp_to_8BUI(double value) {
+ return (uint8_t)fmin(fmax((value), 0), UCHAR_MAX);
+}
+
+int16_t
+rt_util_clamp_to_16BSI(double value) {
+ return (int16_t)fmin(fmax((value), SHRT_MIN), SHRT_MAX);
+}
+
+uint16_t
+rt_util_clamp_to_16BUI(double value) {
+ return (uint16_t)fmin(fmax((value), 0), USHRT_MAX);
+}
+
+int32_t
+rt_util_clamp_to_32BSI(double value) {
+ return (int32_t)fmin(fmax((value), INT_MIN), INT_MAX);
+}
+
+uint32_t
+rt_util_clamp_to_32BUI(double value) {
+ return (uint32_t)fmin(fmax((value), 0), UINT_MAX);
+}
+
+float
+rt_util_clamp_to_32F(double value) {
+ return (float)fmin(fmax((value), FLT_MIN), FLT_MAX);
+}
+
/*- rt_context -------------------------------------------------------*/
static void
ctx->dealloc(ctx);
}
+int
+rt_util_display_dbl_trunc_warning(rt_context ctx,
+ double initialvalue,
+ int32_t checkvalint,
+ uint32_t checkvaluint,
+ float checkvalfloat,
+ double checkvaldouble,
+ rt_pixtype pixtype) {
+ int result = 0;
+ switch (pixtype)
+ {
+ case PT_1BB:
+ case PT_2BUI:
+ case PT_4BUI:
+ case PT_8BSI:
+ case PT_8BUI:
+ case PT_16BSI:
+ case PT_16BUI:
+ case PT_32BSI:
+ {
+ if (fabs(checkvalint - initialvalue) >= 1) {
+ ctx->warn("Initial pixel value for %s band got clamped from %f to %d",
+ rt_pixtype_name(ctx, pixtype),
+ initialvalue, checkvalint);
+ result = -1;
+ }
+ else if (fabs(checkvalint - initialvalue) > FLT_EPSILON) {
+ ctx->warn("Initial pixel value for %s band got truncated from %f to %d",
+ rt_pixtype_name(ctx, pixtype),
+ initialvalue, checkvalint);
+ result = -1;
+ }
+ break;
+ }
+ case PT_32BUI:
+ {
+ if (fabs(checkvaluint - initialvalue) >= 1) {
+ ctx->warn("Initial pixel value for %s band got clamped from %f to %u",
+ rt_pixtype_name(ctx, pixtype),
+ initialvalue, checkvaluint);
+ result = -1;
+ }
+ else if (fabs(checkvaluint - initialvalue) > FLT_EPSILON) {
+ ctx->warn("Initial pixel value for %s band got truncated from %f to %u",
+ rt_pixtype_name(ctx, pixtype),
+ initialvalue, checkvaluint);
+ result = -1;
+ }
+ break;
+ }
+ case PT_32BF:
+ {
+ /* For float, because the initial value is a double,
+ there is very often a difference between the desired value and the obtained one */
+ if (fabs(checkvalfloat - initialvalue) > FLT_EPSILON)
+ ctx->warn("Initial pixel value for %s band got converted from %f to %f",
+ rt_pixtype_name(ctx, pixtype),
+ initialvalue, checkvalfloat);
+ break;
+ }
+ case PT_64BF:
+ {
+ if (fabs(checkvaldouble - initialvalue) > FLT_EPSILON)
+ ctx->warn("Initial pixel value for %s band got converted from %f to %f",
+ rt_pixtype_name(ctx, pixtype),
+ initialvalue, checkvaldouble);
+ break;
+ }
+ case PT_END:
+ break;
+ }
+ return result;
+}
+
/*--- Debug and Testing Utilities --------------------------------------------*/
#if POSTGIS_DEBUG_LEVEL > 3
*hexsize = size * 2; /* hex is 2 times bytes */
hex = (char*) ctx->alloc((*hexsize) + 1);
if (!hex) {
- ctx->err("Out of memory hexifying raw binary\n");
+ ctx->err("d_binary_to_hex: Out of memory hexifying raw binary\n");
return NULL;
}
hex[*hexsize] = '\0'; /* Null-terminate */
pixbytes = 8;
break;
default:
- ctx->err("Unknown pixeltype %d", pixtype);
+ ctx->err("rt_pixtype_size: Unknown pixeltype %d", pixtype);
pixbytes = -1;
break;
}
case PT_64BF:
return "64BF";
default:
- ctx->err("Unknown pixeltype %d", pixtype);
+ ctx->err("rt_pixtype_name: Unknown pixeltype %d", pixtype);
return "Unknown";
}
}
band = ctx->alloc(sizeof (struct rt_band_t));
if (!band) {
- ctx->err("Out of memory allocating rt_band");
+ ctx->err("rt_band_new_inline: Out of memory allocating rt_band");
return 0;
}
band = ctx->alloc(sizeof (struct rt_band_t));
if (!band) {
- ctx->err("Out of memory allocating rt_band");
+ ctx->err("rt_band_new_offline: Out of memory allocating rt_band");
return 0;
}
int
rt_band_set_nodata(rt_context ctx, rt_band band, double val) {
rt_pixtype pixtype = PT_END;
- double oldnodataval = band->nodataval;
+ //double oldnodataval = band->nodataval;
+
+ int32_t checkvalint = 0;
+ uint32_t checkvaluint = 0;
+ float checkvalfloat = 0;
+ double checkvaldouble = 0;
assert(NULL != ctx);
assert(NULL != band);
pixtype = band->pixtype;
- RASTER_DEBUGF(3, "rt_band_set_nodata: setting NODATA %g with band type %s", val, rt_pixtype_name(ctx, pixtype));
+ RASTER_DEBUGF(3, "rt_band_set_nodata: setting nodata value %g with band type %s", val, rt_pixtype_name(ctx, pixtype));
/* return -1 on out of range */
switch (pixtype) {
case PT_1BB:
{
- uint8_t v = val;
- v &= 0x01;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_1BB(val);
+ checkvalint = band->nodataval;
break;
}
case PT_2BUI:
{
- uint8_t v = val;
- v &= 0x03;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_2BUI(val);
+ checkvalint = band->nodataval;
break;
}
case PT_4BUI:
{
- uint8_t v = val;
- v &= 0x0F;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_4BUI(val);
+ checkvalint = band->nodataval;
break;
}
case PT_8BSI:
{
- int8_t v = val;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_8BSI(val);
+ checkvalint = band->nodataval;
break;
}
case PT_8BUI:
{
- uint8_t v = val;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_8BUI(val);
+ checkvalint = band->nodataval;
break;
}
case PT_16BSI:
{
- int16_t v = val;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_16BSI(val);
+ checkvalint = band->nodataval;
break;
}
case PT_16BUI:
{
- uint16_t v = val;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_16BUI(val);
+ checkvalint = band->nodataval;
break;
}
case PT_32BSI:
{
- int32_t v = val;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_32BSI(val);
+ checkvalint = band->nodataval;
break;
}
case PT_32BUI:
{
- uint32_t v = val;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_32BUI(val);
+ checkvaluint = band->nodataval;
break;
}
case PT_32BF:
{
- float v = val;
- band->nodataval = v;
+ band->nodataval = rt_util_clamp_to_32F(val);
+ checkvalfloat = band->nodataval;
break;
}
case PT_64BF:
{
band->nodataval = val;
+ checkvaldouble = band->nodataval;
break;
}
default:
{
- ctx->err("Unknown pixeltype %d", pixtype);
+ ctx->err("rt_band_set_nodata: Unknown pixeltype %d", pixtype);
band->hasnodata = 0;
return -1;
}
RASTER_DEBUGF(3, "rt_band_set_nodata: band->nodataval = %d", band->nodataval);
- // the NODATA value was just set, so this band has NODATA
+ // the nodata value was just set, so this band has NODATA
rt_band_set_hasnodata_flag(ctx, band, 1);
- if (fabs(band->nodataval - val) > FLT_EPSILON) {
#ifdef POSTGIS_RASTER_WARN_ON_TRUNCATION
- ctx->warn("rt_band_set_nodata: NODATA value for %s band got truncated"
- " from %g to %g",
- rt_pixtype_name(ctx, pixtype),
- val, band->nodataval);
-#endif
+ if (rt_util_display_dbl_trunc_warning(ctx, val, checkvalint, checkvaluint, checkvalfloat,
+ checkvaldouble, pixtype))
return -1;
- }
+#endif
/* If the nodata value is different from the previous one, we need to check
- * again if the band is a NODATA band
+ * again if the band is a nodata band
* TODO: NO, THAT'S TOO SLOW!!!
*/
rt_pixtype pixtype = PT_END;
unsigned char* data = NULL;
uint32_t offset = 0;
+
+ int32_t checkvalint = 0;
+ uint32_t checkvaluint = 0;
+ float checkvalfloat = 0;
+ double checkvaldouble = 0;
+
double checkval = 0;
assert(NULL != ctx);
pixtype = band->pixtype;
if (x >= band->width || y >= band->height) {
- ctx->err("Coordinates out of range");
+ ctx->err("rt_band_set_pixel: Coordinates out of range");
return -1;
}
switch (pixtype) {
case PT_1BB:
{
- data[offset] = (int) val & 0x01;
- checkval = data[offset];
+ data[offset] = rt_util_clamp_to_1BB(val);
+ checkvalint = data[offset];
break;
}
case PT_2BUI:
{
- data[offset] = (int) val & 0x03;
- checkval = data[offset];
+ data[offset] = rt_util_clamp_to_2BUI(val);
+ checkvalint = data[offset];
break;
}
case PT_4BUI:
{
- data[offset] = (int) val & 0x0F;
- checkval = data[offset];
+ data[offset] = rt_util_clamp_to_4BUI(val);
+ checkvalint = data[offset];
break;
}
case PT_8BSI:
{
- data[offset] = (int8_t) val;
- checkval = (int8_t) data[offset];
+ data[offset] = rt_util_clamp_to_8BSI(val);
+ checkvalint = (int8_t) data[offset];
break;
}
case PT_8BUI:
{
- data[offset] = val;
- checkval = data[offset];
+ data[offset] = rt_util_clamp_to_8BUI(val);
+ checkvalint = data[offset];
break;
}
case PT_16BSI:
{
int16_t *ptr = (int16_t*) data; /* we assume correct alignment */
- ptr[offset] = val;
- checkval = (int16_t) ptr[offset];
+ ptr[offset] = rt_util_clamp_to_16BSI(val);
+ checkvalint = (int16_t) ptr[offset];
break;
}
case PT_16BUI:
{
uint16_t *ptr = (uint16_t*) data; /* we assume correct alignment */
- ptr[offset] = val;
- checkval = ptr[offset];
+ ptr[offset] = rt_util_clamp_to_16BUI(val);
+ checkvalint = ptr[offset];
break;
}
case PT_32BSI:
{
int32_t *ptr = (int32_t*) data; /* we assume correct alignment */
- ptr[offset] = val;
- checkval = (int32_t) ptr[offset];
+ ptr[offset] = rt_util_clamp_to_32BSI(val);
+ checkvalint = (int32_t) ptr[offset];
break;
}
case PT_32BUI:
{
uint32_t *ptr = (uint32_t*) data; /* we assume correct alignment */
- ptr[offset] = val;
- checkval = ptr[offset];
+ ptr[offset] = rt_util_clamp_to_32BUI(val);
+ checkvaluint = ptr[offset];
break;
}
case PT_32BF:
{
float *ptr = (float*) data; /* we assume correct alignment */
- ptr[offset] = val;
- checkval = ptr[offset];
+ ptr[offset] = rt_util_clamp_to_32F(val);
+ checkvalfloat = ptr[offset];
break;
}
case PT_64BF:
{
double *ptr = (double*) data; /* we assume correct alignment */
ptr[offset] = val;
- checkval = ptr[offset];
+ checkvaldouble = ptr[offset];
break;
}
default:
{
- ctx->err("Unknown pixeltype %d", pixtype);
+ ctx->err("rt_band_set_pixel: Unknown pixeltype %d", pixtype);
return -1;
}
}
/* Overflow checking */
- if (fabs(checkval - val) > FLT_EPSILON) {
#ifdef POSTGIS_RASTER_WARN_ON_TRUNCATION
- ctx->warn("Pixel value for %s band got truncated"
- " from %g to %g",
- rt_pixtype_name(ctx, band->pixtype),
- val, checkval);
+ if (rt_util_display_dbl_trunc_warning(ctx, val, checkvalint, checkvaluint, checkvalfloat,
+ checkvaldouble, pixtype))
+ return -1;
#endif /* POSTGIS_RASTER_WARN_ON_TRUNCATION */
- return -1;
- }
/* If the stored value is different from no data, reset the isnodata flag */
if (fabs(checkval - band->nodataval) > FLT_EPSILON) {
}
/*
- * If the pixel was a NODATA value, now the band may be NODATA band)
+ * If the pixel was a nodata value, now the band may be NODATA band)
* TODO: NO, THAT'S TOO SLOW!!!
*/
rt_band_check_is_nodata(ctx, band);
}
*/
-
+
return 0;
}
}
default:
{
- ctx->err("Unknown pixeltype %d", pixtype);
+ ctx->err("rt_band_get_pixel: Unknown pixeltype %d", pixtype);
return -1;
}
}
assert(NULL != band);
if (!band->hasnodata)
- RASTER_DEBUGF(3, "Getting NODATA value for a band without NODATA values. Using %g", band->nodataval);
-
+ RASTER_DEBUGF(3, "Getting nodata value for a band without NODATA values. Using %g", band->nodataval);
+
return band->nodataval;
}
-/**
- * Returns the minimal possible value for the band according to the pixel type.
- * @param ctx: context, for thread safety
- * @param band: the band to get info from
- * @return the minimal possible value for the band.
- */
-double rt_band_get_min_value(rt_context ctx, rt_band band) {
+double
+rt_band_get_min_value(rt_context ctx, rt_band band) {
rt_pixtype pixtype = PT_END;
assert(NULL != ctx);
{
return (double)CHAR_MIN;
}
-
case PT_8BSI:
{
return (double)SCHAR_MIN;
}
-
case PT_16BSI: case PT_16BUI:
{
return (double)SHRT_MIN;
}
-
case PT_32BSI: case PT_32BUI:
{
return (double)INT_MIN;
}
-
case PT_32BF:
{
return (double)FLT_MIN;
{
return (double)DBL_MIN;
}
-
default:
{
- ctx->err("Unknown pixeltype %d", pixtype);
+ ctx->err("rt_band_get_min_value: Unknown pixeltype %d", pixtype);
return (double)CHAR_MIN;
}
}
}
-/**
- * Returns TRUE if the band is only nodata values
- * @param ctx: context, for thread safety
- * @param band: the band to get info from
- * @return TRUE if the band is only nodata values, FALSE otherwise
- */
-int rt_band_check_is_nodata(rt_context ctx, rt_band band)
+int
+rt_band_check_is_nodata(rt_context ctx, rt_band band)
{
int i, j;
double pxValue = band->nodataval;
/* Check if band has nodata value */
if (!band->hasnodata)
- {
- RASTER_DEBUG(3, "Unknown NODATA value for band");
+ {
+ RASTER_DEBUG(3, "Unknown nodata value for band");
band->isnodata = FALSE;
return FALSE;
}
-
+
/* TODO: How to know it in case of offline bands? */
if (band->offline) {
- RASTER_DEBUG(3, "Unknown NODATA value for OFFDB band");
+ RASTER_DEBUG(3, "Unknown nodata value for OFFDB band");
band->isnodata = FALSE;
}
rt_band_get_pixel(ctx, band, i, j, &pxValue);
dEpsilon = fabs(pxValue - band->nodataval);
if (dEpsilon > FLT_EPSILON) {
- band->isnodata = FALSE;
+ band->isnodata = FALSE;
return FALSE;
}
}
ret = (rt_raster) ctx->alloc(sizeof (struct rt_raster_t));
if (!ret) {
- ctx->err("Out of virtual memory creating an rt_raster");
+ ctx->err("rt_raster_new: Out of virtual memory creating an rt_raster");
return 0;
}
RASTER_DEBUGF(3, "Adding band %p to raster %p", band, raster);
if (band->width != raster->width) {
- ctx->err("Can't add a %dx%d band to a %dx%d raster",
+ ctx->err("rt_raster_add_band: Can't add a %dx%d band to a %dx%d raster",
band->width, band->height, raster->width, raster->height);
return -1;
}
);
if (!raster->bands) {
- ctx->err("Out of virtual memory "
+ ctx->err("rt_raster_add_band: Out of virtual memory "
"reallocating band pointers");
raster->bands = oldbands;
return -1;
}
RASTER_DEBUGF(4, "realloc returned %p", raster->bands);
-
+
for (i = 0; i <= raster->numBands; ++i) {
if (i == index) {
oldband = raster->bands[i];
int32_t
-rt_raster_generate_new_band(rt_context ctx, rt_raster raster, rt_pixtype pixtype,
+rt_raster_generate_new_band(rt_context ctx, rt_raster raster, rt_pixtype pixtype,
double initialvalue, uint32_t hasnodata, double nodatavalue, int index)
-{
+{
rt_band band = NULL;
int width = 0;
int height = 0;
double checkvaldouble = 0;
float checkvalfloat = 0;
int i;
-
-
+
+
assert(NULL != ctx);
assert(NULL != raster);
mem = (int *)ctx->alloc(datasize);
if (!mem) {
- ctx->err("Could not allocate memory for band");
+ ctx->err("rt_raster_generate_new_band: Could not allocate memory for band");
return -1;
}
case PT_1BB:
{
uint8_t *ptr = mem;
+ uint8_t clamped_initval = rt_util_clamp_to_1BB(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (uint8_t) initialvalue&0x01;
+ ptr[i] = clamped_initval;
checkvalint = ptr[0];
break;
}
case PT_2BUI:
{
uint8_t *ptr = mem;
+ uint8_t clamped_initval = rt_util_clamp_to_2BUI(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (uint8_t) initialvalue&0x03;
+ ptr[i] = clamped_initval;
checkvalint = ptr[0];
break;
}
case PT_4BUI:
{
uint8_t *ptr = mem;
+ uint8_t clamped_initval = rt_util_clamp_to_4BUI(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (uint8_t) initialvalue&0x0F;
+ ptr[i] = clamped_initval;
checkvalint = ptr[0];
break;
}
case PT_8BSI:
{
int8_t *ptr = mem;
+ int8_t clamped_initval = rt_util_clamp_to_8BSI(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (int8_t) initialvalue;
+ ptr[i] = clamped_initval;
checkvalint = ptr[0];
break;
}
case PT_8BUI:
{
uint8_t *ptr = mem;
+ uint8_t clamped_initval = rt_util_clamp_to_8BUI(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (uint8_t) initialvalue;
+ ptr[i] = clamped_initval;
checkvalint = ptr[0];
break;
}
case PT_16BSI:
{
int16_t *ptr = mem;
+ int16_t clamped_initval = rt_util_clamp_to_16BSI(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (int16_t) initialvalue;
+ ptr[i] = clamped_initval;
checkvalint = ptr[0];
break;
}
case PT_16BUI:
{
uint16_t *ptr = mem;
+ uint16_t clamped_initval = rt_util_clamp_to_16BUI(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (uint16_t) initialvalue;
+ ptr[i] = clamped_initval;
checkvalint = ptr[0];
break;
}
case PT_32BSI:
{
int32_t *ptr = mem;
+ int32_t clamped_initval = rt_util_clamp_to_32BSI(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (int32_t) initialvalue;
+ ptr[i] = clamped_initval;
checkvalint = ptr[0];
break;
}
case PT_32BUI:
{
uint32_t *ptr = mem;
+ uint32_t clamped_initval = rt_util_clamp_to_32BUI(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (uint32_t) initialvalue;
+ ptr[i] = clamped_initval;
checkvaluint = ptr[0];
break;
}
case PT_32BF:
{
float *ptr = mem;
+ float clamped_initval = rt_util_clamp_to_32F(initialvalue);
for (i = 0; i < numval; i++)
- ptr[i] = (float) initialvalue;
+ ptr[i] = clamped_initval;
checkvalfloat = ptr[0];
break;
}
}
default:
{
- ctx->err("Unknown pixeltype %d", pixtype);
+ ctx->err("rt_raster_generate_new_band: Unknown pixeltype %d", pixtype);
ctx->dealloc(mem);
return -1;
}
#ifdef POSTGIS_RASTER_WARN_ON_TRUNCATION
/* Overflow checking */
- switch (pixtype)
- {
- case PT_1BB:
- case PT_2BUI:
- case PT_4BUI:
- case PT_8BSI:
- case PT_8BUI:
- case PT_16BSI:
- case PT_16BUI:
- case PT_32BSI:
- {
- if (fabs(checkvalint - initialvalue) > FLT_EPSILON)
- ctx->warn("Initial pixel value for %s band got truncated from %f to %d",
- rt_pixtype_name(ctx, pixtype),
- initialvalue, checkvalint);
- break;
- }
- case PT_32BUI:
- {
- if (fabs(checkvaluint - initialvalue) > FLT_EPSILON)
- ctx->warn("Initial pixel value for %s band got truncated from %f to %u",
- rt_pixtype_name(ctx, pixtype),
- initialvalue, checkvaluint);
- break;
- }
- case PT_32BF:
- {
- /* For float, because the initial value is a double,
- there is very often a difference between the desired value and the obtained one */
- if (fabs(checkvalfloat - initialvalue) > FLT_EPSILON)
- ctx->warn("Initial pixel value for %s band got truncated from %f to %g",
- rt_pixtype_name(ctx, pixtype),
- initialvalue, checkvalfloat);
- break;
- }
- case PT_64BF:
- {
- if (fabs(checkvaldouble - initialvalue) > FLT_EPSILON)
- ctx->warn("Initial pixel value for %s band got truncated from %f to %g",
- rt_pixtype_name(ctx, pixtype),
- initialvalue, checkvaldouble);
- break;
- }
- }
+ rt_util_display_dbl_trunc_warning(ctx, initialvalue, checkvalint, checkvaluint, checkvalfloat,
+ checkvaldouble, pixtype);
#endif /* POSTGIS_RASTER_WARN_ON_TRUNCATION */
band = rt_band_new_inline(ctx, width, height, pixtype, hasnodata, nodatavalue, mem);
if (! band) {
- ctx->err("Could not add band to raster. Aborting");
+ ctx->err("rt_raster_generate_new_band: Could not add band to raster. Aborting");
ctx->dealloc(mem);
return -1;
}
index = rt_raster_add_band(ctx, raster, band, index);
numbands = rt_raster_get_num_bands(ctx, raster);
if (numbands == oldnumbands || index == -1) {
- ctx->err("Could not add band to raster. Aborting");
+ ctx->err("rt_raster_generate_new_band: Could not add band to raster. Aborting");
rt_band_destroy(ctx, band);
}
-
+
return index;
}
}
-/* WKT string representing each polygon in WKT format acompagned by its
+/* WKT string representing each polygon in WKT format acompagned by its
correspoding value */
struct rt_geomval_t {
int srid;
*******************************/
band = rt_raster_get_band(ctx, raster, nband - 1);
if (NULL == band) {
- ctx->err("Error getting band %d from raster", nband);
+ ctx->err("rt_raster_dump_as_wktpolygons: Error getting band %d from raster", nband);
return 0;
}
memdatasource = OGR_Dr_CreateDataSource(ogr_drv, "", NULL);
if (NULL == memdatasource) {
- ctx->err("Couldn't create a OGR Datasource to store pols\n");
+ ctx->err("rt_raster_dump_as_wktpolygons: Couldn't create a OGR Datasource to store pols\n");
return 0;
}
* Can MEM driver create new layers?
**/
if (!OGR_DS_TestCapability(memdatasource, ODsCCreateLayer)) {
- ctx->err("MEM driver can't create new layers, aborting\n");
+ ctx->err("rt_raster_dump_as_wktpolygons: MEM driver can't create new layers, aborting\n");
/* xxx jorgearevalo: what should we do now? */
OGRReleaseDataSource(memdatasource);
return 0;
rt_band_get_height(ctx, band), 0, GDT_Byte, NULL);
if (NULL == memdataset) {
- ctx->err("Couldn't create a GDALDataset to polygonize it\n");
+ ctx->err("rt_raster_dump_as_wktpolygons: Couldn't create a GDALDataset to polygonize it\n");
GDALDeregisterDriver(gdal_drv);
GDALDestroyDriver(gdal_drv);
OGRReleaseDataSource(memdatasource);
ctx->dealloc(pszDataPointer);
if (GDALAddBand(memdataset, nPixelType, apszOptions) == CE_Failure) {
- ctx->err("Couldn't transform WKT Raster band in GDALRasterBand format to polygonize it");
+ ctx->err("rt_raster_dump_as_wktpolygons: Couldn't transform raster band in GDALRasterBand format to polygonize it");
GDALClose(memdataset);
GDALDeregisterDriver(gdal_drv);
GDALDestroyDriver(gdal_drv);
/* Checking */
if (GDALGetRasterCount(memdataset) != 1) {
- ctx->err("Error creating GDAL MEM raster bands");
+ ctx->err("rt_raster_dump_as_wktpolygons: Error creating GDAL MEM raster bands");
GDALClose(memdataset);
GDALDeregisterDriver(gdal_drv);
GDALDestroyDriver(gdal_drv);
wkbPolygon, NULL);
if (NULL == hLayer) {
- ctx->err("Couldn't create layer to store polygons");
+ ctx->err("rt_raster_dump_as_wktpolygons: Couldn't create layer to store polygons");
GDALClose(memdataset);
GDALDeregisterDriver(gdal_drv);
GDALDestroyDriver(gdal_drv);
/* Get GDAL raster band */
gdal_band = GDALGetRasterBand(memdataset, 1);
if (NULL == gdal_band) {
- ctx->err("Couldn't get GDAL band to polygonize");
+ ctx->err("rt_raster_dump_as_wktpolygons: Couldn't get GDAL band to polygonize");
GDALClose(memdataset);
GDALDeregisterDriver(gdal_drv);
GDALDestroyDriver(gdal_drv);
**/
GDALPolygonize(gdal_band, NULL, hLayer, iPixVal, NULL, NULL, NULL);
- /*********************************************************************
+ /*********************************************************************
* Transform OGR layers in WKT polygons
* XXX jorgearevalo: GDALPolygonize does not set the coordinate system
* on the output layer. Application code should do this when the layer
/**
- * The field was stored as int, but we can use this function
- * because uses "atof" to transform the string representation of
+ * The field was stored as int, but we can use this function
+ * because uses "atof" to transform the string representation of
* the number into a double. We shouldn't have problems
**/
dValueToCompare = OGR_F_GetFieldAsDouble(hFeature, iPixVal);
sizeof (struct rt_geomval_t));
if (NULL == pols) {
- ctx->err("Couldn't allocate memory for geomval structure");
+ ctx->err("rt_raster_dump_as_wktpolygons: Couldn't allocate memory for geomval structure");
GDALClose(memdataset);
GDALDeregisterDriver(gdal_drv);
GDALDestroyDriver(gdal_drv);
nCont++;
/**
- * We can't use deallocator from rt_context, because it comes from
+ * We can't use deallocator from rt_context, because it comes from
* postgresql backend, that uses pfree. This function needs a
* postgresql memory context to work with, and the memory created
* for pszSrcText is created outside this context.
**/
- //ctx->dealloc(pszSrcText);
+ //ctx->dealloc(pszSrcText);
free(pszSrcText);
pszSrcText = NULL;
}
rings = (POINTARRAY **) ctx->alloc(sizeof (POINTARRAY*));
if (!rings) {
- ctx->err("Out of memory [%s:%d]", __FILE__, __LINE__);
+ ctx->err("rt_raster_get_convex_hull: Out of memory [%s:%d]", __FILE__, __LINE__);
return 0;
}
rings[0] = ptarray_construct(0, 0, 5);
/* TODO: handle error on ptarray construction */
/* XXX jorgearevalo: the error conditions aren't managed in ptarray_construct */
if (!rings[0]) {
- ctx->err("Out of memory [%s:%d]", __FILE__, __LINE__);
+ ctx->err("rt_raster_get_convex_hull: Out of memory [%s:%d]", __FILE__, __LINE__);
return 0;
}
pts = rings[0];
band = ctx->alloc(sizeof (struct rt_band_t));
if (!band) {
- ctx->err("Out of memory allocating rt_band during WKB parsing");
+ ctx->err("rt_band_from_wkb: Out of memory allocating rt_band during WKB parsing");
return 0;
}
if (end - *ptr < 1) {
- ctx->err("Premature end of WKB on band reading (%s:%d)",
+ ctx->err("rt_band_from_wkb: Premature end of WKB on band reading (%s:%d)",
__FILE__, __LINE__);
return 0;
}
type = read_uint8(ptr);
if ((type & BANDTYPE_PIXTYPE_MASK) >= PT_END) {
- ctx->err("Invalid pixtype %d", type & BANDTYPE_PIXTYPE_MASK);
+ ctx->err("rt_band_from_wkb: Invalid pixtype %d", type & BANDTYPE_PIXTYPE_MASK);
ctx->dealloc(band);
return 0;
}
pixbytes = rt_pixtype_size(ctx, band->pixtype);
if (((*ptr) + pixbytes) >= end) {
- ctx->err("Premature end of WKB on band novalue reading");
+ ctx->err("rt_band_from_wkb: Premature end of WKB on band novalue reading");
ctx->dealloc(band);
return 0;
}
}
default:
{
- ctx->err("Unknown pixeltype %d", band->pixtype);
+ ctx->err("rt_band_from_wkb: Unknown pixeltype %d", band->pixtype);
ctx->dealloc(band);
return 0;
}
if (band->offline) {
if (((*ptr) + 1) >= end) {
- ctx->err("Premature end of WKB on offline "
+ ctx->err("rt_band_from_wkb: Premature end of WKB on offline "
"band data bandNum reading (%s:%d)",
__FILE__, __LINE__);
ctx->dealloc(band);
sz = 0;
while ((*ptr)[sz] && &((*ptr)[sz]) < end) ++sz;
if (&((*ptr)[sz]) >= end) {
- ctx->err("Premature end of WKB on band offline path reading");
+ ctx->err("rt_band_from_wkb: Premature end of WKB on band offline path reading");
ctx->dealloc(band);
return 0;
}
*ptr += sz + 1;
- /* TODO: How could we know if the offline band is a NODATA band? */
+ /* TODO: How could we know if the offline band is a nodata band? */
band->isnodata = FALSE;
}
return band;
/* This is an on-disk band */
sz = width * height * pixbytes;
if (((*ptr) + sz) > end) {
- ctx->err("Premature end of WKB on band data reading (%s:%d)",
+ ctx->err("rt_band_from_wkb: Premature end of WKB on band data reading (%s:%d)",
__FILE__, __LINE__);
ctx->dealloc(band);
return 0;
band->data.mem = ctx->alloc(sz);
if (!band->data.mem) {
- ctx->err("Out of memory during band creation in WKB parser");
+ ctx->err("rt_band_from_wkb: Out of memory during band creation in WKB parser");
ctx->dealloc(band);
return 0;
}
else if (pixbytes == 4) flipper = flip_endian_32;
else if (pixbytes == 8) flipper = flip_endian_64;
else {
- ctx->err("Unexpected pix bytes %d", pixbytes);
+ ctx->err("rt_band_from_wkb: Unexpected pix bytes %d", pixbytes);
ctx->dealloc(band);
ctx->dealloc(band->data.mem);
return 0;
for (v = 0; v < sz; ++v) {
val = ((uint8_t*) band->data.mem)[v];
if (val > maxVal) {
- ctx->err("Invalid value %d for pixel of type %s",
+ ctx->err("rt_band_from_wkb: Invalid value %d for pixel of type %s",
val, rt_pixtype_name(ctx, band->pixtype));
ctx->dealloc(band->data.mem);
ctx->dealloc(band);
/* Read other components of raster header */
rast = (rt_raster) ctx->alloc(sizeof (struct rt_raster_t));
if (!rast) {
- ctx->err("Out of memory allocating raster for wkb input");
+ ctx->err("rt_raster_from_wkb: Out of memory allocating raster for wkb input");
return 0;
}
rast->numBands = read_uint16(&ptr, endian);
/* Now read the bands */
rast->bands = (rt_band*) ctx->alloc(sizeof (rt_band) * rast->numBands);
if (!rast->bands) {
- ctx->err("Out of memory allocating bands for WKB raster decoding");
+ ctx->err("rt_raster_from_wkb: Out of memory allocating bands for WKB raster decoding");
ctx->dealloc(rast);
return 0;
}
rt_band band = rt_band_from_wkb(ctx, rast->width, rast->height,
&ptr, wkbend, endian);
if (!band) {
- ctx->err("Error reading WKB form of band %d", i);
+ ctx->err("rt_raster_from_wkb: Error reading WKB form of band %d", i);
ctx->dealloc(rast);
/* TODO: dealloc any previously allocated band too ! */
return 0;
RASTER_DEBUGF(3, "rt_raster_from_hexwkb: input wkb: %s", hexwkb);
if (hexwkbsize % 2) {
- ctx->err("Raster HEXWKB input must have an even number of characters");
+ ctx->err("rt_raster_from_hexwkb: Raster HEXWKB input must have an even number of characters");
return 0;
}
wkbsize = hexwkbsize / 2;
wkb = ctx->alloc(wkbsize);
if (!wkb) {
- ctx->err("Out of memory allocating memory for decoding HEXWKB");
+ ctx->err("rt_raster_from_hexwkb: Out of memory allocating memory for decoding HEXWKB");
return 0;
}
RASTER_DEBUGF(3, "rt_raster_wkb_size: adding size of band %d", i);
if (pixbytes < 1) {
- ctx->err("Corrupted band: unkonwn pixtype");
+ ctx->err("rt_raster_wkb_size: Corrupted band: unknown pixtype");
return 0;
}
wkb = (uint8_t*) ctx->alloc(*wkbsize);
if (!wkb) {
- ctx->err("Out of memory allocating WKB for raster");
+ ctx->err("rt_raster_to_wkb: Out of memory allocating WKB for raster");
return 0;
}
d_binptr_to_pos(ptr, wkbend, *wkbsize));
if (pixbytes < 1) {
- ctx->err("Corrupted band: unkonwn pixtype");
+ ctx->err("rt_raster_to_wkb: Corrupted band: unknown pixtype");
return 0;
}
break;
}
default:
- ctx->err("Fatal error caused by unknown pixel type. Aborting.");
+ ctx->err("rt_raster_to_wkb: Fatal error caused by unknown pixel type. Aborting.");
abort(); /* shoudn't happen */
return 0;
}
hexwkb = (char*) ctx->alloc((*hexwkbsize) + 1);
if (!hexwkb) {
ctx->dealloc(wkb);
- ctx->err("Out of memory hexifying raster WKB");
+ ctx->err("rt_raster_to_hexwkb: Out of memory hexifying raster WKB");
return 0;
}
hexwkb[*hexwkbsize] = '\0'; /* Null-terminate */
int pixbytes = rt_pixtype_size(ctx, pixtype);
if (pixbytes < 1) {
- ctx->err("Corrupted band: unknown pixtype");
+ ctx->err("rt_raster_serialized_size: Corrupted band: unknown pixtype");
return 0;
}
ret = (uint8_t*) ctx->alloc(size);
if (!ret) {
- ctx->err("Out of memory allocating %d bytes for serializing a raster",
+ ctx->err("rt_raster_serialize: Out of memory allocating %d bytes for serializing a raster",
size);
return 0;
}
RASTER_DEBUG(3, "Start hex dump of raster being serialized using 0x2D to mark non-written bytes");
-#if POSTGIS_DEBUG_LEVEL > 2
+#if POSTGIS_DEBUG_LEVEL > 2
uint8_t* dbg_ptr = ptr;
d_print_binary_hex(ctx, "HEADER", dbg_ptr, size);
#endif
rt_pixtype pixtype = band->pixtype;
int pixbytes = rt_pixtype_size(ctx, pixtype);
if (pixbytes < 1) {
- ctx->err("Corrupted band: unkonwn pixtype");
+ ctx->err("rt_raster_serialize: Corrupted band: unknown pixtype");
return 0;
}
break;
}
default:
- ctx->err("Fatal error caused by unknown pixel type. Aborting.");
+ ctx->err("rt_raster_serialize: Fatal error caused by unknown pixel type. Aborting.");
abort(); /* shoudn't happen */
return 0;
}
assert(!((uintptr_t) ptr % pixbytes));
#if POSTGIS_DEBUG_LEVEL > 2
- d_print_binary_hex(ctx, "NODATA", dbg_ptr, size);
+ d_print_binary_hex(ctx, "nodata", dbg_ptr, size);
#endif
if (band->offline) {
/* Allocate memory for deserialized raster header */
rast = (rt_raster) ctx->alloc(sizeof (struct rt_raster_t));
if (!rast) {
- ctx->err("Out of memory allocating raster for deserialization");
+ ctx->err("rt_raster_deserialize: Out of memory allocating raster for deserialization");
return 0;
}
band = ctx->alloc(sizeof (struct rt_band_t));
if (!band) {
- ctx->err("Out of memory allocating rt_band during deserialization");
+ ctx->err("rt_raster_deserialize: Out of memory allocating rt_band during deserialization");
return 0;
}
RASTER_DEBUGF(3, "rt_raster_deserialize: band %d with pixel type %s", i, rt_pixtype_name(ctx, band->pixtype));
band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0;
- band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1 : 0;
+ band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1 : 0;
band->isnodata = BANDTYPE_IS_NODATA(type) ? 1 : 0;
band->width = rast->width;
band->height = rast->height;
}
default:
{
- ctx->err("Unknown pixeltype %d", band->pixtype);
+ ctx->err("rt_raster_deserialize: Unknown pixeltype %d", band->pixtype);
ctx->dealloc(band);
ctx->dealloc(rast);
return 0;
}
}
- RASTER_DEBUGF(3, "rt_raster_deserialize: has NODATA flag %d", band->hasnodata);
- RASTER_DEBUGF(3, "rt_raster_deserialize: NODATA value %g", band->nodataval);
+ RASTER_DEBUGF(3, "rt_raster_deserialize: has nodata flag %d", band->hasnodata);
+ RASTER_DEBUGF(3, "rt_raster_deserialize: nodata value %g", band->nodataval);
/* Consistency checking (ptr is pixbytes-aligned) */
assert(!(((uintptr_t) ptr) % pixbytes));
/* Check raster dimensions */
if (raster1->height != raster2->height || raster1->width != raster2->width)
{
- ctx->err("Attempting to add a band with different width or height");
+ ctx->err("rt_raster_copy_band: Attempting to add a band with different width or height");
return -1;
}
newband = rt_raster_get_band(ctx, raster1, nband1);
/* Add band to the second raster */
- return rt_raster_add_band(ctx, raster2, newband, nband2);
+ return rt_raster_add_band(ctx, raster2, newband, nband2);
}
/* Replace function taken from http://ubuntuforums.org/showthread.php?s=aa6f015109fd7e4c7e30d2fd8b717497&t=141670&page=3 */
/* ---------------------------------------------------------------------------
- Name : replace - Search & replace a substring by another one.
+ Name : replace - Search & replace a substring by another one.
Creation : Thierry Husson, Sept 2010
Parameters :
str : Big string where we search
oldstr : Substring we are looking for
newstr : Substring we want to replace with
- count : Optional pointer to int (input / output value). NULL to ignore.
+ count : Optional pointer to int (input / output value). NULL to ignore.
Input: Maximum replacements to be done. NULL or < 1 to do all.
Output: Number of replacements done or -1 if not enough memory.
Returns : Pointer to the new string or NULL if error.
- Notes :
+ Notes :
- Case sensitive - Otherwise, replace functions "strstr" by "strcasestr"
- Always allocates memory for the result.
--------------------------------------------------------------------------- */
-static char*
+static char*
replace(const char *str, const char *oldstr, const char *newstr, int *count)
{
const char *tmp = str;
int length, reslen;
int oldlen = strlen(oldstr);
int newlen = strlen(newstr);
- int limit = (count != NULL && *count > 0) ? *count : -1;
+ int limit = (count != NULL && *count > 0) ? *count : -1;
tmp = str;
while ((tmp = strstr(tmp, oldstr)) != NULL && found != limit)
found++, tmp += oldlen;
-
+
length = strlen(str) + found * (newlen - oldlen);
if ( (result = (char *)palloc(length+1)) == NULL) {
fprintf(stderr, "Not enough memory\n");
} else {
tmp = str;
limit = found; /* Countdown */
- reslen = 0; /* length of current result */
+ reslen = 0; /* length of current result */
/* Replace each old string found with new string */
while ((limit-- > 0) && (tmp = strstr(tmp, oldstr)) != NULL) {
length = (tmp - str); /* Number of chars to keep intouched */
- strncpy(result + reslen, str, length); /* Original part keeped */
+ strncpy(result + reslen, str, length); /* Original part keeped */
strcpy(result + (reslen += length), newstr); /* Insert new string */
reslen += newlen;
tmp += oldlen;
rt_pgrealloc(void *mem, size_t size)
{
void* ret;
-
+
POSTGIS_RT_DEBUGF(5, "rt_pgrealloc(%p, %ld) called", mem, size);
if ( mem )
{
-
+
POSTGIS_RT_DEBUGF(5, "rt_pgrealloc calling repalloc(%p, %ld) called", mem, size);
ret = repalloc(mem, size);
}
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_out: Could not deserialize raster");
PG_RETURN_NULL();
}
hexwkb = rt_raster_to_hexwkb(ctx, raster, &hexwkbsize);
if ( ! hexwkb )
{
- elog(ERROR, "Could not HEX-WKBize raster");
+ elog(ERROR, "RASTER_out: Could not HEX-WKBize raster");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_to_bytea: Could not deserialize raster");
PG_RETURN_NULL();
}
/*elog(NOTICE, "RASTER_to_binary: rt_raster_deserialize returned %p", raster);*/
/* Uses context allocator */
wkb = rt_raster_to_wkb(ctx, raster, &wkb_size);
if ( ! wkb ) {
- elog(ERROR, "Could not allocate and generate WKB data");
+ elog(ERROR, "RASTER_to_bytea: Could not allocate and generate WKB data");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_to_binary: Could not deserialize raster");
PG_RETURN_NULL();
}
- /*elog(NOTICE, "RASTER_to_binary: rt_raster_deserialize returned %p", raster);*/
/* Uses context allocator */
wkb = rt_raster_to_wkb(ctx, raster, &wkb_size);
if ( ! wkb ) {
- elog(ERROR, "Could not allocate and generate WKB data");
+ elog(ERROR, "RASTER_to_binary: Could not allocate and generate WKB data");
PG_RETURN_NULL();
}
{ /* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_convex_hull: Could not deserialize raster");
PG_RETURN_NULL();
}
convexhull = rt_raster_get_convex_hull(ctx, raster);
if ( ! convexhull ) {
- elog(ERROR, "Could not get raster's convex hull");
+ elog(ERROR, "RASTER_convex_hull: Could not get raster's convex hull");
PG_RETURN_NULL();
}
}
{
#ifdef GSERIALIZED_ON
- size_t gser_size;
- GSERIALIZED *gser;
- gser = gserialized_from_lwgeom(lwpoly_as_lwgeom(convexhull), 0, &gser_size);
- SET_VARSIZE(gser, gser_size);
- pglwgeom = (uchar*)gser;
+ size_t gser_size;
+ GSERIALIZED *gser;
+ gser = gserialized_from_lwgeom(lwpoly_as_lwgeom(convexhull), 0, &gser_size);
+ SET_VARSIZE(gser, gser_size);
+ pglwgeom = (uchar*)gser;
#else
size_t sz = lwpoly_serialize_size(convexhull);
pglwgeom = palloc(VARHDRSZ+sz);
PG_FUNCTION_INFO_V1(RASTER_dumpAsWKTPolygons);
Datum RASTER_dumpAsWKTPolygons(PG_FUNCTION_ARGS)
-{
+{
rt_pgraster *pgraster;
rt_raster raster;
rt_context ctx;
/* Get input arguments */
pgraster = (rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
raster = rt_raster_deserialize(ctx, pgraster);
- if ( ! raster )
+ if ( ! raster )
{
ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
+ (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("Could not deserialize raster")));
PG_RETURN_NULL();
}
nband = PG_GETARG_UINT32(1);
else
nband = 1; /* By default, first band */
-
+
POSTGIS_RT_DEBUGF(3, "band %d", nband);
/* Polygonize raster */
-
+
/**
* Dump raster
*/
if (NULL == geomval)
{
ereport(ERROR,
- (errcode(ERRCODE_NO_DATA_FOUND),
+ (errcode(ERRCODE_NO_DATA_FOUND),
errmsg("Could not polygonize raster")));
PG_RETURN_NULL();
}
-
+
POSTGIS_RT_DEBUGF(3, "raster dump, %d elements returned", nElements);
/**
/* total number of tuples to be returned */
funcctx->max_calls = nElements;
-
+
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
ereport(ERROR,
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
-
+
call_cntr = funcctx->call_cntr;
max_calls = funcctx->max_calls;
attinmeta = funcctx->attinmeta;
char **values;
HeapTuple tuple;
Datum result;
-
+
POSTGIS_RT_DEBUGF(3, "call number %d", call_cntr);
-
+
/*
* Prepare a values array for building the returned tuple.
* This should be an array of C strings which will
* be processed later by the type input functions.
*/
- values = (char **) palloc(3 * sizeof(char *));
+ values = (char **) palloc(3 * sizeof(char *));
values[0] = (char *) palloc(
(strlen(geomval2[call_cntr].geom) + 1) * sizeof(char));
values[1] = (char *) palloc(18 * sizeof(char));
values[2] = (char *) palloc(16 * sizeof(char));
- snprintf(values[0],
- (strlen(geomval2[call_cntr].geom) + 1) * sizeof(char), "%s",
- geomval2[call_cntr].geom);
+ snprintf(values[0],
+ (strlen(geomval2[call_cntr].geom) + 1) * sizeof(char), "%s",
+ geomval2[call_cntr].geom);
snprintf(values[1], 18 * sizeof(char), "%f", geomval2[call_cntr].val);
snprintf(values[2], 16 * sizeof(char), "%d", geomval2[call_cntr].srid);
POSTGIS_RT_DEBUGF(4, "Result %d, val %s", call_cntr, values[1]);
POSTGIS_RT_DEBUGF(4, "Result %d, val %s", call_cntr, values[2]);
- /**
- * Free resources.
- * TODO: Do we have to use the same context we used
- * for creating them?
- */
- pfree(geomval2[call_cntr].geom);
+ /**
+ * Free resources.
+ * TODO: Do we have to use the same context we used
+ * for creating them?
+ */
+ pfree(geomval2[call_cntr].geom);
/* build a tuple */
pfree(values[1]);
pfree(values[2]);
pfree(values);
-
+
SRF_RETURN_NEXT(funcctx, result);
}
else /* do when there is no more left */
- {
- pfree(geomval2);
+ {
+ pfree(geomval2);
SRF_RETURN_DONE(funcctx);
}
if ( PG_NARGS() < 9 )
{
- elog(ERROR, "MakeEmptyRaster requires 9 args");
+ elog(ERROR, "RASTER_makeEmpty: ST_MakeEmptyRaster requires 9 args");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getSRID: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setSRID: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getWidth: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getHeight: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getNumBands: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getXScale: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getYScale: Could not deserialize raster");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
if (! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setScale: Could not deserialize raster");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
if (! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setScaleXY: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getXSkew: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getYSkew: Could not deserialize raster");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
if (! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setSkew: Could not deserialize raster");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
if (! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setSkewXY: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getXUpperLeft: Could not deserialize raster");
PG_RETURN_NULL();
}
/* TODO: can be optimized to only detoast the header! */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getYUpperLeft: Could not deserialize raster");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
if (! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setUpperLeftXY: Could not deserialize raster");
PG_RETURN_NULL();
}
/* Index is 1-based */
index = PG_GETARG_INT32(1);
if ( index < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_getBandPixelType: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (index - 1));
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getBandPixelType: Could not deserialize raster");
PG_RETURN_NULL();
}
/* Fetch requested band and its pixel type */
band = rt_raster_get_band(ctx, raster, index - 1);
if ( ! band ) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", index);
+ elog(NOTICE, "Could not find raster band of index %d when getting pixel type. Returning NULL", index);
PG_RETURN_NULL();
}
/* Index is 1-based */
index = PG_GETARG_INT32(1);
if ( index < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_getBandPixelTypeName: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (index - 1));
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getBandPixelTypeName: Could not deserialize raster");
PG_RETURN_NULL();
}
/* Fetch requested band and its pixel type */
band = rt_raster_get_band(ctx, raster, index - 1);
if ( ! band ) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", index);
+ elog(NOTICE, "Could not find raster band of index %d when getting pixel type name. Returning NULL", index);
PG_RETURN_NULL();
}
result = palloc(VARHDRSZ + name_size);
if ( ! result ) {
- elog(ERROR, "Could not allocate memory for output text object");
+ elog(ERROR, "RASTER_getBandPixelTypeName: Could not allocate memory for output text object");
PG_RETURN_NULL();
}
memset(VARDATA(result), 0, name_size);
strcpy(ptr, "64BF");
break;
default: /* PT_END=13 */
- elog(ERROR, "Invalid value of pixel type");
+ elog(ERROR, "RASTER_getBandPixelTypeName: Invalid value of pixel type");
pfree(result);
PG_RETURN_NULL();
}
}
/**
- * Return NODATA value of the specified band of raster.
+ * Return nodata value of the specified band of raster.
* The value is always returned as FLOAT32 even if the pixel type is INTEGER.
*/
PG_FUNCTION_INFO_V1(RASTER_getBandNoDataValue);
/* Index is 1-based */
index = PG_GETARG_INT32(1);
if ( index < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_getBandNoDataValue: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (index - 1));
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getBandNoDataValue: Could not deserialize raster");
PG_RETURN_NULL();
}
- /* Fetch requested band and its NODATA value */
+ /* Fetch requested band and its nodata value */
band = rt_raster_get_band(ctx, raster, index - 1);
if ( ! band ) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", index);
+ elog(NOTICE, "Could not find raster band of index %d when getting band nodata value. Returning NULL", index);
PG_RETURN_NULL();
}
if ( ! rt_band_get_hasnodata_flag(ctx, band) ) {
- //elog(WARNING, "Raster band %d does not have a NODATA value", index);
+ //elog(WARNING, "RASTER_getBandNoDataValue: Raster band %d does not have a nodata value", index);
PG_RETURN_NULL();
}
PG_RETURN_FLOAT4(nodata);
}
-
+
/**
- * Set the NODATA value of the specified band of raster.
+ * Set the nodata value of the specified band of raster.
*/
PG_FUNCTION_INFO_V1(RASTER_setBandNoDataValue);
Datum RASTER_setBandNoDataValue(PG_FUNCTION_ARGS)
/* Index is 1-based */
index = PG_GETARG_INT32(1);
if ( index < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_setBandNoDataValue: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (index - 1));
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setBandNoDataValue: Could not deserialize raster");
PG_RETURN_NULL();
}
/* Fetch requested band */
band = rt_raster_get_band(ctx, raster, index - 1);
if ( ! band ) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", index);
+ elog(NOTICE, "Could not find raster band of index %d when setting band nodata value. Returning NULL", index);
PG_RETURN_NULL();
}
-
-
+
+
forceChecking = PG_GETARG_BOOL(3);
/* Set the hasnodata flag to FALSE */
rt_band_set_hasnodata_flag(ctx, band, FALSE);
- POSTGIS_RT_DEBUGF(3, "Raster band %d does not have a NODATA value",
+ POSTGIS_RT_DEBUGF(3, "Raster band %d does not have a nodata value",
index);
}
else {
- /* Get the NODATA value */
+ /* Get the nodata value */
nodata = PG_GETARG_FLOAT8(2);
- /* Set the band's NODATA value */
+ /* Set the band's nodata value */
rt_band_set_nodata(ctx, band, nodata);
/* Set the hasnodata flag to TRUE */
/* Recheck all pixels if requested */
if (forceChecking)
- rt_band_check_is_nodata(ctx, band);
+ rt_band_check_is_nodata(ctx, band);
}
rt_raster raster = NULL;
rt_band band = NULL;
rt_context ctx = NULL;
- double nodata;
int32_t index;
/* Index is 1-based */
index = PG_GETARG_INT32(1);
if ( index < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_setBandIsNoData: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (index - 1));
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setBandIsNoData: Could not deserialize raster");
PG_RETURN_NULL();
}
/* Fetch requested band */
band = rt_raster_get_band(ctx, raster, index - 1);
if ( ! band ) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", index);
+ elog(NOTICE, "Could not find raster band of index %d when setting band as nodata. Returning NULL", index);
PG_RETURN_NULL();
}
-
- /* Set the band's NODATA value */
+
+ /* Set the band's nodata value */
rt_band_set_isnodata_flag(ctx, band, 1);
/* Serialize raster again */
SET_VARSIZE(pgraster, pgraster->size);
PG_RETURN_POINTER(pgraster);
-
+
}
/* Index is 1-based */
index = PG_GETARG_INT32(1);
if ( index < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_bandIsNoData: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (index - 1));
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_bandIsNoData: Could not deserialize raster");
PG_RETURN_NULL();
}
- /* Fetch requested band and its NODATA value */
+ /* Fetch requested band and its nodata value */
band = rt_raster_get_band(ctx, raster, index - 1);
if ( ! band ) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", index);
+ elog(NOTICE, "Could not find raster band of index %d when determining if band is nodata. Returning NULL", index);
PG_RETURN_NULL();
}
forceChecking = PG_GETARG_BOOL(2);
-
- if (forceChecking)
- PG_RETURN_BOOL(rt_band_check_is_nodata(ctx, band));
+
+ if (forceChecking)
+ PG_RETURN_BOOL(rt_band_check_is_nodata(ctx, band));
else
PG_RETURN_BOOL(rt_band_get_isnodata_flag(ctx, band));
}
rt_context ctx = NULL;
int32_t index;
const char *bandpath;
- text *result;
+ text *result;
/* Index is 1-based */
index = PG_GETARG_INT32(1);
if ( index < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_getBandPath: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (index - 1));
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getBandPath: Could not deserialize raster");
PG_RETURN_NULL();
}
- /* Fetch requested band and its NODATA value */
+ /* Fetch requested band and its nodata value */
band = rt_raster_get_band(ctx, raster, index - 1);
if ( ! band ) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", index);
+ elog(NOTICE, "Could not find raster band of index %d when getting band path. Returning NULL", index);
PG_RETURN_NULL();
}
result = (text *) palloc(VARHDRSZ + strlen(bandpath) + 1);
if ( ! result ) {
- elog(ERROR, "Could not allocate memory for output text object");
+ elog(ERROR, "RASTER_getBandPath: Could not allocate memory for output text object");
PG_RETURN_NULL();
}
SET_VARSIZE(result, VARHDRSZ + strlen(bandpath) + 1);
/* Index is 1-based */
nband = PG_GETARG_INT32(1);
if ( nband < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_getPixelValue: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (nband - 1));
/* Validate pixel coordinates are in range */
if (PG_ARGISNULL(2)) {
- elog(NOTICE, "x coordinate can not be NULL. Returning NULL");
+ elog(NOTICE, "X coordinate can not be NULL when getting pixel value. Returning NULL");
PG_RETURN_NULL();
}
x = PG_GETARG_INT32(2);
if (PG_ARGISNULL(3)) {
- elog(NOTICE, "y coordinate can not be NULL. Returning NULL");
+ elog(NOTICE, "Y coordinate can not be NULL when getting pixel value. Returning NULL");
PG_RETURN_NULL();
}
y = PG_GETARG_INT32(3);
raster = rt_raster_deserialize(ctx, pgraster);
if (!raster) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_getPixelValue: Could not deserialize raster");
PG_RETURN_NULL();
}
/* Fetch Nth band using 0-based internal index */
band = rt_raster_get_band(ctx, raster, nband - 1);
if (! band) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", nband);
+ elog(NOTICE, "Could not find raster band of index %d when getting pixel value. Returning NULL", nband);
PG_RETURN_NULL();
}
/* Fetch pixel using 0-based coordiantes */
result = rt_band_get_pixel(ctx, band, x - 1, y - 1, &pixvalue);
if (result == -1 || (hasnodata && rt_band_get_hasnodata_flag(ctx, band) && pixvalue == rt_band_get_nodata(ctx, band))) {
- //elog(WARNING, "Raster band %d does not have a NODATA value", index);
+ //elog(WARNING, "RASTER_getPixelValue: Raster band %d does not have a nodata value", index);
PG_RETURN_NULL();
}
/* nband is 1-based */
nband = PG_GETARG_INT32(1);
if ( nband < 1 ) {
- elog(ERROR, "Invalid band index (must use 1-based)");
+ elog(ERROR, "RASTER_setPixelValue: Invalid band index (must use 1-based)");
PG_RETURN_NULL();
}
assert(0 <= (nband - 1));
/* Validate pixel coordinates are in range */
x = PG_GETARG_INT32(2);
y = PG_GETARG_INT32(3);
-
+
POSTGIS_RT_DEBUGF(3, "Pixel coordinates (%d, %d)", x, y);
/* Deserialize raster */
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_setPixelValue: Could not deserialize raster");
PG_RETURN_NULL();
}
/* Fetch requested band */
band = rt_raster_get_band(ctx, raster, nband - 1);
if ( ! band ) {
- elog(NOTICE, "Could not find raster band of index %d. Returning NULL", nband);
+ elog(NOTICE, "Could not find raster band of index %d when setting pixel value. Returning NULL", nband);
PG_RETURN_NULL();
}
pgraster = rt_raster_serialize(ctx, raster);
if ( ! pgraster ) PG_RETURN_NULL();
-
+
SET_VARSIZE(pgraster, pgraster->size);
PG_RETURN_POINTER(pgraster);
}
{
rt_pgraster *pgraster = NULL;
rt_raster raster = NULL;
- rt_band band = NULL;
rt_context ctx = NULL;
-
+
int index = 0;
double initialvalue = 0;
double nodatavalue = 0;
char *new_pixeltypename = NULL;
int pixtype = PT_END;
- int width = 0;
- int height = 0;
int32_t oldnumbands = 0;
int32_t numbands = 0;
-
- int datasize = 0;
- int numval = 0;
- void *mem;
- int32_t checkvalint = 0;
- uint32_t checkvaluint = 0;
- double checkvaldouble = 0;
- float checkvalfloat = 0;
- int i;
-
+
/* Get the initial pixel value */
if (PG_ARGISNULL(3))
initialvalue = 0;
else
initialvalue = PG_GETARG_FLOAT8(3);
-
+
/* Get the nodata value */
if (PG_ARGISNULL(4))
nodatavalue = 0;
nodatavalue = PG_GETARG_FLOAT8(4);
hasnodata = TRUE;
}
-
+
/* Deserialize raster */
pgraster = (rt_pgraster *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
ctx = get_rt_context(fcinfo);
/* Get the pixel type in text form */
if (PG_ARGISNULL(2)) {
- elog(ERROR, "Pixel type can not be null");
+ elog(ERROR, "RASTER_addband: Pixel type can not be null");
PG_RETURN_NULL();
}
-
+
pixeltypename = PG_GETARG_TEXT_P(2);
new_pixeltypename = (char *) palloc(VARSIZE(pixeltypename) + 1 - VARHDRSZ);
SET_VARSIZE(new_pixeltypename, VARSIZE(pixeltypename));
/* Get the pixel type index */
pixtype = rt_pixtype_index_from_name(ctx, new_pixeltypename);
if ( pixtype == PT_END ) {
- elog(ERROR, "Invalid pixel type: %s", new_pixeltypename);
+ elog(ERROR, "RASTER_addband: Invalid pixel type: %s", new_pixeltypename);
PG_RETURN_NULL();
}
assert(-1 < pixtype && pixtype < PT_END);
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_addband: Could not deserialize raster");
PG_RETURN_NULL();
}
-
+
/* Make sure index (1 based) is in a valid range */
oldnumbands = rt_raster_get_num_bands(ctx, raster);
if (PG_ARGISNULL(1))
{
index = PG_GETARG_UINT16(1);
if (index < 1) {
- elog(ERROR, "Invalid band index (must be 1-based)");
+ elog(ERROR, "RASTER_addband: Invalid band index (must be 1-based)");
PG_RETURN_NULL();
}
- if (index > oldnumbands + 1) {
- elog(WARNING, "Band index number exceed possible values, truncated to number of band (%u) + 1", oldnumbands);
+ if (index > oldnumbands + 1) {
+ elog(WARNING, "RASTER_addband: Band index number exceed possible values, truncated to number of band (%u) + 1", oldnumbands);
index = oldnumbands + 1;
}
}
-
+
index = rt_raster_generate_new_band(ctx, raster, pixtype, initialvalue,
hasnodata, nodatavalue, index - 1);
numbands = rt_raster_get_num_bands(ctx, raster);
if (numbands == oldnumbands || index == -1) {
- elog(ERROR, "Could not add band to raster. Returning NULL");
+ elog(ERROR, "RASTER_addband: Could not add band to raster. Returning NULL");
PG_RETURN_NULL();
}
pgraster = rt_raster_serialize(ctx, raster);
int index = 0;
int max = 0;
rt_context ctx = NULL;
-
+
/* Get band numbers */
nband1 = PG_GETARG_UINT16(2);
- nband2 = PG_GETARG_UINT16(3);
+ nband2 = PG_GETARG_UINT16(3);
if (nband1 < 1 || nband2 < 1) {
- elog(ERROR, "Invalid band index (must be 1-based)");
+ elog(ERROR, "RASTER_copyband: Invalid band index (must be 1-based)");
PG_RETURN_NULL();
}
/* Check if raster1 has the given band */
-
+
/* Deserialize raster1 */
pgraster = (rt_pgraster *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
ctx = get_rt_context(fcinfo);
raster1 = rt_raster_deserialize(ctx, pgraster);
if ( ! raster1 ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_copyband: Could not deserialize raster");
PG_RETURN_NULL();
}
-
+
/* Make sure index (1 based) is in range */
max = rt_raster_get_num_bands(ctx, raster1);
if (nband1 > max) {
- elog(WARNING, "Band index number exceed possible values, truncated to "
+ elog(WARNING, "RASTER_copyband: Band index number exceed possible values, truncated to "
"number of band (%u) + 1", max);
nband1 = max;
}
raster2 = rt_raster_deserialize(ctx, pgraster);
if ( ! raster2 ) {
- elog(ERROR, "Could not deserialize raster");
+ elog(ERROR, "RASTER_copyband: Could not deserialize raster");
PG_RETURN_NULL();
}
numbands = rt_raster_get_num_bands(ctx, raster2);
if (numbands == oldnumbands || index == -1) {
- elog(ERROR, "Could not add band to raster. Returning NULL");
+ elog(ERROR, "RASTER_copyband: Could not add band to raster. Returning NULL");
PG_RETURN_NULL();
}
-
+
/* Serialize and return raster2 */
pgraster = rt_raster_serialize(ctx, raster2);
if (!pgraster) PG_RETURN_NULL();
rt_pgraster *pgraster = NULL;
rt_raster raster = NULL;
rt_context ctx = NULL;
-
- /* Deserialize raster */
+
+ /* Deserialize raster */
pgraster = (rt_pgraster *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
ctx = get_rt_context(fcinfo);
- raster = rt_raster_deserialize(ctx, pgraster);
- if ( ! raster )
- {
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("Could not deserialize raster")));
- PG_RETURN_NULL();
- }
-
- PG_RETURN_BOOL(rt_raster_is_empty(ctx, raster));
+ raster = rt_raster_deserialize(ctx, pgraster);
+ if ( ! raster )
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("RASTER_isEmpty: Could not deserialize raster")));
+ PG_RETURN_NULL();
+ }
+
+ PG_RETURN_BOOL(rt_raster_is_empty(ctx, raster));
}
/**
rt_raster raster = NULL;
int nBand = 0;
rt_context ctx = NULL;
-
- /* Deserialize raster */
+
+ /* Deserialize raster */
pgraster = (rt_pgraster *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
ctx = get_rt_context(fcinfo);
- raster = rt_raster_deserialize(ctx, pgraster);
- if ( ! raster )
- {
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("Could not deserialize raster")));
- PG_RETURN_NULL();
- }
-
- /* Get band number */
- nBand = PG_GETARG_INT32(1);
-
- PG_RETURN_BOOL(rt_raster_has_no_band(ctx, raster, nBand));
+ raster = rt_raster_deserialize(ctx, pgraster);
+ if ( ! raster )
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("RASTER_hasNoBand: Could not deserialize raster")));
+ PG_RETURN_NULL();
+ }
+
+ /* Get band number */
+ nBand = PG_GETARG_INT32(1);
+
+ PG_RETURN_BOOL(rt_raster_has_no_band(ctx, raster, nBand));
}
PG_FUNCTION_INFO_V1(RASTER_mapAlgebra);
rt_band newband = NULL;
int x, y, nband, width, height;
double r;
- double newnodatavalue, newinitialvalue, newval;
+ double newnodatavalue = 0.0;
+ double newinitialvalue = 0.0;
+ double newval = 0.0;
char *newexpr = NULL;
char *initexpr = NULL;
char *initndvexpr = NULL;
char *expression = NULL;
char *nodatavalueexpr = NULL;
- rt_pixtype newpixeltype, pixeltype;
+ rt_pixtype newpixeltype;
int skipcomputation = 0;
- bool newhasnodatavalue = FALSE;
char strnewnodatavalue[50];
char strnewval[50];
int count = 0;
- char *command = NULL;
int len = 0;
int ret = -1;
- int proc;
TupleDesc tupdesc;
SPITupleTable * tuptable = NULL;
HeapTuple tuple;
- POSTGIS_RT_DEBUG(2, "RASTER_mapAlgebra: STARTING...");
+ POSTGIS_RT_DEBUG(2, "RASTER_mapAlgebra: Starting...");
/* Check raster */
if (PG_ARGISNULL(0)) {
- elog(WARNING, "MapAlgebra: Raster is NULL. Returning NULL");
+ elog(WARNING, "RASTER_mapAlgebra: Raster is NULL. Returning NULL");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster )
{
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("MapAlgebra: Could not deserialize raster")));
- PG_RETURN_NULL();
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("RASTER_mapAlgebra: Could not deserialize raster")));
+ PG_RETURN_NULL();
}
- POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: GETTING ARGUMENTS...");
+ POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: Getting arguments...");
/* Get the rest of the arguments */
if (nband < 1)
nband = 1;
-
- POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: CREATING NEW RASTER...");
- /**
+ POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: Creating new raster...");
+
+ /**
* Create a new empty raster with having the same georeference as the
* provided raster
**/
height = rt_raster_get_height(ctx, raster);
newrast = rt_raster_new(ctx,
- rt_raster_get_width(ctx, raster),
+ rt_raster_get_width(ctx, raster),
rt_raster_get_height(ctx, raster));
if ( ! newrast ) {
- elog(ERROR, "MapAlgebra: Could not create a new raster");
+ elog(ERROR, "RASTER_mapAlgebra: Could not create a new raster");
PG_RETURN_NULL();
}
- rt_raster_set_scale(ctx, newrast,
+ rt_raster_set_scale(ctx, newrast,
rt_raster_get_x_scale(ctx, raster),
rt_raster_get_y_scale(ctx, raster));
rt_raster_get_x_skew(ctx, raster),
rt_raster_get_y_skew(ctx, raster));
- rt_raster_set_srid(ctx, newrast, rt_raster_get_srid(ctx, raster));
+ rt_raster_set_srid(ctx, newrast, rt_raster_get_srid(ctx, raster));
* If this new raster is empty (width = 0 OR height = 0) then there is
* nothing to compute and we return it right now
**/
- if (rt_raster_is_empty(ctx, newrast)) {
- elog(WARNING, "MapAlgebra: Raster is empty. Returning an empty raster");
+ if (rt_raster_is_empty(ctx, newrast)) {
+ elog(WARNING, "RASTER_mapAlgebra: Raster is empty. Returning an empty raster");
pgraster = rt_raster_serialize(ctx, newrast);
if (!pgraster) PG_RETURN_NULL();
PG_RETURN_POINTER(pgraster);
}
- POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: GETTING RASTER BAND %d...", nband);
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: Getting raster band %d...", nband);
+
-
/**
* Check if the raster has the required band. Otherwise, return a raster
* without band
**/
if (rt_raster_has_no_band(ctx, raster, nband)) {
- elog(WARNING, "Mapalgebra: Raster do not have the required band. "
+ elog(WARNING, "RASTER_mapAlgebra: Raster do not have the required band. "
"Returning a raster without a band");
pgraster = rt_raster_serialize(ctx, newrast);
if (!pgraster) PG_RETURN_NULL();
/* Get the raster band */
band = rt_raster_get_band(ctx, raster, nband - 1);
if ( ! band ) {
- elog(ERROR, "MapAlgebra: Could not get band %d for raster", nband);
+ elog(ERROR, "RASTER_mapAlgebra: Could not get band %d for raster", nband);
PG_RETURN_NULL();
}
newnodatavalue = rt_band_get_min_value(ctx, band);
}
- POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: NODATA VALUE FOR BAND: %f...",
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: nodata value for band: %f...",
newnodatavalue);
/**
* We set the initial value of the future band to nodata value. If nodata
**/
newinitialvalue = newnodatavalue;
- POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: SETTING PIXELTYPE...");
+ POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: Setting pixeltype...");
/**
* Set the new pixeltype
- **/
+ **/
if (PG_ARGISNULL(4)) {
newpixeltype = rt_band_get_pixtype(ctx, band);
}
else {
newpixeltype = rt_pixtype_index_from_name(ctx,
- text_to_cstring(PG_GETARG_TEXT_P(4)));
+ text_to_cstring(PG_GETARG_TEXT_P(4)));
if (newpixeltype == PT_END)
newpixeltype = rt_band_get_pixtype(ctx, band);
}
-
+
if (newpixeltype == PT_END) {
- elog(ERROR, "MapAlgebra: Invalid pixeltype. Aborting");
+ elog(ERROR, "RASTER_mapAlgebra: Invalid pixeltype. Aborting");
PG_RETURN_NULL();
- }
-
+ }
+
/* Connect with SPI manager */
SPI_connect();
expression = text_to_cstring(PG_GETARG_TEXT_P(2));
len = strlen("SELECT ") + strlen(expression);
initexpr = (char *)palloc(len + 1);
-
+
strncpy(initexpr, "SELECT ", strlen("SELECT "));
strncpy(initexpr + strlen("SELECT "), strtoupper(expression),
strlen(expression));
- initexpr[len] = '\0';
+ initexpr[len] = '\0';
- POSTGIS_RT_DEBUGF(3, "MapAlgebra: Expression is %s", initexpr);
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: Expression is %s", initexpr);
- }
+ }
/**
* Optimization: If a nodatavalueexpr is provided, recompute the initial
* value. Then, we can initialize the raster with this value and skip the
* computation of nodata values one by one in the main computing loop
- **/
- if (!PG_ARGISNULL(3)) {
+ **/
+ if (!PG_ARGISNULL(3)) {
nodatavalueexpr = text_to_cstring(PG_GETARG_TEXT_P(3));
len = strlen("SELECT ") + strlen(nodatavalueexpr);
initndvexpr = (char *)palloc(len + 1);
newexpr = replace(initndvexpr, "RAST", strnewnodatavalue, &count);
- POSTGIS_RT_DEBUGF(3, "MapAlgebra: initndvexpr = %s", initndvexpr);
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: initndvexpr = %s", initndvexpr);
- /**
+ /**
* Execute the expression for nodata value and store the result as new
* initial value
**/
ret = SPI_execute(newexpr, FALSE, 0);
if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
- elog(ERROR, "MapAlgebra: invalid construction for NODATA "
+ elog(ERROR, "RASTER_mapAlgebra: Invalid construction for nodata "
"expression. Aborting");
SPI_finish();
PG_RETURN_NULL();
tuple = tuptable->vals[0];
newinitialvalue = atof(SPI_getvalue(tuple, tupdesc, 1));
- POSTGIS_RT_DEBUGF(3, "MapAlgebra: new initial value = %f",
- newinitialvalue);
-
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: new initial value = %f",
+ newinitialvalue);
+
}
**/
if (rt_band_get_isnodata_flag(ctx, band)) {
- POSTGIS_RT_DEBUG(3, "MapAlgebra: Band is a nodata band, returning "
+ POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: Band is a nodata band, returning "
"a raster filled with nodata");
ret = rt_raster_generate_new_band(ctx, newrast, newpixeltype,
if (!pgraster) PG_RETURN_NULL();
SET_VARSIZE(pgraster, pgraster->size);
-
+
/* Disconnect function from SPI manager */
SPI_finish();
-
- PG_RETURN_POINTER(pgraster);
+
+ PG_RETURN_POINTER(pgraster);
}
/**
* Optimization: If expression resume to 'RAST' and nodatavalueexpr is NULL
* or also equal to 'RAST', we can just return the band from the original
- * raster
+ * raster
**/
- if (initexpr != NULL && !strcmp(initexpr, "SELECT RAST") &&
+ if (initexpr != NULL && !strcmp(initexpr, "SELECT RAST") &&
(nodatavalueexpr == NULL || !strcmp(initndvexpr, "SELECT RAST"))) {
- POSTGIS_RT_DEBUGF(3, "MapAlgebra: Expression resumes to RAST. Returning "
- "raster with band %d from original raster", nband);
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: Expression resumes to RAST. Returning "
+ "raster with band %d from original raster", nband);
- POSTGIS_RT_DEBUGF(4, "MapAlgebra: New raster has %d bands",
+ POSTGIS_RT_DEBUGF(4, "RASTER_mapAlgebra: New raster has %d bands",
rt_raster_get_num_bands(ctx, newrast));
rt_raster_copy_band(ctx, raster, newrast, nband - 1, 0);
-
- POSTGIS_RT_DEBUGF(4, "MapAlgebra: New raster now has %d bands",
+
+ POSTGIS_RT_DEBUGF(4, "RASTER_mapAlgebra: New raster now has %d bands",
rt_raster_get_num_bands(ctx, newrast));
/* Serialize created raster */
if (!pgraster) PG_RETURN_NULL();
SET_VARSIZE(pgraster, pgraster->size);
-
+
/* Disconnect function from SPI manager */
SPI_finish();
-
- PG_RETURN_POINTER(pgraster);
+
+ PG_RETURN_POINTER(pgraster);
}
/**
ret = SPI_execute(initexpr, FALSE, 0);
if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
- elog(ERROR, "MapAlgebra: invalid construction for expression. Aborting");
+ elog(ERROR, "RASTER_mapAlgebra: Invalid construction for expression. Aborting");
SPI_finish();
PG_RETURN_NULL();
}
tuple = tuptable->vals[0];
newval = atof(SPI_getvalue(tuple, tupdesc, 1));
- POSTGIS_RT_DEBUGF(3, "MapAlgebra: new raster value = %f",
- newval);
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: New raster value = %f",
+ newval);
skipcomputation = 1;
/**
- * Compute the new value, set it and we will return after creating the
+ * Compute the new value, set it and we will return after creating the
* new raster
**/
if (nodatavalueexpr == NULL) {
newinitialvalue = newval;
- skipcomputation = 2;
+ skipcomputation = 2;
}
/* Return the new raster as it will be before computing pixel by pixel */
/* Disconnect function from SPI manager */
SPI_finish();
-
- PG_RETURN_POINTER(pgraster);
+
+ PG_RETURN_POINTER(pgraster);
}
/* Get the new raster band */
newband = rt_raster_get_band(ctx, newrast, 0);
if ( ! newband ) {
- elog(WARNING, "MapAlgebra: Could not modify band for new raster. "
+ elog(WARNING, "RASTER_mapAlgebra: Could not modify band for new raster. "
"Returning new raster with the original band");
/* Serialize created raster */
/* Disconnect function from SPI manager */
SPI_finish();
-
- PG_RETURN_POINTER(pgraster);
+
+ PG_RETURN_POINTER(pgraster);
}
-
- POSTGIS_RT_DEBUGF(3, "MapAlgebra: Main computing loop (%d x %d)",
+
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: Main computing loop (%d x %d)",
width, height);
for (x = 0; x < width; x++) {
if (ret != -1 && fabs(r - newnodatavalue) > FLT_EPSILON) {
if (skipcomputation == 0) {
sprintf(strnewval, "%f", r);
-
- if (initexpr != NULL) {
+
+ if (initexpr != NULL) {
newexpr = replace(initexpr, "RAST", strnewval, &count);
- POSTGIS_RT_DEBUGF(3, "MapAlgebra: (%dx%d), r = %s, newexpr = %s",
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: (%dx%d), r = %s, newexpr = %s",
x, y, strnewval, newexpr);
-
+
ret = SPI_execute(newexpr, FALSE, 0);
if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
- elog(ERROR, "MapAlgebra: invalid construction for expression. Aborting");
+ elog(ERROR, "RASTER_mapAlgebra: Invalid construction for expression. Aborting");
SPI_finish();
PG_RETURN_NULL();
}
tupdesc = SPI_tuptable->tupdesc;
tuptable = SPI_tuptable;
-
+
tuple = tuptable->vals[0];
newval = atof(SPI_getvalue(tuple, tupdesc, 1));
}
else
newval = newinitialvalue;
- POSTGIS_RT_DEBUGF(3, "MapAlgebra: new value = %f", newval);
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: new value = %f", newval);
}
-
+
rt_band_set_pixel(ctx, newband, x, y, newval);
}
}
}
-
+
/* The newrast band has been modified */
/* Serialize created raster */
pgraster = rt_raster_serialize(ctx, newrast);
if (!pgraster) PG_RETURN_NULL();
- SET_VARSIZE(pgraster, pgraster->size);
-
+ SET_VARSIZE(pgraster, pgraster->size);
+
/* Disconnect function from SPI manager */
SPI_finish();
static void *
rt_pg_alloc(size_t size)
{
- void * result;
+ void * result;
- result = palloc(size);
+ result = palloc(size);
- if ( ! result )
- {
- ereport(ERROR, (errmsg_internal("Out of virtual memory")));
- return NULL;
- }
- return result;
+ if ( ! result )
+ {
+ ereport(ERROR, (errmsg_internal("Out of virtual memory")));
+ return NULL;
+ }
+ return result;
}
static void *
rt_pg_realloc(void *mem, size_t size)
{
- void * result;
+ void * result;
- result = repalloc(mem, size);
+ result = repalloc(mem, size);
- return result;
+ return result;
}
static void
rt_pg_free(void *ptr)
{
- pfree(ptr);
+ pfree(ptr);
}
static void
{
#define ERRMSG_MAXLEN 256
- char errmsg[ERRMSG_MAXLEN+1];
+ char errmsg[ERRMSG_MAXLEN+1];
- vsnprintf (errmsg, ERRMSG_MAXLEN, fmt, ap);
+ vsnprintf (errmsg, ERRMSG_MAXLEN, fmt, ap);
- errmsg[ERRMSG_MAXLEN]='\0';
- ereport(ERROR, (errmsg_internal("%s", errmsg)));
+ errmsg[ERRMSG_MAXLEN]='\0';
+ ereport(ERROR, (errmsg_internal("%s", errmsg)));
}
static void
rt_pg_notice(const char *fmt, va_list ap)
{
- char *msg;
-
- /*
- * This is a GNU extension.
- * Dunno how to handle errors here.
- */
- if (!lw_vasprintf (&msg, fmt, ap))
- {
- va_end (ap);
- return;
- }
- ereport(NOTICE, (errmsg_internal("%s", msg)));
- free(msg);
+ char *msg;
+
+ /*
+ * This is a GNU extension.
+ * Dunno how to handle errors here.
+ */
+ if (!lw_vasprintf (&msg, fmt, ap))
+ {
+ va_end (ap);
+ return;
+ }
+ ereport(NOTICE, (errmsg_internal("%s", msg)));
+ free(msg);
}