PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ RASTER_clip()

Datum RASTER_clip ( PG_FUNCTION_ARGS  )

Used to send to GDAL if ALL_TOUCHED rasterization is requested

How many options we have currently. Right now we'll have at most 1, but that could change in future

Definition at line 2973 of file rtpg_mapalgebra.c.

2974 {
2975  rt_pgraster *pgraster = NULL;
2976  LWGEOM *rastgeom = NULL;
2977  double gt[6] = {0};
2978  int32_t srid = SRID_UNKNOWN;
2979 
2980  rt_pgraster *pgrtn = NULL;
2981  rt_raster rtn = NULL;
2982 
2983  GSERIALIZED *gser = NULL;
2984  LWGEOM *geom = NULL;
2985  lwvarlena_t *wkb = NULL;
2986 
2987  ArrayType *array;
2988  Oid etype;
2989  Datum *e;
2990  bool *nulls;
2991 
2992  int16 typlen;
2993  bool typbyval;
2994  char typalign;
2995 
2996  int i = 0;
2997  int j = 0;
2998  int k = 0;
2999  rtpg_clip_arg arg = NULL;
3000  LWGEOM *tmpgeom = NULL;
3001 
3002  rt_pixtype pixtype;
3003  int hasnodata;
3004  double nodataval;
3005 
3006  double offset[4] = {0.};
3007  int input_x = 0;
3008  int input_y = 0;
3009  int mask_x = 0;
3010  int mask_y = 0;
3011  int x = 0;
3012  int y = 0;
3013  int width = 0;
3014  int height = 0;
3015  int mask_width = 0;
3016  int mask_height = 0;
3017  rt_band input_band = NULL;
3018  rt_band mask_band = NULL;
3019  rt_band output_band = NULL;
3020  double value;
3021  int isnodata;
3023  char **options = NULL;
3025  int options_len = 0;
3026 
3027  POSTGIS_RT_DEBUG(3, "Starting...");
3028 
3029  /* raster or geometry is NULL, return NULL */
3030  if (PG_ARGISNULL(0) || PG_ARGISNULL(2))
3031  PG_RETURN_NULL();
3032 
3033  /* init arg */
3034  arg = rtpg_clip_arg_init();
3035  if (arg == NULL) {
3036  elog(ERROR, "RASTER_clip: Could not initialize argument structure");
3037  PG_RETURN_NULL();
3038  }
3039 
3040  /* raster (0) */
3041  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
3042 
3043  /* Get raster object */
3044  arg->raster = rt_raster_deserialize(pgraster, FALSE);
3045  if (arg->raster == NULL) {
3046  rtpg_clip_arg_destroy(arg);
3047  PG_FREE_IF_COPY(pgraster, 0);
3048  elog(ERROR, "RASTER_clip: Could not deserialize raster");
3049  PG_RETURN_NULL();
3050  }
3051 
3052  /* raster is empty, return empty raster */
3053  if (rt_raster_is_empty(arg->raster) || rt_raster_get_num_bands(arg->raster) == 0) {
3054  elog(NOTICE, "Input raster is empty or has no bands. Returning empty raster");
3055 
3056  rtpg_clip_arg_destroy(arg);
3057  PG_FREE_IF_COPY(pgraster, 0);
3058 
3059  rtn = rt_raster_new(0, 0);
3060  if (rtn == NULL) {
3061  elog(ERROR, "RASTER_clip: Could not create empty raster");
3062  PG_RETURN_NULL();
3063  }
3064 
3065  pgrtn = rt_raster_serialize(rtn);
3066  rt_raster_destroy(rtn);
3067  if (NULL == pgrtn)
3068  PG_RETURN_NULL();
3069 
3070  SET_VARSIZE(pgrtn, pgrtn->size);
3071  PG_RETURN_POINTER(pgrtn);
3072  }
3073 
3074  /* metadata */
3076  srid = clamp_srid(rt_raster_get_srid(arg->raster));
3077 
3078  /* geometry (2) */
3079  gser = PG_GETARG_GSERIALIZED_P(2);
3080  geom = lwgeom_from_gserialized(gser);
3081 
3082  /* Get a 2D version of the geometry if necessary */
3083  if (lwgeom_ndims(geom) > 2) {
3084  LWGEOM *geom2d = lwgeom_force_2d(geom);
3085  lwgeom_free(geom);
3086  geom = geom2d;
3087  }
3088 
3089  /* check that SRIDs match */
3090  if (srid != clamp_srid(gserialized_get_srid(gser))) {
3091  elog(NOTICE, "Geometry provided does not have the same SRID as the raster. Returning NULL");
3092 
3093  rtpg_clip_arg_destroy(arg);
3094  PG_FREE_IF_COPY(pgraster, 0);
3095  lwgeom_free(geom);
3096  PG_FREE_IF_COPY(gser, 2);
3097 
3098  PG_RETURN_NULL();
3099  }
3100 
3101  /* crop (4) */
3102  if (!PG_ARGISNULL(4) && !PG_GETARG_BOOL(4))
3103  arg->extenttype = ET_FIRST;
3104 
3105  /* get intersection geometry of input raster and input geometry */
3106  if (rt_raster_get_convex_hull(arg->raster, &rastgeom) != ES_NONE) {
3107 
3108  rtpg_clip_arg_destroy(arg);
3109  PG_FREE_IF_COPY(pgraster, 0);
3110  lwgeom_free(geom);
3111  PG_FREE_IF_COPY(gser, 2);
3112 
3113  elog(ERROR, "RASTER_clip: Could not get convex hull of raster");
3114  PG_RETURN_NULL();
3115  }
3116 
3117  tmpgeom = lwgeom_intersection(rastgeom, geom);
3118  lwgeom_free(rastgeom);
3119  lwgeom_free(geom);
3120  PG_FREE_IF_COPY(gser, 2);
3121  geom = tmpgeom;
3122 
3123  /* intersection is empty AND extent type is INTERSECTION, return empty */
3124  if (lwgeom_is_empty(geom) && arg->extenttype == ET_INTERSECTION) {
3125  elog(NOTICE, "The input raster and input geometry do not intersect. Returning empty raster");
3126 
3127  rtpg_clip_arg_destroy(arg);
3128  PG_FREE_IF_COPY(pgraster, 0);
3129  lwgeom_free(geom);
3130 
3131  rtn = rt_raster_new(0, 0);
3132  if (rtn == NULL) {
3133  elog(ERROR, "RASTER_clip: Could not create empty raster");
3134  PG_RETURN_NULL();
3135  }
3136 
3137  pgrtn = rt_raster_serialize(rtn);
3138  rt_raster_destroy(rtn);
3139  if (NULL == pgrtn)
3140  PG_RETURN_NULL();
3141 
3142  SET_VARSIZE(pgrtn, pgrtn->size);
3143  PG_RETURN_POINTER(pgrtn);
3144  }
3145 
3146  /* nband (1) */
3147  if (!PG_ARGISNULL(1)) {
3148  array = PG_GETARG_ARRAYTYPE_P(1);
3149  etype = ARR_ELEMTYPE(array);
3150  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3151 
3152  switch (etype) {
3153  case INT2OID:
3154  case INT4OID:
3155  break;
3156  default:
3157  rtpg_clip_arg_destroy(arg);
3158  PG_FREE_IF_COPY(pgraster, 0);
3159  lwgeom_free(geom);
3160  elog(ERROR, "RASTER_clip: Invalid data type for band indexes");
3161  PG_RETURN_NULL();
3162  break;
3163  }
3164 
3165  deconstruct_array(
3166  array, etype,
3167  typlen, typbyval, typalign,
3168  &e, &nulls, &(arg->numbands)
3169  );
3170 
3171  arg->band = palloc(sizeof(struct rtpg_clip_band_t) * arg->numbands);
3172  if (arg->band == NULL) {
3173  rtpg_clip_arg_destroy(arg);
3174  PG_FREE_IF_COPY(pgraster, 0);
3175  lwgeom_free(geom);
3176  elog(ERROR, "RASTER_clip: Could not allocate memory for band arguments");
3177  PG_RETURN_NULL();
3178  }
3179 
3180  for (i = 0, j = 0; i < arg->numbands; i++) {
3181  if (nulls[i]) continue;
3182 
3183  switch (etype) {
3184  case INT2OID:
3185  arg->band[j].nband = DatumGetInt16(e[i]) - 1;
3186  break;
3187  case INT4OID:
3188  arg->band[j].nband = DatumGetInt32(e[i]) - 1;
3189  break;
3190  }
3191 
3192  j++;
3193  }
3194 
3195  if (j < arg->numbands) {
3196  arg->band = repalloc(arg->band, sizeof(struct rtpg_clip_band_t) * j);
3197  if (arg->band == NULL) {
3198  rtpg_clip_arg_destroy(arg);
3199  PG_FREE_IF_COPY(pgraster, 0);
3200  lwgeom_free(geom);
3201  elog(ERROR, "RASTER_clip: Could not reallocate memory for band arguments");
3202  PG_RETURN_NULL();
3203  }
3204 
3205  arg->numbands = j;
3206  }
3207 
3208  /* validate band */
3209  for (i = 0; i < arg->numbands; i++) {
3210  if (!rt_raster_has_band(arg->raster, arg->band[i].nband)) {
3211  elog(NOTICE, "Band at index %d not found in raster", arg->band[i].nband + 1);
3212  rtpg_clip_arg_destroy(arg);
3213  PG_FREE_IF_COPY(pgraster, 0);
3214  lwgeom_free(geom);
3215  PG_RETURN_NULL();
3216  }
3217 
3218  arg->band[i].hasnodata = 0;
3219  arg->band[i].nodataval = 0;
3220  }
3221  }
3222  else {
3224 
3225  /* raster may have no bands */
3226  if (arg->numbands) {
3227  arg->band = palloc(sizeof(struct rtpg_clip_band_t) * arg->numbands);
3228  if (arg->band == NULL) {
3229 
3230  rtpg_clip_arg_destroy(arg);
3231  PG_FREE_IF_COPY(pgraster, 0);
3232  lwgeom_free(geom);
3233 
3234  elog(ERROR, "RASTER_clip: Could not allocate memory for band arguments");
3235  PG_RETURN_NULL();
3236  }
3237 
3238  for (i = 0; i < arg->numbands; i++) {
3239  arg->band[i].nband = i;
3240  arg->band[i].hasnodata = 0;
3241  arg->band[i].nodataval = 0;
3242  }
3243  }
3244  }
3245 
3246  /* nodataval (3) */
3247  if (!PG_ARGISNULL(3)) {
3248  array = PG_GETARG_ARRAYTYPE_P(3);
3249  etype = ARR_ELEMTYPE(array);
3250  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3251 
3252  switch (etype) {
3253  case FLOAT4OID:
3254  case FLOAT8OID:
3255  break;
3256  default:
3257  rtpg_clip_arg_destroy(arg);
3258  PG_FREE_IF_COPY(pgraster, 0);
3259  lwgeom_free(geom);
3260  elog(ERROR, "RASTER_clip: Invalid data type for NODATA values");
3261  PG_RETURN_NULL();
3262  break;
3263  }
3264 
3265  deconstruct_array(
3266  array, etype,
3267  typlen, typbyval, typalign,
3268  &e, &nulls, &k
3269  );
3270 
3271  /* it doesn't matter if there are more nodataval */
3272  for (i = 0, j = 0; i < arg->numbands; i++, j++) {
3273  /* cap j to the last nodataval element */
3274  if (j >= k)
3275  j = k - 1;
3276 
3277  if (nulls[j])
3278  continue;
3279 
3280  arg->band[i].hasnodata = 1;
3281  switch (etype) {
3282  case FLOAT4OID:
3283  arg->band[i].nodataval = DatumGetFloat4(e[j]);
3284  break;
3285  case FLOAT8OID:
3286  arg->band[i].nodataval = DatumGetFloat8(e[j]);
3287  break;
3288  }
3289  }
3290  }
3291 
3292  /* get wkb of geometry */
3293  POSTGIS_RT_DEBUG(3, "getting wkb of geometry");
3294  wkb = lwgeom_to_wkb_varlena(geom, WKB_SFSQL);
3295  lwgeom_free(geom);
3296 
3297  /* we want to mark all pixels that are inside or touching the geometry - touched (5) */
3298  if (!PG_ARGISNULL(5) && PG_GETARG_BOOL(5) == TRUE){
3299  options_len = options_len + 1;
3300  options = (char **) palloc(sizeof(char *) * options_len);
3301  options[options_len - 1] = palloc(sizeof(char*) * (strlen("ALL_TOUCHED=TRUE") + 1));
3302  strcpy(options[options_len - 1], "ALL_TOUCHED=TRUE");
3303  }
3304 
3305  if (options_len) {
3306  options_len++;
3307  options = (char **) repalloc(options, sizeof(char *) * options_len);
3308  options[options_len - 1] = NULL;
3309  }
3310 
3311  /* rasterize geometry */
3312  arg->mask = rt_raster_gdal_rasterize((unsigned char *)wkb->data,
3313  LWSIZE_GET(wkb->size) - LWVARHDRSZ,
3314  NULL,
3315  0,
3316  NULL,
3317  NULL,
3318  NULL,
3319  NULL,
3320  NULL,
3321  NULL,
3322  NULL,
3323  &(gt[1]),
3324  &(gt[5]),
3325  NULL,
3326  NULL,
3327  &(gt[0]),
3328  &(gt[3]),
3329  &(gt[2]),
3330  &(gt[4]),
3331  options);
3332 
3333  pfree(wkb);
3334 
3335  if (options_len) pfree(options);
3336 
3337  if (arg->mask == NULL) {
3338  rtpg_clip_arg_destroy(arg);
3339  PG_FREE_IF_COPY(pgraster, 0);
3340  elog(ERROR, "RASTER_clip: Could not rasterize intersection geometry");
3341  PG_RETURN_NULL();
3342  }
3343 
3344  /* set SRID */
3345  rt_raster_set_srid(arg->mask, srid);
3346 
3347  mask_width = rt_raster_get_width(arg->mask);
3348  mask_height = rt_raster_get_height(arg->mask);
3349 
3350  if (rt_raster_from_two_rasters(arg->raster, arg->mask, arg->extenttype, &rtn, offset) != ES_NONE) {
3351  rtpg_clip_arg_destroy(arg);
3352  PG_FREE_IF_COPY(pgraster, 0);
3353  elog(ERROR, "RASTER_clip: Could not compute extent of rasters");
3354  PG_RETURN_NULL();
3355  }
3356 
3357  width = rt_raster_get_width(rtn);
3358  height = rt_raster_get_height(rtn);
3359 
3360  mask_band = rt_raster_get_band(arg->mask, 0);
3361 
3362  for (i = 0; i < arg->numbands; i++) {
3363  input_band = rt_raster_get_band(arg->raster, arg->band[i].nband);
3364 
3365  /* band metadata */
3366  pixtype = rt_band_get_pixtype(input_band);
3367 
3368  if (arg->band[i].hasnodata) {
3369  hasnodata = 1;
3370  nodataval = arg->band[i].nodataval;
3371  }
3372  else if (rt_band_get_hasnodata_flag(input_band)) {
3373  hasnodata = 1;
3374  rt_band_get_nodata(input_band, &nodataval);
3375  }
3376  else {
3377  hasnodata = 0;
3378  nodataval = rt_band_get_min_value(input_band);
3379  }
3380 
3381  if (rt_raster_generate_new_band(rtn, pixtype, nodataval, hasnodata, nodataval, i) < 0) {
3382  rtpg_clip_arg_destroy(arg);
3383  PG_FREE_IF_COPY(pgraster, 0);
3384  elog(ERROR, "RASTER_clip: Could not add new band in output raster");
3385  PG_RETURN_NULL();
3386  }
3387 
3388  if (rt_band_get_isnodata_flag(input_band)) {
3389  continue;
3390  }
3391 
3392  output_band = rt_raster_get_band(rtn, arg->band[i].nband);
3393 
3394  if (!mask_band) {
3395  continue;
3396  }
3397 
3398  for (y = 0; y < height; y++) {
3399  for (x = 0; x < width; x++) {
3400  mask_x = x - (int)offset[2];
3401  mask_y = y - (int)offset[3];
3402 
3403  if (!(
3404  mask_x >= 0 &&
3405  mask_x < mask_width &&
3406  mask_y >= 0 &&
3407  mask_y < mask_height
3408  )) {
3409  continue;
3410  }
3411 
3412  if (rt_band_get_pixel(mask_band, mask_x, mask_y, &value, &isnodata) != ES_NONE) {
3413  rtpg_clip_arg_destroy(arg);
3414  PG_FREE_IF_COPY(pgraster, 0);
3415  elog(ERROR, "RASTER_clip: Could not get pixel value");
3416  PG_RETURN_NULL();
3417  }
3418 
3419  if (isnodata) {
3420  continue;
3421  }
3422 
3423  input_x = x - (int)offset[0];
3424  input_y = y - (int)offset[1];
3425 
3426  if (rt_band_get_pixel(input_band, input_x, input_y, &value, &isnodata) != ES_NONE) {
3427  rtpg_clip_arg_destroy(arg);
3428  PG_FREE_IF_COPY(pgraster, 0);
3429  elog(ERROR, "RASTER_clip: Could not get pixel value");
3430  PG_RETURN_NULL();
3431  }
3432 
3433  if (isnodata) {
3434  continue;
3435  }
3436 
3437  if (rt_band_set_pixel(output_band, x, y, value, NULL)) {
3438  rtpg_clip_arg_destroy(arg);
3439  PG_FREE_IF_COPY(pgraster, 0);
3440  elog(ERROR, "RASTER_clip: Could not set pixel value");
3441  PG_RETURN_NULL();
3442  }
3443  }
3444  }
3445  }
3446 
3447  rtpg_clip_arg_destroy(arg);
3448  PG_FREE_IF_COPY(pgraster, 0);
3449 
3450  pgrtn = rt_raster_serialize(rtn);
3451  rt_raster_destroy(rtn);
3452 
3453  POSTGIS_RT_DEBUG(3, "Finished");
3454 
3455  if (!pgrtn)
3456  PG_RETURN_NULL();
3457 
3458  SET_VARSIZE(pgrtn, pgrtn->size);
3459  PG_RETURN_POINTER(pgrtn);
3460 }
#define TRUE
Definition: dbfopen.c:73
#define FALSE
Definition: dbfopen.c:72
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
Definition: gserialized.c:155
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:268
int lwgeom_ndims(const LWGEOM *geom)
Return the number of dimensions (2, 3, 4) in a geometry.
Definition: lwgeom.c:955
#define LWVARHDRSZ
Definition: liblwgeom.h:311
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1218
LWGEOM * lwgeom_intersection(const LWGEOM *geom1, const LWGEOM *geom2)
#define LWSIZE_GET(varsize)
Macro for reading the size from the GSERIALIZED size attribute.
Definition: liblwgeom.h:324
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:215
lwvarlena_t * lwgeom_to_wkb_varlena(const LWGEOM *geom, uint8_t variant)
Definition: lwout_wkb.c:851
#define WKB_SFSQL
Definition: liblwgeom.h:2208
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition: lwutil.c:339
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
Definition: lwgeom.c:793
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_raster.c:360
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:489
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:825
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1527
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:86
rt_pixtype
Definition: librtcore.h:187
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition: rt_band.c:865
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_raster.c:52
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:1253
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
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:2053
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
Definition: rt_band.c:1125
@ ES_NONE
Definition: librtcore.h:182
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:2502
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:376
rt_errorstate rt_raster_get_convex_hull(rt_raster raster, LWGEOM **hull)
Get raster's convex hull.
Definition: rt_geometry.c:838
uint16_t rt_raster_get_height(rt_raster raster)
Definition: rt_raster.c:133
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition: rt_raster.c:367
@ ET_INTERSECTION
Definition: librtcore.h:203
@ ET_FIRST
Definition: librtcore.h:205
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:2038
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:782
uint16_t rt_raster_get_width(rt_raster raster)
Definition: rt_raster.c:125
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:3348
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_raster.c:588
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:725
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_raster.c:1240
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:385
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition: lwinline.h:199
int value
Definition: genraster.py:62
gt
Definition: window.py:78
static rtpg_clip_arg rtpg_clip_arg_init(void)
static void rtpg_clip_arg_destroy(rtpg_clip_arg arg)
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:65
uint32_t size
Definition: liblwgeom.h:307
char data[]
Definition: liblwgeom.h:308
Struct definitions.
Definition: librtcore.h:2440
rtpg_clip_band band
rt_extenttype extenttype

References rtpg_clip_arg_t::band, clamp_srid(), lwvarlena_t::data, 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_varlena(), LWSIZE_GET, LWVARHDRSZ, rtpg_clip_arg_t::mask, rtpg_clip_band_t::nband, rtpg_clip_band_t::nodataval, rtpg_clip_arg_t::numbands, POSTGIS_RT_DEBUG, 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_pixel(), rt_band_get_pixtype(), rt_band_set_pixel(), 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_height(), rt_raster_get_num_bands(), rt_raster_get_srid(), rt_raster_get_width(), rt_raster_has_band(), rt_raster_is_empty(), rt_raster_new(), rt_raster_serialize(), rt_raster_set_srid(), rtpg_clip_arg_destroy(), rtpg_clip_arg_init(), lwvarlena_t::size, rt_raster_serialized_t::size, SRID_UNKNOWN, TRUE, genraster::value, WKB_SFSQL, pixval::x, and pixval::y.

Here is the call graph for this function: