PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ RASTER_mapAlgebra2()

Datum RASTER_mapAlgebra2 ( PG_FUNCTION_ARGS  )

Definition at line 6085 of file rtpg_mapalgebra.c.

6086 {
6087  const uint32_t set_count = 2;
6088  rt_pgraster *pgrast[2] = { NULL, NULL };
6089  int pgrastpos[2] = {-1, -1};
6090  rt_pgraster *pgrtn;
6091  rt_raster rast[2] = {NULL};
6092  int _isempty[2] = {0};
6093  uint32_t bandindex[2] = {0};
6094  rt_raster _rast[2] = {NULL};
6095  rt_band _band[2] = {NULL};
6096  int _hasnodata[2] = {0};
6097  double _nodataval[2] = {0};
6098  double _offset[4] = {0.};
6099  double _rastoffset[2][4] = {{0.}};
6100  int _haspixel[2] = {0};
6101  double _pixel[2] = {0};
6102  int _pos[2][2] = {{0}};
6103  uint16_t _dim[2][2] = {{0}};
6104 
6105  char *pixtypename = NULL;
6106  rt_pixtype pixtype = PT_END;
6107  char *extenttypename = NULL;
6108  rt_extenttype extenttype = ET_INTERSECTION;
6109 
6110  rt_raster raster = NULL;
6111  rt_band band = NULL;
6112  uint16_t dim[2] = {0};
6113  int haspixel = 0;
6114  double pixel = 0.;
6115  double nodataval = 0;
6116  double gt[6] = {0.};
6117 
6118  Oid calltype = InvalidOid;
6119 
6120  const uint32_t spi_count = 3;
6121  uint16_t spi_exprpos[3] = {4, 7, 8};
6122  uint32_t spi_argcount[3] = {0};
6123  char *expr = NULL;
6124  char *sql = NULL;
6125  SPIPlanPtr spi_plan[3] = {NULL};
6126  uint16_t spi_empty = 0;
6127  Oid *argtype = NULL;
6128  uint8_t argpos[3][8] = {{0}};
6129  char *argkw[] = {"[rast1.x]", "[rast1.y]", "[rast1.val]", "[rast1]", "[rast2.x]", "[rast2.y]", "[rast2.val]", "[rast2]"};
6130  Datum values[ARGKWCOUNT];
6131  char nulls[ARGKWCOUNT];
6132  TupleDesc tupdesc;
6133  SPITupleTable *tuptable = NULL;
6134  HeapTuple tuple;
6135  Datum datum;
6136  bool isnull = FALSE;
6137  int hasargval[3] = {0};
6138  double argval[3] = {0.};
6139  int hasnodatanodataval = 0;
6140  double nodatanodataval = 0;
6141  int isnodata = 0;
6142 
6143  Oid ufc_noid = InvalidOid;
6144  FmgrInfo ufl_info;
6145  LOCAL_FCINFO(ufc_info, FUNC_MAX_ARGS); /* Could be optimized */
6146 
6147  int ufc_nullcount = 0;
6148 
6149  int idx = 0;
6150  uint32_t i = 0;
6151  uint32_t j = 0;
6152  uint32_t k = 0;
6153  uint32_t x = 0;
6154  uint32_t y = 0;
6155  int _x = 0;
6156  int _y = 0;
6157  int err;
6158  int aligned = 0;
6159  int len = 0;
6160 
6161  POSTGIS_RT_DEBUG(3, "Starting RASTER_mapAlgebra2");
6162 
6163  for (i = 0, j = 0; i < set_count; i++) {
6164  if (!PG_ARGISNULL(j)) {
6165  pgrast[i] = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
6166  pgrastpos[i] = j;
6167  j++;
6168 
6169  /* raster */
6170  rast[i] = rt_raster_deserialize(pgrast[i], FALSE);
6171  if (!rast[i]) {
6172  for (k = 0; k <= i; k++) {
6173  if (k < i && rast[k] != NULL)
6174  rt_raster_destroy(rast[k]);
6175  if (pgrastpos[k] != -1)
6176  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6177  }
6178  elog(ERROR, "RASTER_mapAlgebra2: Could not deserialize the %s raster", i < 1 ? "first" : "second");
6179  PG_RETURN_NULL();
6180  }
6181 
6182  /* empty */
6183  _isempty[i] = rt_raster_is_empty(rast[i]);
6184 
6185  /* band index */
6186  if (!PG_ARGISNULL(j)) {
6187  bandindex[i] = PG_GETARG_INT32(j);
6188  }
6189  j++;
6190  }
6191  else {
6192  _isempty[i] = 1;
6193  j += 2;
6194  }
6195 
6196  POSTGIS_RT_DEBUGF(3, "_isempty[%d] = %d", i, _isempty[i]);
6197  }
6198 
6199  /* both rasters are NULL */
6200  if (rast[0] == NULL && rast[1] == NULL) {
6201  elog(NOTICE, "The two rasters provided are NULL. Returning NULL");
6202  for (k = 0; k < set_count; k++) {
6203  if (pgrastpos[k] != -1)
6204  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6205  }
6206  PG_RETURN_NULL();
6207  }
6208 
6209  /* both rasters are empty */
6210  if (_isempty[0] && _isempty[1]) {
6211  elog(NOTICE, "The two rasters provided are empty. Returning empty raster");
6212 
6213  raster = rt_raster_new(0, 0);
6214  if (raster == NULL) {
6215  for (k = 0; k < set_count; k++) {
6216  if (rast[k] != NULL)
6217  rt_raster_destroy(rast[k]);
6218  if (pgrastpos[k] != -1)
6219  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6220  }
6221  elog(ERROR, "RASTER_mapAlgebra2: Could not create empty raster");
6222  PG_RETURN_NULL();
6223  }
6224  rt_raster_set_scale(raster, 0, 0);
6225 
6226  pgrtn = rt_raster_serialize(raster);
6228  if (!pgrtn)
6229  PG_RETURN_NULL();
6230 
6231  SET_VARSIZE(pgrtn, pgrtn->size);
6232  PG_RETURN_POINTER(pgrtn);
6233  }
6234 
6235  /* replace the empty or NULL raster with one matching the other */
6236  if (
6237  (rast[0] == NULL || _isempty[0]) ||
6238  (rast[1] == NULL || _isempty[1])
6239  ) {
6240  /* first raster is empty */
6241  if (rast[0] == NULL || _isempty[0]) {
6242  i = 0;
6243  j = 1;
6244  }
6245  /* second raster is empty */
6246  else {
6247  i = 1;
6248  j = 0;
6249  }
6250 
6251  _rast[j] = rast[j];
6252 
6253  /* raster is empty, destroy it */
6254  if (_rast[i] != NULL)
6255  rt_raster_destroy(_rast[i]);
6256 
6257  _dim[i][0] = rt_raster_get_width(_rast[j]);
6258  _dim[i][1] = rt_raster_get_height(_rast[j]);
6259  _dim[j][0] = rt_raster_get_width(_rast[j]);
6260  _dim[j][1] = rt_raster_get_height(_rast[j]);
6261 
6262  _rast[i] = rt_raster_new(
6263  _dim[j][0],
6264  _dim[j][1]
6265  );
6266  if (_rast[i] == NULL) {
6267  rt_raster_destroy(_rast[j]);
6268  for (k = 0; k < set_count; k++) {
6269  if (pgrastpos[k] != -1)
6270  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6271  }
6272  elog(ERROR, "RASTER_mapAlgebra2: Could not create NODATA raster");
6273  PG_RETURN_NULL();
6274  }
6275  rt_raster_set_srid(_rast[i], rt_raster_get_srid(_rast[j]));
6276 
6279  }
6280  else {
6281  _rast[0] = rast[0];
6282  _dim[0][0] = rt_raster_get_width(_rast[0]);
6283  _dim[0][1] = rt_raster_get_height(_rast[0]);
6284 
6285  _rast[1] = rast[1];
6286  _dim[1][0] = rt_raster_get_width(_rast[1]);
6287  _dim[1][1] = rt_raster_get_height(_rast[1]);
6288  }
6289 
6290  /* SRID must match */
6291  /*
6292  if (rt_raster_get_srid(_rast[0]) != rt_raster_get_srid(_rast[1])) {
6293  elog(NOTICE, "The two rasters provided have different SRIDs. Returning NULL");
6294  for (k = 0; k < set_count; k++) {
6295  if (_rast[k] != NULL)
6296  rt_raster_destroy(_rast[k]);
6297  if (pgrastpos[k] != -1)
6298  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6299  }
6300  PG_RETURN_NULL();
6301  }
6302  */
6303 
6304  /* same alignment */
6305  if (rt_raster_same_alignment(_rast[0], _rast[1], &aligned, NULL) != ES_NONE) {
6306  for (k = 0; k < set_count; k++) {
6307  if (_rast[k] != NULL)
6308  rt_raster_destroy(_rast[k]);
6309  if (pgrastpos[k] != -1)
6310  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6311  }
6312  elog(ERROR, "RASTER_mapAlgebra2: Could not test for alignment on the two rasters");
6313  PG_RETURN_NULL();
6314  }
6315  if (!aligned) {
6316  elog(NOTICE, "The two rasters provided do not have the same alignment. Returning NULL");
6317  for (k = 0; k < set_count; k++) {
6318  if (_rast[k] != NULL)
6319  rt_raster_destroy(_rast[k]);
6320  if (pgrastpos[k] != -1)
6321  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6322  }
6323  PG_RETURN_NULL();
6324  }
6325 
6326  /* pixel type */
6327  if (!PG_ARGISNULL(5)) {
6328  pixtypename = text_to_cstring(PG_GETARG_TEXT_P(5));
6329  /* Get the pixel type index */
6330  pixtype = rt_pixtype_index_from_name(pixtypename);
6331  if (pixtype == PT_END ) {
6332  for (k = 0; k < set_count; k++) {
6333  if (_rast[k] != NULL)
6334  rt_raster_destroy(_rast[k]);
6335  if (pgrastpos[k] != -1)
6336  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6337  }
6338  elog(ERROR, "RASTER_mapAlgebra2: Invalid pixel type: %s", pixtypename);
6339  PG_RETURN_NULL();
6340  }
6341  }
6342 
6343  /* extent type */
6344  if (!PG_ARGISNULL(6)) {
6345  extenttypename = rtpg_strtoupper(rtpg_trim(text_to_cstring(PG_GETARG_TEXT_P(6))));
6346  extenttype = rt_util_extent_type(extenttypename);
6347  }
6348  POSTGIS_RT_DEBUGF(3, "extenttype: %d %s", extenttype, extenttypename);
6349 
6350  /* computed raster from extent type */
6352  _rast[0], _rast[1],
6353  extenttype,
6354  &raster, _offset
6355  );
6356  if (err != ES_NONE) {
6357  for (k = 0; k < set_count; k++) {
6358  if (_rast[k] != NULL)
6359  rt_raster_destroy(_rast[k]);
6360  if (pgrastpos[k] != -1)
6361  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6362  }
6363  elog(ERROR, "RASTER_mapAlgebra2: Could not get output raster of correct extent");
6364  PG_RETURN_NULL();
6365  }
6366 
6367  /* copy offsets */
6368  _rastoffset[0][0] = _offset[0];
6369  _rastoffset[0][1] = _offset[1];
6370  _rastoffset[1][0] = _offset[2];
6371  _rastoffset[1][1] = _offset[3];
6372 
6373  /* get output raster dimensions */
6374  dim[0] = rt_raster_get_width(raster);
6375  dim[1] = rt_raster_get_height(raster);
6376 
6377  i = 2;
6378  /* handle special cases for extent */
6379  switch (extenttype) {
6380  case ET_FIRST:
6381  i = 0;
6382  /* fall through */
6383  case ET_SECOND:
6384  if (i > 1)
6385  i = 1;
6386 
6387  if (
6388  _isempty[i] && (
6389  (extenttype == ET_FIRST && i == 0) ||
6390  (extenttype == ET_SECOND && i == 1)
6391  )
6392  ) {
6393  elog(NOTICE, "The %s raster is NULL. Returning NULL", (i != 1 ? "FIRST" : "SECOND"));
6394  for (k = 0; k < set_count; k++) {
6395  if (_rast[k] != NULL)
6396  rt_raster_destroy(_rast[k]);
6397  if (pgrastpos[k] != -1)
6398  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6399  }
6401  PG_RETURN_NULL();
6402  }
6403 
6404  /* specified band not found */
6405  if (!rt_raster_has_band(_rast[i], bandindex[i] - 1)) {
6406  elog(NOTICE, "The %s raster does not have the band at index %d. Returning no band raster of correct extent",
6407  (i != 1 ? "FIRST" : "SECOND"), bandindex[i]
6408  );
6409 
6410  for (k = 0; k < set_count; k++) {
6411  if (_rast[k] != NULL)
6412  rt_raster_destroy(_rast[k]);
6413  if (pgrastpos[k] != -1)
6414  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6415  }
6416 
6417  pgrtn = rt_raster_serialize(raster);
6419  if (!pgrtn) PG_RETURN_NULL();
6420 
6421  SET_VARSIZE(pgrtn, pgrtn->size);
6422  PG_RETURN_POINTER(pgrtn);
6423  }
6424  break;
6425  case ET_UNION:
6426  break;
6427  case ET_INTERSECTION:
6428  /* no intersection */
6429  if (
6430  _isempty[0] || _isempty[1] ||
6431  !dim[0] || !dim[1]
6432  ) {
6433  elog(NOTICE, "The two rasters provided have no intersection. Returning no band raster");
6434 
6435  /* raster has dimension, replace with no band raster */
6436  if (dim[0] || dim[1]) {
6438 
6439  raster = rt_raster_new(0, 0);
6440  if (raster == NULL) {
6441  for (k = 0; k < set_count; k++) {
6442  if (_rast[k] != NULL)
6443  rt_raster_destroy(_rast[k]);
6444  if (pgrastpos[k] != -1)
6445  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6446  }
6447  elog(ERROR, "RASTER_mapAlgebra2: Could not create no band raster");
6448  PG_RETURN_NULL();
6449  }
6450 
6451  rt_raster_set_scale(raster, 0, 0);
6453  }
6454 
6455  for (k = 0; k < set_count; k++) {
6456  if (_rast[k] != NULL)
6457  rt_raster_destroy(_rast[k]);
6458  if (pgrastpos[k] != -1)
6459  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6460  }
6461 
6462  pgrtn = rt_raster_serialize(raster);
6464  if (!pgrtn) PG_RETURN_NULL();
6465 
6466  SET_VARSIZE(pgrtn, pgrtn->size);
6467  PG_RETURN_POINTER(pgrtn);
6468  }
6469  break;
6470  case ET_LAST:
6471  case ET_CUSTOM:
6472  for (k = 0; k < set_count; k++) {
6473  if (_rast[k] != NULL)
6474  rt_raster_destroy(_rast[k]);
6475  if (pgrastpos[k] != -1)
6476  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6477  }
6478  elog(ERROR, "RASTER_mapAlgebra2: ET_LAST and ET_CUSTOM are not implemented");
6479  PG_RETURN_NULL();
6480  break;
6481  }
6482 
6483  /* both rasters do not have specified bands */
6484  if (
6485  (!_isempty[0] && !rt_raster_has_band(_rast[0], bandindex[0] - 1)) &&
6486  (!_isempty[1] && !rt_raster_has_band(_rast[1], bandindex[1] - 1))
6487  ) {
6488  elog(NOTICE, "The two rasters provided do not have the respectively specified band indices. Returning no band raster of correct extent");
6489 
6490  for (k = 0; k < set_count; k++) {
6491  if (_rast[k] != NULL)
6492  rt_raster_destroy(_rast[k]);
6493  if (pgrastpos[k] != -1)
6494  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6495  }
6496 
6497  pgrtn = rt_raster_serialize(raster);
6499  if (!pgrtn) PG_RETURN_NULL();
6500 
6501  SET_VARSIZE(pgrtn, pgrtn->size);
6502  PG_RETURN_POINTER(pgrtn);
6503  }
6504 
6505  /* get bands */
6506  for (i = 0; i < set_count; i++) {
6507  if (_isempty[i] || !rt_raster_has_band(_rast[i], bandindex[i] - 1)) {
6508  _hasnodata[i] = 1;
6509  _nodataval[i] = 0;
6510 
6511  continue;
6512  }
6513 
6514  _band[i] = rt_raster_get_band(_rast[i], bandindex[i] - 1);
6515  if (_band[i] == NULL) {
6516  for (k = 0; k < set_count; k++) {
6517  if (_rast[k] != NULL)
6518  rt_raster_destroy(_rast[k]);
6519  if (pgrastpos[k] != -1)
6520  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6521  }
6523  elog(ERROR, "RASTER_mapAlgebra2: Could not get band %d of the %s raster",
6524  bandindex[i],
6525  (i < 1 ? "FIRST" : "SECOND")
6526  );
6527  PG_RETURN_NULL();
6528  }
6529 
6530  _hasnodata[i] = rt_band_get_hasnodata_flag(_band[i]);
6531  if (_hasnodata[i])
6532  rt_band_get_nodata(_band[i], &(_nodataval[i]));
6533  }
6534 
6535  /* pixtype is PT_END, get pixtype based upon extent */
6536  if (pixtype == PT_END) {
6537  if ((extenttype == ET_SECOND && !_isempty[1]) || _isempty[0])
6538  pixtype = rt_band_get_pixtype(_band[1]);
6539  else
6540  pixtype = rt_band_get_pixtype(_band[0]);
6541  }
6542 
6543  /* nodata value for new band */
6544  if (extenttype == ET_SECOND && !_isempty[1] && _hasnodata[1]) {
6545  nodataval = _nodataval[1];
6546  }
6547  else if (!_isempty[0] && _hasnodata[0]) {
6548  nodataval = _nodataval[0];
6549  }
6550  else if (!_isempty[1] && _hasnodata[1]) {
6551  nodataval = _nodataval[1];
6552  }
6553  else {
6554  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));
6555  nodataval = rt_pixtype_get_min_value(pixtype);
6556  }
6557 
6558  /* add band to output raster */
6560  raster,
6561  pixtype,
6562  nodataval,
6563  1, nodataval,
6564  0
6565  ) < 0) {
6566  for (k = 0; k < set_count; k++) {
6567  if (_rast[k] != NULL)
6568  rt_raster_destroy(_rast[k]);
6569  if (pgrastpos[k] != -1)
6570  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6571  }
6573  elog(ERROR, "RASTER_mapAlgebra2: Could not add new band to output raster");
6574  PG_RETURN_NULL();
6575  }
6576 
6577  /* get output band */
6579  if (band == NULL) {
6580  for (k = 0; k < set_count; k++) {
6581  if (_rast[k] != NULL)
6582  rt_raster_destroy(_rast[k]);
6583  if (pgrastpos[k] != -1)
6584  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6585  }
6587  elog(ERROR, "RASTER_mapAlgebra2: Could not get newly added band of output raster");
6588  PG_RETURN_NULL();
6589  }
6590 
6591  POSTGIS_RT_DEBUGF(4, "offsets = (%d, %d, %d, %d)",
6592  (int) _rastoffset[0][0],
6593  (int) _rastoffset[0][1],
6594  (int) _rastoffset[1][0],
6595  (int) _rastoffset[1][1]
6596  );
6597 
6598  POSTGIS_RT_DEBUGF(4, "metadata = (%f, %f, %d, %d, %f, %f, %f, %f, %d)",
6608  );
6609 
6610  /*
6611  determine who called this function
6612  Arg 4 will either be text or regprocedure
6613  */
6614  POSTGIS_RT_DEBUG(3, "checking parameter type for arg 4");
6615  calltype = get_fn_expr_argtype(fcinfo->flinfo, 4);
6616 
6617  switch(calltype) {
6618  case TEXTOID: {
6619  POSTGIS_RT_DEBUG(3, "arg 4 is \"expression\"!");
6620 
6621  /* connect SPI */
6622  if (SPI_connect() != SPI_OK_CONNECT) {
6623  for (k = 0; k < set_count; k++) {
6624  if (_rast[k] != NULL)
6625  rt_raster_destroy(_rast[k]);
6626  if (pgrastpos[k] != -1)
6627  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6628  }
6630  elog(ERROR, "RASTER_mapAlgebra2: Could not connect to the SPI manager");
6631  PG_RETURN_NULL();
6632  }
6633 
6634  /* reset hasargval */
6635  memset(hasargval, 0, sizeof(int) * spi_count);
6636 
6637  /*
6638  process expressions
6639 
6640  spi_exprpos elements are:
6641  4 - expression => spi_plan[0]
6642  7 - nodata1expr => spi_plan[1]
6643  8 - nodata2expr => spi_plan[2]
6644  */
6645  for (i = 0; i < spi_count; i++) {
6646  if (!PG_ARGISNULL(spi_exprpos[i])) {
6647  char *tmp = NULL;
6648  char place[5] = "$1";
6649  expr = text_to_cstring(PG_GETARG_TEXT_P(spi_exprpos[i]));
6650  POSTGIS_RT_DEBUGF(3, "raw expr #%d: %s", i, expr);
6651 
6652  for (j = 0, k = 1; j < ARGKWCOUNT; j++) {
6653  /* attempt to replace keyword with placeholder */
6654  len = 0;
6655  tmp = rtpg_strreplace(expr, argkw[j], place, &len);
6656  pfree(expr);
6657  expr = tmp;
6658 
6659  if (len) {
6660  spi_argcount[i]++;
6661  argpos[i][j] = k++;
6662 
6663  sprintf(place, "$%d", k);
6664  }
6665  else
6666  argpos[i][j] = 0;
6667  }
6668 
6669  len = strlen("SELECT (") + strlen(expr) + strlen(")::double precision");
6670  sql = (char *) palloc(len + 1);
6671  if (sql == NULL) {
6672 
6673  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6674  SPI_finish();
6675 
6676  for (k = 0; k < set_count; k++) {
6677  if (_rast[k] != NULL)
6678  rt_raster_destroy(_rast[k]);
6679  if (pgrastpos[k] != -1)
6680  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6681  }
6683 
6684  elog(ERROR, "RASTER_mapAlgebra2: Could not allocate memory for expression parameter %d", spi_exprpos[i]);
6685  PG_RETURN_NULL();
6686  }
6687 
6688  memcpy(sql, "SELECT (", strlen("SELECT ("));
6689  memcpy(sql + strlen("SELECT ("), expr, strlen(expr));
6690  memcpy(sql + strlen("SELECT (") + strlen(expr), ")::double precision", strlen(")::double precision"));
6691  sql[len] = '\0';
6692 
6693  POSTGIS_RT_DEBUGF(3, "sql #%d: %s", i, sql);
6694 
6695  /* create prepared plan */
6696  if (spi_argcount[i]) {
6697  argtype = (Oid *) palloc(spi_argcount[i] * sizeof(Oid));
6698  if (argtype == NULL) {
6699 
6700  pfree(sql);
6701  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6702  SPI_finish();
6703 
6704  for (k = 0; k < set_count; k++) {
6705  if (_rast[k] != NULL)
6706  rt_raster_destroy(_rast[k]);
6707  if (pgrastpos[k] != -1)
6708  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6709  }
6711 
6712  elog(ERROR, "RASTER_mapAlgebra2: Could not allocate memory for prepared plan argtypes of expression parameter %d", spi_exprpos[i]);
6713  PG_RETURN_NULL();
6714  }
6715 
6716  /* specify datatypes of parameters */
6717  for (j = 0, k = 0; j < ARGKWCOUNT; j++) {
6718  if (argpos[i][j] < 1) continue;
6719 
6720  /* positions are INT4 */
6721  if (
6722  (strstr(argkw[j], "[rast1.x]") != NULL) ||
6723  (strstr(argkw[j], "[rast1.y]") != NULL) ||
6724  (strstr(argkw[j], "[rast2.x]") != NULL) ||
6725  (strstr(argkw[j], "[rast2.y]") != NULL)
6726  ) {
6727  argtype[k] = INT4OID;
6728  }
6729  /* everything else is FLOAT8 */
6730  else {
6731  argtype[k] = FLOAT8OID;
6732  }
6733 
6734  k++;
6735  }
6736 
6737  spi_plan[i] = SPI_prepare(sql, spi_argcount[i], argtype);
6738  pfree(argtype);
6739 
6740  if (spi_plan[i] == NULL) {
6741 
6742  pfree(sql);
6743  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6744  SPI_finish();
6745 
6746  for (k = 0; k < set_count; k++) {
6747  if (_rast[k] != NULL)
6748  rt_raster_destroy(_rast[k]);
6749  if (pgrastpos[k] != -1)
6750  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6751  }
6753 
6754  elog(ERROR, "RASTER_mapAlgebra2: Could not create prepared plan of expression parameter %d", spi_exprpos[i]);
6755  PG_RETURN_NULL();
6756  }
6757  }
6758  /* no args, just execute query */
6759  else {
6760  err = SPI_execute(sql, TRUE, 0);
6761  if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
6762 
6763  pfree(sql);
6764  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6765  SPI_finish();
6766 
6767  for (k = 0; k < set_count; k++) {
6768  if (_rast[k] != NULL)
6769  rt_raster_destroy(_rast[k]);
6770  if (pgrastpos[k] != -1)
6771  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6772  }
6774 
6775  elog(ERROR, "RASTER_mapAlgebra2: Could not evaluate expression parameter %d", spi_exprpos[i]);
6776  PG_RETURN_NULL();
6777  }
6778 
6779  /* get output of prepared plan */
6780  tupdesc = SPI_tuptable->tupdesc;
6781  tuptable = SPI_tuptable;
6782  tuple = tuptable->vals[0];
6783 
6784  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
6785  if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
6786 
6787  pfree(sql);
6788  if (SPI_tuptable) SPI_freetuptable(tuptable);
6789  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6790  SPI_finish();
6791 
6792  for (k = 0; k < set_count; k++) {
6793  if (_rast[k] != NULL)
6794  rt_raster_destroy(_rast[k]);
6795  if (pgrastpos[k] != -1)
6796  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6797  }
6799 
6800  elog(ERROR, "RASTER_mapAlgebra2: Could not get result of expression parameter %d", spi_exprpos[i]);
6801  PG_RETURN_NULL();
6802  }
6803 
6804  if (!isnull) {
6805  hasargval[i] = 1;
6806  argval[i] = DatumGetFloat8(datum);
6807  }
6808 
6809  if (SPI_tuptable) SPI_freetuptable(tuptable);
6810  }
6811 
6812  pfree(sql);
6813  }
6814  else
6815  spi_empty++;
6816  }
6817 
6818  /* nodatanodataval */
6819  if (!PG_ARGISNULL(9)) {
6820  hasnodatanodataval = 1;
6821  nodatanodataval = PG_GETARG_FLOAT8(9);
6822  }
6823  else
6824  hasnodatanodataval = 0;
6825  break;
6826  }
6827  case REGPROCEDUREOID: {
6828  POSTGIS_RT_DEBUG(3, "arg 4 is \"userfunction\"!");
6829  if (!PG_ARGISNULL(4)) {
6830 
6831  ufc_nullcount = 0;
6832  ufc_noid = PG_GETARG_OID(4);
6833 
6834  /* get function info */
6835  fmgr_info(ufc_noid, &ufl_info);
6836 
6837  /* function cannot return set */
6838  err = 0;
6839  if (ufl_info.fn_retset) {
6840  err = 1;
6841  }
6842  /* function should have correct # of args */
6843  else if (ufl_info.fn_nargs < 3 || ufl_info.fn_nargs > 4) {
6844  err = 2;
6845  }
6846 
6847  /*
6848  TODO: consider adding checks of the userfunction parameters
6849  should be able to use get_fn_expr_argtype() of fmgr.c
6850  */
6851 
6852  if (err > 0) {
6853  for (k = 0; k < set_count; k++) {
6854  if (_rast[k] != NULL)
6855  rt_raster_destroy(_rast[k]);
6856  if (pgrastpos[k] != -1)
6857  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6858  }
6860 
6861  if (err > 1)
6862  elog(ERROR, "RASTER_mapAlgebra2: Function provided must have three or four input parameters");
6863  else
6864  elog(ERROR, "RASTER_mapAlgebra2: Function provided must return double precision not resultset");
6865  PG_RETURN_NULL();
6866  }
6867 
6868  if (func_volatile(ufc_noid) == 'v') {
6869  elog(NOTICE, "Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
6870  }
6871 
6872  /* prep function call data */
6873  InitFunctionCallInfoData(
6874  *ufc_info, &ufl_info, ufl_info.fn_nargs, InvalidOid, NULL, NULL);
6875  ufc_info->args[0].isnull = FALSE;
6876  ufc_info->args[1].isnull = FALSE;
6877  ufc_info->args[2].isnull = FALSE;
6878  if (ufl_info.fn_nargs == 4)
6879  ufc_info->args[3].isnull = FALSE;
6880 
6881  if (ufl_info.fn_nargs != 4)
6882  k = 2;
6883  else
6884  k = 3;
6885  if (!PG_ARGISNULL(7))
6886  {
6887  ufc_info->args[k].value = PG_GETARG_DATUM(7);
6888  }
6889  else
6890  {
6891  ufc_info->args[k].value = (Datum)NULL;
6892  ufc_info->args[k].isnull = TRUE;
6893  ufc_nullcount++;
6894  }
6895  }
6896  break;
6897  }
6898  default:
6899  for (k = 0; k < set_count; k++) {
6900  if (_rast[k] != NULL)
6901  rt_raster_destroy(_rast[k]);
6902  if (pgrastpos[k] != -1)
6903  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6904  }
6906  elog(ERROR, "RASTER_mapAlgebra2: Invalid data type for expression or userfunction");
6907  PG_RETURN_NULL();
6908  break;
6909  }
6910 
6911  /* loop over pixels */
6912  /* if any expression present, run */
6913  if ((
6914  (calltype == TEXTOID) && (
6915  (spi_empty != spi_count) || hasnodatanodataval
6916  )
6917  ) || (
6918  (calltype == REGPROCEDUREOID) && (ufc_noid != InvalidOid)
6919  )) {
6920  for (x = 0; x < dim[0]; x++) {
6921  for (y = 0; y < dim[1]; y++) {
6922 
6923  /* get pixel from each raster */
6924  for (i = 0; i < set_count; i++) {
6925  _haspixel[i] = 0;
6926  _pixel[i] = 0;
6927 
6928  /* row/column */
6929  _x = (int)x - (int)_rastoffset[i][0];
6930  _y = (int)y - (int)_rastoffset[i][1];
6931 
6932  /* store _x and _y in 1-based */
6933  _pos[i][0] = _x + 1;
6934  _pos[i][1] = _y + 1;
6935 
6936  /* get pixel value */
6937  if (_band[i] == NULL) {
6938  if (!_hasnodata[i]) {
6939  _haspixel[i] = 1;
6940  _pixel[i] = _nodataval[i];
6941  }
6942  }
6943  else if (
6944  !_isempty[i] &&
6945  (_x >= 0 && _x < _dim[i][0]) &&
6946  (_y >= 0 && _y < _dim[i][1])
6947  ) {
6948  err = rt_band_get_pixel(_band[i], _x, _y, &(_pixel[i]), &isnodata);
6949  if (err != ES_NONE) {
6950 
6951  if (calltype == TEXTOID) {
6952  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6953  SPI_finish();
6954  }
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 pixel of %s raster", (i < 1 ? "FIRST" : "SECOND"));
6965  PG_RETURN_NULL();
6966  }
6967 
6968  if (!_hasnodata[i] || !isnodata)
6969  _haspixel[i] = 1;
6970  }
6971 
6972  POSTGIS_RT_DEBUGF(5, "pixel r%d(%d, %d) = %d, %f",
6973  i,
6974  _x, _y,
6975  _haspixel[i],
6976  _pixel[i]
6977  );
6978  }
6979 
6980  haspixel = 0;
6981 
6982  switch (calltype) {
6983  case TEXTOID: {
6984  /* which prepared plan to use? */
6985  /* !pixel0 && !pixel1 */
6986  /* use nodatanodataval */
6987  if (!_haspixel[0] && !_haspixel[1])
6988  i = 3;
6989  /* pixel0 && !pixel1 */
6990  /* run spi_plan[2] (nodata2expr) */
6991  else if (_haspixel[0] && !_haspixel[1])
6992  i = 2;
6993  /* !pixel0 && pixel1 */
6994  /* run spi_plan[1] (nodata1expr) */
6995  else if (!_haspixel[0] && _haspixel[1])
6996  i = 1;
6997  /* pixel0 && pixel1 */
6998  /* run spi_plan[0] (expression) */
6999  else
7000  i = 0;
7001 
7002  /* process values */
7003  if (i == 3) {
7004  if (hasnodatanodataval) {
7005  haspixel = 1;
7006  pixel = nodatanodataval;
7007  }
7008  }
7009  /* has an evaluated value */
7010  else if (hasargval[i]) {
7011  haspixel = 1;
7012  pixel = argval[i];
7013  }
7014  /* prepared plan exists */
7015  else if (spi_plan[i] != NULL) {
7016  POSTGIS_RT_DEBUGF(4, "Using prepared plan: %d", i);
7017 
7018  /* reset values to (Datum) NULL */
7019  memset(values, (Datum) NULL, sizeof(Datum) * ARGKWCOUNT);
7020  /* reset nulls to FALSE */
7021  memset(nulls, FALSE, sizeof(char) * ARGKWCOUNT);
7022 
7023  /* expression has argument(s) */
7024  if (spi_argcount[i]) {
7025  /* set values and nulls */
7026  for (j = 0; j < ARGKWCOUNT; j++) {
7027  idx = argpos[i][j];
7028  if (idx < 1) continue;
7029  idx--; /* 1-based becomes 0-based */
7030 
7031  if (strstr(argkw[j], "[rast1.x]") != NULL) {
7032  values[idx] = _pos[0][0];
7033  }
7034  else if (strstr(argkw[j], "[rast1.y]") != NULL) {
7035  values[idx] = _pos[0][1];
7036  }
7037  else if (
7038  (strstr(argkw[j], "[rast1.val]") != NULL) ||
7039  (strstr(argkw[j], "[rast1]") != NULL)
7040  ) {
7041  if (_isempty[0] || !_haspixel[0])
7042  nulls[idx] = TRUE;
7043  else
7044  values[idx] = Float8GetDatum(_pixel[0]);
7045  }
7046  else if (strstr(argkw[j], "[rast2.x]") != NULL) {
7047  values[idx] = _pos[1][0];
7048  }
7049  else if (strstr(argkw[j], "[rast2.y]") != NULL) {
7050  values[idx] = _pos[1][1];
7051  }
7052  else if (
7053  (strstr(argkw[j], "[rast2.val]") != NULL) ||
7054  (strstr(argkw[j], "[rast2]") != NULL)
7055  ) {
7056  if (_isempty[1] || !_haspixel[1])
7057  nulls[idx] = TRUE;
7058  else
7059  values[idx] = Float8GetDatum(_pixel[1]);
7060  }
7061  }
7062  }
7063 
7064  /* run prepared plan */
7065  err = SPI_execute_plan(spi_plan[i], values, nulls, TRUE, 1);
7066  if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
7067 
7068  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7069  SPI_finish();
7070 
7071  for (k = 0; k < set_count; k++) {
7072  if (_rast[k] != NULL)
7073  rt_raster_destroy(_rast[k]);
7074  if (pgrastpos[k] != -1)
7075  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7076  }
7078 
7079  elog(ERROR, "RASTER_mapAlgebra2: Unexpected error when running prepared statement %d", i);
7080  PG_RETURN_NULL();
7081  }
7082 
7083  /* get output of prepared plan */
7084  tupdesc = SPI_tuptable->tupdesc;
7085  tuptable = SPI_tuptable;
7086  tuple = tuptable->vals[0];
7087 
7088  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
7089  if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
7090 
7091  if (SPI_tuptable) SPI_freetuptable(tuptable);
7092  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7093  SPI_finish();
7094 
7095  for (k = 0; k < set_count; k++) {
7096  if (_rast[k] != NULL)
7097  rt_raster_destroy(_rast[k]);
7098  if (pgrastpos[k] != -1)
7099  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7100  }
7102 
7103  elog(ERROR, "RASTER_mapAlgebra2: Could not get result of prepared statement %d", i);
7104  PG_RETURN_NULL();
7105  }
7106 
7107  if (!isnull) {
7108  haspixel = 1;
7109  pixel = DatumGetFloat8(datum);
7110  }
7111 
7112  if (SPI_tuptable) SPI_freetuptable(tuptable);
7113  }
7114  } break;
7115  case REGPROCEDUREOID: {
7116  Datum d[4];
7117  ArrayType *a;
7118 
7119  /* build fcnarg */
7120  for (i = 0; i < set_count; i++) {
7121  ufc_info->args[i].value = Float8GetDatum(_pixel[i]);
7122  if (_haspixel[i]) {
7123  ufc_info->args[i].isnull = FALSE;
7124  ufc_nullcount--;
7125  }
7126  else {
7127  ufc_info->args[i].isnull = TRUE;
7128  ufc_nullcount++;
7129  }
7130  }
7131 
7132  /* function is strict and null parameter is passed */
7133  /* http://archives.postgresql.org/pgsql-general/2011-11/msg00424.php */
7134  if (ufl_info.fn_strict && ufc_nullcount)
7135  break;
7136 
7137  /* 4 parameters, add position */
7138  if (ufl_info.fn_nargs == 4) {
7139  /* Datum of 4 element array */
7140  /* array is (x1, y1, x2, y2) */
7141  for (i = 0; i < set_count; i++) {
7142  if (i < 1) {
7143  d[0] = Int32GetDatum(_pos[i][0]);
7144  d[1] = Int32GetDatum(_pos[i][1]);
7145  }
7146  else {
7147  d[2] = Int32GetDatum(_pos[i][0]);
7148  d[3] = Int32GetDatum(_pos[i][1]);
7149  }
7150  }
7151 
7152  a = construct_array(d, 4, INT4OID, sizeof(int32), true, 'i');
7153  ufc_info->args[2].value = PointerGetDatum(a);
7154  ufc_info->args[2].isnull = FALSE;
7155  }
7156 
7157  datum = FunctionCallInvoke(ufc_info);
7158 
7159  /* result is not null*/
7160  if (!ufc_info->isnull)
7161  {
7162  haspixel = 1;
7163  pixel = DatumGetFloat8(datum);
7164  }
7165  } break;
7166  }
7167 
7168  /* burn pixel if haspixel != 0 */
7169  if (haspixel) {
7170  if (rt_band_set_pixel(band, x, y, pixel, NULL) != ES_NONE) {
7171 
7172  if (calltype == TEXTOID) {
7173  for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7174  SPI_finish();
7175  }
7176 
7177  for (k = 0; k < set_count; k++) {
7178  if (_rast[k] != NULL)
7179  rt_raster_destroy(_rast[k]);
7180  if (pgrastpos[k] != -1)
7181  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7182  }
7184 
7185  elog(ERROR, "RASTER_mapAlgebra2: Could not set pixel value of output raster");
7186  PG_RETURN_NULL();
7187  }
7188  }
7189 
7190  POSTGIS_RT_DEBUGF(5, "(x, y, val) = (%d, %d, %f)", x, y, haspixel ? pixel : nodataval);
7191 
7192  } /* y: height */
7193  } /* x: width */
7194  }
7195 
7196  /* CLEANUP */
7197  if (calltype == TEXTOID) {
7198  for (i = 0; i < spi_count; i++) {
7199  if (spi_plan[i] != NULL) SPI_freeplan(spi_plan[i]);
7200  }
7201  SPI_finish();
7202  }
7203 
7204  for (k = 0; k < set_count; k++) {
7205  if (_rast[k] != NULL)
7206  rt_raster_destroy(_rast[k]);
7207  if (pgrastpos[k] != -1)
7208  PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7209  }
7210 
7211  pgrtn = rt_raster_serialize(raster);
7213  if (!pgrtn) PG_RETURN_NULL();
7214 
7215  POSTGIS_RT_DEBUG(3, "Finished RASTER_mapAlgebra2");
7216 
7217  SET_VARSIZE(pgrtn, pgrtn->size);
7218  PG_RETURN_POINTER(pgrtn);
7219 }
#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:731
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:674
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:1376
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:197
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:1375
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:974
@ 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:1887
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:631
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:3464
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:710
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:1362
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:91
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:2403

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: