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

◆ RASTER_union_finalfn()

Datum RASTER_union_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 2799 of file rtpg_mapalgebra.c.

2800{
2801 rtpg_union_arg iwr;
2802 rt_raster _rtn = NULL;
2803 rt_raster _raster = NULL;
2804 rt_pgraster *pgraster = NULL;
2805
2806 int i = 0;
2807 int j = 0;
2808 rt_iterator itrset = NULL;
2809 rt_band _band = NULL;
2810 int noerr = 1;
2811 int status = 0;
2812 rt_pixtype pixtype = PT_END;
2813 int hasnodata = 0;
2814 double nodataval = 0;
2815
2816 POSTGIS_RT_DEBUG(3, "Starting...");
2817
2818 /* cannot be called directly as this is exclusive aggregate function */
2819 if (!AggCheckCallContext(fcinfo, NULL)) {
2820 elog(ERROR, "RASTER_union_finalfn: Cannot be called in a non-aggregate context");
2821 PG_RETURN_NULL();
2822 }
2823
2824 /* NULL, return null */
2825 if (PG_ARGISNULL(0))
2826 PG_RETURN_NULL();
2827
2828 iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
2829
2830 /* init itrset */
2831 itrset = palloc(sizeof(struct rt_iterator_t) * 2);
2832 if (itrset == NULL) {
2834 elog(ERROR, "RASTER_union_finalfn: Could not allocate memory for iterator arguments");
2835 PG_RETURN_NULL();
2836 }
2837
2838 for (i = 0; i < iwr->numband; i++) {
2839 if (
2840 iwr->bandarg[i].uniontype == UT_MEAN ||
2841 iwr->bandarg[i].uniontype == UT_RANGE
2842 ) {
2843 /* raster containing the SUM or MAX is at index 1 */
2844 _band = rt_raster_get_band(iwr->bandarg[i].raster[1], 0);
2845
2846 pixtype = rt_band_get_pixtype(_band);
2847 hasnodata = rt_band_get_hasnodata_flag(_band);
2848 if (hasnodata)
2849 rt_band_get_nodata(_band, &nodataval);
2850 POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
2851
2852 itrset[0].raster = iwr->bandarg[i].raster[0];
2853 itrset[0].nband = 0;
2854 itrset[1].raster = iwr->bandarg[i].raster[1];
2855 itrset[1].nband = 0;
2856
2857 /* pass everything to iterator */
2858 if (iwr->bandarg[i].uniontype == UT_MEAN) {
2859 noerr = rt_raster_iterator(
2860 itrset, 2,
2861 ET_UNION, NULL,
2862 pixtype,
2863 hasnodata, nodataval,
2864 0, 0,
2865 NULL,
2866 NULL,
2868 &_raster
2869 );
2870 }
2871 else if (iwr->bandarg[i].uniontype == UT_RANGE) {
2872 noerr = rt_raster_iterator(
2873 itrset, 2,
2874 ET_UNION, NULL,
2875 pixtype,
2876 hasnodata, nodataval,
2877 0, 0,
2878 NULL,
2879 NULL,
2881 &_raster
2882 );
2883 }
2884
2885 if (noerr != ES_NONE) {
2886 pfree(itrset);
2888 if (_rtn != NULL)
2889 rt_raster_destroy(_rtn);
2890 elog(ERROR, "RASTER_union_finalfn: Could not run raster iterator function");
2891 PG_RETURN_NULL();
2892 }
2893 }
2894 else {
2895 _raster = iwr->bandarg[i].raster[0];
2896 if (_raster == NULL)
2897 continue;
2898 }
2899
2900 /* first band, _rtn doesn't exist */
2901 if (i < 1) {
2902 uint32_t bandNums[1] = {0};
2903 _rtn = rt_raster_from_band(_raster, bandNums, 1);
2904 status = (_rtn == NULL) ? -1 : 0;
2905 }
2906 else
2907 status = rt_raster_copy_band(_rtn, _raster, 0, i);
2908
2909 POSTGIS_RT_DEBUG(4, "destroying source rasters");
2910
2911 /* destroy source rasters */
2912 if (
2913 iwr->bandarg[i].uniontype == UT_MEAN ||
2914 iwr->bandarg[i].uniontype == UT_RANGE
2915 ) {
2916 rt_raster_destroy(_raster);
2917 }
2918
2919 for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2920 if (iwr->bandarg[i].raster[j] == NULL)
2921 continue;
2922 rt_raster_destroy(iwr->bandarg[i].raster[j]);
2923 iwr->bandarg[i].raster[j] = NULL;
2924 }
2925
2926 if (status < 0) {
2928 rt_raster_destroy(_rtn);
2929 elog(ERROR, "RASTER_union_finalfn: Could not add band to final raster");
2930 PG_RETURN_NULL();
2931 }
2932 }
2933
2934 /* cleanup */
2935 /* For Windowing functions, it is important to leave */
2936 /* the state intact, knowing that the aggcontext will be */
2937 /* freed by PgSQL when the statement is complete. */
2938 /* https://trac.osgeo.org/postgis/ticket/4770 */
2939 // pfree(itrset);
2940 // rtpg_union_arg_destroy(iwr);
2941
2942 if (!_rtn) PG_RETURN_NULL();
2943
2944 pgraster = rt_raster_serialize(_rtn);
2945 rt_raster_destroy(_rtn);
2946
2947 POSTGIS_RT_DEBUG(3, "Finished");
2948
2949 if (!pgraster)
2950 PG_RETURN_NULL();
2951
2952 SET_VARSIZE(pgraster, pgraster->size);
2953 PG_RETURN_POINTER(pgraster);
2954}
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition rt_band.c:674
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition rt_raster.c:82
rt_pixtype
Definition librtcore.h:185
@ PT_END
Definition librtcore.h:197
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition rt_pixel.c:110
@ ES_NONE
Definition librtcore.h:180
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.
@ ET_UNION
Definition librtcore.h:202
rt_raster rt_raster_from_band(rt_raster raster, uint32_t *bandNums, int count)
Construct a new rt_raster from an existing rt_raster and an array of band numbers.
Definition rt_raster.c:1430
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition rt_band.c:1730
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition rt_band.c:631
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
int rt_raster_copy_band(rt_raster torast, rt_raster fromrast, int fromindex, int toindex)
Copy one band from one raster to another.
Definition rt_raster.c:1365
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition rt_raster.c:381
static int rtpg_union_mean_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
static int rtpg_union_range_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
static void rtpg_union_arg_destroy(rtpg_union_arg arg)
struct rtpg_union_arg_t * rtpg_union_arg
@ UT_MEAN
@ UT_RANGE
#define POSTGIS_RT_DEBUG(level, msg)
Definition rtpostgis.h:61
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition rtpostgis.h:65
rt_raster raster
Definition librtcore.h:2444
uint16_t nband
Definition librtcore.h:2445
Struct definitions.
Definition librtcore.h:2251
rtpg_union_band_arg bandarg
rtpg_union_type uniontype

References rtpg_union_arg_t::bandarg, ES_NONE, ET_UNION, rt_iterator_t::nband, rtpg_union_arg_t::numband, rtpg_union_band_arg_t::numraster, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, PT_END, rt_iterator_t::raster, rtpg_union_band_arg_t::raster, rt_band_get_hasnodata_flag(), rt_band_get_nodata(), rt_band_get_pixtype(), rt_pixtype_name(), rt_raster_copy_band(), rt_raster_destroy(), rt_raster_from_band(), rt_raster_get_band(), rt_raster_iterator(), rt_raster_serialize(), rtpg_union_arg_destroy(), rtpg_union_mean_callback(), rtpg_union_range_callback(), rt_raster_serialized_t::size, rtpg_union_band_arg_t::uniontype, UT_MEAN, and UT_RANGE.

Here is the call graph for this function: