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

Definition at line 11593 of file rt_pg.c.

References clamp_srid(), FALSE, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, rtrowdump::raster, result, rt_raster_deserialize(), rt_raster_destroy(), rt_raster_get_srid(), rt_raster_to_gdal(), rtpg_getSR(), rtpg_trim(), and SRID_UNKNOWN.

11594 {
11595  rt_pgraster *pgraster = NULL;
11596  rt_raster raster;
11597 
11598  text *formattext = NULL;
11599  char *format = NULL;
11600  char **options = NULL;
11601  text *optiontext = NULL;
11602  char *option = NULL;
11603  int srid = SRID_UNKNOWN;
11604  char *srs = NULL;
11605 
11606  ArrayType *array;
11607  Oid etype;
11608  Datum *e;
11609  bool *nulls;
11610  int16 typlen;
11611  bool typbyval;
11612  char typalign;
11613  int n = 0;
11614  int i = 0;
11615  int j = 0;
11616 
11617  uint8_t *gdal = NULL;
11618  uint64_t gdal_size = 0;
11619  bytea *result = NULL;
11620  uint64_t result_size = 0;
11621 
11622  POSTGIS_RT_DEBUG(3, "RASTER_asGDALRaster: Starting");
11623 
11624  /* pgraster is null, return null */
11625  if (PG_ARGISNULL(0)) PG_RETURN_NULL();
11626  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
11627 
11628  raster = rt_raster_deserialize(pgraster, FALSE);
11629  if (!raster) {
11630  PG_FREE_IF_COPY(pgraster, 0);
11631  elog(ERROR, "RASTER_asGDALRaster: Could not deserialize raster");
11632  PG_RETURN_NULL();
11633  }
11634 
11635  /* format is required */
11636  if (PG_ARGISNULL(1)) {
11637  elog(NOTICE, "Format must be provided");
11638  rt_raster_destroy(raster);
11639  PG_FREE_IF_COPY(pgraster, 0);
11640  PG_RETURN_NULL();
11641  }
11642  else {
11643  formattext = PG_GETARG_TEXT_P(1);
11644  format = text_to_cstring(formattext);
11645  }
11646 
11647  POSTGIS_RT_DEBUGF(3, "RASTER_asGDALRaster: Arg 1 (format) is %s", format);
11648 
11649  /* process options */
11650  if (!PG_ARGISNULL(2)) {
11651  POSTGIS_RT_DEBUG(3, "RASTER_asGDALRaster: Processing Arg 2 (options)");
11652  array = PG_GETARG_ARRAYTYPE_P(2);
11653  etype = ARR_ELEMTYPE(array);
11654  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
11655 
11656  switch (etype) {
11657  case TEXTOID:
11658  break;
11659  default:
11660  rt_raster_destroy(raster);
11661  PG_FREE_IF_COPY(pgraster, 0);
11662  elog(ERROR, "RASTER_asGDALRaster: Invalid data type for options");
11663  PG_RETURN_NULL();
11664  break;
11665  }
11666 
11667  deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
11668  &nulls, &n);
11669 
11670  if (n) {
11671  options = (char **) palloc(sizeof(char *) * (n + 1));
11672  if (options == NULL) {
11673  rt_raster_destroy(raster);
11674  PG_FREE_IF_COPY(pgraster, 0);
11675  elog(ERROR, "RASTER_asGDALRaster: Could not allocate memory for options");
11676  PG_RETURN_NULL();
11677  }
11678 
11679  /* clean each option */
11680  for (i = 0, j = 0; i < n; i++) {
11681  if (nulls[i]) continue;
11682 
11683  option = NULL;
11684  switch (etype) {
11685  case TEXTOID:
11686  optiontext = (text *) DatumGetPointer(e[i]);
11687  if (NULL == optiontext) break;
11688  option = text_to_cstring(optiontext);
11689 
11690  /* trim string */
11691  option = rtpg_trim(option);
11692  POSTGIS_RT_DEBUGF(3, "RASTER_asGDALRaster: option is '%s'", option);
11693  break;
11694  }
11695 
11696  if (strlen(option)) {
11697  options[j] = (char *) palloc(sizeof(char) * (strlen(option) + 1));
11698  options[j] = option;
11699  j++;
11700  }
11701  }
11702 
11703  if (j > 0) {
11704  /* trim allocation */
11705  options = repalloc(options, (j + 1) * sizeof(char *));
11706 
11707  /* add NULL to end */
11708  options[j] = NULL;
11709 
11710  }
11711  else {
11712  pfree(options);
11713  options = NULL;
11714  }
11715  }
11716  }
11717 
11718  /* process srid */
11719  /* NULL srid means use raster's srid */
11720  if (PG_ARGISNULL(3))
11721  srid = rt_raster_get_srid(raster);
11722  else
11723  srid = PG_GETARG_INT32(3);
11724 
11725  /* get srs from srid */
11726  if (clamp_srid(srid) != SRID_UNKNOWN) {
11727  srs = rtpg_getSR(srid);
11728  if (NULL == srs) {
11729  if (NULL != options) {
11730  for (i = j - 1; i >= 0; i--) pfree(options[i]);
11731  pfree(options);
11732  }
11733  rt_raster_destroy(raster);
11734  PG_FREE_IF_COPY(pgraster, 0);
11735  elog(ERROR, "RASTER_asGDALRaster: Could not find srtext for SRID (%d)", srid);
11736  PG_RETURN_NULL();
11737  }
11738  POSTGIS_RT_DEBUGF(3, "RASTER_asGDALRaster: Arg 3 (srs) is %s", srs);
11739  }
11740  else
11741  srs = NULL;
11742 
11743  POSTGIS_RT_DEBUG(3, "RASTER_asGDALRaster: Generating GDAL raster");
11744  gdal = rt_raster_to_gdal(raster, srs, format, options, &gdal_size);
11745 
11746  /* free memory */
11747  if (NULL != options) {
11748  for (i = j - 1; i >= 0; i--) pfree(options[i]);
11749  pfree(options);
11750  }
11751  if (NULL != srs) pfree(srs);
11752  rt_raster_destroy(raster);
11753  PG_FREE_IF_COPY(pgraster, 0);
11754 
11755  if (!gdal) {
11756  elog(ERROR, "RASTER_asGDALRaster: Could not allocate and generate GDAL raster");
11757  PG_RETURN_NULL();
11758  }
11759  POSTGIS_RT_DEBUGF(3, "RASTER_asGDALRaster: GDAL raster generated with %d bytes", (int) gdal_size);
11760 
11761  /* result is a varlena */
11762  result_size = gdal_size + VARHDRSZ;
11763  result = (bytea *) palloc(result_size);
11764  if (NULL == result) {
11765  elog(ERROR, "RASTER_asGDALRaster: Insufficient virtual memory for GDAL raster");
11766  PG_RETURN_NULL();
11767  }
11768  SET_VARSIZE(result, result_size);
11769  memcpy(VARDATA(result), gdal, VARSIZE(result) - VARHDRSZ);
11770 
11771  /* for test output
11772  FILE *fh = NULL;
11773  fh = fopen("/tmp/out.dat", "w");
11774  fwrite(gdal, sizeof(uint8_t), gdal_size, fh);
11775  fclose(fh);
11776  */
11777 
11778  /* free gdal mem buffer */
11779  if (gdal) CPLFree(gdal);
11780 
11781  POSTGIS_RT_DEBUG(3, "RASTER_asGDALRaster: Returning pointer to GDAL raster");
11782  PG_RETURN_POINTER(result);
11783 }
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition: lwutil.c:326
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
static char * rtpg_trim(const char *input)
Definition: rt_pg.c:856
static char * rtpg_getSR(int srid)
Definition: rt_pg.c:912
tuple raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:123
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_api.c:5661
char ** result
Definition: liblwgeom.h:218
uint8_t * rt_raster_to_gdal(rt_raster raster, const char *srs, char *format, char **options, uint64_t *gdalsize)
Return formatted GDAL raster from raster.
Definition: rt_api.c:8794
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rt_pg.h:58
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:154
#define FALSE
Definition: dbfopen.c:169
Struct definitions.
Definition: rt_api.h:2175
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rt_pg.h:62
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_api.c:8350

Here is the call graph for this function: