PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ RASTER_mapAlgebra2()

Datum RASTER_mapAlgebra2 ( PG_FUNCTION_ARGS  )

Definition at line 6249 of file rtpg_mapalgebra.c.

6250 {
6251  const uint32_t set_count = 2;
6252  rt_pgraster *pgrast[2] = { NULL, NULL };
6253  int pgrastpos[2] = {-1, -1};
6254  rt_pgraster *pgrtn;
6255  rt_raster rast[2] = {NULL};
6256  int _isempty[2] = {0};
6257  uint32_t bandindex[2] = {0};
6258  rt_raster _rast[2] = {NULL};
6259  rt_band _band[2] = {NULL};
6260  int _hasnodata[2] = {0};
6261  double _nodataval[2] = {0};
6262  double _offset[4] = {0.};
6263  double _rastoffset[2][4] = {{0.}};
6264  int _haspixel[2] = {0};
6265  double _pixel[2] = {0};
6266  int _pos[2][2] = {{0}};
6267  uint16_t _dim[2][2] = {{0}};
6268 
6269  char *pixtypename = NULL;
6270  rt_pixtype pixtype = PT_END;
6271  char *extenttypename = NULL;
6272  rt_extenttype extenttype = ET_INTERSECTION;
6273 
6274  rt_raster raster = NULL;
6275  rt_band band = NULL;
6276  uint16_t dim[2] = {0};
6277  int haspixel = 0;
6278  double pixel = 0.;
6279  double nodataval = 0;
6280  double gt[6] = {0.};
6281 
6282  Oid calltype = InvalidOid;
6283 
6284  const uint32_t spi_count = 3;
6285  uint16_t spi_exprpos[3] = {4, 7, 8};
6286  uint32_t spi_argcount[3] = {0};
6287  char *expr = NULL;
6288  char *sql = NULL;
6289  SPIPlanPtr spi_plan[3] = {NULL};
6290  uint16_t spi_empty = 0;
6291  Oid *argtype = NULL;
6292  uint8_t argpos[3][8] = {{0}};
6293  char *argkw[] = {"[rast1.x]", "[rast1.y]", "[rast1.val]", "[rast1]", "[rast2.x]", "[rast2.y]", "[rast2.val]", "[rast2]"};
6294  Datum values[ARGKWCOUNT];
6295  char nulls[ARGKWCOUNT];
6296  TupleDesc tupdesc;
6297  SPITupleTable *tuptable = NULL;
6298  HeapTuple tuple;
6299  Datum datum;
6300  bool isnull = FALSE;
6301  int hasargval[3] = {0};
6302  double argval[3] = {0.};
6303  int hasnodatanodataval = 0;
6304  double nodatanodataval = 0;
6305  int isnodata = 0;
6306 
6307  Oid ufc_noid = InvalidOid;
6308  FmgrInfo ufl_info;
6309  LOCAL_FCINFO(ufc_info, FUNC_MAX_ARGS); /* Could be optimized */
6310 
6311  int ufc_nullcount = 0;
6312 
6313  int idx = 0;
6314  uint32_t i = 0;
6315  uint32_t j = 0;
6316  uint32_t k = 0;
6317  uint32_t x = 0;
6318  uint32_t y = 0;
6319  int _x = 0;
6320  int _y = 0;
6321  int err;
6322  int aligned = 0;
6323  int len = 0;
6324 
6325  POSTGIS_RT_DEBUG(3, "Starting RASTER_mapAlgebra2");
6326 
6327  for (i = 0, j = 0; i < set_count; i++) {
6328  if (!PG_ARGISNULL(j)) {
6329  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
6330  pgrastpos[i] = j;
6331  j++;
6332 
6333  /* raster */
6334  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
6335  if (!rast[i]) {
6336  for (k = 0; k <= i; k++) {
6337  if (k < i && rast[k] != NULL)
6338  rt_raster_destroy(rast[k]);
6339  if (pgrastpos[k] != -1)
6340  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6341  }
6342  elog(ERROR, "RASTER_mapAlgebra2: Could not deserialize the %s raster", i < 1 ? "first" : "second");
6343  PG_RETURN_NULL();
6344  }
6345 
6346  /* empty */
6347  _isempty[i] = rt_raster_is_empty(rast[i]);
6348 
6349  /* band index */
6350  if (!PG_ARGISNULL(j)) {
6351  bandindex[i] = PG_GETARG_INT32(j);
6352  }
6353  j++;
6354  }
6355  else {
6356  _isempty[i] = 1;
6357  j += 2;
6358  }
6359 
6360  POSTGIS_RT_DEBUGF(3, "_isempty[%d] = %d", i, _isempty[i]);
6361  }
6362 
6363  /* both rasters are NULL */
6364  if (rast[0] == NULL && rast[1] == NULL) {
6365  elog(NOTICE, "The two rasters provided are NULL. Returning NULL");
6366  for (k = 0; k < set_count; k++) {
6367  if (pgrastpos[k] != -1)
6368  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6369  }
6370  PG_RETURN_NULL();
6371  }
6372 
6373  /* both rasters are empty */
6374  if (_isempty[0] && _isempty[1]) {
6375  elog(NOTICE, "The two rasters provided are empty. Returning empty raster");
6376 
6377  raster = rt_raster_new(0, 0);
6378  if (raster == NULL) {
6379  for (k = 0; k < set_count; k++) {
6380  if (rast[k] != NULL)
6381  rt_raster_destroy(rast[k]);
6382  if (pgrastpos[k] != -1)
6383  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6384  }
6385  elog(ERROR, "RASTER_mapAlgebra2: Could not create empty raster");
6386  PG_RETURN_NULL();
6387  }
6388  rt_raster_set_scale(raster, 0, 0);
6389 
6390  pgrtn = rt_raster_serialize(raster);
6392  if (!pgrtn)
6393  PG_RETURN_NULL();
6394 
6395  SET_VARSIZE(pgrtn, pgrtn->size);
6396  PG_RETURN_POINTER(pgrtn);
6397  }
6398 
6399  /* replace the empty or NULL raster with one matching the other */
6400  if (
6401  (rast[0] == NULL || _isempty[0]) ||
6402  (rast[1] == NULL || _isempty[1])
6403  ) {
6404  /* first raster is empty */
6405  if (rast[0] == NULL || _isempty[0]) {
6406  i = 0;
6407  j = 1;
6408  }
6409  /* second raster is empty */
6410  else {
6411  i = 1;
6412  j = 0;
6413  }
6414 
6415  _rast[j] = rast[j];
6416 
6417  /* raster is empty, destroy it */
6418  if (_rast[i] != NULL)
6419  rt_raster_destroy(_rast[i]);
6420 
6421  _dim[i][0] = rt_raster_get_width(_rast[j]);
6422  _dim[i][1] = rt_raster_get_height(_rast[j]);
6423  _dim[j][0] = rt_raster_get_width(_rast[j]);
6424  _dim[j][1] = rt_raster_get_height(_rast[j]);
6425 
6426  _rast[i] = rt_raster_new(
6427  _dim[j][0],
6428  _dim[j][1]
6429  );
6430  if (_rast[i] == NULL) {
6431  rt_raster_destroy(_rast[j]);
6432  for (k = 0; k < set_count; k++) {
6433  if (pgrastpos[k] != -1)
6434  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6435  }
6436  elog(ERROR, "RASTER_mapAlgebra2: Could not create NODATA raster");
6437  PG_RETURN_NULL();
6438  }
6439  rt_raster_set_srid(_rast[i], rt_raster_get_srid(_rast[j]));
6440 
6443  }
6444  else {
6445  _rast[0] = rast[0];
6446  _dim[0][0] = rt_raster_get_width(_rast[0]);
6447  _dim[0][1] = rt_raster_get_height(_rast[0]);
6448 
6449  _rast[1] = rast[1];
6450  _dim[1][0] = rt_raster_get_width(_rast[1]);
6451  _dim[1][1] = rt_raster_get_height(_rast[1]);
6452  }
6453 
6454  /* SRID must match */
6455  /*
6456  if (rt_raster_get_srid(_rast[0]) != rt_raster_get_srid(_rast[1])) {
6457  elog(NOTICE, "The two rasters provided have different SRIDs. Returning NULL");
6458  for (k = 0; k < set_count; k++) {
6459  if (_rast[k] != NULL)
6460  rt_raster_destroy(_rast[k]);
6461  if (pgrastpos[k] != -1)
6462  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6463  }
6464  PG_RETURN_NULL();
6465  }
6466  */
6467 
6468  /* same alignment */
6469  if (rt_raster_same_alignment(_rast[0], _rast[1], &aligned, NULL) != ES_NONE) {
6470  for (k = 0; k < set_count; k++) {
6471  if (_rast[k] != NULL)
6472  rt_raster_destroy(_rast[k]);
6473  if (pgrastpos[k] != -1)
6474  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6475  }
6476  elog(ERROR, "RASTER_mapAlgebra2: Could not test for alignment on the two rasters");
6477  PG_RETURN_NULL();
6478  }
6479  if (!aligned) {
6480  elog(NOTICE, "The two rasters provided do not have the same alignment. Returning NULL");
6481  for (k = 0; k < set_count; k++) {
6482  if (_rast[k] != NULL)
6483  rt_raster_destroy(_rast[k]);
6484  if (pgrastpos[k] != -1)
6485  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6486  }
6487  PG_RETURN_NULL();
6488  }
6489 
6490  /* pixel type */
6491  if (!PG_ARGISNULL(5)) {
6492  pixtypename = text_to_cstring(PG_GETARG_TEXT_P(5));
6493  /* Get the pixel type index */
6494  pixtype = rt_pixtype_index_from_name(pixtypename);
6495  if (pixtype == PT_END ) {
6496  for (k = 0; k < set_count; k++) {
6497  if (_rast[k] != NULL)
6498  rt_raster_destroy(_rast[k]);
6499  if (pgrastpos[k] != -1)
6500  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6501  }
6502  elog(ERROR, "RASTER_mapAlgebra2: Invalid pixel type: %s", pixtypename);
6503  PG_RETURN_NULL();
6504  }
6505  }
6506 
6507  /* extent type */
6508  if (!PG_ARGISNULL(6)) {
6509  extenttypename = rtpg_strtoupper(rtpg_trim(text_to_cstring(PG_GETARG_TEXT_P(6))));
6510  extenttype = rt_util_extent_type(extenttypename);
6511  }
6512  POSTGIS_RT_DEBUGF(3, "extenttype: %d %s", extenttype, extenttypename);
6513 
6514  /* computed raster from extent type */
6516  _rast[0], _rast[1],
6517  extenttype,
6518  &raster, _offset
6519  );
6520  if (err != ES_NONE) {
6521  for (k = 0; k < set_count; k++) {
6522  if (_rast[k] != NULL)
6523  rt_raster_destroy(_rast[k]);
6524  if (pgrastpos[k] != -1)
6525  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6526  }
6527  elog(ERROR, "RASTER_mapAlgebra2: Could not get output raster of correct extent");
6528  PG_RETURN_NULL();
6529  }
6530 
6531  /* copy offsets */
6532  _rastoffset[0][0] = _offset[0];
6533  _rastoffset[0][1] = _offset[1];
6534  _rastoffset[1][0] = _offset[2];
6535  _rastoffset[1][1] = _offset[3];
6536 
6537  /* get output raster dimensions */
6538  dim[0] = rt_raster_get_width(raster);
6539  dim[1] = rt_raster_get_height(raster);
6540 
6541  i = 2;
6542  /* handle special cases for extent */
6543  switch (extenttype) {
6544  case ET_FIRST:
6545  i = 0;
6546  /* fall through */
6547  case ET_SECOND:
6548  if (i > 1)
6549  i = 1;
6550 
6551  if (
6552  _isempty[i] && (
6553  (extenttype == ET_FIRST && i == 0) ||
6554  (extenttype == ET_SECOND && i == 1)
6555  )
6556  ) {
6557  elog(NOTICE, "The %s raster is NULL. Returning NULL", (i != 1 ? "FIRST" : "SECOND"));
6558  for (k = 0; k < set_count; k++) {
6559  if (_rast[k] != NULL)
6560  rt_raster_destroy(_rast[k]);
6561  if (pgrastpos[k] != -1)
6562  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6563  }
6565  PG_RETURN_NULL();
6566  }
6567 
6568  /* specified band not found */
6569  if (!rt_raster_has_band(_rast[i], bandindex[i] - 1)) {
6570  elog(NOTICE, "The %s raster does not have the band at index %d. Returning no band raster of correct extent",
6571  (i != 1 ? "FIRST" : "SECOND"), bandindex[i]
6572  );
6573 
6574  for (k = 0; k < set_count; k++) {
6575  if (_rast[k] != NULL)
6576  rt_raster_destroy(_rast[k]);
6577  if (pgrastpos[k] != -1)
6578  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6579  }
6580 
6581  pgrtn = rt_raster_serialize(raster);
6583  if (!pgrtn) PG_RETURN_NULL();
6584 
6585  SET_VARSIZE(pgrtn, pgrtn->size);
6586  PG_RETURN_POINTER(pgrtn);
6587  }
6588  break;
6589  case ET_UNION:
6590  break;
6591  case ET_INTERSECTION:
6592  /* no intersection */
6593  if (
6594  _isempty[0] || _isempty[1] ||
6595  !dim[0] || !dim[1]
6596  ) {
6597  elog(NOTICE, "The two rasters provided have no intersection. Returning no band raster");
6598 
6599  /* raster has dimension, replace with no band raster */
6600  if (dim[0] || dim[1]) {
6602 
6603  raster = rt_raster_new(0, 0);
6604  if (raster == NULL) {
6605  for (k = 0; k < set_count; k++) {
6606  if (_rast[k] != NULL)
6607  rt_raster_destroy(_rast[k]);
6608  if (pgrastpos[k] != -1)
6609  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6610  }
6611  elog(ERROR, "RASTER_mapAlgebra2: Could not create no band raster");
6612  PG_RETURN_NULL();
6613  }
6614 
6615  rt_raster_set_scale(raster, 0, 0);
6617  }
6618 
6619  for (k = 0; k < set_count; k++) {
6620  if (_rast[k] != NULL)
6621  rt_raster_destroy(_rast[k]);
6622  if (pgrastpos[k] != -1)
6623  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6624  }
6625 
6626  pgrtn = rt_raster_serialize(raster);
6628  if (!pgrtn) PG_RETURN_NULL();
6629 
6630  SET_VARSIZE(pgrtn, pgrtn->size);
6631  PG_RETURN_POINTER(pgrtn);
6632  }
6633  break;
6634  case ET_LAST:
6635  case ET_CUSTOM:
6636  for (k = 0; k < set_count; k++) {
6637  if (_rast[k] != NULL)
6638  rt_raster_destroy(_rast[k]);
6639  if (pgrastpos[k] != -1)
6640  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6641  }
6642  elog(ERROR, "RASTER_mapAlgebra2: ET_LAST and ET_CUSTOM are not implemented");
6643  PG_RETURN_NULL();
6644  break;
6645  }
6646 
6647  /* both rasters do not have specified bands */
6648  if (
6649  (!_isempty[0] && !rt_raster_has_band(_rast[0], bandindex[0] - 1)) &&
6650  (!_isempty[1] && !rt_raster_has_band(_rast[1], bandindex[1] - 1))
6651  ) {
6652  elog(NOTICE, "The two rasters provided do not have the respectively specified band indices. Returning no band raster of correct extent");
6653 
6654  for (k = 0; k < set_count; k++) {
6655  if (_rast[k] != NULL)
6656  rt_raster_destroy(_rast[k]);
6657  if (pgrastpos[k] != -1)
6658  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6659  }
6660 
6661  pgrtn = rt_raster_serialize(raster);
6663  if (!pgrtn) PG_RETURN_NULL();
6664 
6665  SET_VARSIZE(pgrtn, pgrtn->size);
6666  PG_RETURN_POINTER(pgrtn);
6667  }
6668 
6669  /* get bands */
6670  for (i = 0; i < set_count; i++) {
6671  if (_isempty[i] || !rt_raster_has_band(_rast[i], bandindex[i] - 1)) {
6672  _hasnodata[i] = 1;
6673  _nodataval[i] = 0;
6674 
6675  continue;
6676  }
6677 
6678  _band[i] = rt_raster_get_band(_rast[i], bandindex[i] - 1);
6679  if (_band[i] == NULL) {
6680  for (k = 0; k < set_count; k++) {
6681  if (_rast[k] != NULL)
6682  rt_raster_destroy(_rast[k]);
6683  if (pgrastpos[k] != -1)
6684  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6685  }
6687  elog(ERROR, "RASTER_mapAlgebra2: Could not get band %d of the %s raster",
6688  bandindex[i],
6689  (i < 1 ? "FIRST" : "SECOND")
6690  );
6691  PG_RETURN_NULL();
6692  }
6693 
6694  _hasnodata[i] = rt_band_get_hasnodata_flag(_band[i]);
6695  if (_hasnodata[i])
6696  rt_band_get_nodata(_band[i], &(_nodataval[i]));
6697  }
6698 
6699  /* pixtype is PT_END, get pixtype based upon extent */
6700  if (pixtype == PT_END) {
6701  if ((extenttype == ET_SECOND && !_isempty[1]) || _isempty[0])
6702  pixtype = rt_band_get_pixtype(_band[1]);
6703  else
6704  pixtype = rt_band_get_pixtype(_band[0]);
6705  }
6706 
6707  /* nodata value for new band */
6708  if (extenttype == ET_SECOND && !_isempty[1] && _hasnodata[1]) {
6709  nodataval = _nodataval[1];
6710  }
6711  else if (!_isempty[0] && _hasnodata[0]) {
6712  nodataval = _nodataval[0];
6713  }
6714  else if (!_isempty[1] && _hasnodata[1]) {
6715  nodataval = _nodataval[1];
6716  }
6717  else {
6718  elog(NOTICE, "Neither raster provided has a NODATA value for the specified band indices. NODATA value set to minimum possible for %s", rt_pixtype_name(pixtype));
6719  nodataval = rt_pixtype_get_min_value(pixtype);
6720  }
6721 
6722  /* add band to output raster */
6724  raster,
6725  pixtype,
6726  nodataval,
6727  1, nodataval,
6728  0
6729  ) < 0) {
6730  for (k = 0; k < set_count; k++) {
6731  if (_rast[k] != NULL)
6732  rt_raster_destroy(_rast[k]);
6733  if (pgrastpos[k] != -1)
6734  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6735  }
6737  elog(ERROR, "RASTER_mapAlgebra2: Could not add new band to output raster");
6738  PG_RETURN_NULL();
6739  }
6740 
6741  /* get output band */
6743  if (band == NULL) {
6744  for (k = 0; k < set_count; k++) {
6745  if (_rast[k] != NULL)
6746  rt_raster_destroy(_rast[k]);
6747  if (pgrastpos[k] != -1)
6748  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6749  }
6751  elog(ERROR, "RASTER_mapAlgebra2: Could not get newly added band of output raster");
6752  PG_RETURN_NULL();
6753  }
6754 
6755  POSTGIS_RT_DEBUGF(4, "offsets = (%d, %d, %d, %d)",
6756  (int) _rastoffset[0][0],
6757  (int) _rastoffset[0][1],
6758  (int) _rastoffset[1][0],
6759  (int) _rastoffset[1][1]
6760  );
6761 
6762  POSTGIS_RT_DEBUGF(4, "metadata = (%f, %f, %d, %d, %f, %f, %f, %f, %d)",
6772  );
6773 
6774  /*
6775  determine who called this function
6776  Arg 4 will either be text or regprocedure
6777  */
6778  POSTGIS_RT_DEBUG(3, "checking parameter type for arg 4");
6779  calltype = get_fn_expr_argtype(fcinfo->flinfo, 4);
6780 
6781  switch(calltype) {
6782  case TEXTOID: {
6783  POSTGIS_RT_DEBUG(3, "arg 4 is \"expression\"!");
6784 
6785  /* connect SPI */
6786  if (SPI_connect() != SPI_OK_CONNECT) {
6787  for (k = 0; k < set_count; k++) {
6788  if (_rast[k] != NULL)
6789  rt_raster_destroy(_rast[k]);
6790  if (pgrastpos[k] != -1)
6791  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6792  }
6794  elog(ERROR, "RASTER_mapAlgebra2: Could not connect to the SPI manager");
6795  PG_RETURN_NULL();
6796  }
6797 
6798  /* reset hasargval */
6799  memset(hasargval, 0, sizeof(int) * spi_count);
6800 
6801  /*
6802  process expressions
6803 
6804  spi_exprpos elements are:
6805  4 - expression => spi_plan[0]
6806  7 - nodata1expr => spi_plan[1]
6807  8 - nodata2expr => spi_plan[2]
6808  */
6809  for (i = 0; i < spi_count; i++) {
6810  if (!PG_ARGISNULL(spi_exprpos[i])) {
6811  char *tmp = NULL;
6812  char place[5] = "$1";
6813  expr = text_to_cstring(PG_GETARG_TEXT_P(spi_exprpos[i]));
6814  POSTGIS_RT_DEBUGF(3, "raw expr #%d: %s", i, expr);
6815 
6816  for (j = 0, k = 1; j < ARGKWCOUNT; j++) {
6817  /* attempt to replace keyword with placeholder */
6818  len = 0;
6819  tmp = rtpg_strreplace(expr, argkw[j], place, &len);
6820  pfree(expr);
6821  expr = tmp;
6822 
6823  if (len) {
6824  spi_argcount[i]++;
6825  argpos[i][j] = k++;
6826 
6827  sprintf(place, "$%d", k);
6828  }
6829  else
6830  argpos[i][j] = 0;
6831  }
6832 
6833  len = strlen("SELECT (") + strlen(expr) + strlen(")::double precision");
6834  sql = (char *) palloc(len + 1);
6835  if (sql == NULL) {
6836 
6837  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6838  SPI_finish();
6839 
6840  for (k = 0; k < set_count; k++) {
6841  if (_rast[k] != NULL)
6842  rt_raster_destroy(_rast[k]);
6843  if (pgrastpos[k] != -1)
6844  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6845  }
6847 
6848  elog(ERROR, "RASTER_mapAlgebra2: Could not allocate memory for expression parameter %d", spi_exprpos[i]);
6849  PG_RETURN_NULL();
6850  }
6851 
6852  memcpy(sql, "SELECT (", strlen("SELECT ("));
6853  memcpy(sql + strlen("SELECT ("), expr, strlen(expr));
6854  memcpy(sql + strlen("SELECT (") + strlen(expr), ")::double precision", strlen(")::double precision"));
6855  sql[len] = '\0';
6856 
6857  POSTGIS_RT_DEBUGF(3, "sql #%d: %s", i, sql);
6858 
6859  /* create prepared plan */
6860  if (spi_argcount[i]) {
6861  argtype = (Oid *) palloc(spi_argcount[i] * sizeof(Oid));
6862  if (argtype == NULL) {
6863 
6864  pfree(sql);
6865  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6866  SPI_finish();
6867 
6868  for (k = 0; k < set_count; k++) {
6869  if (_rast[k] != NULL)
6870  rt_raster_destroy(_rast[k]);
6871  if (pgrastpos[k] != -1)
6872  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6873  }
6875 
6876  elog(ERROR, "RASTER_mapAlgebra2: Could not allocate memory for prepared plan argtypes of expression parameter %d", spi_exprpos[i]);
6877  PG_RETURN_NULL();
6878  }
6879 
6880  /* specify datatypes of parameters */
6881  for (j = 0, k = 0; j < ARGKWCOUNT; j++) {
6882  if (argpos[i][j] < 1) continue;
6883 
6884  /* positions are INT4 */
6885  if (
6886  (strstr(argkw[j], "[rast1.x]") != NULL) ||
6887  (strstr(argkw[j], "[rast1.y]") != NULL) ||
6888  (strstr(argkw[j], "[rast2.x]") != NULL) ||
6889  (strstr(argkw[j], "[rast2.y]") != NULL)
6890  ) {
6891  argtype[k] = INT4OID;
6892  }
6893  /* everything else is FLOAT8 */
6894  else {
6895  argtype[k] = FLOAT8OID;
6896  }
6897 
6898  k++;
6899  }
6900 
6901  spi_plan[i] = SPI_prepare(sql, spi_argcount[i], argtype);
6902  pfree(argtype);
6903 
6904  if (spi_plan[i] == NULL) {
6905 
6906  pfree(sql);
6907  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6908  SPI_finish();
6909 
6910  for (k = 0; k < set_count; k++) {
6911  if (_rast[k] != NULL)
6912  rt_raster_destroy(_rast[k]);
6913  if (pgrastpos[k] != -1)
6914  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6915  }
6917 
6918  elog(ERROR, "RASTER_mapAlgebra2: Could not create prepared plan of expression parameter %d", spi_exprpos[i]);
6919  PG_RETURN_NULL();
6920  }
6921  }
6922  /* no args, just execute query */
6923  else {
6924  err = SPI_execute(sql, TRUE, 0);
6925  if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
6926 
6927  pfree(sql);
6928  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6929  SPI_finish();
6930 
6931  for (k = 0; k < set_count; k++) {
6932  if (_rast[k] != NULL)
6933  rt_raster_destroy(_rast[k]);
6934  if (pgrastpos[k] != -1)
6935  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6936  }
6938 
6939  elog(ERROR, "RASTER_mapAlgebra2: Could not evaluate expression parameter %d", spi_exprpos[i]);
6940  PG_RETURN_NULL();
6941  }
6942 
6943  /* get output of prepared plan */
6944  tupdesc = SPI_tuptable->tupdesc;
6945  tuptable = SPI_tuptable;
6946  tuple = tuptable->vals[0];
6947 
6948  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
6949  if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
6950 
6951  pfree(sql);
6952  if (SPI_tuptable) SPI_freetuptable(tuptable);
6953  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6954  SPI_finish();
6955 
6956  for (k = 0; k < set_count; k++) {
6957  if (_rast[k] != NULL)
6958  rt_raster_destroy(_rast[k]);
6959  if (pgrastpos[k] != -1)
6960  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6961  }
6963 
6964  elog(ERROR, "RASTER_mapAlgebra2: Could not get result of expression parameter %d", spi_exprpos[i]);
6965  PG_RETURN_NULL();
6966  }
6967 
6968  if (!isnull) {
6969  hasargval[i] = 1;
6970  argval[i] = DatumGetFloat8(datum);
6971  }
6972 
6973  if (SPI_tuptable) SPI_freetuptable(tuptable);
6974  }
6975 
6976  pfree(sql);
6977  }
6978  else
6979  spi_empty++;
6980  }
6981 
6982  /* nodatanodataval */
6983  if (!PG_ARGISNULL(9)) {
6984  hasnodatanodataval = 1;
6985  nodatanodataval = PG_GETARG_FLOAT8(9);
6986  }
6987  else
6988  hasnodatanodataval = 0;
6989  break;
6990  }
6991  case REGPROCEDUREOID: {
6992  POSTGIS_RT_DEBUG(3, "arg 4 is \"userfunction\"!");
6993  if (!PG_ARGISNULL(4)) {
6994 
6995  ufc_nullcount = 0;
6996  ufc_noid = PG_GETARG_OID(4);
6997 
6998  /* get function info */
6999  fmgr_info(ufc_noid, &ufl_info);
7000 
7001  /* function cannot return set */
7002  err = 0;
7003  if (ufl_info.fn_retset) {
7004  err = 1;
7005  }
7006  /* function should have correct # of args */
7007  else if (ufl_info.fn_nargs < 3 || ufl_info.fn_nargs > 4) {
7008  err = 2;
7009  }
7010 
7011  /*
7012  TODO: consider adding checks of the userfunction parameters
7013  should be able to use get_fn_expr_argtype() of fmgr.c
7014  */
7015 
7016  if (err > 0) {
7017  for (k = 0; k < set_count; k++) {
7018  if (_rast[k] != NULL)
7019  rt_raster_destroy(_rast[k]);
7020  if (pgrastpos[k] != -1)
7021  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7022  }
7024 
7025  if (err > 1)
7026  elog(ERROR, "RASTER_mapAlgebra2: Function provided must have three or four input parameters");
7027  else
7028  elog(ERROR, "RASTER_mapAlgebra2: Function provided must return double precision not resultset");
7029  PG_RETURN_NULL();
7030  }
7031 
7032  if (func_volatile(ufc_noid) == 'v') {
7033  elog(NOTICE, "Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
7034  }
7035 
7036  /* prep function call data */
7037  InitFunctionCallInfoData(
7038  *ufc_info, &ufl_info, ufl_info.fn_nargs, InvalidOid, NULL, NULL);
7039  ufc_info->args[0].isnull = FALSE;
7040  ufc_info->args[1].isnull = FALSE;
7041  ufc_info->args[2].isnull = FALSE;
7042  if (ufl_info.fn_nargs == 4)
7043  ufc_info->args[3].isnull = FALSE;
7044 
7045  if (ufl_info.fn_nargs != 4)
7046  k = 2;
7047  else
7048  k = 3;
7049  if (!PG_ARGISNULL(7))
7050  {
7051  ufc_info->args[k].value = PG_GETARG_DATUM(7);
7052  }
7053  else
7054  {
7055  ufc_info->args[k].value = (Datum)NULL;
7056  ufc_info->args[k].isnull = TRUE;
7057  ufc_nullcount++;
7058  }
7059  }
7060  break;
7061  }
7062  default:
7063  for (k = 0; k < set_count; k++) {
7064  if (_rast[k] != NULL)
7065  rt_raster_destroy(_rast[k]);
7066  if (pgrastpos[k] != -1)
7067  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7068  }
7070  elog(ERROR, "RASTER_mapAlgebra2: Invalid data type for expression or userfunction");
7071  PG_RETURN_NULL();
7072  break;
7073  }
7074 
7075  /* loop over pixels */
7076  /* if any expression present, run */
7077  if ((
7078  (calltype == TEXTOID) && (
7079  (spi_empty != spi_count) || hasnodatanodataval
7080  )
7081  ) || (
7082  (calltype == REGPROCEDUREOID) && (ufc_noid != InvalidOid)
7083  )) {
7084  for (x = 0; x < dim[0]; x++) {
7085  for (y = 0; y < dim[1]; y++) {
7086 
7087  /* get pixel from each raster */
7088  for (i = 0; i < set_count; i++) {
7089  _haspixel[i] = 0;
7090  _pixel[i] = 0;
7091 
7092  /* row/column */
7093  _x = (int)x - (int)_rastoffset[i][0];
7094  _y = (int)y - (int)_rastoffset[i][1];
7095 
7096  /* store _x and _y in 1-based */
7097  _pos[i][0] = _x + 1;
7098  _pos[i][1] = _y + 1;
7099 
7100  /* get pixel value */
7101  if (_band[i] == NULL) {
7102  if (!_hasnodata[i]) {
7103  _haspixel[i] = 1;
7104  _pixel[i] = _nodataval[i];
7105  }
7106  }
7107  else if (
7108  !_isempty[i] &&
7109  (_x >= 0 && _x < _dim[i][0]) &&
7110  (_y >= 0 && _y < _dim[i][1])
7111  ) {
7112  err = rt_band_get_pixel(_band[i], _x, _y, &(_pixel[i]), &isnodata);
7113  if (err != ES_NONE) {
7114 
7115  if (calltype == TEXTOID) {
7116  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7117  SPI_finish();
7118  }
7119 
7120  for (k = 0; k < set_count; k++) {
7121  if (_rast[k] != NULL)
7122  rt_raster_destroy(_rast[k]);
7123  if (pgrastpos[k] != -1)
7124  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7125  }
7127 
7128  elog(ERROR, "RASTER_mapAlgebra2: Could not get pixel of %s raster", (i < 1 ? "FIRST" : "SECOND"));
7129  PG_RETURN_NULL();
7130  }
7131 
7132  if (!_hasnodata[i] || !isnodata)
7133  _haspixel[i] = 1;
7134  }
7135 
7136  POSTGIS_RT_DEBUGF(5, "pixel r%d(%d, %d) = %d, %f",
7137  i,
7138  _x, _y,
7139  _haspixel[i],
7140  _pixel[i]
7141  );
7142  }
7143 
7144  haspixel = 0;
7145 
7146  switch (calltype) {
7147  case TEXTOID: {
7148  /* which prepared plan to use? */
7149  /* !pixel0 && !pixel1 */
7150  /* use nodatanodataval */
7151  if (!_haspixel[0] && !_haspixel[1])
7152  i = 3;
7153  /* pixel0 && !pixel1 */
7154  /* run spi_plan[2] (nodata2expr) */
7155  else if (_haspixel[0] && !_haspixel[1])
7156  i = 2;
7157  /* !pixel0 && pixel1 */
7158  /* run spi_plan[1] (nodata1expr) */
7159  else if (!_haspixel[0] && _haspixel[1])
7160  i = 1;
7161  /* pixel0 && pixel1 */
7162  /* run spi_plan[0] (expression) */
7163  else
7164  i = 0;
7165 
7166  /* process values */
7167  if (i == 3) {
7168  if (hasnodatanodataval) {
7169  haspixel = 1;
7170  pixel = nodatanodataval;
7171  }
7172  }
7173  /* has an evaluated value */
7174  else if (hasargval[i]) {
7175  haspixel = 1;
7176  pixel = argval[i];
7177  }
7178  /* prepared plan exists */
7179  else if (spi_plan[i] != NULL) {
7180  POSTGIS_RT_DEBUGF(4, "Using prepared plan: %d", i);
7181 
7182  /* reset values to (Datum) NULL */
7183  memset(values, (Datum) NULL, sizeof(Datum) * ARGKWCOUNT);
7184  /* reset nulls to FALSE */
7185  memset(nulls, FALSE, sizeof(char) * ARGKWCOUNT);
7186 
7187  /* expression has argument(s) */
7188  if (spi_argcount[i]) {
7189  /* set values and nulls */
7190  for (j = 0; j < ARGKWCOUNT; j++) {
7191  idx = argpos[i][j];
7192  if (idx < 1) continue;
7193  idx--; /* 1-based becomes 0-based */
7194 
7195  if (strstr(argkw[j], "[rast1.x]") != NULL) {
7196  values[idx] = _pos[0][0];
7197  }
7198  else if (strstr(argkw[j], "[rast1.y]") != NULL) {
7199  values[idx] = _pos[0][1];
7200  }
7201  else if (
7202  (strstr(argkw[j], "[rast1.val]") != NULL) ||
7203  (strstr(argkw[j], "[rast1]") != NULL)
7204  ) {
7205  if (_isempty[0] || !_haspixel[0])
7206  nulls[idx] = TRUE;
7207  else
7208  values[idx] = Float8GetDatum(_pixel[0]);
7209  }
7210  else if (strstr(argkw[j], "[rast2.x]") != NULL) {
7211  values[idx] = _pos[1][0];
7212  }
7213  else if (strstr(argkw[j], "[rast2.y]") != NULL) {
7214  values[idx] = _pos[1][1];
7215  }
7216  else if (
7217  (strstr(argkw[j], "[rast2.val]") != NULL) ||
7218  (strstr(argkw[j], "[rast2]") != NULL)
7219  ) {
7220  if (_isempty[1] || !_haspixel[1])
7221  nulls[idx] = TRUE;
7222  else
7223  values[idx] = Float8GetDatum(_pixel[1]);
7224  }
7225  }
7226  }
7227 
7228  /* run prepared plan */
7229  err = SPI_execute_plan(spi_plan[i], values, nulls, TRUE, 1);
7230  if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
7231 
7232  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7233  SPI_finish();
7234 
7235  for (k = 0; k < set_count; k++) {
7236  if (_rast[k] != NULL)
7237  rt_raster_destroy(_rast[k]);
7238  if (pgrastpos[k] != -1)
7239  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7240  }
7242 
7243  elog(ERROR, "RASTER_mapAlgebra2: Unexpected error when running prepared statement %d", i);
7244  PG_RETURN_NULL();
7245  }
7246 
7247  /* get output of prepared plan */
7248  tupdesc = SPI_tuptable->tupdesc;
7249  tuptable = SPI_tuptable;
7250  tuple = tuptable->vals[0];
7251 
7252  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
7253  if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
7254 
7255  if (SPI_tuptable) SPI_freetuptable(tuptable);
7256  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7257  SPI_finish();
7258 
7259  for (k = 0; k < set_count; k++) {
7260  if (_rast[k] != NULL)
7261  rt_raster_destroy(_rast[k]);
7262  if (pgrastpos[k] != -1)
7263  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7264  }
7266 
7267  elog(ERROR, "RASTER_mapAlgebra2: Could not get result of prepared statement %d", i);
7268  PG_RETURN_NULL();
7269  }
7270 
7271  if (!isnull) {
7272  haspixel = 1;
7273  pixel = DatumGetFloat8(datum);
7274  }
7275 
7276  if (SPI_tuptable) SPI_freetuptable(tuptable);
7277  }
7278  } break;
7279  case REGPROCEDUREOID: {
7280  Datum d[4];
7281  ArrayType *a;
7282 
7283  /* build fcnarg */
7284  for (i = 0; i < set_count; i++) {
7285  ufc_info->args[i].value = Float8GetDatum(_pixel[i]);
7286  if (_haspixel[i]) {
7287  ufc_info->args[i].isnull = FALSE;
7288  ufc_nullcount--;
7289  }
7290  else {
7291  ufc_info->args[i].isnull = TRUE;
7292  ufc_nullcount++;
7293  }
7294  }
7295 
7296  /* function is strict and null parameter is passed */
7297  /* http://archives.postgresql.org/pgsql-general/2011-11/msg00424.php */
7298  if (ufl_info.fn_strict && ufc_nullcount)
7299  break;
7300 
7301  /* 4 parameters, add position */
7302  if (ufl_info.fn_nargs == 4) {
7303  /* Datum of 4 element array */
7304  /* array is (x1, y1, x2, y2) */
7305  for (i = 0; i < set_count; i++) {
7306  if (i < 1) {
7307  d[0] = Int32GetDatum(_pos[i][0]);
7308  d[1] = Int32GetDatum(_pos[i][1]);
7309  }
7310  else {
7311  d[2] = Int32GetDatum(_pos[i][0]);
7312  d[3] = Int32GetDatum(_pos[i][1]);
7313  }
7314  }
7315 
7316  a = construct_array(d, 4, INT4OID, sizeof(int32), true, 'i');
7317  ufc_info->args[2].value = PointerGetDatum(a);
7318  ufc_info->args[2].isnull = FALSE;
7319  }
7320 
7321  datum = FunctionCallInvoke(ufc_info);
7322 
7323  /* result is not null*/
7324  if (!ufc_info->isnull)
7325  {
7326  haspixel = 1;
7327  pixel = DatumGetFloat8(datum);
7328  }
7329  } break;
7330  }
7331 
7332  /* burn pixel if haspixel != 0 */
7333  if (haspixel) {
7334  if (rt_band_set_pixel(band, x, y, pixel, NULL) != ES_NONE) {
7335 
7336  if (calltype == TEXTOID) {
7337  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7338  SPI_finish();
7339  }
7340 
7341  for (k = 0; k < set_count; k++) {
7342  if (_rast[k] != NULL)
7343  rt_raster_destroy(_rast[k]);
7344  if (pgrastpos[k] != -1)
7345  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7346  }
7348 
7349  elog(ERROR, "RASTER_mapAlgebra2: Could not set pixel value of output raster");
7350  PG_RETURN_NULL();
7351  }
7352  }
7353 
7354  POSTGIS_RT_DEBUGF(5, "(x, y, val) = (%d, %d, %f)", x, y, haspixel ? pixel : nodataval);
7355 
7356  } /* y: height */
7357  } /* x: width */
7358  }
7359 
7360  /* CLEANUP */
7361  if (calltype == TEXTOID) {
7362  for (i = 0; i < spi_count; i++) {
7363  if (spi_plan[i] != NULL) SPI_freeplan(spi_plan[i]);
7364  }
7365  SPI_finish();
7366  }
7367 
7368  for (k = 0; k < set_count; k++) {
7369  if (_rast[k] != NULL)
7370  rt_raster_destroy(_rast[k]);
7371  if (pgrastpos[k] != -1)
7372  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7373  }
7374 
7375  pgrtn = rt_raster_serialize(raster);
7377  if (!pgrtn) PG_RETURN_NULL();
7378 
7379  POSTGIS_RT_DEBUG(3, "Finished RASTER_mapAlgebra2");
7380 
7381  SET_VARSIZE(pgrtn, pgrtn->size);
7382  PG_RETURN_POINTER(pgrtn);
7383 }
#define TRUE
Definition: dbfopen.c:73
#define FALSE
Definition: dbfopen.c:72
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_raster.c:360
double rt_raster_get_x_skew(rt_raster raster)
Get skew about the X axis.
Definition: rt_raster.c:185
double rt_raster_get_x_offset(rt_raster raster)
Get raster x offset, in projection units.
Definition: rt_raster.c:217
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:489
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
Definition: rt_raster.c:609
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
Definition: rt_raster.c:141
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:825
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
Definition: rt_pixel.c:80
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1527
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:86
rt_pixtype
Definition: librtcore.h:187
@ PT_END
Definition: librtcore.h:199
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_raster.c:52
rt_extenttype rt_util_extent_type(const char *name)
Definition: rt_util.c:204
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition: rt_pixel.c:150
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:1253
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
double rt_raster_get_x_scale(rt_raster raster)
Get scale X in projection units.
Definition: rt_raster.c:154
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
Definition: rt_band.c:1125
@ ES_NONE
Definition: librtcore.h:182
uint16_t rt_raster_get_height(rt_raster raster)
Definition: rt_raster.c:133
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition: rt_raster.c:367
rt_extenttype
Definition: librtcore.h:202
@ ET_CUSTOM
Definition: librtcore.h:208
@ ET_LAST
Definition: librtcore.h:207
@ ET_INTERSECTION
Definition: librtcore.h:203
@ ET_UNION
Definition: librtcore.h:204
@ ET_SECOND
Definition: librtcore.h:206
@ ET_FIRST
Definition: librtcore.h:205
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:2038
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:782
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_pixel.c:110
uint16_t rt_raster_get_width(rt_raster raster)
Definition: rt_raster.c:125
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:3348
double rt_raster_get_y_scale(rt_raster raster)
Get scale Y in projection units.
Definition: rt_raster.c:163
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
double rt_raster_get_y_skew(rt_raster raster)
Get skew about the Y axis.
Definition: rt_raster.c:194
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_raster.c:588
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:725
double rt_raster_get_y_offset(rt_raster raster)
Get raster y offset, in projection units.
Definition: rt_raster.c:226
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_raster.c:1240
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:385
band
Definition: ovdump.py:58
pixel
Definition: pixval.py:92
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
gt
Definition: window.py:78
char * rtpg_strtoupper(char *str)
char * rtpg_trim(const char *input)
char * rtpg_strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
Definition: rtpg_internal.c:55
#define ARGKWCOUNT
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:65
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:69
unsigned int int32
Definition: shpopen.c:54
Struct definitions.
Definition: librtcore.h:2440

References ARGKWCOUNT, ovdump::band, ES_NONE, ET_CUSTOM, ET_FIRST, ET_INTERSECTION, ET_LAST, ET_SECOND, ET_UNION, FALSE, window::gt, pixval::pixel, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, PT_END, rtpixdump::rast, rtrowdump::raster, rt_band_get_hasnodata_flag(), rt_band_get_nodata(), rt_band_get_pixel(), rt_band_get_pixtype(), rt_band_set_pixel(), rt_pixtype_get_min_value(), rt_pixtype_index_from_name(), rt_pixtype_name(), 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_srid(), rt_raster_get_width(), rt_raster_get_x_offset(), rt_raster_get_x_scale(), rt_raster_get_x_skew(), rt_raster_get_y_offset(), rt_raster_get_y_scale(), rt_raster_get_y_skew(), rt_raster_has_band(), rt_raster_is_empty(), rt_raster_new(), rt_raster_same_alignment(), rt_raster_serialize(), rt_raster_set_geotransform_matrix(), rt_raster_set_scale(), rt_raster_set_srid(), rt_util_extent_type(), rtpg_strreplace(), rtpg_strtoupper(), rtpg_trim(), rt_raster_serialized_t::size, rtgdalraster::sql, TRUE, pixval::x, and pixval::y.

Here is the call graph for this function: