PostGIS  2.3.7dev-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 4412 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.

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