PostGIS  2.3.8dev-r@@SVN_REVISION@@

◆ RASTER_union_transfn()

Datum RASTER_union_transfn ( PG_FUNCTION_ARGS  )

Definition at line 2060 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, UT_SUM, and pixval::y.

Referenced by rtpg_union_noarg().

2061 {
2062  MemoryContext aggcontext;
2063  MemoryContext oldcontext;
2064  rtpg_union_arg iwr = NULL;
2065  int skiparg = 0;
2066 
2067  rt_pgraster *pgraster = NULL;
2068  rt_raster raster = NULL;
2069  rt_raster _raster = NULL;
2070  rt_band _band = NULL;
2071  int nband = 1;
2072  int noerr = 1;
2073  int isempty[2] = {0};
2074  int hasband[2] = {0};
2075  int nargs = 0;
2076  double _offset[4] = {0.};
2077  int nbnodata = 0; /* 1 if adding bands */
2078 
2079  int i = 0;
2080  int j = 0;
2081  int k = 0;
2082 
2083  rt_iterator itrset;
2084  char *utypename = NULL;
2085  rtpg_union_type utype = UT_LAST;
2086  rt_pixtype pixtype = PT_END;
2087  int hasnodata = 1;
2088  double nodataval = 0;
2089 
2090  rt_raster iraster = NULL;
2091  rt_band iband = NULL;
2092  int reuserast = 0;
2093  int y = 0;
2094  uint16_t _dim[2] = {0};
2095  void *vals = NULL;
2096  uint16_t nvals = 0;
2097 
2098  POSTGIS_RT_DEBUG(3, "Starting...");
2099 
2100  /* cannot be called directly as this is exclusive aggregate function */
2101  if (!AggCheckCallContext(fcinfo, &aggcontext)) {
2102  elog(ERROR, "RASTER_union_transfn: Cannot be called in a non-aggregate context");
2103  PG_RETURN_NULL();
2104  }
2105 
2106  /* switch to aggcontext */
2107  oldcontext = MemoryContextSwitchTo(aggcontext);
2108 
2109  if (PG_ARGISNULL(0)) {
2110  POSTGIS_RT_DEBUG(3, "Creating state variable");
2111  /* allocate container in aggcontext */
2112  iwr = palloc(sizeof(struct rtpg_union_arg_t));
2113  if (iwr == NULL) {
2114  MemoryContextSwitchTo(oldcontext);
2115  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for state variable");
2116  PG_RETURN_NULL();
2117  }
2118 
2119  iwr->numband = 0;
2120  iwr->bandarg = NULL;
2121 
2122  skiparg = 0;
2123  }
2124  else {
2125  POSTGIS_RT_DEBUG(3, "State variable already exists");
2126  iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
2127  skiparg = 1;
2128  }
2129 
2130  /* raster arg is NOT NULL */
2131  if (!PG_ARGISNULL(1)) {
2132  /* deserialize raster */
2133  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
2134 
2135  /* Get raster object */
2136  raster = rt_raster_deserialize(pgraster, FALSE);
2137  if (raster == NULL) {
2138 
2140  PG_FREE_IF_COPY(pgraster, 1);
2141 
2142  MemoryContextSwitchTo(oldcontext);
2143  elog(ERROR, "RASTER_union_transfn: Could not deserialize raster");
2144  PG_RETURN_NULL();
2145  }
2146  }
2147 
2148  /* process additional args if needed */
2149  nargs = PG_NARGS();
2150  POSTGIS_RT_DEBUGF(4, "nargs = %d", nargs);
2151  if (nargs > 2) {
2152  POSTGIS_RT_DEBUG(4, "processing additional arguments");
2153 
2154  /* if more than 2 arguments, determine the type of argument 3 */
2155  /* band number, UNION type or unionarg */
2156  if (!PG_ARGISNULL(2)) {
2157  Oid calltype = get_fn_expr_argtype(fcinfo->flinfo, 2);
2158 
2159  switch (calltype) {
2160  /* UNION type */
2161  case TEXTOID: {
2162  int idx = 0;
2163  int numband = 0;
2164 
2165  POSTGIS_RT_DEBUG(4, "Processing arg 3 as UNION type");
2166  nbnodata = 1;
2167 
2168  utypename = text_to_cstring(PG_GETARG_TEXT_P(2));
2169  utype = rtpg_uniontype_index_from_name(rtpg_strtoupper(utypename));
2170  POSTGIS_RT_DEBUGF(4, "Union type: %s", utypename);
2171 
2172  POSTGIS_RT_DEBUGF(4, "iwr->numband: %d", iwr->numband);
2173  /* see if we need to append new bands */
2174  if (raster) {
2175  idx = iwr->numband;
2176  numband = rt_raster_get_num_bands(raster);
2177  POSTGIS_RT_DEBUGF(4, "numband: %d", numband);
2178 
2179  /* only worry about appended bands */
2180  if (numband > iwr->numband)
2181  iwr->numband = numband;
2182  }
2183 
2184  if (!iwr->numband)
2185  iwr->numband = 1;
2186  POSTGIS_RT_DEBUGF(4, "iwr->numband: %d", iwr->numband);
2187  POSTGIS_RT_DEBUGF(4, "numband, idx: %d, %d", numband, idx);
2188 
2189  /* bandarg set. only possible after the first call to function */
2190  if (iwr->bandarg) {
2191  /* only reallocate if new bands need to be added */
2192  if (numband > idx) {
2193  POSTGIS_RT_DEBUG(4, "Reallocating iwr->bandarg");
2194  iwr->bandarg = repalloc(iwr->bandarg, sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
2195  }
2196  /* prevent initial values step happening below */
2197  else
2198  idx = iwr->numband;
2199  }
2200  /* bandarg not set, first call to function */
2201  else {
2202  POSTGIS_RT_DEBUG(4, "Allocating iwr->bandarg");
2203  iwr->bandarg = palloc(sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
2204  }
2205  if (iwr->bandarg == NULL) {
2206 
2208  if (raster != NULL) {
2209  rt_raster_destroy(raster);
2210  PG_FREE_IF_COPY(pgraster, 1);
2211  }
2212 
2213  MemoryContextSwitchTo(oldcontext);
2214  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for band information");
2215  PG_RETURN_NULL();
2216  }
2217 
2218  /* set initial values for bands that are "new" */
2219  for (i = idx; i < iwr->numband; i++) {
2220  iwr->bandarg[i].uniontype = utype;
2221  iwr->bandarg[i].nband = i;
2222 
2223  if (
2224  utype == UT_MEAN ||
2225  utype == UT_RANGE
2226  ) {
2227  iwr->bandarg[i].numraster = 2;
2228  }
2229  else
2230  iwr->bandarg[i].numraster = 1;
2231  iwr->bandarg[i].raster = NULL;
2232  }
2233 
2234  break;
2235  }
2236  /* band number */
2237  case INT2OID:
2238  case INT4OID:
2239  if (skiparg)
2240  break;
2241 
2242  POSTGIS_RT_DEBUG(4, "Processing arg 3 as band number");
2243  nband = PG_GETARG_INT32(2);
2244  if (nband < 1) {
2245 
2247  if (raster != NULL) {
2248  rt_raster_destroy(raster);
2249  PG_FREE_IF_COPY(pgraster, 1);
2250  }
2251 
2252  MemoryContextSwitchTo(oldcontext);
2253  elog(ERROR, "RASTER_union_transfn: Band number must be greater than zero (1-based)");
2254  PG_RETURN_NULL();
2255  }
2256 
2257  iwr->numband = 1;
2258  iwr->bandarg = palloc(sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
2259  if (iwr->bandarg == NULL) {
2260 
2262  if (raster != NULL) {
2263  rt_raster_destroy(raster);
2264  PG_FREE_IF_COPY(pgraster, 1);
2265  }
2266 
2267  MemoryContextSwitchTo(oldcontext);
2268  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for band information");
2269  PG_RETURN_NULL();
2270  }
2271 
2272  iwr->bandarg[0].uniontype = UT_LAST;
2273  iwr->bandarg[0].nband = nband - 1;
2274 
2275  iwr->bandarg[0].numraster = 1;
2276  iwr->bandarg[0].raster = NULL;
2277  break;
2278  /* only other type allowed is unionarg */
2279  default:
2280  if (skiparg)
2281  break;
2282 
2283  POSTGIS_RT_DEBUG(4, "Processing arg 3 as unionarg");
2284  if (!rtpg_union_unionarg_process(iwr, PG_GETARG_ARRAYTYPE_P(2))) {
2285 
2287  if (raster != NULL) {
2288  rt_raster_destroy(raster);
2289  PG_FREE_IF_COPY(pgraster, 1);
2290  }
2291 
2292  MemoryContextSwitchTo(oldcontext);
2293  elog(ERROR, "RASTER_union_transfn: Could not process unionarg");
2294  PG_RETURN_NULL();
2295  }
2296 
2297  break;
2298  }
2299  }
2300 
2301  /* UNION type */
2302  if (nargs > 3 && !PG_ARGISNULL(3)) {
2303  utypename = text_to_cstring(PG_GETARG_TEXT_P(3));
2304  utype = rtpg_uniontype_index_from_name(rtpg_strtoupper(utypename));
2305  iwr->bandarg[0].uniontype = utype;
2306  POSTGIS_RT_DEBUGF(4, "Union type: %s", utypename);
2307 
2308  if (
2309  utype == UT_MEAN ||
2310  utype == UT_RANGE
2311  ) {
2312  iwr->bandarg[0].numraster = 2;
2313  }
2314  }
2315 
2316  /* allocate space for pointers to rt_raster */
2317  for (i = 0; i < iwr->numband; i++) {
2318  POSTGIS_RT_DEBUGF(4, "iwr->bandarg[%d].raster @ %p", i, iwr->bandarg[i].raster);
2319 
2320  /* no need to allocate */
2321  if (iwr->bandarg[i].raster != NULL)
2322  continue;
2323 
2324  POSTGIS_RT_DEBUGF(4, "Allocating space for working rasters of band %d", i);
2325 
2326  iwr->bandarg[i].raster = (rt_raster *) palloc(sizeof(rt_raster) * iwr->bandarg[i].numraster);
2327  if (iwr->bandarg[i].raster == NULL) {
2328 
2330  if (raster != NULL) {
2331  rt_raster_destroy(raster);
2332  PG_FREE_IF_COPY(pgraster, 1);
2333  }
2334 
2335  MemoryContextSwitchTo(oldcontext);
2336  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for working raster(s)");
2337  PG_RETURN_NULL();
2338  }
2339 
2340  memset(iwr->bandarg[i].raster, 0, sizeof(rt_raster) * iwr->bandarg[i].numraster);
2341 
2342  /* add new working rt_raster but only if working raster already exists */
2343  if (i > 0 && !rt_raster_is_empty(iwr->bandarg[0].raster[0])) {
2344  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2345  iwr->bandarg[i].raster[j] = rt_raster_clone(iwr->bandarg[0].raster[0], 0); /* shallow clone */
2346  if (iwr->bandarg[i].raster[j] == NULL) {
2347 
2349  if (raster != NULL) {
2350  rt_raster_destroy(raster);
2351  PG_FREE_IF_COPY(pgraster, 1);
2352  }
2353 
2354  MemoryContextSwitchTo(oldcontext);
2355  elog(ERROR, "RASTER_union_transfn: Could not create working raster");
2356  PG_RETURN_NULL();
2357  }
2358  }
2359  }
2360  }
2361  }
2362  /* only raster, no additional args */
2363  /* only do this if raster isn't empty */
2364  else {
2365  POSTGIS_RT_DEBUG(4, "no additional args, checking input raster");
2366  nbnodata = 1;
2367  if (!rtpg_union_noarg(iwr, raster)) {
2368 
2370  if (raster != NULL) {
2371  rt_raster_destroy(raster);
2372  PG_FREE_IF_COPY(pgraster, 1);
2373  }
2374 
2375  MemoryContextSwitchTo(oldcontext);
2376  elog(ERROR, "RASTER_union_transfn: Could not check and balance number of bands");
2377  PG_RETURN_NULL();
2378  }
2379  }
2380 
2381  /* init itrset */
2382  itrset = palloc(sizeof(struct rt_iterator_t) * 2);
2383  if (itrset == NULL) {
2384 
2386  if (raster != NULL) {
2387  rt_raster_destroy(raster);
2388  PG_FREE_IF_COPY(pgraster, 1);
2389  }
2390 
2391  MemoryContextSwitchTo(oldcontext);
2392  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for iterator arguments");
2393  PG_RETURN_NULL();
2394  }
2395 
2396  /* by band to UNION */
2397  for (i = 0; i < iwr->numband; i++) {
2398 
2399  /* by raster */
2400  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2401  reuserast = 0;
2402 
2403  /* type of union */
2404  utype = iwr->bandarg[i].uniontype;
2405 
2406  /* raster flags */
2407  isempty[0] = rt_raster_is_empty(iwr->bandarg[i].raster[j]);
2408  isempty[1] = rt_raster_is_empty(raster);
2409 
2410  if (!isempty[0])
2411  hasband[0] = rt_raster_has_band(iwr->bandarg[i].raster[j], 0);
2412  if (!isempty[1])
2413  hasband[1] = rt_raster_has_band(raster, iwr->bandarg[i].nband);
2414 
2415  /* determine pixtype, hasnodata and nodataval */
2416  _band = NULL;
2417  if (!isempty[0] && hasband[0])
2418  _band = rt_raster_get_band(iwr->bandarg[i].raster[j], 0);
2419  else if (!isempty[1] && hasband[1])
2420  _band = rt_raster_get_band(raster, iwr->bandarg[i].nband);
2421  else {
2422  pixtype = PT_64BF;
2423  hasnodata = 1;
2424  nodataval = rt_pixtype_get_min_value(pixtype);
2425  }
2426  if (_band != NULL) {
2427  pixtype = rt_band_get_pixtype(_band);
2428  hasnodata = 1;
2429  if (rt_band_get_hasnodata_flag(_band))
2430  rt_band_get_nodata(_band, &nodataval);
2431  else
2432  nodataval = rt_band_get_min_value(_band);
2433  }
2434 
2435  /* UT_MEAN and UT_RANGE require two passes */
2436  /* UT_MEAN: first for UT_COUNT and second for UT_SUM */
2437  if (iwr->bandarg[i].uniontype == UT_MEAN) {
2438  /* first pass, UT_COUNT */
2439  if (j < 1)
2440  utype = UT_COUNT;
2441  else
2442  utype = UT_SUM;
2443  }
2444  /* UT_RANGE: first for UT_MIN and second for UT_MAX */
2445  else if (iwr->bandarg[i].uniontype == UT_RANGE) {
2446  /* first pass, UT_MIN */
2447  if (j < 1)
2448  utype = UT_MIN;
2449  else
2450  utype = UT_MAX;
2451  }
2452 
2453  /* force band settings for UT_COUNT */
2454  if (utype == UT_COUNT) {
2455  pixtype = PT_32BUI;
2456  hasnodata = 0;
2457  nodataval = 0;
2458  }
2459 
2460  POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
2461 
2462  /* set itrset */
2463  itrset[0].raster = iwr->bandarg[i].raster[j];
2464  itrset[0].nband = 0;
2465  itrset[1].raster = raster;
2466  itrset[1].nband = iwr->bandarg[i].nband;
2467 
2468  /* allow use NODATA to replace missing bands */
2469  if (nbnodata) {
2470  itrset[0].nbnodata = 1;
2471  itrset[1].nbnodata = 1;
2472  }
2473  /* missing bands are not ignored */
2474  else {
2475  itrset[0].nbnodata = 0;
2476  itrset[1].nbnodata = 0;
2477  }
2478 
2479  /* if rasters AND bands are present, use copy approach */
2480  if (!isempty[0] && !isempty[1] && hasband[0] && hasband[1]) {
2481  POSTGIS_RT_DEBUG(3, "using line method");
2482 
2483  /* generate empty out raster */
2485  iwr->bandarg[i].raster[j], raster,
2486  ET_UNION,
2487  &iraster, _offset
2488  ) != ES_NONE) {
2489 
2490  pfree(itrset);
2492  if (raster != NULL) {
2493  rt_raster_destroy(raster);
2494  PG_FREE_IF_COPY(pgraster, 1);
2495  }
2496 
2497  MemoryContextSwitchTo(oldcontext);
2498  elog(ERROR, "RASTER_union_transfn: Could not create internal raster");
2499  PG_RETURN_NULL();
2500  }
2501  POSTGIS_RT_DEBUGF(4, "_offset = %f, %f, %f, %f",
2502  _offset[0], _offset[1], _offset[2], _offset[3]);
2503 
2504  /* rasters are spatially the same? */
2505  if (
2506  rt_raster_get_width(iwr->bandarg[i].raster[j]) == rt_raster_get_width(iraster) &&
2508  ) {
2509  double igt[6] = {0};
2510  double gt[6] = {0};
2511 
2513  rt_raster_get_geotransform_matrix(iraster, igt);
2514 
2515  reuserast = rt_util_same_geotransform_matrix(gt, igt);
2516  }
2517 
2518  /* use internal raster */
2519  if (!reuserast) {
2520  /* create band of same type */
2522  iraster,
2523  pixtype,
2524  nodataval,
2525  hasnodata, nodataval,
2526  0
2527  ) == -1) {
2528 
2529  pfree(itrset);
2531  rt_raster_destroy(iraster);
2532  if (raster != NULL) {
2533  rt_raster_destroy(raster);
2534  PG_FREE_IF_COPY(pgraster, 1);
2535  }
2536 
2537  MemoryContextSwitchTo(oldcontext);
2538  elog(ERROR, "RASTER_union_transfn: Could not add new band to internal raster");
2539  PG_RETURN_NULL();
2540  }
2541  iband = rt_raster_get_band(iraster, 0);
2542 
2543  /* copy working raster to output raster */
2544  _dim[0] = rt_raster_get_width(iwr->bandarg[i].raster[j]);
2545  _dim[1] = rt_raster_get_height(iwr->bandarg[i].raster[j]);
2546  for (y = 0; y < _dim[1]; y++) {
2547  POSTGIS_RT_DEBUGF(4, "Getting pixel line of working raster at (x, y, length) = (0, %d, %d)", y, _dim[0]);
2549  _band,
2550  0, y,
2551  _dim[0],
2552  &vals, &nvals
2553  ) != ES_NONE) {
2554 
2555  pfree(itrset);
2557  rt_band_destroy(iband);
2558  rt_raster_destroy(iraster);
2559  if (raster != NULL) {
2560  rt_raster_destroy(raster);
2561  PG_FREE_IF_COPY(pgraster, 1);
2562  }
2563 
2564  MemoryContextSwitchTo(oldcontext);
2565  elog(ERROR, "RASTER_union_transfn: Could not get pixel line from band of working raster");
2566  PG_RETURN_NULL();
2567  }
2568 
2569  POSTGIS_RT_DEBUGF(4, "Setting pixel line at (x, y, length) = (%d, %d, %d)", (int) _offset[0], (int) _offset[1] + y, nvals);
2571  iband,
2572  (int) _offset[0], (int) _offset[1] + y,
2573  vals, nvals
2574  ) != ES_NONE) {
2575 
2576  pfree(itrset);
2578  rt_band_destroy(iband);
2579  rt_raster_destroy(iraster);
2580  if (raster != NULL) {
2581  rt_raster_destroy(raster);
2582  PG_FREE_IF_COPY(pgraster, 1);
2583  }
2584 
2585  MemoryContextSwitchTo(oldcontext);
2586  elog(ERROR, "RASTER_union_transfn: Could not set pixel line to band of internal raster");
2587  PG_RETURN_NULL();
2588  }
2589  }
2590  }
2591  else {
2592  rt_raster_destroy(iraster);
2593  iraster = iwr->bandarg[i].raster[j];
2594  iband = rt_raster_get_band(iraster, 0);
2595  }
2596 
2597  /* run iterator for extent of input raster */
2598  noerr = rt_raster_iterator(
2599  itrset, 2,
2600  ET_LAST, NULL,
2601  pixtype,
2602  hasnodata, nodataval,
2603  0, 0,
2604  NULL,
2605  &utype,
2607  &_raster
2608  );
2609  if (noerr != ES_NONE) {
2610 
2611  pfree(itrset);
2613  if (!reuserast) {
2614  rt_band_destroy(iband);
2615  rt_raster_destroy(iraster);
2616  }
2617  if (raster != NULL) {
2618  rt_raster_destroy(raster);
2619  PG_FREE_IF_COPY(pgraster, 1);
2620  }
2621 
2622  MemoryContextSwitchTo(oldcontext);
2623  elog(ERROR, "RASTER_union_transfn: Could not run raster iterator function");
2624  PG_RETURN_NULL();
2625  }
2626 
2627  /* with iterator raster, copy data to output raster */
2628  _band = rt_raster_get_band(_raster, 0);
2629  _dim[0] = rt_raster_get_width(_raster);
2630  _dim[1] = rt_raster_get_height(_raster);
2631  for (y = 0; y < _dim[1]; y++) {
2632  POSTGIS_RT_DEBUGF(4, "Getting pixel line of iterator raster at (x, y, length) = (0, %d, %d)", y, _dim[0]);
2634  _band,
2635  0, y,
2636  _dim[0],
2637  &vals, &nvals
2638  ) != ES_NONE) {
2639 
2640  pfree(itrset);
2642  if (!reuserast) {
2643  rt_band_destroy(iband);
2644  rt_raster_destroy(iraster);
2645  }
2646  if (raster != NULL) {
2647  rt_raster_destroy(raster);
2648  PG_FREE_IF_COPY(pgraster, 1);
2649  }
2650 
2651  MemoryContextSwitchTo(oldcontext);
2652  elog(ERROR, "RASTER_union_transfn: Could not get pixel line from band of working raster");
2653  PG_RETURN_NULL();
2654  }
2655 
2656  POSTGIS_RT_DEBUGF(4, "Setting pixel line at (x, y, length) = (%d, %d, %d)", (int) _offset[2], (int) _offset[3] + y, nvals);
2658  iband,
2659  (int) _offset[2], (int) _offset[3] + y,
2660  vals, nvals
2661  ) != ES_NONE) {
2662 
2663  pfree(itrset);
2665  if (!reuserast) {
2666  rt_band_destroy(iband);
2667  rt_raster_destroy(iraster);
2668  }
2669  if (raster != NULL) {
2670  rt_raster_destroy(raster);
2671  PG_FREE_IF_COPY(pgraster, 1);
2672  }
2673 
2674  MemoryContextSwitchTo(oldcontext);
2675  elog(ERROR, "RASTER_union_transfn: Could not set pixel line to band of internal raster");
2676  PG_RETURN_NULL();
2677  }
2678  }
2679 
2680  /* free _raster */
2681  rt_band_destroy(_band);
2682  rt_raster_destroy(_raster);
2683 
2684  /* replace working raster with output raster */
2685  _raster = iraster;
2686  }
2687  else {
2688  POSTGIS_RT_DEBUG(3, "using pixel method");
2689 
2690  /* pass everything to iterator */
2691  noerr = rt_raster_iterator(
2692  itrset, 2,
2693  ET_UNION, NULL,
2694  pixtype,
2695  hasnodata, nodataval,
2696  0, 0,
2697  NULL,
2698  &utype,
2700  &_raster
2701  );
2702 
2703  if (noerr != ES_NONE) {
2704 
2705  pfree(itrset);
2707  if (raster != NULL) {
2708  rt_raster_destroy(raster);
2709  PG_FREE_IF_COPY(pgraster, 1);
2710  }
2711 
2712  MemoryContextSwitchTo(oldcontext);
2713  elog(ERROR, "RASTER_union_transfn: Could not run raster iterator function");
2714  PG_RETURN_NULL();
2715  }
2716  }
2717 
2718  /* replace working raster */
2719  if (iwr->bandarg[i].raster[j] != NULL && !reuserast) {
2720  for (k = rt_raster_get_num_bands(iwr->bandarg[i].raster[j]) - 1; k >= 0; k--)
2722  rt_raster_destroy(iwr->bandarg[i].raster[j]);
2723  }
2724  iwr->bandarg[i].raster[j] = _raster;
2725  }
2726 
2727  }
2728 
2729  pfree(itrset);
2730  if (raster != NULL) {
2731  rt_raster_destroy(raster);
2732  PG_FREE_IF_COPY(pgraster, 1);
2733  }
2734 
2735  /* switch back to local context */
2736  MemoryContextSwitchTo(oldcontext);
2737 
2738  POSTGIS_RT_DEBUG(3, "Finished");
2739 
2740  PG_RETURN_POINTER(iwr);
2741 }
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:197
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:57
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:2406
static int rtpg_union_noarg(rtpg_union_arg arg, rt_raster raster)
uint16_t nband
Definition: librtcore.h:2407
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:2408
Struct definitions.
Definition: librtcore.h:2213
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:53
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: