PostGIS  3.0.0dev-r@@SVN_REVISION@@

◆ RASTER_clip()

Datum RASTER_clip ( PG_FUNCTION_ARGS  )

Definition at line 2959 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, PG_FUNCTION_INFO_V1(), POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, rt_iterator_t::raster, rtpg_clip_arg_t::raster, RASTER_reclass(), 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, rt_raster_serialized_t::srid, SRID_UNKNOWN, and WKB_SFSQL.

Referenced by rtpg_clip_callback().

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