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

◆ RASTER_union_finalfn()

Datum RASTER_union_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 2764 of file rtpg_mapalgebra.c.

2765{
2766 rtpg_union_arg iwr;
2767 rt_raster _rtn = NULL;
2768 rt_raster _raster = NULL;
2769 rt_pgraster *pgraster = NULL;
2770
2771 int i = 0;
2772 int j = 0;
2773 rt_iterator itrset = NULL;
2774 rt_band _band = NULL;
2775 int noerr = 1;
2776 int status = 0;
2777 rt_pixtype pixtype = PT_END;
2778 int hasnodata = 0;
2779 double nodataval = 0;
2780
2781 POSTGIS_RT_DEBUG(3, "Starting...");
2782
2783 /* cannot be called directly as this is exclusive aggregate function */
2784 if (!AggCheckCallContext(fcinfo, NULL)) {
2785 elog(ERROR, "RASTER_union_finalfn: Cannot be called in a non-aggregate context");
2786 PG_RETURN_NULL();
2787 }
2788
2789 /* NULL, return null */
2790 if (PG_ARGISNULL(0))
2791 PG_RETURN_NULL();
2792
2793 iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
2794
2795 /* init itrset */
2796 itrset = palloc(sizeof(struct rt_iterator_t) * 2);
2797 if (itrset == NULL) {
2799 elog(ERROR, "RASTER_union_finalfn: Could not allocate memory for iterator arguments");
2800 PG_RETURN_NULL();
2801 }
2802
2803 for (i = 0; i < iwr->numband; i++) {
2804 if (
2805 iwr->bandarg[i].uniontype == UT_MEAN ||
2806 iwr->bandarg[i].uniontype == UT_RANGE
2807 ) {
2808 /* raster containing the SUM or MAX is at index 1 */
2809 _band = rt_raster_get_band(iwr->bandarg[i].raster[1], 0);
2810
2811 pixtype = rt_band_get_pixtype(_band);
2812 hasnodata = rt_band_get_hasnodata_flag(_band);
2813 if (hasnodata)
2814 rt_band_get_nodata(_band, &nodataval);
2815 POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
2816
2817 itrset[0].raster = iwr->bandarg[i].raster[0];
2818 itrset[0].nband = 0;
2819 itrset[1].raster = iwr->bandarg[i].raster[1];
2820 itrset[1].nband = 0;
2821
2822 /* pass everything to iterator */
2823 if (iwr->bandarg[i].uniontype == UT_MEAN) {
2824 noerr = rt_raster_iterator(
2825 itrset, 2,
2826 ET_UNION, NULL,
2827 pixtype,
2828 hasnodata, nodataval,
2829 0, 0,
2830 NULL,
2831 NULL,
2833 &_raster
2834 );
2835 }
2836 else if (iwr->bandarg[i].uniontype == UT_RANGE) {
2837 noerr = rt_raster_iterator(
2838 itrset, 2,
2839 ET_UNION, NULL,
2840 pixtype,
2841 hasnodata, nodataval,
2842 0, 0,
2843 NULL,
2844 NULL,
2846 &_raster
2847 );
2848 }
2849
2850 if (noerr != ES_NONE) {
2851 pfree(itrset);
2853 if (_rtn != NULL)
2854 rt_raster_destroy(_rtn);
2855 elog(ERROR, "RASTER_union_finalfn: Could not run raster iterator function");
2856 PG_RETURN_NULL();
2857 }
2858 }
2859 else {
2860 _raster = iwr->bandarg[i].raster[0];
2861 if (_raster == NULL)
2862 continue;
2863 }
2864
2865 /* first band, _rtn doesn't exist */
2866 if (i < 1) {
2867 uint32_t bandNums[1] = {0};
2868 _rtn = rt_raster_from_band(_raster, bandNums, 1);
2869 status = (_rtn == NULL) ? -1 : 0;
2870 }
2871 else
2872 status = rt_raster_copy_band(_rtn, _raster, 0, i);
2873
2874 POSTGIS_RT_DEBUG(4, "destroying source rasters");
2875
2876 /* destroy source rasters */
2877 if (
2878 iwr->bandarg[i].uniontype == UT_MEAN ||
2879 iwr->bandarg[i].uniontype == UT_RANGE
2880 ) {
2881 rt_raster_destroy(_raster);
2882 }
2883
2884 for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2885 if (iwr->bandarg[i].raster[j] == NULL)
2886 continue;
2887 rt_raster_destroy(iwr->bandarg[i].raster[j]);
2888 iwr->bandarg[i].raster[j] = NULL;
2889 }
2890
2891 if (status < 0) {
2893 rt_raster_destroy(_rtn);
2894 elog(ERROR, "RASTER_union_finalfn: Could not add band to final raster");
2895 PG_RETURN_NULL();
2896 }
2897 }
2898
2899 /* cleanup */
2900 /* For Windowing functions, it is important to leave */
2901 /* the state intact, knowing that the aggcontext will be */
2902 /* freed by PgSQL when the statement is complete. */
2903 /* https://trac.osgeo.org/postgis/ticket/4770 */
2904 // pfree(itrset);
2905 // rtpg_union_arg_destroy(iwr);
2906
2907 if (!_rtn) PG_RETURN_NULL();
2908
2909 pgraster = rt_raster_serialize(_rtn);
2910 rt_raster_destroy(_rtn);
2911
2912 POSTGIS_RT_DEBUG(3, "Finished");
2913
2914 if (!pgraster)
2915 PG_RETURN_NULL();
2916
2917 SET_VARSIZE(pgraster, pgraster->size);
2918 PG_RETURN_POINTER(pgraster);
2919}
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition rt_band.c:833
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
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition rt_pixel.c:114
@ ES_NONE
Definition librtcore.h:182
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:206
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:1341
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition rt_band.c:2067
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.
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:1276
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 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:65
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition rtpostgis.h:69
rt_raster raster
Definition librtcore.h:2659
uint16_t nband
Definition librtcore.h:2660
Struct definitions.
Definition librtcore.h:2452
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: