PostGIS  2.1.10dev-r@@SVN_REVISION@@
Datum RASTER_mapAlgebraExpr ( PG_FUNCTION_ARGS  )

Create a new empty raster with having the same georeference as the provided raster

If this new raster is empty (width = 0 OR height = 0) then there is nothing to compute and we return it right now

Check if the raster has the required band. Otherwise, return a raster without band

We set the initial value of the future band to nodata value. If nodata value is null, then the raster will be initialized to rt_band_get_min_value but all the values should be recomputed anyway

Set the new pixeltype

Optimization: If a nodataval is provided, use it for newinitialvalue. Then, we can initialize the raster with this value and skip the computation of nodata values one by one in the main computing loop

Optimization: If the raster is only filled with nodata values return right now a raster filled with the newinitialvalue TODO: Call rt_band_check_isnodata instead?

Optimization: If expression resume to 'RAST' and hasnodataval is zero, we can just return the band from the original raster

Optimization: If expression resume to a constant (it does not contain [rast)

Compute the new value, set it and we will return after creating the new raster

Create the raster receiving all the computed values. Initialize it to the new initial value

Optimization: If expression is NULL, or all the pixels could be set in one step, return the initialized raster now

We compute a value only for the withdata value pixel since the nodata value has already been set by the first optimization

Definition at line 6763 of file rt_pg.c.

References ovdump::band, ES_NONE, FALSE, FLT_NEQ, rt_raster_serialized_t::height, pixval::nband, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, PT_END, r, rtrowdump::raster, RASTER_DEBUG, rt_band_get_hasnodata_flag(), rt_band_get_isnodata_flag(), rt_band_get_min_value(), rt_band_get_nodata(), rt_band_get_pixel(), rt_band_get_pixtype(), rt_band_set_pixel(), rt_pixtype_index_from_name(), rt_pixtype_name(), rt_raster_copy_band(), rt_raster_deserialize(), rt_raster_destroy(), rt_raster_generate_new_band(), rt_raster_get_band(), rt_raster_get_height(), rt_raster_get_num_bands(), 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_serialize(), rt_raster_set_offsets(), rt_raster_set_scale(), rt_raster_set_skews(), rt_raster_set_srid(), rtpg_strreplace(), rt_raster_serialized_t::size, TRUE, rt_raster_serialized_t::width, pixval::x, and pixval::y.

6764 {
6765  rt_pgraster *pgraster = NULL;
6766  rt_pgraster *pgrtn = NULL;
6767  rt_raster raster = NULL;
6768  rt_raster newrast = NULL;
6769  rt_band band = NULL;
6770  rt_band newband = NULL;
6771  int x, y, nband, width, height;
6772  double r;
6773  double newnodatavalue = 0.0;
6774  double newinitialvalue = 0.0;
6775  double newval = 0.0;
6776  char *newexpr = NULL;
6777  char *initexpr = NULL;
6778  char *expression = NULL;
6779  int hasnodataval = 0;
6780  double nodataval = 0.;
6781  rt_pixtype newpixeltype;
6782  int skipcomputation = 0;
6783  int len = 0;
6784  const int argkwcount = 3;
6785  enum KEYWORDS { kVAL=0, kX=1, kY=2 };
6786  char *argkw[] = {"[rast]", "[rast.x]", "[rast.y]"};
6787  Oid argkwtypes[] = { FLOAT8OID, INT4OID, INT4OID };
6788  int argcount = 0;
6789  Oid argtype[] = { FLOAT8OID, INT4OID, INT4OID };
6790  uint8_t argpos[3] = {0};
6791  char place[5];
6792  int idx = 0;
6793  int ret = -1;
6794  TupleDesc tupdesc;
6795  SPIPlanPtr spi_plan = NULL;
6796  SPITupleTable * tuptable = NULL;
6797  HeapTuple tuple;
6798  char * strFromText = NULL;
6799  Datum *values = NULL;
6800  Datum datum = (Datum)NULL;
6801  char *nulls = NULL;
6802  bool isnull = FALSE;
6803  int i = 0;
6804  int j = 0;
6805 
6806  POSTGIS_RT_DEBUG(2, "RASTER_mapAlgebraExpr: Starting...");
6807 
6808  /* Check raster */
6809  if (PG_ARGISNULL(0)) {
6810  elog(NOTICE, "Raster is NULL. Returning NULL");
6811  PG_RETURN_NULL();
6812  }
6813 
6814 
6815  /* Deserialize raster */
6816  pgraster = (rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
6817  raster = rt_raster_deserialize(pgraster, FALSE);
6818  if (NULL == raster) {
6819  PG_FREE_IF_COPY(pgraster, 0);
6820  elog(ERROR, "RASTER_mapAlgebraExpr: Could not deserialize raster");
6821  PG_RETURN_NULL();
6822  }
6823 
6824  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Getting arguments...");
6825 
6826  if (PG_ARGISNULL(1))
6827  nband = 1;
6828  else
6829  nband = PG_GETARG_INT32(1);
6830 
6831  if (nband < 1)
6832  nband = 1;
6833 
6834 
6835  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Creating new empty raster...");
6836 
6841  width = rt_raster_get_width(raster);
6842  height = rt_raster_get_height(raster);
6843 
6844  newrast = rt_raster_new(width, height);
6845 
6846  if ( NULL == newrast ) {
6847  PG_FREE_IF_COPY(pgraster, 0);
6848  elog(ERROR, "RASTER_mapAlgebraExpr: Could not create a new raster");
6849  PG_RETURN_NULL();
6850  }
6851 
6852  rt_raster_set_scale(newrast,
6853  rt_raster_get_x_scale(raster),
6854  rt_raster_get_y_scale(raster));
6855 
6856  rt_raster_set_offsets(newrast,
6857  rt_raster_get_x_offset(raster),
6858  rt_raster_get_y_offset(raster));
6859 
6860  rt_raster_set_skews(newrast,
6861  rt_raster_get_x_skew(raster),
6862  rt_raster_get_y_skew(raster));
6863 
6864  rt_raster_set_srid(newrast, rt_raster_get_srid(raster));
6865 
6866 
6871  if (rt_raster_is_empty(newrast))
6872  {
6873  elog(NOTICE, "Raster is empty. Returning an empty raster");
6874  rt_raster_destroy(raster);
6875  PG_FREE_IF_COPY(pgraster, 0);
6876 
6877  pgrtn = rt_raster_serialize(newrast);
6878  rt_raster_destroy(newrast);
6879  if (NULL == pgrtn) {
6880 
6881  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
6882  PG_RETURN_NULL();
6883  }
6884 
6885  SET_VARSIZE(pgrtn, pgrtn->size);
6886  PG_RETURN_POINTER(pgrtn);
6887  }
6888 
6889 
6890  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Getting raster band %d...", nband);
6891 
6896  if (!rt_raster_has_band(raster, nband - 1)) {
6897  elog(NOTICE, "Raster does not have the required band. Returning a raster "
6898  "without a band");
6899  rt_raster_destroy(raster);
6900  PG_FREE_IF_COPY(pgraster, 0);
6901 
6902  pgrtn = rt_raster_serialize(newrast);
6903  rt_raster_destroy(newrast);
6904  if (NULL == pgrtn) {
6905  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
6906  PG_RETURN_NULL();
6907  }
6908 
6909  SET_VARSIZE(pgrtn, pgrtn->size);
6910  PG_RETURN_POINTER(pgrtn);
6911  }
6912 
6913  /* Get the raster band */
6914  band = rt_raster_get_band(raster, nband - 1);
6915  if ( NULL == band ) {
6916  elog(NOTICE, "Could not get the required band. Returning a raster "
6917  "without a band");
6918  rt_raster_destroy(raster);
6919  PG_FREE_IF_COPY(pgraster, 0);
6920 
6921  pgrtn = rt_raster_serialize(newrast);
6922  rt_raster_destroy(newrast);
6923  if (NULL == pgrtn) {
6924  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
6925  PG_RETURN_NULL();
6926  }
6927 
6928  SET_VARSIZE(pgrtn, pgrtn->size);
6929  PG_RETURN_POINTER(pgrtn);
6930  }
6931 
6932  /*
6933  * Get NODATA value
6934  */
6935  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Getting NODATA value for band...");
6936 
6937  if (rt_band_get_hasnodata_flag(band)) {
6938  rt_band_get_nodata(band, &newnodatavalue);
6939  }
6940 
6941  else {
6942  newnodatavalue = rt_band_get_min_value(band);
6943  }
6944 
6945  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: NODATA value for band: = %f",
6946  newnodatavalue);
6947 
6953  newinitialvalue = newnodatavalue;
6954 
6958  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Setting pixeltype...");
6959 
6960  if (PG_ARGISNULL(2)) {
6961  newpixeltype = rt_band_get_pixtype(band);
6962  }
6963 
6964  else {
6965  strFromText = text_to_cstring(PG_GETARG_TEXT_P(2));
6966  newpixeltype = rt_pixtype_index_from_name(strFromText);
6967  pfree(strFromText);
6968  if (newpixeltype == PT_END)
6969  newpixeltype = rt_band_get_pixtype(band);
6970  }
6971 
6972  if (newpixeltype == PT_END) {
6973  PG_FREE_IF_COPY(pgraster, 0);
6974  elog(ERROR, "RASTER_mapAlgebraExpr: Invalid pixeltype");
6975  PG_RETURN_NULL();
6976  }
6977 
6978  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Pixeltype set to %s",
6979  rt_pixtype_name(newpixeltype));
6980 
6981 
6982  /* Construct expression for raster values */
6983  if (!PG_ARGISNULL(3)) {
6984  expression = text_to_cstring(PG_GETARG_TEXT_P(3));
6985  len = strlen("SELECT (") + strlen(expression) + strlen(")::double precision");
6986  initexpr = (char *)palloc(len + 1);
6987 
6988  strncpy(initexpr, "SELECT (", strlen("SELECT ("));
6989  strncpy(initexpr + strlen("SELECT ("), expression, strlen(expression));
6990  strncpy(initexpr + strlen("SELECT (") + strlen(expression), ")::double precision", strlen(")::double precision"));
6991  initexpr[len] = '\0';
6992 
6993  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Expression is %s", initexpr);
6994 
6995  /* We don't need this memory */
6996  /*
6997  pfree(expression);
6998  expression = NULL;
6999  */
7000  }
7001 
7002 
7003 
7009  if (!PG_ARGISNULL(4)) {
7010  hasnodataval = 1;
7011  nodataval = PG_GETARG_FLOAT8(4);
7012  newinitialvalue = nodataval;
7013 
7014  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: new initial value = %f",
7015  newinitialvalue);
7016  }
7017  else
7018  hasnodataval = 0;
7019 
7020 
7021 
7027  if (rt_band_get_isnodata_flag(band)) {
7028 
7029  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Band is a nodata band, returning "
7030  "a raster filled with nodata");
7031 
7032  ret = rt_raster_generate_new_band(newrast, newpixeltype,
7033  newinitialvalue, TRUE, newnodatavalue, 0);
7034 
7035  /* Free memory */
7036  if (initexpr)
7037  pfree(initexpr);
7038  rt_raster_destroy(raster);
7039  PG_FREE_IF_COPY(pgraster, 0);
7040 
7041  /* Serialize created raster */
7042  pgrtn = rt_raster_serialize(newrast);
7043  rt_raster_destroy(newrast);
7044  if (NULL == pgrtn) {
7045  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
7046  PG_RETURN_NULL();
7047  }
7048 
7049  SET_VARSIZE(pgrtn, pgrtn->size);
7050  PG_RETURN_POINTER(pgrtn);
7051  }
7052 
7053 
7058  if (initexpr != NULL && ( !strcmp(initexpr, "SELECT [rast]") || !strcmp(initexpr, "SELECT [rast.val]") ) && !hasnodataval) {
7059 
7060  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Expression resumes to RAST. "
7061  "Returning raster with band %d from original raster", nband);
7062 
7063  POSTGIS_RT_DEBUGF(4, "RASTER_mapAlgebraExpr: New raster has %d bands",
7064  rt_raster_get_num_bands(newrast));
7065 
7066  rt_raster_copy_band(newrast, raster, nband - 1, 0);
7067 
7068  POSTGIS_RT_DEBUGF(4, "RASTER_mapAlgebraExpr: New raster now has %d bands",
7069  rt_raster_get_num_bands(newrast));
7070 
7071  if (initexpr)
7072  pfree(initexpr);
7073  rt_raster_destroy(raster);
7074  PG_FREE_IF_COPY(pgraster, 0);
7075 
7076  /* Serialize created raster */
7077  pgrtn = rt_raster_serialize(newrast);
7078  rt_raster_destroy(newrast);
7079  if (NULL == pgrtn) {
7080  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
7081  PG_RETURN_NULL();
7082  }
7083 
7084  SET_VARSIZE(pgrtn, pgrtn->size);
7085  PG_RETURN_POINTER(pgrtn);
7086  }
7087 
7092  if (initexpr != NULL && strstr(initexpr, "[rast") == NULL) {
7093  ret = SPI_connect();
7094  if (ret != SPI_OK_CONNECT) {
7095  PG_FREE_IF_COPY(pgraster, 0);
7096  elog(ERROR, "RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
7097  PG_RETURN_NULL();
7098  };
7099 
7100  /* Execute the expresion into newval */
7101  ret = SPI_execute(initexpr, FALSE, 0);
7102 
7103  if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
7104 
7105  /* Free memory allocated out of the current context */
7106  if (SPI_tuptable)
7107  SPI_freetuptable(tuptable);
7108  PG_FREE_IF_COPY(pgraster, 0);
7109 
7110  SPI_finish();
7111  elog(ERROR, "RASTER_mapAlgebraExpr: Invalid construction for expression");
7112  PG_RETURN_NULL();
7113  }
7114 
7115  tupdesc = SPI_tuptable->tupdesc;
7116  tuptable = SPI_tuptable;
7117 
7118  tuple = tuptable->vals[0];
7119  newexpr = SPI_getvalue(tuple, tupdesc, 1);
7120  if ( ! newexpr ) {
7121  POSTGIS_RT_DEBUG(3, "Constant expression evaluated to NULL, keeping initvalue");
7122  newval = newinitialvalue;
7123  } else {
7124  newval = atof(newexpr);
7125  }
7126 
7127  SPI_freetuptable(tuptable);
7128 
7129  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: New raster value = %f",
7130  newval);
7131 
7132  SPI_finish();
7133 
7134  skipcomputation = 1;
7135 
7140  if (!hasnodataval) {
7141  newinitialvalue = newval;
7142  skipcomputation = 2;
7143  }
7144 
7145  /* Return the new raster as it will be before computing pixel by pixel */
7146  else if (FLT_NEQ(newval, newinitialvalue)) {
7147  skipcomputation = 2;
7148  }
7149  }
7150 
7155  ret = rt_raster_generate_new_band(newrast, newpixeltype,
7156  newinitialvalue, TRUE, newnodatavalue, 0);
7157 
7162  /*if (initexpr == NULL || skipcomputation == 2) {*/
7163  if (expression == NULL || skipcomputation == 2) {
7164 
7165  /* Free memory */
7166  if (initexpr)
7167  pfree(initexpr);
7168  rt_raster_destroy(raster);
7169  PG_FREE_IF_COPY(pgraster, 0);
7170 
7171  /* Serialize created raster */
7172  pgrtn = rt_raster_serialize(newrast);
7173  rt_raster_destroy(newrast);
7174  if (NULL == pgrtn) {
7175  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
7176  PG_RETURN_NULL();
7177  }
7178 
7179  SET_VARSIZE(pgrtn, pgrtn->size);
7180  PG_RETURN_POINTER(pgrtn);
7181  }
7182 
7183  RASTER_DEBUG(3, "RASTER_mapAlgebraExpr: Creating new raster band...");
7184 
7185  /* Get the new raster band */
7186  newband = rt_raster_get_band(newrast, 0);
7187  if ( NULL == newband ) {
7188  elog(NOTICE, "Could not modify band for new raster. Returning new "
7189  "raster with the original band");
7190 
7191  if (initexpr)
7192  pfree(initexpr);
7193  rt_raster_destroy(raster);
7194  PG_FREE_IF_COPY(pgraster, 0);
7195 
7196  /* Serialize created raster */
7197  pgrtn = rt_raster_serialize(newrast);
7198  rt_raster_destroy(newrast);
7199  if (NULL == pgrtn) {
7200  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
7201  PG_RETURN_NULL();
7202  }
7203 
7204  SET_VARSIZE(pgrtn, pgrtn->size);
7205  PG_RETURN_POINTER(pgrtn);
7206  }
7207 
7208  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Main computing loop (%d x %d)",
7209  width, height);
7210 
7211  if (initexpr != NULL) {
7212  /* Convert [rast.val] to [rast] */
7213  newexpr = rtpg_strreplace(initexpr, "[rast.val]", "[rast]", NULL);
7214  pfree(initexpr); initexpr=newexpr;
7215 
7216  sprintf(place,"$1");
7217  for (i = 0, j = 1; i < argkwcount; i++) {
7218  len = 0;
7219  newexpr = rtpg_strreplace(initexpr, argkw[i], place, &len);
7220  pfree(initexpr); initexpr=newexpr;
7221  if (len > 0) {
7222  argtype[argcount] = argkwtypes[i];
7223  argcount++;
7224  argpos[i] = j++;
7225 
7226  sprintf(place, "$%d", j);
7227  }
7228  else {
7229  argpos[i] = 0;
7230  }
7231  }
7232 
7233  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: initexpr = %s", initexpr);
7234 
7235  /* define values */
7236  values = (Datum *) palloc(sizeof(Datum) * argcount);
7237  if (values == NULL) {
7238 
7239  SPI_finish();
7240 
7241  rt_raster_destroy(raster);
7242  PG_FREE_IF_COPY(pgraster, 0);
7243  rt_raster_destroy(newrast);
7244 
7245  elog(ERROR, "RASTER_mapAlgebraExpr: Could not allocate memory for value parameters of prepared statement");
7246  PG_RETURN_NULL();
7247  }
7248 
7249  /* define nulls */
7250  nulls = (char *)palloc(argcount);
7251  if (nulls == NULL) {
7252 
7253  SPI_finish();
7254 
7255  rt_raster_destroy(raster);
7256  PG_FREE_IF_COPY(pgraster, 0);
7257  rt_raster_destroy(newrast);
7258 
7259  elog(ERROR, "RASTER_mapAlgebraExpr: Could not allocate memory for null parameters of prepared statement");
7260  PG_RETURN_NULL();
7261  }
7262 
7263  /* Connect to SPI and prepare the expression */
7264  ret = SPI_connect();
7265  if (ret != SPI_OK_CONNECT) {
7266 
7267  if (initexpr)
7268  pfree(initexpr);
7269  rt_raster_destroy(raster);
7270  PG_FREE_IF_COPY(pgraster, 0);
7271  rt_raster_destroy(newrast);
7272 
7273  elog(ERROR, "RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
7274  PG_RETURN_NULL();
7275  };
7276 
7277  /* Type of all arguments is FLOAT8OID */
7278  spi_plan = SPI_prepare(initexpr, argcount, argtype);
7279 
7280  if (spi_plan == NULL) {
7281 
7282  rt_raster_destroy(raster);
7283  PG_FREE_IF_COPY(pgraster, 0);
7284  rt_raster_destroy(newrast);
7285 
7286  SPI_finish();
7287 
7288  pfree(initexpr);
7289 
7290  elog(ERROR, "RASTER_mapAlgebraExpr: Could not prepare expression");
7291  PG_RETURN_NULL();
7292  }
7293  }
7294 
7295  for (x = 0; x < width; x++) {
7296  for(y = 0; y < height; y++) {
7297  ret = rt_band_get_pixel(band, x, y, &r, NULL);
7298 
7303  if (ret == ES_NONE && FLT_NEQ(r, newnodatavalue)) {
7304  if (skipcomputation == 0) {
7305  if (initexpr != NULL) {
7306  /* Reset the null arg flags. */
7307  memset(nulls, 'n', argcount);
7308 
7309  for (i = 0; i < argkwcount; i++) {
7310  idx = argpos[i];
7311  if (idx < 1) continue;
7312  idx--;
7313 
7314  if (i == kX ) {
7315  /* x is 0 based index, but SQL expects 1 based index */
7316  values[idx] = Int32GetDatum(x+1);
7317  nulls[idx] = ' ';
7318  }
7319  else if (i == kY) {
7320  /* y is 0 based index, but SQL expects 1 based index */
7321  values[idx] = Int32GetDatum(y+1);
7322  nulls[idx] = ' ';
7323  }
7324  else if (i == kVAL ) {
7325  values[idx] = Float8GetDatum(r);
7326  nulls[idx] = ' ';
7327  }
7328 
7329  }
7330 
7331  ret = SPI_execute_plan(spi_plan, values, nulls, FALSE, 0);
7332  if (ret != SPI_OK_SELECT || SPI_tuptable == NULL ||
7333  SPI_processed != 1) {
7334  if (SPI_tuptable)
7335  SPI_freetuptable(tuptable);
7336 
7337  SPI_freeplan(spi_plan);
7338  SPI_finish();
7339 
7340  pfree(values);
7341  pfree(nulls);
7342  pfree(initexpr);
7343 
7344  rt_raster_destroy(raster);
7345  PG_FREE_IF_COPY(pgraster, 0);
7346  rt_raster_destroy(newrast);
7347 
7348  elog(ERROR, "RASTER_mapAlgebraExpr: Error executing prepared plan");
7349 
7350  PG_RETURN_NULL();
7351  }
7352 
7353  tupdesc = SPI_tuptable->tupdesc;
7354  tuptable = SPI_tuptable;
7355 
7356  tuple = tuptable->vals[0];
7357  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
7358  if ( SPI_result == SPI_ERROR_NOATTRIBUTE ) {
7359  POSTGIS_RT_DEBUGF(3, "Expression for pixel %d,%d (value %g) errored, skip setting", x+1,y+1,r);
7360  newval = newinitialvalue;
7361  }
7362  else if ( isnull ) {
7363  POSTGIS_RT_DEBUGF(3, "Expression for pixel %d,%d (value %g) evaluated to NULL, skip setting", x+1,y+1,r);
7364  newval = newinitialvalue;
7365  } else {
7366  newval = DatumGetFloat8(datum);
7367  }
7368 
7369  SPI_freetuptable(tuptable);
7370  }
7371 
7372  else
7373  newval = newinitialvalue;
7374 
7375  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: new value = %f",
7376  newval);
7377  }
7378 
7379 
7380  rt_band_set_pixel(newband, x, y, newval, NULL);
7381  }
7382 
7383  }
7384  }
7385 
7386  if (initexpr != NULL) {
7387  SPI_freeplan(spi_plan);
7388  SPI_finish();
7389 
7390  pfree(values);
7391  pfree(nulls);
7392  pfree(initexpr);
7393  }
7394  else {
7395  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: no SPI cleanup");
7396  }
7397 
7398 
7399  /* The newrast band has been modified */
7400 
7401  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: raster modified, serializing it.");
7402  /* Serialize created raster */
7403 
7404  rt_raster_destroy(raster);
7405  PG_FREE_IF_COPY(pgraster, 0);
7406 
7407  pgrtn = rt_raster_serialize(newrast);
7408  rt_raster_destroy(newrast);
7409  if (NULL == pgrtn)
7410  PG_RETURN_NULL();
7411 
7412  SET_VARSIZE(pgrtn, pgrtn->size);
7413 
7414  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: raster serialized");
7415 
7416 
7417  POSTGIS_RT_DEBUG(4, "RASTER_mapAlgebraExpr: returning raster");
7418 
7419 
7420  PG_RETURN_POINTER(pgrtn);
7421 }
int rt_raster_get_num_bands(rt_raster raster)
Definition: rt_api.c:5677
static char * rtpg_strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
Definition: rt_pg.c:685
#define FLT_NEQ(x, y)
Definition: rt_api.h:2158
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_api.c:8158
double rt_raster_get_y_offset(rt_raster raster)
Get raster y offset, in projection units.
Definition: rt_api.c:5527
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
char * r
Definition: cu_in_wkt.c:25
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_api.c:1168
int rt_raster_copy_band(rt_raster torast, rt_raster fromrast, int fromindex, int toindex)
Copy one band from one raster to another.
Definition: rt_api.c:8582
Definition: rt_api.h:184
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_api.c:1900
double rt_raster_get_x_skew(rt_raster raster)
Get skew about the X axis.
Definition: rt_api.c:5486
tuple band
Definition: ovdump.py:57
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
Definition: rt_api.c:8563
double rt_raster_get_y_skew(rt_raster raster)
Get skew about the Y axis.
Definition: rt_api.c:5495
double rt_raster_get_x_offset(rt_raster raster)
Get raster x offset, in projection units.
Definition: rt_api.c:5518
tuple raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:123
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition: rt_api.c:5668
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_api.c:5661
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition: rt_api.c:2042
void rt_raster_set_skews(rt_raster raster, double skewX, double skewY)
Set skews about the X and Y axis.
Definition: rt_api.c:5473
#define RASTER_DEBUG(level, msg)
Definition: rt_api.h:281
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
Definition: rt_api.c:5442
rt_pixtype
Definition: rt_api.h:172
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rt_pg.h:58
tuple nband
Definition: pixval.py:52
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
Definition: rt_api.c:3073
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_api.c:3058
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_api.c:2549
double rt_raster_get_x_scale(rt_raster raster)
Get scale X in projection units.
Definition: rt_api.c:5455
tuple x
Definition: pixval.py:53
uint16_t rt_raster_get_height(rt_raster raster)
Definition: rt_api.c:5434
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.
Definition: rt_api.c:5686
#define FALSE
Definition: dbfopen.c:169
Struct definitions.
Definition: rt_api.h:2175
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rt_pg.h:62
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_api.c:8550
double rt_raster_get_y_scale(rt_raster raster)
Get scale Y in projection units.
Definition: rt_api.c:5464
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_api.c:8350
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
Definition: rt_api.c:1138
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_api.c:5353
#define TRUE
Definition: dbfopen.c:170
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_api.c:2002
void rt_raster_set_offsets(rt_raster raster, double x, double y)
Set insertion points in projection units.
Definition: rt_api.c:5504
tuple y
Definition: pixval.py:54
uint16_t rt_raster_get_width(rt_raster raster)
Definition: rt_api.c:5426
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_api.c:5784
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
Definition: rt_api.c:2302

Here is the call graph for this function: