PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ RASTER_union_transfn()

Datum RASTER_union_transfn ( PG_FUNCTION_ARGS  )

Definition at line 2110 of file rtpg_mapalgebra.c.

References rtpg_union_arg_t::bandarg, ES_NONE, ET_LAST, ET_UNION, FALSE, window::gt, pixval::nband, rtpg_union_band_arg_t::nband, rt_iterator_t::nband, rt_iterator_t::nbnodata, rtpg_union_arg_t::numband, rtpg_union_band_arg_t::numraster, PG_FUNCTION_INFO_V1(), POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, PT_32BUI, PT_64BF, PT_END, rtrowdump::raster, rtpg_union_band_arg_t::raster, rt_iterator_t::raster, RASTER_union_finalfn(), rt_band_destroy(), rt_band_get_hasnodata_flag(), rt_band_get_min_value(), rt_band_get_nodata(), rt_band_get_pixel_line(), rt_band_get_pixtype(), rt_band_set_pixel_line(), rt_pixtype_get_min_value(), rt_pixtype_name(), rt_raster_clone(), rt_raster_deserialize(), rt_raster_destroy(), rt_raster_from_two_rasters(), rt_raster_generate_new_band(), rt_raster_get_band(), rt_raster_get_geotransform_matrix(), rt_raster_get_height(), rt_raster_get_num_bands(), rt_raster_get_width(), rt_raster_has_band(), rt_raster_is_empty(), rt_raster_iterator(), rt_util_same_geotransform_matrix(), rtpg_strtoupper(), rtpg_union_arg_destroy(), rtpg_union_callback(), rtpg_union_noarg(), rtpg_union_unionarg_process(), rtpg_uniontype_index_from_name(), rtpg_union_band_arg_t::uniontype, UT_COUNT, UT_LAST, UT_MAX, UT_MEAN, UT_MIN, UT_RANGE, and UT_SUM.

Referenced by rtpg_union_noarg().

2111 {
2112  MemoryContext aggcontext;
2113  MemoryContext oldcontext;
2114  rtpg_union_arg iwr = NULL;
2115  int skiparg = 0;
2116 
2117  rt_pgraster *pgraster = NULL;
2118  rt_raster raster = NULL;
2119  rt_raster _raster = NULL;
2120  rt_band _band = NULL;
2121  int nband = 1;
2122  int noerr = 1;
2123  int isempty[2] = {0};
2124  int hasband[2] = {0};
2125  int nargs = 0;
2126  double _offset[4] = {0.};
2127  int nbnodata = 0; /* 1 if adding bands */
2128 
2129  int i = 0;
2130  int j = 0;
2131  int k = 0;
2132 
2133  rt_iterator itrset;
2134  char *utypename = NULL;
2135  rtpg_union_type utype = UT_LAST;
2136  rt_pixtype pixtype = PT_END;
2137  int hasnodata = 1;
2138  double nodataval = 0;
2139 
2140  rt_raster iraster = NULL;
2141  rt_band iband = NULL;
2142  int reuserast = 0;
2143  int y = 0;
2144  uint16_t _dim[2] = {0};
2145  void *vals = NULL;
2146  uint16_t nvals = 0;
2147 
2148  POSTGIS_RT_DEBUG(3, "Starting...");
2149 
2150  /* cannot be called directly as this is exclusive aggregate function */
2151  if (!AggCheckCallContext(fcinfo, &aggcontext)) {
2152  elog(ERROR, "RASTER_union_transfn: Cannot be called in a non-aggregate context");
2153  PG_RETURN_NULL();
2154  }
2155 
2156  /* switch to aggcontext */
2157  oldcontext = MemoryContextSwitchTo(aggcontext);
2158 
2159  if (PG_ARGISNULL(0)) {
2160  POSTGIS_RT_DEBUG(3, "Creating state variable");
2161  /* allocate container in aggcontext */
2162  iwr = palloc(sizeof(struct rtpg_union_arg_t));
2163  if (iwr == NULL) {
2164  MemoryContextSwitchTo(oldcontext);
2165  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for state variable");
2166  PG_RETURN_NULL();
2167  }
2168 
2169  iwr->numband = 0;
2170  iwr->bandarg = NULL;
2171 
2172  skiparg = 0;
2173  }
2174  else {
2175  POSTGIS_RT_DEBUG(3, "State variable already exists");
2176  iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
2177  skiparg = 1;
2178  }
2179 
2180  /* raster arg is NOT NULL */
2181  if (!PG_ARGISNULL(1)) {
2182  /* deserialize raster */
2183  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
2184 
2185  /* Get raster object */
2186  raster = rt_raster_deserialize(pgraster, FALSE);
2187  if (raster == NULL) {
2188 
2190  PG_FREE_IF_COPY(pgraster, 1);
2191 
2192  MemoryContextSwitchTo(oldcontext);
2193  elog(ERROR, "RASTER_union_transfn: Could not deserialize raster");
2194  PG_RETURN_NULL();
2195  }
2196  }
2197 
2198  /* process additional args if needed */
2199  nargs = PG_NARGS();
2200  POSTGIS_RT_DEBUGF(4, "nargs = %d", nargs);
2201  if (nargs > 2) {
2202  POSTGIS_RT_DEBUG(4, "processing additional arguments");
2203 
2204  /* if more than 2 arguments, determine the type of argument 3 */
2205  /* band number, UNION type or unionarg */
2206  if (!PG_ARGISNULL(2)) {
2207  Oid calltype = get_fn_expr_argtype(fcinfo->flinfo, 2);
2208 
2209  switch (calltype) {
2210  /* UNION type */
2211  case TEXTOID: {
2212  int idx = 0;
2213  int numband = 0;
2214 
2215  POSTGIS_RT_DEBUG(4, "Processing arg 3 as UNION type");
2216  nbnodata = 1;
2217 
2218  utypename = text_to_cstring(PG_GETARG_TEXT_P(2));
2219  utype = rtpg_uniontype_index_from_name(rtpg_strtoupper(utypename));
2220  POSTGIS_RT_DEBUGF(4, "Union type: %s", utypename);
2221 
2222  POSTGIS_RT_DEBUGF(4, "iwr->numband: %d", iwr->numband);
2223  /* see if we need to append new bands */
2224  if (raster) {
2225  idx = iwr->numband;
2226  numband = rt_raster_get_num_bands(raster);
2227  POSTGIS_RT_DEBUGF(4, "numband: %d", numband);
2228 
2229  /* only worry about appended bands */
2230  if (numband > iwr->numband)
2231  iwr->numband = numband;
2232  }
2233 
2234  if (!iwr->numband)
2235  iwr->numband = 1;
2236  POSTGIS_RT_DEBUGF(4, "iwr->numband: %d", iwr->numband);
2237  POSTGIS_RT_DEBUGF(4, "numband, idx: %d, %d", numband, idx);
2238 
2239  /* bandarg set. only possible after the first call to function */
2240  if (iwr->bandarg) {
2241  /* only reallocate if new bands need to be added */
2242  if (numband > idx) {
2243  POSTGIS_RT_DEBUG(4, "Reallocating iwr->bandarg");
2244  iwr->bandarg = repalloc(iwr->bandarg, sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
2245  }
2246  /* prevent initial values step happening below */
2247  else
2248  idx = iwr->numband;
2249  }
2250  /* bandarg not set, first call to function */
2251  else {
2252  POSTGIS_RT_DEBUG(4, "Allocating iwr->bandarg");
2253  iwr->bandarg = palloc(sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
2254  }
2255  if (iwr->bandarg == NULL) {
2256 
2258  if (raster != NULL) {
2259  rt_raster_destroy(raster);
2260  PG_FREE_IF_COPY(pgraster, 1);
2261  }
2262 
2263  MemoryContextSwitchTo(oldcontext);
2264  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for band information");
2265  PG_RETURN_NULL();
2266  }
2267 
2268  /* set initial values for bands that are "new" */
2269  for (i = idx; i < iwr->numband; i++) {
2270  iwr->bandarg[i].uniontype = utype;
2271  iwr->bandarg[i].nband = i;
2272 
2273  if (
2274  utype == UT_MEAN ||
2275  utype == UT_RANGE
2276  ) {
2277  iwr->bandarg[i].numraster = 2;
2278  }
2279  else
2280  iwr->bandarg[i].numraster = 1;
2281  iwr->bandarg[i].raster = NULL;
2282  }
2283 
2284  break;
2285  }
2286  /* band number */
2287  case INT2OID:
2288  case INT4OID:
2289  if (skiparg)
2290  break;
2291 
2292  POSTGIS_RT_DEBUG(4, "Processing arg 3 as band number");
2293  nband = PG_GETARG_INT32(2);
2294  if (nband < 1) {
2295 
2297  if (raster != NULL) {
2298  rt_raster_destroy(raster);
2299  PG_FREE_IF_COPY(pgraster, 1);
2300  }
2301 
2302  MemoryContextSwitchTo(oldcontext);
2303  elog(ERROR, "RASTER_union_transfn: Band number must be greater than zero (1-based)");
2304  PG_RETURN_NULL();
2305  }
2306 
2307  iwr->numband = 1;
2308  iwr->bandarg = palloc(sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
2309  if (iwr->bandarg == NULL) {
2310 
2312  if (raster != NULL) {
2313  rt_raster_destroy(raster);
2314  PG_FREE_IF_COPY(pgraster, 1);
2315  }
2316 
2317  MemoryContextSwitchTo(oldcontext);
2318  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for band information");
2319  PG_RETURN_NULL();
2320  }
2321 
2322  iwr->bandarg[0].uniontype = UT_LAST;
2323  iwr->bandarg[0].nband = nband - 1;
2324 
2325  iwr->bandarg[0].numraster = 1;
2326  iwr->bandarg[0].raster = NULL;
2327  break;
2328  /* only other type allowed is unionarg */
2329  default:
2330  if (skiparg)
2331  break;
2332 
2333  POSTGIS_RT_DEBUG(4, "Processing arg 3 as unionarg");
2334  if (!rtpg_union_unionarg_process(iwr, PG_GETARG_ARRAYTYPE_P(2))) {
2335 
2337  if (raster != NULL) {
2338  rt_raster_destroy(raster);
2339  PG_FREE_IF_COPY(pgraster, 1);
2340  }
2341 
2342  MemoryContextSwitchTo(oldcontext);
2343  elog(ERROR, "RASTER_union_transfn: Could not process unionarg");
2344  PG_RETURN_NULL();
2345  }
2346 
2347  break;
2348  }
2349  }
2350 
2351  /* UNION type */
2352  if (nargs > 3 && !PG_ARGISNULL(3)) {
2353  utypename = text_to_cstring(PG_GETARG_TEXT_P(3));
2354  utype = rtpg_uniontype_index_from_name(rtpg_strtoupper(utypename));
2355  iwr->bandarg[0].uniontype = utype;
2356  POSTGIS_RT_DEBUGF(4, "Union type: %s", utypename);
2357 
2358  if (
2359  utype == UT_MEAN ||
2360  utype == UT_RANGE
2361  ) {
2362  iwr->bandarg[0].numraster = 2;
2363  }
2364  }
2365 
2366  /* allocate space for pointers to rt_raster */
2367  for (i = 0; i < iwr->numband; i++) {
2368  POSTGIS_RT_DEBUGF(4, "iwr->bandarg[%d].raster @ %p", i, iwr->bandarg[i].raster);
2369 
2370  /* no need to allocate */
2371  if (iwr->bandarg[i].raster != NULL)
2372  continue;
2373 
2374  POSTGIS_RT_DEBUGF(4, "Allocating space for working rasters of band %d", i);
2375 
2376  iwr->bandarg[i].raster = (rt_raster *) palloc(sizeof(rt_raster) * iwr->bandarg[i].numraster);
2377  if (iwr->bandarg[i].raster == NULL) {
2378 
2380  if (raster != NULL) {
2381  rt_raster_destroy(raster);
2382  PG_FREE_IF_COPY(pgraster, 1);
2383  }
2384 
2385  MemoryContextSwitchTo(oldcontext);
2386  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for working raster(s)");
2387  PG_RETURN_NULL();
2388  }
2389 
2390  memset(iwr->bandarg[i].raster, 0, sizeof(rt_raster) * iwr->bandarg[i].numraster);
2391 
2392  /* add new working rt_raster but only if working raster already exists */
2393  if (i > 0 && !rt_raster_is_empty(iwr->bandarg[0].raster[0])) {
2394  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2395  iwr->bandarg[i].raster[j] = rt_raster_clone(iwr->bandarg[0].raster[0], 0); /* shallow clone */
2396  if (iwr->bandarg[i].raster[j] == NULL) {
2397 
2399  if (raster != NULL) {
2400  rt_raster_destroy(raster);
2401  PG_FREE_IF_COPY(pgraster, 1);
2402  }
2403 
2404  MemoryContextSwitchTo(oldcontext);
2405  elog(ERROR, "RASTER_union_transfn: Could not create working raster");
2406  PG_RETURN_NULL();
2407  }
2408  }
2409  }
2410  }
2411  }
2412  /* only raster, no additional args */
2413  /* only do this if raster isn't empty */
2414  else {
2415  POSTGIS_RT_DEBUG(4, "no additional args, checking input raster");
2416  nbnodata = 1;
2417  if (!rtpg_union_noarg(iwr, raster)) {
2418 
2420  if (raster != NULL) {
2421  rt_raster_destroy(raster);
2422  PG_FREE_IF_COPY(pgraster, 1);
2423  }
2424 
2425  MemoryContextSwitchTo(oldcontext);
2426  elog(ERROR, "RASTER_union_transfn: Could not check and balance number of bands");
2427  PG_RETURN_NULL();
2428  }
2429  }
2430 
2431  /* init itrset */
2432  itrset = palloc(sizeof(struct rt_iterator_t) * 2);
2433  if (itrset == NULL) {
2434 
2436  if (raster != NULL) {
2437  rt_raster_destroy(raster);
2438  PG_FREE_IF_COPY(pgraster, 1);
2439  }
2440 
2441  MemoryContextSwitchTo(oldcontext);
2442  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for iterator arguments");
2443  PG_RETURN_NULL();
2444  }
2445 
2446  /* by band to UNION */
2447  for (i = 0; i < iwr->numband; i++) {
2448 
2449  /* by raster */
2450  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2451  reuserast = 0;
2452 
2453  /* type of union */
2454  utype = iwr->bandarg[i].uniontype;
2455 
2456  /* raster flags */
2457  isempty[0] = rt_raster_is_empty(iwr->bandarg[i].raster[j]);
2458  isempty[1] = rt_raster_is_empty(raster);
2459 
2460  if (!isempty[0])
2461  hasband[0] = rt_raster_has_band(iwr->bandarg[i].raster[j], 0);
2462  if (!isempty[1])
2463  hasband[1] = rt_raster_has_band(raster, iwr->bandarg[i].nband);
2464 
2465  /* determine pixtype, hasnodata and nodataval */
2466  _band = NULL;
2467  if (!isempty[0] && hasband[0])
2468  _band = rt_raster_get_band(iwr->bandarg[i].raster[j], 0);
2469  else if (!isempty[1] && hasband[1])
2470  _band = rt_raster_get_band(raster, iwr->bandarg[i].nband);
2471  else {
2472  pixtype = PT_64BF;
2473  hasnodata = 1;
2474  nodataval = rt_pixtype_get_min_value(pixtype);
2475  }
2476  if (_band != NULL) {
2477  pixtype = rt_band_get_pixtype(_band);
2478  hasnodata = 1;
2479  if (rt_band_get_hasnodata_flag(_band))
2480  rt_band_get_nodata(_band, &nodataval);
2481  else
2482  nodataval = rt_band_get_min_value(_band);
2483  }
2484 
2485  /* UT_MEAN and UT_RANGE require two passes */
2486  /* UT_MEAN: first for UT_COUNT and second for UT_SUM */
2487  if (iwr->bandarg[i].uniontype == UT_MEAN) {
2488  /* first pass, UT_COUNT */
2489  if (j < 1)
2490  utype = UT_COUNT;
2491  else
2492  utype = UT_SUM;
2493  }
2494  /* UT_RANGE: first for UT_MIN and second for UT_MAX */
2495  else if (iwr->bandarg[i].uniontype == UT_RANGE) {
2496  /* first pass, UT_MIN */
2497  if (j < 1)
2498  utype = UT_MIN;
2499  else
2500  utype = UT_MAX;
2501  }
2502 
2503  /* force band settings for UT_COUNT */
2504  if (utype == UT_COUNT) {
2505  pixtype = PT_32BUI;
2506  hasnodata = 0;
2507  nodataval = 0;
2508  }
2509 
2510  POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
2511 
2512  /* set itrset */
2513  itrset[0].raster = iwr->bandarg[i].raster[j];
2514  itrset[0].nband = 0;
2515  itrset[1].raster = raster;
2516  itrset[1].nband = iwr->bandarg[i].nband;
2517 
2518  /* allow use NODATA to replace missing bands */
2519  if (nbnodata) {
2520  itrset[0].nbnodata = 1;
2521  itrset[1].nbnodata = 1;
2522  }
2523  /* missing bands are not ignored */
2524  else {
2525  itrset[0].nbnodata = 0;
2526  itrset[1].nbnodata = 0;
2527  }
2528 
2529  /* if rasters AND bands are present, use copy approach */
2530  if (!isempty[0] && !isempty[1] && hasband[0] && hasband[1]) {
2531  POSTGIS_RT_DEBUG(3, "using line method");
2532 
2533  /* generate empty out raster */
2535  iwr->bandarg[i].raster[j], raster,
2536  ET_UNION,
2537  &iraster, _offset
2538  ) != ES_NONE) {
2539 
2540  pfree(itrset);
2542  if (raster != NULL) {
2543  rt_raster_destroy(raster);
2544  PG_FREE_IF_COPY(pgraster, 1);
2545  }
2546 
2547  MemoryContextSwitchTo(oldcontext);
2548  elog(ERROR, "RASTER_union_transfn: Could not create internal raster");
2549  PG_RETURN_NULL();
2550  }
2551  POSTGIS_RT_DEBUGF(4, "_offset = %f, %f, %f, %f",
2552  _offset[0], _offset[1], _offset[2], _offset[3]);
2553 
2554  /* rasters are spatially the same? */
2555  if (
2556  rt_raster_get_width(iwr->bandarg[i].raster[j]) == rt_raster_get_width(iraster) &&
2558  ) {
2559  double igt[6] = {0};
2560  double gt[6] = {0};
2561 
2563  rt_raster_get_geotransform_matrix(iraster, igt);
2564 
2565  reuserast = rt_util_same_geotransform_matrix(gt, igt);
2566  }
2567 
2568  /* use internal raster */
2569  if (!reuserast) {
2570  /* create band of same type */
2572  iraster,
2573  pixtype,
2574  nodataval,
2575  hasnodata, nodataval,
2576  0
2577  ) == -1) {
2578 
2579  pfree(itrset);
2581  rt_raster_destroy(iraster);
2582  if (raster != NULL) {
2583  rt_raster_destroy(raster);
2584  PG_FREE_IF_COPY(pgraster, 1);
2585  }
2586 
2587  MemoryContextSwitchTo(oldcontext);
2588  elog(ERROR, "RASTER_union_transfn: Could not add new band to internal raster");
2589  PG_RETURN_NULL();
2590  }
2591  iband = rt_raster_get_band(iraster, 0);
2592 
2593  /* copy working raster to output raster */
2594  _dim[0] = rt_raster_get_width(iwr->bandarg[i].raster[j]);
2595  _dim[1] = rt_raster_get_height(iwr->bandarg[i].raster[j]);
2596  for (y = 0; y < _dim[1]; y++) {
2597  POSTGIS_RT_DEBUGF(4, "Getting pixel line of working raster at (x, y, length) = (0, %d, %d)", y, _dim[0]);
2599  _band,
2600  0, y,
2601  _dim[0],
2602  &vals, &nvals
2603  ) != ES_NONE) {
2604 
2605  pfree(itrset);
2607  rt_band_destroy(iband);
2608  rt_raster_destroy(iraster);
2609  if (raster != NULL) {
2610  rt_raster_destroy(raster);
2611  PG_FREE_IF_COPY(pgraster, 1);
2612  }
2613 
2614  MemoryContextSwitchTo(oldcontext);
2615  elog(ERROR, "RASTER_union_transfn: Could not get pixel line from band of working raster");
2616  PG_RETURN_NULL();
2617  }
2618 
2619  POSTGIS_RT_DEBUGF(4, "Setting pixel line at (x, y, length) = (%d, %d, %d)", (int) _offset[0], (int) _offset[1] + y, nvals);
2621  iband,
2622  (int) _offset[0], (int) _offset[1] + y,
2623  vals, nvals
2624  ) != ES_NONE) {
2625 
2626  pfree(itrset);
2628  rt_band_destroy(iband);
2629  rt_raster_destroy(iraster);
2630  if (raster != NULL) {
2631  rt_raster_destroy(raster);
2632  PG_FREE_IF_COPY(pgraster, 1);
2633  }
2634 
2635  MemoryContextSwitchTo(oldcontext);
2636  elog(ERROR, "RASTER_union_transfn: Could not set pixel line to band of internal raster");
2637  PG_RETURN_NULL();
2638  }
2639  }
2640  }
2641  else {
2642  rt_raster_destroy(iraster);
2643  iraster = iwr->bandarg[i].raster[j];
2644  iband = rt_raster_get_band(iraster, 0);
2645  }
2646 
2647  /* run iterator for extent of input raster */
2648  noerr = rt_raster_iterator(
2649  itrset, 2,
2650  ET_LAST, NULL,
2651  pixtype,
2652  hasnodata, nodataval,
2653  0, 0,
2654  NULL,
2655  &utype,
2657  &_raster
2658  );
2659  if (noerr != ES_NONE) {
2660 
2661  pfree(itrset);
2663  if (!reuserast) {
2664  rt_band_destroy(iband);
2665  rt_raster_destroy(iraster);
2666  }
2667  if (raster != NULL) {
2668  rt_raster_destroy(raster);
2669  PG_FREE_IF_COPY(pgraster, 1);
2670  }
2671 
2672  MemoryContextSwitchTo(oldcontext);
2673  elog(ERROR, "RASTER_union_transfn: Could not run raster iterator function");
2674  PG_RETURN_NULL();
2675  }
2676 
2677  /* with iterator raster, copy data to output raster */
2678  _band = rt_raster_get_band(_raster, 0);
2679  _dim[0] = rt_raster_get_width(_raster);
2680  _dim[1] = rt_raster_get_height(_raster);
2681  for (y = 0; y < _dim[1]; y++) {
2682  POSTGIS_RT_DEBUGF(4, "Getting pixel line of iterator raster at (x, y, length) = (0, %d, %d)", y, _dim[0]);
2684  _band,
2685  0, y,
2686  _dim[0],
2687  &vals, &nvals
2688  ) != ES_NONE) {
2689 
2690  pfree(itrset);
2692  if (!reuserast) {
2693  rt_band_destroy(iband);
2694  rt_raster_destroy(iraster);
2695  }
2696  if (raster != NULL) {
2697  rt_raster_destroy(raster);
2698  PG_FREE_IF_COPY(pgraster, 1);
2699  }
2700 
2701  MemoryContextSwitchTo(oldcontext);
2702  elog(ERROR, "RASTER_union_transfn: Could not get pixel line from band of working raster");
2703  PG_RETURN_NULL();
2704  }
2705 
2706  POSTGIS_RT_DEBUGF(4, "Setting pixel line at (x, y, length) = (%d, %d, %d)", (int) _offset[2], (int) _offset[3] + y, nvals);
2708  iband,
2709  (int) _offset[2], (int) _offset[3] + y,
2710  vals, nvals
2711  ) != ES_NONE) {
2712 
2713  pfree(itrset);
2715  if (!reuserast) {
2716  rt_band_destroy(iband);
2717  rt_raster_destroy(iraster);
2718  }
2719  if (raster != NULL) {
2720  rt_raster_destroy(raster);
2721  PG_FREE_IF_COPY(pgraster, 1);
2722  }
2723 
2724  MemoryContextSwitchTo(oldcontext);
2725  elog(ERROR, "RASTER_union_transfn: Could not set pixel line to band of internal raster");
2726  PG_RETURN_NULL();
2727  }
2728  }
2729 
2730  /* free _raster */
2731  rt_band_destroy(_band);
2732  rt_raster_destroy(_raster);
2733 
2734  /* replace working raster with output raster */
2735  _raster = iraster;
2736  }
2737  else {
2738  POSTGIS_RT_DEBUG(3, "using pixel method");
2739 
2740  /* pass everything to iterator */
2741  noerr = rt_raster_iterator(
2742  itrset, 2,
2743  ET_UNION, NULL,
2744  pixtype,
2745  hasnodata, nodataval,
2746  0, 0,
2747  NULL,
2748  &utype,
2750  &_raster
2751  );
2752 
2753  if (noerr != ES_NONE) {
2754 
2755  pfree(itrset);
2757  if (raster != NULL) {
2758  rt_raster_destroy(raster);
2759  PG_FREE_IF_COPY(pgraster, 1);
2760  }
2761 
2762  MemoryContextSwitchTo(oldcontext);
2763  elog(ERROR, "RASTER_union_transfn: Could not run raster iterator function");
2764  PG_RETURN_NULL();
2765  }
2766  }
2767 
2768  /* replace working raster */
2769  if (iwr->bandarg[i].raster[j] != NULL && !reuserast) {
2770  for (k = rt_raster_get_num_bands(iwr->bandarg[i].raster[j]) - 1; k >= 0; k--)
2772  rt_raster_destroy(iwr->bandarg[i].raster[j]);
2773  }
2774  iwr->bandarg[i].raster[j] = _raster;
2775  }
2776 
2777  }
2778 
2779  pfree(itrset);
2780  if (raster != NULL) {
2781  rt_raster_destroy(raster);
2782  PG_FREE_IF_COPY(pgraster, 1);
2783  }
2784 
2785  /* switch back to local context */
2786  MemoryContextSwitchTo(oldcontext);
2787 
2788  POSTGIS_RT_DEBUG(3, "Finished");
2789 
2790  PG_RETURN_POINTER(iwr);
2791 }
int rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:372
raster
Be careful!! Zeros function&#39;s input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
rtpg_union_band_arg bandarg
rtpg_union_type
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_raster.c:706
static int rtpg_union_unionarg_process(rtpg_union_arg arg, ArrayType *array)
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:3444
int rt_util_same_geotransform_matrix(double *gt1, double *gt2)
Definition: rt_util.c:487
gt
Definition: window.py:77
rt_pixtype
Definition: librtcore.h:185
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_band.c:242
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_raster.c:1338
#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:1597
nband
Definition: pixval.py:52
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
rt_errorstate rt_band_get_pixel_line(rt_band band, int x, int y, uint16_t len, void **vals, uint16_t *nvals)
Get values of multiple pixels.
Definition: rt_band.c:1004
rt_raster rt_raster_clone(rt_raster raster, uint8_t deep)
Clone an existing raster.
Definition: rt_raster.c:1544
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:541
static int rtpg_union_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
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:1351
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition: rt_pixel.c:148
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
rt_raster raster
Definition: librtcore.h:2394
static int rtpg_union_noarg(rtpg_union_arg arg, rt_raster raster)
uint16_t nband
Definition: librtcore.h:2395
static void rtpg_union_arg_destroy(rtpg_union_arg arg)
static rtpg_union_type rtpg_uniontype_index_from_name(const char *cutype)
uint16_t rt_raster_get_width(rt_raster raster)
Definition: rt_raster.c:121
#define FALSE
Definition: dbfopen.c:168
uint8_t nbnodata
Definition: librtcore.h:2396
Struct definitions.
Definition: librtcore.h:2201
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:1612
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_pixel.c:110
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.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:498
rt_errorstate rt_band_set_pixel_line(rt_band band, int x, int y, void *vals, uint32_t len)
Set values of multiple pixels.
Definition: rt_band.c:720
struct rtpg_union_arg_t * rtpg_union_arg
rtpg_union_type uniontype
uint16_t rt_raster_get_height(rt_raster raster)
Definition: rt_raster.c:129
#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:717
char * rtpg_strtoupper(char *str)
Here is the call graph for this function:
Here is the caller graph for this function: