PostGIS  2.5.0dev-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 4410 of file rtpg_mapalgebra.c.

References ovdump::band, ES_NONE, FALSE, FLT_NEQ, 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, pixval::x, and pixval::y.

4411 {
4412  rt_pgraster *pgraster = NULL;
4413  rt_pgraster *pgrtn = NULL;
4414  rt_raster raster = NULL;
4415  rt_raster newrast = NULL;
4416  rt_band band = NULL;
4417  rt_band newband = NULL;
4418  int x, y, nband, width, height;
4419  double r;
4420  double newnodatavalue = 0.0;
4421  double newinitialvalue = 0.0;
4422  double newval = 0.0;
4423  char *newexpr = NULL;
4424  char *initexpr = NULL;
4425  char *expression = NULL;
4426  int hasnodataval = 0;
4427  double nodataval = 0.;
4428  rt_pixtype newpixeltype;
4429  int skipcomputation = 0;
4430  int len = 0;
4431  const int argkwcount = 3;
4432  enum KEYWORDS { kVAL=0, kX=1, kY=2 };
4433  char *argkw[] = {"[rast]", "[rast.x]", "[rast.y]"};
4434  Oid argkwtypes[] = { FLOAT8OID, INT4OID, INT4OID };
4435  int argcount = 0;
4436  Oid argtype[] = { FLOAT8OID, INT4OID, INT4OID };
4437  uint8_t argpos[3] = {0};
4438  char place[12];
4439  int idx = 0;
4440  int ret = -1;
4441  TupleDesc tupdesc;
4442  SPIPlanPtr spi_plan = NULL;
4443  SPITupleTable * tuptable = NULL;
4444  HeapTuple tuple;
4445  char * strFromText = NULL;
4446  Datum *values = NULL;
4447  Datum datum = (Datum)NULL;
4448  char *nulls = NULL;
4449  bool isnull = FALSE;
4450  int i = 0;
4451  int j = 0;
4452 
4453  POSTGIS_RT_DEBUG(2, "RASTER_mapAlgebraExpr: Starting...");
4454 
4455  /* Check raster */
4456  if (PG_ARGISNULL(0)) {
4457  elog(NOTICE, "Raster is NULL. Returning NULL");
4458  PG_RETURN_NULL();
4459  }
4460 
4461 
4462  /* Deserialize raster */
4463  pgraster = (rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
4464  raster = rt_raster_deserialize(pgraster, FALSE);
4465  if (NULL == raster) {
4466  PG_FREE_IF_COPY(pgraster, 0);
4467  elog(ERROR, "RASTER_mapAlgebraExpr: Could not deserialize raster");
4468  PG_RETURN_NULL();
4469  }
4470 
4471  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Getting arguments...");
4472 
4473  if (PG_ARGISNULL(1))
4474  nband = 1;
4475  else
4476  nband = PG_GETARG_INT32(1);
4477 
4478  if (nband < 1)
4479  nband = 1;
4480 
4481 
4482  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Creating new empty raster...");
4483 
4488  width = rt_raster_get_width(raster);
4489  height = rt_raster_get_height(raster);
4490 
4491  newrast = rt_raster_new(width, height);
4492 
4493  if ( NULL == newrast ) {
4494  PG_FREE_IF_COPY(pgraster, 0);
4495  elog(ERROR, "RASTER_mapAlgebraExpr: Could not create a new raster");
4496  PG_RETURN_NULL();
4497  }
4498 
4499  rt_raster_set_scale(newrast,
4500  rt_raster_get_x_scale(raster),
4501  rt_raster_get_y_scale(raster));
4502 
4503  rt_raster_set_offsets(newrast,
4504  rt_raster_get_x_offset(raster),
4505  rt_raster_get_y_offset(raster));
4506 
4507  rt_raster_set_skews(newrast,
4508  rt_raster_get_x_skew(raster),
4509  rt_raster_get_y_skew(raster));
4510 
4511  rt_raster_set_srid(newrast, rt_raster_get_srid(raster));
4512 
4513 
4518  if (rt_raster_is_empty(newrast))
4519  {
4520  elog(NOTICE, "Raster is empty. Returning an empty raster");
4521  rt_raster_destroy(raster);
4522  PG_FREE_IF_COPY(pgraster, 0);
4523 
4524  pgrtn = rt_raster_serialize(newrast);
4525  rt_raster_destroy(newrast);
4526  if (NULL == pgrtn) {
4527 
4528  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4529  PG_RETURN_NULL();
4530  }
4531 
4532  SET_VARSIZE(pgrtn, pgrtn->size);
4533  PG_RETURN_POINTER(pgrtn);
4534  }
4535 
4536 
4537  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Getting raster band %d...", nband);
4538 
4543  if (!rt_raster_has_band(raster, nband - 1)) {
4544  elog(NOTICE, "Raster does not have the required band. Returning a raster "
4545  "without a band");
4546  rt_raster_destroy(raster);
4547  PG_FREE_IF_COPY(pgraster, 0);
4548 
4549  pgrtn = rt_raster_serialize(newrast);
4550  rt_raster_destroy(newrast);
4551  if (NULL == pgrtn) {
4552  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4553  PG_RETURN_NULL();
4554  }
4555 
4556  SET_VARSIZE(pgrtn, pgrtn->size);
4557  PG_RETURN_POINTER(pgrtn);
4558  }
4559 
4560  /* Get the raster band */
4561  band = rt_raster_get_band(raster, nband - 1);
4562  if ( NULL == band ) {
4563  elog(NOTICE, "Could not get the required band. Returning a raster "
4564  "without a band");
4565  rt_raster_destroy(raster);
4566  PG_FREE_IF_COPY(pgraster, 0);
4567 
4568  pgrtn = rt_raster_serialize(newrast);
4569  rt_raster_destroy(newrast);
4570  if (NULL == pgrtn) {
4571  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4572  PG_RETURN_NULL();
4573  }
4574 
4575  SET_VARSIZE(pgrtn, pgrtn->size);
4576  PG_RETURN_POINTER(pgrtn);
4577  }
4578 
4579  /*
4580  * Get NODATA value
4581  */
4582  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Getting NODATA value for band...");
4583 
4584  if (rt_band_get_hasnodata_flag(band)) {
4585  rt_band_get_nodata(band, &newnodatavalue);
4586  }
4587 
4588  else {
4589  newnodatavalue = rt_band_get_min_value(band);
4590  }
4591 
4592  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: NODATA value for band: = %f",
4593  newnodatavalue);
4594 
4600  newinitialvalue = newnodatavalue;
4601 
4605  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Setting pixeltype...");
4606 
4607  if (PG_ARGISNULL(2)) {
4608  newpixeltype = rt_band_get_pixtype(band);
4609  }
4610 
4611  else {
4612  strFromText = text_to_cstring(PG_GETARG_TEXT_P(2));
4613  newpixeltype = rt_pixtype_index_from_name(strFromText);
4614  pfree(strFromText);
4615  if (newpixeltype == PT_END)
4616  newpixeltype = rt_band_get_pixtype(band);
4617  }
4618 
4619  if (newpixeltype == PT_END) {
4620  PG_FREE_IF_COPY(pgraster, 0);
4621  elog(ERROR, "RASTER_mapAlgebraExpr: Invalid pixeltype");
4622  PG_RETURN_NULL();
4623  }
4624 
4625  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Pixeltype set to %s",
4626  rt_pixtype_name(newpixeltype));
4627 
4628 
4629  /* Construct expression for raster values */
4630  if (!PG_ARGISNULL(3)) {
4631  expression = text_to_cstring(PG_GETARG_TEXT_P(3));
4632  len = strlen("SELECT (") + strlen(expression) + strlen(")::double precision");
4633  initexpr = (char *)palloc(len + 1);
4634 
4635  strncpy(initexpr, "SELECT (", strlen("SELECT ("));
4636  strncpy(initexpr + strlen("SELECT ("), expression, strlen(expression));
4637  strncpy(initexpr + strlen("SELECT (") + strlen(expression), ")::double precision", strlen(")::double precision"));
4638  initexpr[len] = '\0';
4639 
4640  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Expression is %s", initexpr);
4641 
4642  /* We don't need this memory */
4643  /*
4644  pfree(expression);
4645  expression = NULL;
4646  */
4647  }
4648 
4649 
4650 
4656  if (!PG_ARGISNULL(4)) {
4657  hasnodataval = 1;
4658  nodataval = PG_GETARG_FLOAT8(4);
4659  newinitialvalue = nodataval;
4660 
4661  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: new initial value = %f",
4662  newinitialvalue);
4663  }
4664  else
4665  hasnodataval = 0;
4666 
4667 
4668 
4674  if (rt_band_get_isnodata_flag(band)) {
4675 
4676  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: Band is a nodata band, returning "
4677  "a raster filled with nodata");
4678 
4679  ret = rt_raster_generate_new_band(newrast, newpixeltype,
4680  newinitialvalue, TRUE, newnodatavalue, 0);
4681 
4682  /* Free memory */
4683  if (initexpr)
4684  pfree(initexpr);
4685  rt_raster_destroy(raster);
4686  PG_FREE_IF_COPY(pgraster, 0);
4687 
4688  /* Serialize created raster */
4689  pgrtn = rt_raster_serialize(newrast);
4690  rt_raster_destroy(newrast);
4691  if (NULL == pgrtn) {
4692  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4693  PG_RETURN_NULL();
4694  }
4695 
4696  SET_VARSIZE(pgrtn, pgrtn->size);
4697  PG_RETURN_POINTER(pgrtn);
4698  }
4699 
4700 
4705  if (initexpr != NULL && ( !strcmp(initexpr, "SELECT [rast]") || !strcmp(initexpr, "SELECT [rast.val]") ) && !hasnodataval) {
4706 
4707  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Expression resumes to RAST. "
4708  "Returning raster with band %d from original raster", nband);
4709 
4710  POSTGIS_RT_DEBUGF(4, "RASTER_mapAlgebraExpr: New raster has %d bands",
4711  rt_raster_get_num_bands(newrast));
4712 
4713  rt_raster_copy_band(newrast, raster, nband - 1, 0);
4714 
4715  POSTGIS_RT_DEBUGF(4, "RASTER_mapAlgebraExpr: New raster now has %d bands",
4716  rt_raster_get_num_bands(newrast));
4717 
4718  if (initexpr)
4719  pfree(initexpr);
4720  rt_raster_destroy(raster);
4721  PG_FREE_IF_COPY(pgraster, 0);
4722 
4723  /* Serialize created raster */
4724  pgrtn = rt_raster_serialize(newrast);
4725  rt_raster_destroy(newrast);
4726  if (NULL == pgrtn) {
4727  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4728  PG_RETURN_NULL();
4729  }
4730 
4731  SET_VARSIZE(pgrtn, pgrtn->size);
4732  PG_RETURN_POINTER(pgrtn);
4733  }
4734 
4739  if (initexpr != NULL && strstr(initexpr, "[rast") == NULL) {
4740  ret = SPI_connect();
4741  if (ret != SPI_OK_CONNECT) {
4742  PG_FREE_IF_COPY(pgraster, 0);
4743  elog(ERROR, "RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
4744  PG_RETURN_NULL();
4745  };
4746 
4747  /* Execute the expresion into newval */
4748  ret = SPI_execute(initexpr, FALSE, 0);
4749 
4750  if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
4751 
4752  /* Free memory allocated out of the current context */
4753  if (SPI_tuptable)
4754  SPI_freetuptable(tuptable);
4755  PG_FREE_IF_COPY(pgraster, 0);
4756 
4757  SPI_finish();
4758  elog(ERROR, "RASTER_mapAlgebraExpr: Invalid construction for expression");
4759  PG_RETURN_NULL();
4760  }
4761 
4762  tupdesc = SPI_tuptable->tupdesc;
4763  tuptable = SPI_tuptable;
4764 
4765  tuple = tuptable->vals[0];
4766  newexpr = SPI_getvalue(tuple, tupdesc, 1);
4767  if ( ! newexpr ) {
4768  POSTGIS_RT_DEBUG(3, "Constant expression evaluated to NULL, keeping initvalue");
4769  newval = newinitialvalue;
4770  } else {
4771  newval = atof(newexpr);
4772  }
4773 
4774  SPI_freetuptable(tuptable);
4775 
4776  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: New raster value = %f",
4777  newval);
4778 
4779  SPI_finish();
4780 
4781  skipcomputation = 1;
4782 
4787  if (!hasnodataval) {
4788  newinitialvalue = newval;
4789  skipcomputation = 2;
4790  }
4791 
4792  /* Return the new raster as it will be before computing pixel by pixel */
4793  else if (FLT_NEQ(newval, newinitialvalue)) {
4794  skipcomputation = 2;
4795  }
4796  }
4797 
4802  ret = rt_raster_generate_new_band(newrast, newpixeltype,
4803  newinitialvalue, TRUE, newnodatavalue, 0);
4804 
4809  /*if (initexpr == NULL || skipcomputation == 2) {*/
4810  if (expression == NULL || skipcomputation == 2) {
4811 
4812  /* Free memory */
4813  if (initexpr)
4814  pfree(initexpr);
4815  rt_raster_destroy(raster);
4816  PG_FREE_IF_COPY(pgraster, 0);
4817 
4818  /* Serialize created raster */
4819  pgrtn = rt_raster_serialize(newrast);
4820  rt_raster_destroy(newrast);
4821  if (NULL == pgrtn) {
4822  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4823  PG_RETURN_NULL();
4824  }
4825 
4826  SET_VARSIZE(pgrtn, pgrtn->size);
4827  PG_RETURN_POINTER(pgrtn);
4828  }
4829 
4830  RASTER_DEBUG(3, "RASTER_mapAlgebraExpr: Creating new raster band...");
4831 
4832  /* Get the new raster band */
4833  newband = rt_raster_get_band(newrast, 0);
4834  if ( NULL == newband ) {
4835  elog(NOTICE, "Could not modify band for new raster. Returning new "
4836  "raster with the original band");
4837 
4838  if (initexpr)
4839  pfree(initexpr);
4840  rt_raster_destroy(raster);
4841  PG_FREE_IF_COPY(pgraster, 0);
4842 
4843  /* Serialize created raster */
4844  pgrtn = rt_raster_serialize(newrast);
4845  rt_raster_destroy(newrast);
4846  if (NULL == pgrtn) {
4847  elog(ERROR, "RASTER_mapAlgebraExpr: Could not serialize raster");
4848  PG_RETURN_NULL();
4849  }
4850 
4851  SET_VARSIZE(pgrtn, pgrtn->size);
4852  PG_RETURN_POINTER(pgrtn);
4853  }
4854 
4855  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: Main computing loop (%d x %d)",
4856  width, height);
4857 
4858  if (initexpr != NULL) {
4859  /* Convert [rast.val] to [rast] */
4860  newexpr = rtpg_strreplace(initexpr, "[rast.val]", "[rast]", NULL);
4861  pfree(initexpr); initexpr=newexpr;
4862 
4863  sprintf(place,"$1");
4864  for (i = 0, j = 1; i < argkwcount; i++) {
4865  len = 0;
4866  newexpr = rtpg_strreplace(initexpr, argkw[i], place, &len);
4867  pfree(initexpr); initexpr=newexpr;
4868  if (len > 0) {
4869  argtype[argcount] = argkwtypes[i];
4870  argcount++;
4871  argpos[i] = j++;
4872 
4873  sprintf(place, "$%d", j);
4874  }
4875  else {
4876  argpos[i] = 0;
4877  }
4878  }
4879 
4880  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: initexpr = %s", initexpr);
4881 
4882  /* define values */
4883  values = (Datum *) palloc(sizeof(Datum) * argcount);
4884  if (values == NULL) {
4885 
4886  SPI_finish();
4887 
4888  rt_raster_destroy(raster);
4889  PG_FREE_IF_COPY(pgraster, 0);
4890  rt_raster_destroy(newrast);
4891 
4892  elog(ERROR, "RASTER_mapAlgebraExpr: Could not allocate memory for value parameters of prepared statement");
4893  PG_RETURN_NULL();
4894  }
4895 
4896  /* define nulls */
4897  nulls = (char *)palloc(argcount);
4898  if (nulls == NULL) {
4899 
4900  SPI_finish();
4901 
4902  rt_raster_destroy(raster);
4903  PG_FREE_IF_COPY(pgraster, 0);
4904  rt_raster_destroy(newrast);
4905 
4906  elog(ERROR, "RASTER_mapAlgebraExpr: Could not allocate memory for null parameters of prepared statement");
4907  PG_RETURN_NULL();
4908  }
4909 
4910  /* Connect to SPI and prepare the expression */
4911  ret = SPI_connect();
4912  if (ret != SPI_OK_CONNECT) {
4913 
4914  if (initexpr)
4915  pfree(initexpr);
4916  rt_raster_destroy(raster);
4917  PG_FREE_IF_COPY(pgraster, 0);
4918  rt_raster_destroy(newrast);
4919 
4920  elog(ERROR, "RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
4921  PG_RETURN_NULL();
4922  };
4923 
4924  /* Type of all arguments is FLOAT8OID */
4925  spi_plan = SPI_prepare(initexpr, argcount, argtype);
4926 
4927  if (spi_plan == NULL) {
4928 
4929  rt_raster_destroy(raster);
4930  PG_FREE_IF_COPY(pgraster, 0);
4931  rt_raster_destroy(newrast);
4932 
4933  SPI_finish();
4934 
4935  pfree(initexpr);
4936 
4937  elog(ERROR, "RASTER_mapAlgebraExpr: Could not prepare expression");
4938  PG_RETURN_NULL();
4939  }
4940  }
4941 
4942  for (x = 0; x < width; x++) {
4943  for(y = 0; y < height; y++) {
4944  ret = rt_band_get_pixel(band, x, y, &r, NULL);
4945 
4950  if (ret == ES_NONE && FLT_NEQ(r, newnodatavalue)) {
4951  if (skipcomputation == 0) {
4952  if (initexpr != NULL) {
4953  /* Reset the null arg flags. */
4954  memset(nulls, 'n', argcount);
4955 
4956  for (i = 0; i < argkwcount; i++) {
4957  idx = argpos[i];
4958  if (idx < 1) continue;
4959  idx--;
4960 
4961  if (i == kX ) {
4962  /* x is 0 based index, but SQL expects 1 based index */
4963  values[idx] = Int32GetDatum(x+1);
4964  nulls[idx] = ' ';
4965  }
4966  else if (i == kY) {
4967  /* y is 0 based index, but SQL expects 1 based index */
4968  values[idx] = Int32GetDatum(y+1);
4969  nulls[idx] = ' ';
4970  }
4971  else if (i == kVAL ) {
4972  values[idx] = Float8GetDatum(r);
4973  nulls[idx] = ' ';
4974  }
4975 
4976  }
4977 
4978  ret = SPI_execute_plan(spi_plan, values, nulls, FALSE, 0);
4979  if (ret != SPI_OK_SELECT || SPI_tuptable == NULL ||
4980  SPI_processed != 1) {
4981  if (SPI_tuptable)
4982  SPI_freetuptable(tuptable);
4983 
4984  SPI_freeplan(spi_plan);
4985  SPI_finish();
4986 
4987  pfree(values);
4988  pfree(nulls);
4989  pfree(initexpr);
4990 
4991  rt_raster_destroy(raster);
4992  PG_FREE_IF_COPY(pgraster, 0);
4993  rt_raster_destroy(newrast);
4994 
4995  elog(ERROR, "RASTER_mapAlgebraExpr: Error executing prepared plan");
4996 
4997  PG_RETURN_NULL();
4998  }
4999 
5000  tupdesc = SPI_tuptable->tupdesc;
5001  tuptable = SPI_tuptable;
5002 
5003  tuple = tuptable->vals[0];
5004  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
5005  if ( SPI_result == SPI_ERROR_NOATTRIBUTE ) {
5006  POSTGIS_RT_DEBUGF(3, "Expression for pixel %d,%d (value %g) errored, skip setting", x+1,y+1,r);
5007  newval = newinitialvalue;
5008  }
5009  else if ( isnull ) {
5010  POSTGIS_RT_DEBUGF(3, "Expression for pixel %d,%d (value %g) evaluated to NULL, skip setting", x+1,y+1,r);
5011  newval = newinitialvalue;
5012  } else {
5013  newval = DatumGetFloat8(datum);
5014  }
5015 
5016  SPI_freetuptable(tuptable);
5017  }
5018 
5019  else
5020  newval = newinitialvalue;
5021 
5022  POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebraExpr: new value = %f",
5023  newval);
5024  }
5025 
5026 
5027  rt_band_set_pixel(newband, x, y, newval, NULL);
5028  }
5029 
5030  }
5031  }
5032 
5033  if (initexpr != NULL) {
5034  SPI_freeplan(spi_plan);
5035  SPI_finish();
5036 
5037  pfree(values);
5038  pfree(nulls);
5039  pfree(initexpr);
5040  }
5041  else {
5042  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: no SPI cleanup");
5043  }
5044 
5045 
5046  /* The newrast band has been modified */
5047 
5048  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: raster modified, serializing it.");
5049  /* Serialize created raster */
5050 
5051  rt_raster_destroy(raster);
5052  PG_FREE_IF_COPY(pgraster, 0);
5053 
5054  pgrtn = rt_raster_serialize(newrast);
5055  rt_raster_destroy(newrast);
5056  if (NULL == pgrtn)
5057  PG_RETURN_NULL();
5058 
5059  SET_VARSIZE(pgrtn, pgrtn->size);
5060 
5061  POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebraExpr: raster serialized");
5062 
5063 
5064  POSTGIS_RT_DEBUG(4, "RASTER_mapAlgebraExpr: returning raster");
5065 
5066 
5067  PG_RETURN_POINTER(pgrtn);
5068 }
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
double rt_raster_get_y_skew(rt_raster raster)
Get skew about the Y axis.
Definition: rt_raster.c:190
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:372
char * r
Definition: cu_in_wkt.c:24
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
tuple band
Definition: ovdump.py:57
tuple raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
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
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
tuple nband
Definition: pixval.py:52
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's SRID.
Definition: rt_raster.c:363
int32_t rt_raster_get_srid(rt_raster raster)
Get raster'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
tuple x
Definition: pixval.py:53
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'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
tuple y
Definition: pixval.py:54

Here is the call graph for this function: