PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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);
4120 rt_raster_destroy(raster);
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);
4126 rt_raster_destroy(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:82
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition rt_raster.c:86
rt_pixtype
Definition librtcore.h:188
@ PT_END
Definition librtcore.h:201
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition rt_pixel.c:156
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:499
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:790
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition rt_raster.c:385
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition rtrowdump.py:125
Struct definitions.
Definition librtcore.h:2452
rt_pixtype dsttype
Definition librtcore.h:2653
struct rt_classpair_t * pairs
Definition librtcore.h:2654
rt_pixtype srctype
Definition librtcore.h:2652

References rt_reclassmap_t::count, rt_classpair_t::dst, rt_reclassmap_t::dsttype, FALSE, rt_reclassmap_t::pairs, PT_END, 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: