PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ RASTER_reclass_exact()

Datum RASTER_reclass_exact ( PG_FUNCTION_ARGS  )

Definition at line 4013 of file rtpg_mapalgebra.c.

4013  {
4014  rt_pgraster *pgraster = NULL;
4015  rt_pgraster *pgrtn = NULL;
4016  rt_raster raster = NULL;
4017  rt_band band = NULL;
4018  rt_band newband = NULL;
4019  uint32_t bandnum = 0, numbands = 0;
4020  ArrayType *arraysrc, *arraydst;
4021  bool hasnodata = false;
4022  double nodataval = 0.0;
4023  text *pixeltype = NULL;
4024  uint32_t szsrc, szdst;
4025  ArrayIterator itersrc, iterdst;
4026  Datum dsrc, ddst;
4027  bool nullsrc, nulldst;
4028  rt_reclassmap reclassmap;
4029  rt_pixtype pixtypsrc, pixtypdst;
4030 
4031  /* Check null on all arguments since function is not strict */
4032  if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3) || PG_ARGISNULL(4))
4033  PG_RETURN_NULL();
4034 
4035  /* Read SQL arguments */
4036  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
4037  arraysrc = PG_GETARG_ARRAYTYPE_P(1);
4038  arraydst = PG_GETARG_ARRAYTYPE_P(2);
4039  bandnum = PG_GETARG_INT32(3); /* One-based band number */
4040  pixeltype = PG_GETARG_TEXT_P(4);
4041  if (!PG_ARGISNULL(5)) {
4042  hasnodata = true;
4043  nodataval = PG_GETARG_FLOAT8(5);
4044  }
4045 
4046  /* Check arrays have same size */
4047  szsrc = ArrayGetNItems(ARR_NDIM(arraysrc), ARR_DIMS(arraysrc));
4048  szdst = ArrayGetNItems(ARR_NDIM(arraydst), ARR_DIMS(arraydst));
4049  if (szsrc != szdst)
4050  elog(ERROR, "array lengths must be the same");
4051 
4052  /* Read the raster */
4053  raster = rt_raster_deserialize(pgraster, FALSE);
4054  if (!raster) {
4055  PG_FREE_IF_COPY(pgraster, 0);
4056  elog(ERROR, "%s: Could not deserialize raster", __func__);
4057  }
4058 
4059  /* Check that this raster has bands we can work with */
4060  numbands = rt_raster_get_num_bands(raster);
4061  if (numbands < 1)
4062  elog(ERROR, "Raster has no bands");
4063  if (bandnum < 1 || bandnum > numbands)
4064  elog(ERROR, "Invalid band index %d, input raster has %d bands. Band indexes are one-based.",
4065  bandnum, numbands);
4066 
4067  /* Read the band */
4068  band = rt_raster_get_band(raster, bandnum-1);
4069  if (!band)
4070  elog(ERROR, "Could not find raster band of index %d", bandnum);
4071 
4072  /* Get array element types */
4073  pixtypsrc = rt_band_get_pixtype(band);
4074  pixtypdst = rt_pixtype_index_from_name(text_to_cstring(pixeltype));
4075 
4076  if (pixtypdst == PT_END)
4077  elog(ERROR, "Unknown output pixel type '%s'", text_to_cstring(pixeltype));
4078 
4079  /* Error out on unreadable pixeltype */
4080  if (pixtypsrc == PT_END)
4081  elog(ERROR, "Unsupported pixtype");
4082 
4083  /* Create the rt_reclassmap */
4084  reclassmap = palloc(sizeof(struct rt_reclassmap_t));
4085  reclassmap->count = 0;
4086  reclassmap->srctype = pixtypsrc;
4087  reclassmap->dsttype = pixtypdst;
4088  reclassmap->pairs = palloc(sizeof(struct rt_classpair_t) * szdst);
4089 
4090  if (!hasnodata)
4091  nodataval = rt_pixtype_get_min_value(pixtypdst);
4092 
4093  /* Build up rt_reclassmap.pairs from arrays */
4094  itersrc = array_create_iterator(arraysrc, 0, NULL);
4095  iterdst = array_create_iterator(arraydst, 0, NULL);
4096  while(array_iterate(itersrc, &dsrc, &nullsrc) &&
4097  array_iterate(iterdst, &ddst, &nulldst))
4098  {
4099  double valsrc = nullsrc ? nodataval : (double)DatumGetFloat8(dsrc);
4100  double valdst = nulldst ? nodataval : (double)DatumGetFloat8(ddst);
4101  Assert(szdst > reclassmap->count);
4102  reclassmap->pairs[reclassmap->count].src = valsrc;
4103  reclassmap->pairs[reclassmap->count].dst = valdst;
4104  reclassmap->count++;
4105  }
4106  array_free_iterator(itersrc);
4107  array_free_iterator(iterdst);
4108 
4109  /* Carry out reclassification */
4110  newband = rt_band_reclass_exact(band, reclassmap, hasnodata, nodataval);
4111  /* Clean up finished map */
4112  pfree(reclassmap->pairs);
4113  pfree(reclassmap);
4114  if (!newband)
4115  elog(ERROR, "Band reclassification failed");
4116 
4117  /* replace old band with new band */
4118  if (rt_raster_replace_band(raster, newband, bandnum-1) == NULL) {
4119  rt_band_destroy(newband);
4121  PG_FREE_IF_COPY(pgraster, 0);
4122  elog(ERROR, "Could not replace raster band of index %d with reclassified band", bandnum);
4123  }
4124 
4125  pgrtn = rt_raster_serialize(raster);
4127  PG_FREE_IF_COPY(pgraster, 0);
4128  if (!pgrtn)
4129  PG_RETURN_NULL();
4130 
4131  SET_VARSIZE(pgrtn, pgrtn->size);
4132  PG_RETURN_POINTER(pgrtn);
4133 }
#define FALSE
Definition: dbfopen.c:72
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
Definition: rt_pixel.c:80
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:86
rt_pixtype
Definition: librtcore.h:187
@ PT_END
Definition: librtcore.h:199
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition: rt_pixel.c:150
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
rt_band rt_raster_replace_band(rt_raster raster, rt_band band, int index)
Replace band at provided index with new band.
Definition: rt_raster.c:1404
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_band.c:491
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:376
rt_band rt_band_reclass_exact(rt_band srcband, rt_reclassmap map, uint32_t hasnodata, double nodataval)
Returns new band with values reclassified.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:782
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:725
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:385
band
Definition: ovdump.py:58
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
Struct definitions.
Definition: librtcore.h:2440
uint32_t count
Definition: librtcore.h:2639
rt_pixtype dsttype
Definition: librtcore.h:2641
struct rt_classpair_t * pairs
Definition: librtcore.h:2642
rt_pixtype srctype
Definition: librtcore.h:2640

References ovdump::band, rt_reclassmap_t::count, rt_classpair_t::dst, rt_reclassmap_t::dsttype, FALSE, rt_reclassmap_t::pairs, PT_END, rtrowdump::raster, rt_band_destroy(), rt_band_get_pixtype(), rt_band_reclass_exact(), rt_pixtype_get_min_value(), rt_pixtype_index_from_name(), rt_raster_deserialize(), rt_raster_destroy(), rt_raster_get_band(), rt_raster_get_num_bands(), rt_raster_replace_band(), rt_raster_serialize(), rt_raster_serialized_t::size, rt_classpair_t::src, and rt_reclassmap_t::srctype.

Here is the call graph for this function: