PostGIS  2.5.0dev-r@@SVN_REVISION@@
Datum RASTER_clip ( PG_FUNCTION_ARGS  )

Definition at line 2961 of file rtpg_mapalgebra.c.

References ovdump::band, rtpg_clip_arg_t::band, clamp_srid(), ES_NONE, ET_FIRST, ET_INTERSECTION, rtpg_clip_arg_t::extenttype, FALSE, gserialized_get_srid(), window::gt, rtpg_clip_band_t::hasnodata, lwgeom_force_2d(), lwgeom_free(), lwgeom_from_gserialized(), lwgeom_intersection(), lwgeom_is_empty(), lwgeom_ndims(), lwgeom_to_wkb(), rtpg_clip_arg_t::mask, rt_iterator_t::nband, rtpg_clip_band_t::nband, rt_iterator_t::nbnodata, rtpg_clip_band_t::nodataval, rtpg_clip_arg_t::numbands, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, rt_iterator_t::raster, rtpg_clip_arg_t::raster, rt_band_get_hasnodata_flag(), rt_band_get_isnodata_flag(), rt_band_get_min_value(), rt_band_get_nodata(), rt_band_get_pixtype(), rt_raster_add_band(), rt_raster_deserialize(), rt_raster_destroy(), rt_raster_from_two_rasters(), rt_raster_gdal_rasterize(), rt_raster_generate_new_band(), rt_raster_get_band(), rt_raster_get_convex_hull(), rt_raster_get_geotransform_matrix(), rt_raster_get_num_bands(), rt_raster_get_srid(), rt_raster_has_band(), rt_raster_is_empty(), rt_raster_iterator(), rt_raster_new(), rt_raster_serialize(), rt_raster_set_srid(), rtpg_clip_arg_destroy(), rtpg_clip_arg_init(), rtpg_clip_callback(), rt_raster_serialized_t::size, SRID_UNKNOWN, and WKB_SFSQL.

2962 {
2963  rt_pgraster *pgraster = NULL;
2964  LWGEOM *rastgeom = NULL;
2965  double gt[6] = {0};
2966  int srid = SRID_UNKNOWN;
2967 
2968  rt_pgraster *pgrtn = NULL;
2969  rt_raster rtn = NULL;
2970 
2971  GSERIALIZED *gser = NULL;
2972  LWGEOM *geom = NULL;
2973  unsigned char *wkb = NULL;
2974  size_t wkb_len;
2975 
2976  ArrayType *array;
2977  Oid etype;
2978  Datum *e;
2979  bool *nulls;
2980 
2981  int16 typlen;
2982  bool typbyval;
2983  char typalign;
2984 
2985  int i = 0;
2986  int j = 0;
2987  int k = 0;
2988  rtpg_clip_arg arg = NULL;
2989  LWGEOM *tmpgeom = NULL;
2990  rt_iterator itrset;
2991 
2992  rt_raster _raster = NULL;
2993  rt_band band = NULL;
2994  rt_pixtype pixtype;
2995  int hasnodata;
2996  double nodataval;
2997  int noerr = 0;
2998 
2999  POSTGIS_RT_DEBUG(3, "Starting...");
3000 
3001  /* raster or geometry is NULL, return NULL */
3002  if (PG_ARGISNULL(0) || PG_ARGISNULL(2))
3003  PG_RETURN_NULL();
3004 
3005  /* init arg */
3006  arg = rtpg_clip_arg_init();
3007  if (arg == NULL) {
3008  elog(ERROR, "RASTER_clip: Could not initialize argument structure");
3009  PG_RETURN_NULL();
3010  }
3011 
3012  /* raster (0) */
3013  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
3014 
3015  /* Get raster object */
3016  arg->raster = rt_raster_deserialize(pgraster, FALSE);
3017  if (arg->raster == NULL) {
3018  rtpg_clip_arg_destroy(arg);
3019  PG_FREE_IF_COPY(pgraster, 0);
3020  elog(ERROR, "RASTER_clip: Could not deserialize raster");
3021  PG_RETURN_NULL();
3022  }
3023 
3024  /* raster is empty, return empty raster */
3025  if (rt_raster_is_empty(arg->raster)) {
3026  elog(NOTICE, "Input raster is empty. Returning empty raster");
3027 
3028  rtpg_clip_arg_destroy(arg);
3029  PG_FREE_IF_COPY(pgraster, 0);
3030 
3031  rtn = rt_raster_new(0, 0);
3032  if (rtn == NULL) {
3033  elog(ERROR, "RASTER_clip: Could not create empty raster");
3034  PG_RETURN_NULL();
3035  }
3036 
3037  pgrtn = rt_raster_serialize(rtn);
3038  rt_raster_destroy(rtn);
3039  if (NULL == pgrtn)
3040  PG_RETURN_NULL();
3041 
3042  SET_VARSIZE(pgrtn, pgrtn->size);
3043  PG_RETURN_POINTER(pgrtn);
3044  }
3045 
3046  /* metadata */
3048  srid = clamp_srid(rt_raster_get_srid(arg->raster));
3049 
3050  /* geometry (2) */
3051  gser = PG_GETARG_GSERIALIZED_P(2);
3052  geom = lwgeom_from_gserialized(gser);
3053 
3054  /* Get a 2D version of the geometry if necessary */
3055  if (lwgeom_ndims(geom) > 2) {
3056  LWGEOM *geom2d = lwgeom_force_2d(geom);
3057  lwgeom_free(geom);
3058  geom = geom2d;
3059  }
3060 
3061  /* check that SRIDs match */
3062  if (srid != clamp_srid(gserialized_get_srid(gser))) {
3063  elog(NOTICE, "Geometry provided does not have the same SRID as the raster. Returning NULL");
3064 
3065  rtpg_clip_arg_destroy(arg);
3066  PG_FREE_IF_COPY(pgraster, 0);
3067  lwgeom_free(geom);
3068  PG_FREE_IF_COPY(gser, 2);
3069 
3070  PG_RETURN_NULL();
3071  }
3072 
3073  /* crop (4) */
3074  if (!PG_ARGISNULL(4) && !PG_GETARG_BOOL(4))
3075  arg->extenttype = ET_FIRST;
3076 
3077  /* get intersection geometry of input raster and input geometry */
3078  if (rt_raster_get_convex_hull(arg->raster, &rastgeom) != ES_NONE) {
3079 
3080  rtpg_clip_arg_destroy(arg);
3081  PG_FREE_IF_COPY(pgraster, 0);
3082  lwgeom_free(geom);
3083  PG_FREE_IF_COPY(gser, 2);
3084 
3085  elog(ERROR, "RASTER_clip: Could not get convex hull of raster");
3086  PG_RETURN_NULL();
3087  }
3088 
3089  tmpgeom = lwgeom_intersection(rastgeom, geom);
3090  lwgeom_free(rastgeom);
3091  lwgeom_free(geom);
3092  PG_FREE_IF_COPY(gser, 2);
3093  geom = tmpgeom;
3094 
3095  /* intersection is empty AND extent type is INTERSECTION, return empty */
3096  if (lwgeom_is_empty(geom) && arg->extenttype == ET_INTERSECTION) {
3097  elog(NOTICE, "The input raster and input geometry do not intersect. Returning empty raster");
3098 
3099  rtpg_clip_arg_destroy(arg);
3100  PG_FREE_IF_COPY(pgraster, 0);
3101  lwgeom_free(geom);
3102 
3103  rtn = rt_raster_new(0, 0);
3104  if (rtn == NULL) {
3105  elog(ERROR, "RASTER_clip: Could not create empty raster");
3106  PG_RETURN_NULL();
3107  }
3108 
3109  pgrtn = rt_raster_serialize(rtn);
3110  rt_raster_destroy(rtn);
3111  if (NULL == pgrtn)
3112  PG_RETURN_NULL();
3113 
3114  SET_VARSIZE(pgrtn, pgrtn->size);
3115  PG_RETURN_POINTER(pgrtn);
3116  }
3117 
3118  /* nband (1) */
3119  if (!PG_ARGISNULL(1)) {
3120  array = PG_GETARG_ARRAYTYPE_P(1);
3121  etype = ARR_ELEMTYPE(array);
3122  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3123 
3124  switch (etype) {
3125  case INT2OID:
3126  case INT4OID:
3127  break;
3128  default:
3129  rtpg_clip_arg_destroy(arg);
3130  PG_FREE_IF_COPY(pgraster, 0);
3131  lwgeom_free(geom);
3132  elog(ERROR, "RASTER_clip: Invalid data type for band indexes");
3133  PG_RETURN_NULL();
3134  break;
3135  }
3136 
3137  deconstruct_array(
3138  array, etype,
3139  typlen, typbyval, typalign,
3140  &e, &nulls, &(arg->numbands)
3141  );
3142 
3143  arg->band = palloc(sizeof(struct rtpg_clip_band_t) * arg->numbands);
3144  if (arg->band == NULL) {
3145  rtpg_clip_arg_destroy(arg);
3146  PG_FREE_IF_COPY(pgraster, 0);
3147  lwgeom_free(geom);
3148  elog(ERROR, "RASTER_clip: Could not allocate memory for band arguments");
3149  PG_RETURN_NULL();
3150  }
3151 
3152  for (i = 0, j = 0; i < arg->numbands; i++) {
3153  if (nulls[i]) continue;
3154 
3155  switch (etype) {
3156  case INT2OID:
3157  arg->band[j].nband = DatumGetInt16(e[i]) - 1;
3158  break;
3159  case INT4OID:
3160  arg->band[j].nband = DatumGetInt32(e[i]) - 1;
3161  break;
3162  }
3163 
3164  j++;
3165  }
3166 
3167  if (j < arg->numbands) {
3168  arg->band = repalloc(arg->band, sizeof(struct rtpg_clip_band_t) * j);
3169  if (arg->band == NULL) {
3170  rtpg_clip_arg_destroy(arg);
3171  PG_FREE_IF_COPY(pgraster, 0);
3172  lwgeom_free(geom);
3173  elog(ERROR, "RASTER_clip: Could not reallocate memory for band arguments");
3174  PG_RETURN_NULL();
3175  }
3176 
3177  arg->numbands = j;
3178  }
3179 
3180  /* validate band */
3181  for (i = 0; i < arg->numbands; i++) {
3182  if (!rt_raster_has_band(arg->raster, arg->band[i].nband)) {
3183  elog(NOTICE, "Band at index %d not found in raster", arg->band[i].nband + 1);
3184  rtpg_clip_arg_destroy(arg);
3185  PG_FREE_IF_COPY(pgraster, 0);
3186  lwgeom_free(geom);
3187  PG_RETURN_NULL();
3188  }
3189 
3190  arg->band[i].hasnodata = 0;
3191  arg->band[i].nodataval = 0;
3192  }
3193  }
3194  else {
3196 
3197  /* raster may have no bands */
3198  if (arg->numbands) {
3199  arg->band = palloc(sizeof(struct rtpg_clip_band_t) * arg->numbands);
3200  if (arg->band == NULL) {
3201 
3202  rtpg_clip_arg_destroy(arg);
3203  PG_FREE_IF_COPY(pgraster, 0);
3204  lwgeom_free(geom);
3205 
3206  elog(ERROR, "RASTER_clip: Could not allocate memory for band arguments");
3207  PG_RETURN_NULL();
3208  }
3209 
3210  for (i = 0; i < arg->numbands; i++) {
3211  arg->band[i].nband = i;
3212  arg->band[i].hasnodata = 0;
3213  arg->band[i].nodataval = 0;
3214  }
3215  }
3216  }
3217 
3218  /* nodataval (3) */
3219  if (!PG_ARGISNULL(3)) {
3220  array = PG_GETARG_ARRAYTYPE_P(3);
3221  etype = ARR_ELEMTYPE(array);
3222  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3223 
3224  switch (etype) {
3225  case FLOAT4OID:
3226  case FLOAT8OID:
3227  break;
3228  default:
3229  rtpg_clip_arg_destroy(arg);
3230  PG_FREE_IF_COPY(pgraster, 0);
3231  lwgeom_free(geom);
3232  elog(ERROR, "RASTER_clip: Invalid data type for NODATA values");
3233  PG_RETURN_NULL();
3234  break;
3235  }
3236 
3237  deconstruct_array(
3238  array, etype,
3239  typlen, typbyval, typalign,
3240  &e, &nulls, &k
3241  );
3242 
3243  /* it doesn't matter if there are more nodataval */
3244  for (i = 0, j = 0; i < arg->numbands; i++, j++) {
3245  /* cap j to the last nodataval element */
3246  if (j >= k)
3247  j = k - 1;
3248 
3249  if (nulls[j])
3250  continue;
3251 
3252  arg->band[i].hasnodata = 1;
3253  switch (etype) {
3254  case FLOAT4OID:
3255  arg->band[i].nodataval = DatumGetFloat4(e[j]);
3256  break;
3257  case FLOAT8OID:
3258  arg->band[i].nodataval = DatumGetFloat8(e[j]);
3259  break;
3260  }
3261  }
3262  }
3263 
3264  /* get wkb of geometry */
3265  POSTGIS_RT_DEBUG(3, "getting wkb of geometry");
3266  wkb = lwgeom_to_wkb(geom, WKB_SFSQL, &wkb_len);
3267  lwgeom_free(geom);
3268 
3269  /* rasterize geometry */
3271  wkb, wkb_len,
3272  NULL,
3273  0, NULL,
3274  NULL, NULL,
3275  NULL, NULL,
3276  NULL, NULL,
3277  &(gt[1]), &(gt[5]),
3278  NULL, NULL,
3279  &(gt[0]), &(gt[3]),
3280  &(gt[2]), &(gt[4]),
3281  NULL
3282  );
3283 
3284  pfree(wkb);
3285  if (arg->mask == NULL) {
3286  rtpg_clip_arg_destroy(arg);
3287  PG_FREE_IF_COPY(pgraster, 0);
3288  elog(ERROR, "RASTER_clip: Could not rasterize intersection geometry");
3289  PG_RETURN_NULL();
3290  }
3291 
3292  /* set SRID */
3293  rt_raster_set_srid(arg->mask, srid);
3294 
3295  /* run iterator */
3296 
3297  /* init itrset */
3298  itrset = palloc(sizeof(struct rt_iterator_t) * 2);
3299  if (itrset == NULL) {
3300  rtpg_clip_arg_destroy(arg);
3301  PG_FREE_IF_COPY(pgraster, 0);
3302  elog(ERROR, "RASTER_clip: Could not allocate memory for iterator arguments");
3303  PG_RETURN_NULL();
3304  }
3305 
3306  /* one band at a time */
3307  for (i = 0; i < arg->numbands; i++) {
3308  POSTGIS_RT_DEBUGF(4, "band arg %d (nband, hasnodata, nodataval) = (%d, %d, %f)",
3309  i, arg->band[i].nband, arg->band[i].hasnodata, arg->band[i].nodataval);
3310 
3311  band = rt_raster_get_band(arg->raster, arg->band[i].nband);
3312 
3313  /* band metadata */
3314  pixtype = rt_band_get_pixtype(band);
3315 
3316  if (arg->band[i].hasnodata) {
3317  hasnodata = 1;
3318  nodataval = arg->band[i].nodataval;
3319  }
3320  else if (rt_band_get_hasnodata_flag(band)) {
3321  hasnodata = 1;
3322  rt_band_get_nodata(band, &nodataval);
3323  }
3324  else {
3325  hasnodata = 0;
3326  nodataval = rt_band_get_min_value(band);
3327  }
3328 
3329  /* band is NODATA, create NODATA band and continue */
3330  if (rt_band_get_isnodata_flag(band)) {
3331  /* create raster */
3332  if (rtn == NULL) {
3333  noerr = rt_raster_from_two_rasters(arg->raster, arg->mask, arg->extenttype, &rtn, NULL);
3334  if (noerr != ES_NONE) {
3335  rtpg_clip_arg_destroy(arg);
3336  PG_FREE_IF_COPY(pgraster, 0);
3337  elog(ERROR, "RASTER_clip: Could not create output raster");
3338  PG_RETURN_NULL();
3339  }
3340  }
3341 
3342  /* create NODATA band */
3343  if (rt_raster_generate_new_band(rtn, pixtype, nodataval, hasnodata, nodataval, i) < 0) {
3344  rt_raster_destroy(rtn);
3345  rtpg_clip_arg_destroy(arg);
3346  PG_FREE_IF_COPY(pgraster, 0);
3347  elog(ERROR, "RASTER_clip: Could not add NODATA band to output raster");
3348  PG_RETURN_NULL();
3349  }
3350 
3351  continue;
3352  }
3353 
3354  /* raster */
3355  itrset[0].raster = arg->raster;
3356  itrset[0].nband = arg->band[i].nband;
3357  itrset[0].nbnodata = 1;
3358 
3359  /* mask */
3360  itrset[1].raster = arg->mask;
3361  itrset[1].nband = 0;
3362  itrset[1].nbnodata = 1;
3363 
3364  /* pass to iterator */
3365  noerr = rt_raster_iterator(
3366  itrset, 2,
3367  arg->extenttype, NULL,
3368  pixtype,
3369  hasnodata, nodataval,
3370  0, 0,
3371  NULL,
3372  NULL,
3374  &_raster
3375  );
3376 
3377  if (noerr != ES_NONE) {
3378  pfree(itrset);
3379  rtpg_clip_arg_destroy(arg);
3380  if (rtn != NULL) rt_raster_destroy(rtn);
3381  PG_FREE_IF_COPY(pgraster, 0);
3382  elog(ERROR, "RASTER_clip: Could not run raster iterator function");
3383  PG_RETURN_NULL();
3384  }
3385 
3386  /* new raster */
3387  if (rtn == NULL)
3388  rtn = _raster;
3389  /* copy band */
3390  else {
3391  band = rt_raster_get_band(_raster, 0);
3392  if (band == NULL) {
3393  pfree(itrset);
3394  rtpg_clip_arg_destroy(arg);
3395  rt_raster_destroy(_raster);
3396  rt_raster_destroy(rtn);
3397  PG_FREE_IF_COPY(pgraster, 0);
3398  elog(NOTICE, "RASTER_clip: Could not get band from working raster");
3399  PG_RETURN_NULL();
3400  }
3401 
3402  if (rt_raster_add_band(rtn, band, i) < 0) {
3403  pfree(itrset);
3404  rtpg_clip_arg_destroy(arg);
3405  rt_raster_destroy(_raster);
3406  rt_raster_destroy(rtn);
3407  PG_FREE_IF_COPY(pgraster, 0);
3408  elog(ERROR, "RASTER_clip: Could not add new band to output raster");
3409  PG_RETURN_NULL();
3410  }
3411 
3412  rt_raster_destroy(_raster);
3413  }
3414  }
3415 
3416  pfree(itrset);
3417  rtpg_clip_arg_destroy(arg);
3418  PG_FREE_IF_COPY(pgraster, 0);
3419 
3420  pgrtn = rt_raster_serialize(rtn);
3421  rt_raster_destroy(rtn);
3422 
3423  POSTGIS_RT_DEBUG(3, "Finished");
3424 
3425  if (!pgrtn)
3426  PG_RETURN_NULL();
3427 
3428  SET_VARSIZE(pgrtn, pgrtn->size);
3429  PG_RETURN_POINTER(pgrtn);
3430 }
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition: lwutil.c:347
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:372
static void rtpg_clip_arg_destroy(rtpg_clip_arg arg)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_raster.c:706
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1137
tuple gt
Definition: window.py:77
rt_errorstate rt_raster_from_two_rasters(rt_raster rast1, rt_raster rast2, rt_extenttype extenttype, rt_raster *rtnraster, double *offset)
Definition: rt_raster.c:3465
tuple band
Definition: ovdump.py:57
rt_raster rt_raster_gdal_rasterize(const unsigned char *wkb, uint32_t wkb_len, const char *srs, uint32_t num_bands, rt_pixtype *pixtype, double *init, double *value, double *nodata, uint8_t *hasnodata, int *width, int *height, double *scale_x, double *scale_y, double *ul_xw, double *ul_yw, double *grid_xw, double *grid_yw, double *skew_x, double *skew_y, char **options)
Return a raster of the provided geometry.
Definition: rt_raster.c:2513
rt_pixtype
Definition: librtcore.h:185
static int rtpg_clip_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
int lwgeom_ndims(const LWGEOM *geom)
Return the number of dimensions (2, 3, 4) in a geometry.
Definition: lwgeom.c:937
#define WKB_SFSQL
Definition: liblwgeom.h:2060
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_raster.c:1338
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1597
rt_errorstate rt_raster_get_convex_hull(rt_raster raster, LWGEOM **hull)
Get raster's convex hull.
Definition: rt_geometry.c:803
rt_extenttype extenttype
uint8_t * lwgeom_to_wkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Convert LWGEOM to a char* in WKB format.
Definition: lwout_wkb.c:764
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.
Definition: rt_raster.c:485
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:187
LWGEOM * lwgeom_intersection(const LWGEOM *geom1, const LWGEOM *geom2)
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
Definition: lwgeom.c:777
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:381
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:541
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
Definition: rt_raster.c:1351
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition: rt_raster.c:363
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_raster.c:356
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
rt_raster raster
Definition: librtcore.h:2394
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_raster.c:48
uint16_t nband
Definition: librtcore.h:2395
rtpg_clip_band band
#define FALSE
Definition: dbfopen.c:168
uint8_t nbnodata
Definition: librtcore.h:2396
Struct definitions.
Definition: librtcore.h:2201
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
Definition: rt_band.c:1612
rt_errorstate rt_raster_iterator(rt_iterator itrset, uint16_t itrcount, rt_extenttype extenttype, rt_raster customextent, rt_pixtype pixtype, uint8_t hasnodata, double nodataval, uint16_t distancex, uint16_t distancey, rt_mask mask, void *userarg, int(*callback)(rt_iterator_arg arg, void *userarg, double *value, int *nodata), rt_raster *rtnraster)
n-raster iterator.
static rtpg_clip_arg rtpg_clip_arg_init()
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:498
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
Definition: rt_raster.c:405
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition: rt_band.c:581
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Definition: lwgeom.c:1386
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:717
int32_t gserialized_get_srid(const GSERIALIZED *s)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
Definition: g_serialized.c:99

Here is the call graph for this function: