PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ RASTER_mapAlgebraExpr()

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 4462 of file rtpg_mapalgebra.c.

References ovdump::band, ES_NONE, FALSE, FLT_NEQ, rt_raster_serialized_t::height, pixval::nband, PG_FUNCTION_INFO_V1(), POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, PT_END, r, rtrowdump::raster, RASTER_DEBUG, RASTER_mapAlgebraFct(), 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.

Referenced by RASTER_colorMap().

4463 {
4464  rt_pgraster *pgraster = NULL;
4465  rt_pgraster *pgrtn = NULL;
4466  rt_raster raster = NULL;
4467  rt_raster newrast = NULL;
4468  rt_band band = NULL;
4469  rt_band newband = NULL;
4470  int x, y, nband, width, height;
4471  double r;
4472  double newnodatavalue = 0.0;
4473  double newinitialvalue = 0.0;
4474  double newval = 0.0;
4475  char *newexpr = NULL;
4476  char *initexpr = NULL;
4477  char *expression = NULL;
4478  int hasnodataval = 0;
4479  double nodataval = 0.;
4480  rt_pixtype newpixeltype;
4481  int skipcomputation = 0;
4482  int len = 0;
4483  const int argkwcount = 3;
4484  enum KEYWORDS { kVAL=0, kX=1, kY=2 };
4485  char *argkw[] = {"[rast]", "[rast.x]", "[rast.y]"};
4486  Oid argkwtypes[] = { FLOAT8OID, INT4OID, INT4OID };
4487  int argcount = 0;
4488  Oid argtype[] = { FLOAT8OID, INT4OID, INT4OID };
4489  uint8_t argpos[3] = {0};
4490  char place[5];
4491  int idx = 0;
4492  int ret = -1;
4493  TupleDesc tupdesc;
4494  SPIPlanPtr spi_plan = NULL;
4495  SPITupleTable * tuptable = NULL;
4496  HeapTuple tuple;
4497  char * strFromText = NULL;
4498  Datum *values = NULL;
4499  Datum datum = (Datum)NULL;
4500  char *nulls = NULL;
4501  bool isnull = FALSE;
4502  int i = 0;
4503  int j = 0;
4504 
4505  POSTGIS_RT_DEBUG(2, "RASTER_mapAlgebraExpr: Starting...");
4506 
4507  /* Check raster */
4508  if (PG_ARGISNULL(0)) {
4509  elog(NOTICE, "Raster is NULL. Returning NULL");
4510  PG_RETURN_NULL();
4511  }
4512 
4513 
4514  /* Deserialize raster */
4515  pgraster = (rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
4516  raster = rt_raster_deserialize(pgraster, FALSE);
4517  if (NULL == raster) {
4518  PG_FREE_IF_COPY(pgraster, 0);
4519  elog(ERROR, "RASTER_mapAlgebraExpr: Could not deserialize raster");
4520  PG_RETURN_NULL();
4521  }
4522 
4523  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Getting arguments...");
4524 
4525  if (PG_ARGISNULL(1))
4526  nband = 1;
4527  else
4528  nband = PG_GETARG_INT32(1);
4529 
4530  if (nband < 1)
4531  nband = 1;
4532 
4533 
4534  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Creating new empty raster...");
4535 
4540  width = rt_raster_get_width(raster);
4541  height = rt_raster_get_height(raster);
4542 
4543  newrast = rt_raster_new(width, height);
4544 
4545  if ( NULL == newrast ) {
4546  PG_FREE_IF_COPY(pgraster, 0);
4547  elog(ERROR, "RASTER_mapAlgebraExpr: Could not create a new raster");
4548  PG_RETURN_NULL();
4549  }
4550 
4551  rt_raster_set_scale(newrast,
4552  rt_raster_get_x_scale(raster),
4553  rt_raster_get_y_scale(raster));
4554 
4555  rt_raster_set_offsets(newrast,
4556  rt_raster_get_x_offset(raster),
4557  rt_raster_get_y_offset(raster));
4558 
4559  rt_raster_set_skews(newrast,
4560  rt_raster_get_x_skew(raster),
4561  rt_raster_get_y_skew(raster));
4562 
4563  rt_raster_set_srid(newrast, rt_raster_get_srid(raster));
4564 
4565 
4570  if (rt_raster_is_empty(newrast))
4571  {
4572  elog(NOTICE, "Raster is empty. Returning an empty raster");
4573  rt_raster_destroy(raster);
4574  PG_FREE_IF_COPY(pgraster, 0);
4575 
4576  pgrtn = rt_raster_serialize(newrast);
4577  rt_raster_destroy(newrast);
4578  if (NULL == pgrtn) {
4579 
4580  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4581  PG_RETURN_NULL();
4582  }
4583 
4584  SET_VARSIZE(pgrtn, pgrtn->size);
4585  PG_RETURN_POINTER(pgrtn);
4586  }
4587 
4588 
4589  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Getting raster band %d...", nband);
4590 
4595  if (!rt_raster_has_band(raster, nband - 1)) {
4596  elog(NOTICE, "Raster does not have the required band. Returning a raster "
4597  "without a band");
4598  rt_raster_destroy(raster);
4599  PG_FREE_IF_COPY(pgraster, 0);
4600 
4601  pgrtn = rt_raster_serialize(newrast);
4602  rt_raster_destroy(newrast);
4603  if (NULL == pgrtn) {
4604  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4605  PG_RETURN_NULL();
4606  }
4607 
4608  SET_VARSIZE(pgrtn, pgrtn->size);
4609  PG_RETURN_POINTER(pgrtn);
4610  }
4611 
4612  /* Get the raster band */
4613  band = rt_raster_get_band(raster, nband - 1);
4614  if ( NULL == band ) {
4615  elog(NOTICE, "Could not get the required band. Returning a raster "
4616  "without a band");
4617  rt_raster_destroy(raster);
4618  PG_FREE_IF_COPY(pgraster, 0);
4619 
4620  pgrtn = rt_raster_serialize(newrast);
4621  rt_raster_destroy(newrast);
4622  if (NULL == pgrtn) {
4623  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4624  PG_RETURN_NULL();
4625  }
4626 
4627  SET_VARSIZE(pgrtn, pgrtn->size);
4628  PG_RETURN_POINTER(pgrtn);
4629  }
4630 
4631  /*
4632  * Get NODATA value
4633  */
4634  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Getting NODATA value for band...");
4635 
4636  if (rt_band_get_hasnodata_flag(band)) {
4637  rt_band_get_nodata(band, &newnodatavalue);
4638  }
4639 
4640  else {
4641  newnodatavalue = rt_band_get_min_value(band);
4642  }
4643 
4644  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: NODATA value for band: = %f",
4645  newnodatavalue);
4646 
4652  newinitialvalue = newnodatavalue;
4653 
4657  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Setting pixeltype...");
4658 
4659  if (PG_ARGISNULL(2)) {
4660  newpixeltype = rt_band_get_pixtype(band);
4661  }
4662 
4663  else {
4664  strFromText = text_to_cstring(PG_GETARG_TEXT_P(2));
4665  newpixeltype = rt_pixtype_index_from_name(strFromText);
4666  pfree(strFromText);
4667  if (newpixeltype == PT_END)
4668  newpixeltype = rt_band_get_pixtype(band);
4669  }
4670 
4671  if (newpixeltype == PT_END) {
4672  PG_FREE_IF_COPY(pgraster, 0);
4673  elog(ERROR, "RASTER_mapAlgebraExpr: Invalid pixeltype");
4674  PG_RETURN_NULL();
4675  }
4676 
4677  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Pixeltype set to %s",
4678  rt_pixtype_name(newpixeltype));
4679 
4680 
4681  /* Construct expression for raster values */
4682  if (!PG_ARGISNULL(3)) {
4683  expression = text_to_cstring(PG_GETARG_TEXT_P(3));
4684  len = strlen("SELECT (") + strlen(expression) + strlen(")::double precision");
4685  initexpr = (char *)palloc(len + 1);
4686 
4687  strncpy(initexpr, "SELECT (", strlen("SELECT ("));
4688  strncpy(initexpr + strlen("SELECT ("), expression, strlen(expression));
4689  strncpy(initexpr + strlen("SELECT (") + strlen(expression), ")::double precision", strlen(")::double precision"));
4690  initexpr[len] = '\0';
4691 
4692  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Expression is %s", initexpr);
4693 
4694  /* We don't need this memory */
4695  /*
4696  pfree(expression);
4697  expression = NULL;
4698  */
4699  }
4700 
4701 
4702 
4708  if (!PG_ARGISNULL(4)) {
4709  hasnodataval = 1;
4710  nodataval = PG_GETARG_FLOAT8(4);
4711  newinitialvalue = nodataval;
4712 
4713  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: new initial value = %f",
4714  newinitialvalue);
4715  }
4716  else
4717  hasnodataval = 0;
4718 
4719 
4720 
4726  if (rt_band_get_isnodata_flag(band)) {
4727 
4728  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Band is a nodata band, returning "
4729  "a raster filled with nodata");
4730 
4731  ret = rt_raster_generate_new_band(newrast, newpixeltype,
4732  newinitialvalue, TRUE, newnodatavalue, 0);
4733 
4734  /* Free memory */
4735  if (initexpr)
4736  pfree(initexpr);
4737  rt_raster_destroy(raster);
4738  PG_FREE_IF_COPY(pgraster, 0);
4739 
4740  /* Serialize created raster */
4741  pgrtn = rt_raster_serialize(newrast);
4742  rt_raster_destroy(newrast);
4743  if (NULL == pgrtn) {
4744  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4745  PG_RETURN_NULL();
4746  }
4747 
4748  SET_VARSIZE(pgrtn, pgrtn->size);
4749  PG_RETURN_POINTER(pgrtn);
4750  }
4751 
4752 
4757  if (initexpr != NULL && ( !strcmp(initexpr, "SELECT [rast]") || !strcmp(initexpr, "SELECT [rast.val]") ) && !hasnodataval) {
4758 
4759  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Expression resumes to RAST. "
4760  "Returning raster with band %d from original raster", nband);
4761 
4762  POSTGIS_RT_DEBUGF(4, "RASTER_mapAlgebraExpr: New raster has %d bands",
4763  rt_raster_get_num_bands(newrast));
4764 
4765  rt_raster_copy_band(newrast, raster, nband - 1, 0);
4766 
4767  POSTGIS_RT_DEBUGF(4, "RASTER_mapAlgebraExpr: New raster now has %d bands",
4768  rt_raster_get_num_bands(newrast));
4769 
4770  if (initexpr)
4771  pfree(initexpr);
4772  rt_raster_destroy(raster);
4773  PG_FREE_IF_COPY(pgraster, 0);
4774 
4775  /* Serialize created raster */
4776  pgrtn = rt_raster_serialize(newrast);
4777  rt_raster_destroy(newrast);
4778  if (NULL == pgrtn) {
4779  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4780  PG_RETURN_NULL();
4781  }
4782 
4783  SET_VARSIZE(pgrtn, pgrtn->size);
4784  PG_RETURN_POINTER(pgrtn);
4785  }
4786 
4791  if (initexpr != NULL && strstr(initexpr, "[rast") == NULL) {
4792  ret = SPI_connect();
4793  if (ret != SPI_OK_CONNECT) {
4794  PG_FREE_IF_COPY(pgraster, 0);
4795  elog(ERROR, "RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
4796  PG_RETURN_NULL();
4797  };
4798 
4799  /* Execute the expresion into newval */
4800  ret = SPI_execute(initexpr, FALSE, 0);
4801 
4802  if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
4803 
4804  /* Free memory allocated out of the current context */
4805  if (SPI_tuptable)
4806  SPI_freetuptable(tuptable);
4807  PG_FREE_IF_COPY(pgraster, 0);
4808 
4809  SPI_finish();
4810  elog(ERROR, "RASTER_mapAlgebraExpr: Invalid construction for expression");
4811  PG_RETURN_NULL();
4812  }
4813 
4814  tupdesc = SPI_tuptable->tupdesc;
4815  tuptable = SPI_tuptable;
4816 
4817  tuple = tuptable->vals[0];
4818  newexpr = SPI_getvalue(tuple, tupdesc, 1);
4819  if ( ! newexpr ) {
4820  POSTGIS_RT_DEBUG(3, "Constant expression evaluated to NULL, keeping initvalue");
4821  newval = newinitialvalue;
4822  } else {
4823  newval = atof(newexpr);
4824  }
4825 
4826  SPI_freetuptable(tuptable);
4827 
4828  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: New raster value = %f",
4829  newval);
4830 
4831  SPI_finish();
4832 
4833  skipcomputation = 1;
4834 
4839  if (!hasnodataval) {
4840  newinitialvalue = newval;
4841  skipcomputation = 2;
4842  }
4843 
4844  /* Return the new raster as it will be before computing pixel by pixel */
4845  else if (FLT_NEQ(newval, newinitialvalue)) {
4846  skipcomputation = 2;
4847  }
4848  }
4849 
4854  ret = rt_raster_generate_new_band(newrast, newpixeltype,
4855  newinitialvalue, TRUE, newnodatavalue, 0);
4856 
4861  /*if (initexpr == NULL || skipcomputation == 2) {*/
4862  if (expression == NULL || skipcomputation == 2) {
4863 
4864  /* Free memory */
4865  if (initexpr)
4866  pfree(initexpr);
4867  rt_raster_destroy(raster);
4868  PG_FREE_IF_COPY(pgraster, 0);
4869 
4870  /* Serialize created raster */
4871  pgrtn = rt_raster_serialize(newrast);
4872  rt_raster_destroy(newrast);
4873  if (NULL == pgrtn) {
4874  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4875  PG_RETURN_NULL();
4876  }
4877 
4878  SET_VARSIZE(pgrtn, pgrtn->size);
4879  PG_RETURN_POINTER(pgrtn);
4880  }
4881 
4882  RASTER_DEBUG(3, "RASTER_mapAlgebraExpr: Creating new raster band...");
4883 
4884  /* Get the new raster band */
4885  newband = rt_raster_get_band(newrast, 0);
4886  if ( NULL == newband ) {
4887  elog(NOTICE, "Could not modify band for new raster. Returning new "
4888  "raster with the original band");
4889 
4890  if (initexpr)
4891  pfree(initexpr);
4892  rt_raster_destroy(raster);
4893  PG_FREE_IF_COPY(pgraster, 0);
4894 
4895  /* Serialize created raster */
4896  pgrtn = rt_raster_serialize(newrast);
4897  rt_raster_destroy(newrast);
4898  if (NULL == pgrtn) {
4899  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4900  PG_RETURN_NULL();
4901  }
4902 
4903  SET_VARSIZE(pgrtn, pgrtn->size);
4904  PG_RETURN_POINTER(pgrtn);
4905  }
4906 
4907  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Main computing loop (%d x %d)",
4908  width, height);
4909 
4910  if (initexpr != NULL) {
4911  /* Convert [rast.val] to [rast] */
4912  newexpr = rtpg_strreplace(initexpr, "[rast.val]", "[rast]", NULL);
4913  pfree(initexpr); initexpr=newexpr;
4914 
4915  sprintf(place,"$1");
4916  for (i = 0, j = 1; i < argkwcount; i++) {
4917  len = 0;
4918  newexpr = rtpg_strreplace(initexpr, argkw[i], place, &len);
4919  pfree(initexpr); initexpr=newexpr;
4920  if (len > 0) {
4921  argtype[argcount] = argkwtypes[i];
4922  argcount++;
4923  argpos[i] = j++;
4924 
4925  sprintf(place, "$%d", j);
4926  }
4927  else {
4928  argpos[i] = 0;
4929  }
4930  }
4931 
4932  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: initexpr = %s", initexpr);
4933 
4934  /* define values */
4935  values = (Datum *) palloc(sizeof(Datum) * argcount);
4936  if (values == NULL) {
4937 
4938  SPI_finish();
4939 
4940  rt_raster_destroy(raster);
4941  PG_FREE_IF_COPY(pgraster, 0);
4942  rt_raster_destroy(newrast);
4943 
4944  elog(ERROR, "RASTER_mapAlgebraExpr: Could not allocate memory for value parameters of prepared statement");
4945  PG_RETURN_NULL();
4946  }
4947 
4948  /* define nulls */
4949  nulls = (char *)palloc(argcount);
4950  if (nulls == NULL) {
4951 
4952  SPI_finish();
4953 
4954  rt_raster_destroy(raster);
4955  PG_FREE_IF_COPY(pgraster, 0);
4956  rt_raster_destroy(newrast);
4957 
4958  elog(ERROR, "RASTER_mapAlgebraExpr: Could not allocate memory for null parameters of prepared statement");
4959  PG_RETURN_NULL();
4960  }
4961 
4962  /* Connect to SPI and prepare the expression */
4963  ret = SPI_connect();
4964  if (ret != SPI_OK_CONNECT) {
4965 
4966  if (initexpr)
4967  pfree(initexpr);
4968  rt_raster_destroy(raster);
4969  PG_FREE_IF_COPY(pgraster, 0);
4970  rt_raster_destroy(newrast);
4971 
4972  elog(ERROR, "RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
4973  PG_RETURN_NULL();
4974  };
4975 
4976  /* Type of all arguments is FLOAT8OID */
4977  spi_plan = SPI_prepare(initexpr, argcount, argtype);
4978 
4979  if (spi_plan == NULL) {
4980 
4981  rt_raster_destroy(raster);
4982  PG_FREE_IF_COPY(pgraster, 0);
4983  rt_raster_destroy(newrast);
4984 
4985  SPI_finish();
4986 
4987  pfree(initexpr);
4988 
4989  elog(ERROR, "RASTER_mapAlgebraExpr: Could not prepare expression");
4990  PG_RETURN_NULL();
4991  }
4992  }
4993 
4994  for (x = 0; x < width; x++) {
4995  for(y = 0; y < height; y++) {
4996  ret = rt_band_get_pixel(band, x, y, &r, NULL);
4997 
5002  if (ret == ES_NONE && FLT_NEQ(r, newnodatavalue)) {
5003  if (skipcomputation == 0) {
5004  if (initexpr != NULL) {
5005  /* Reset the null arg flags. */
5006  memset(nulls, 'n', argcount);
5007 
5008  for (i = 0; i < argkwcount; i++) {
5009  idx = argpos[i];
5010  if (idx < 1) continue;
5011  idx--;
5012 
5013  if (i == kX ) {
5014  /* x is 0 based index, but SQL expects 1 based index */
5015  values[idx] = Int32GetDatum(x+1);
5016  nulls[idx] = ' ';
5017  }
5018  else if (i == kY) {
5019  /* y is 0 based index, but SQL expects 1 based index */
5020  values[idx] = Int32GetDatum(y+1);
5021  nulls[idx] = ' ';
5022  }
5023  else if (i == kVAL ) {
5024  values[idx] = Float8GetDatum(r);
5025  nulls[idx] = ' ';
5026  }
5027 
5028  }
5029 
5030  ret = SPI_execute_plan(spi_plan, values, nulls, FALSE, 0);
5031  if (ret != SPI_OK_SELECT || SPI_tuptable == NULL ||
5032  SPI_processed != 1) {
5033  if (SPI_tuptable)
5034  SPI_freetuptable(tuptable);
5035 
5036  SPI_freeplan(spi_plan);
5037  SPI_finish();
5038 
5039  pfree(values);
5040  pfree(nulls);
5041  pfree(initexpr);
5042 
5043  rt_raster_destroy(raster);
5044  PG_FREE_IF_COPY(pgraster, 0);
5045  rt_raster_destroy(newrast);
5046 
5047  elog(ERROR, "RASTER_mapAlgebraExpr: Error executing prepared plan");
5048 
5049  PG_RETURN_NULL();
5050  }
5051 
5052  tupdesc = SPI_tuptable->tupdesc;
5053  tuptable = SPI_tuptable;
5054 
5055  tuple = tuptable->vals[0];
5056  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
5057  if ( SPI_result == SPI_ERROR_NOATTRIBUTE ) {
5058  POSTGIS_RT_DEBUGF(3, "Expression for pixel %d,%d (value %g) errored, skip setting", x+1,y+1,r);
5059  newval = newinitialvalue;
5060  }
5061  else if ( isnull ) {
5062  POSTGIS_RT_DEBUGF(3, "Expression for pixel %d,%d (value %g) evaluated to NULL, skip setting", x+1,y+1,r);
5063  newval = newinitialvalue;
5064  } else {
5065  newval = DatumGetFloat8(datum);
5066  }
5067 
5068  SPI_freetuptable(tuptable);
5069  }
5070 
5071  else
5072  newval = newinitialvalue;
5073 
5074  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: new value = %f",
5075  newval);
5076  }
5077 
5078 
5079  rt_band_set_pixel(newband, x, y, newval, NULL);
5080  }
5081 
5082  }
5083  }
5084 
5085  if (initexpr != NULL) {
5086  SPI_freeplan(spi_plan);
5087  SPI_finish();
5088 
5089  pfree(values);
5090  pfree(nulls);
5091  pfree(initexpr);
5092  }
5093  else {
5094  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: no SPI cleanup");
5095  }
5096 
5097 
5098  /* The newrast band has been modified */
5099 
5100  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: raster modified, serializing it.");
5101  /* Serialize created raster */
5102 
5103  rt_raster_destroy(raster);
5104  PG_FREE_IF_COPY(pgraster, 0);
5105 
5106  pgrtn = rt_raster_serialize(newrast);
5107  rt_raster_destroy(newrast);
5108  if (NULL == pgrtn)
5109  PG_RETURN_NULL();
5110 
5111  SET_VARSIZE(pgrtn, pgrtn->size);
5112 
5113  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: raster serialized");
5114 
5115 
5116  POSTGIS_RT_DEBUG(4, "RASTER_mapAlgebraExpr: returning raster");
5117 
5118 
5119  PG_RETURN_POINTER(pgrtn);
5120 }
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
double rt_raster_get_x_offset(rt_raster raster)
Get raster x offset, in projection units.
Definition: rt_raster.c:213
int rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:372
double rt_raster_get_y_skew(rt_raster raster)
Get skew about the Y axis.
Definition: rt_raster.c:190
char * r
Definition: cu_in_wkt.c:24
raster
Be careful!! Zeros function&#39;s input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
void rt_raster_set_skews(rt_raster raster, double skewX, double skewY)
Set skews about the X and Y axis.
Definition: rt_raster.c:168
char * rtpg_strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
Definition: rtpg_internal.c:55
band
Definition: ovdump.py:57
rt_pixtype
Definition: librtcore.h:185
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_raster.c:1338
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1597
nband
Definition: pixval.py:52
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1088
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
Definition: rt_raster.c:137
int rt_raster_generate_new_band(rt_raster raster, rt_pixtype pixtype, double initialvalue, uint32_t hasnodata, double nodatavalue, int index)
Generate a new inline band and add it to a raster.
Definition: rt_raster.c:485
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
Definition: rt_pixel.c:80
void rt_raster_set_offsets(rt_raster raster, double x, double y)
Set insertion points in projection units.
Definition: rt_raster.c:199
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:381
int rt_raster_copy_band(rt_raster torast, rt_raster fromrast, int fromindex, int toindex)
Copy one band from one raster to another.
Definition: rt_raster.c:1374
#define FLT_NEQ(x, y)
Definition: librtcore.h:2184
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:541
double rt_raster_get_x_scale(rt_raster raster)
Get scale X in projection units.
Definition: rt_raster.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:1351
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster&#39;s SRID.
Definition: rt_raster.c:363
int32_t rt_raster_get_srid(rt_raster raster)
Get raster&#39;s SRID.
Definition: rt_raster.c:356
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
double rt_raster_get_y_scale(rt_raster raster)
Get scale Y in projection units.
Definition: rt_raster.c:159
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_raster.c:48
double rt_raster_get_x_skew(rt_raster raster)
Get skew about the X axis.
Definition: rt_raster.c:181
uint16_t rt_raster_get_width(rt_raster raster)
Definition: rt_raster.c:121
#define FALSE
Definition: dbfopen.c:168
#define RASTER_DEBUG(level, msg)
Definition: librtcore.h:295
Struct definitions.
Definition: librtcore.h:2201
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
Definition: rt_band.c:1612
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_pixel.c:110
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:498
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition: rt_band.c:581
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel&#39;s value.
Definition: rt_band.c:841
uint16_t rt_raster_get_height(rt_raster raster)
Definition: rt_raster.c:129
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
unsigned char uint8_t
Definition: uthash.h:79
#define TRUE
Definition: dbfopen.c:169
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:717
double rt_raster_get_y_offset(rt_raster raster)
Get raster y offset, in projection units.
Definition: rt_raster.c:222
Here is the call graph for this function:
Here is the caller graph for this function: