PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ RASTER_asGDALRaster()

Datum RASTER_asGDALRaster ( PG_FUNCTION_ARGS  )

Definition at line 149 of file rtpg_gdal.c.

150 {
151  rt_pgraster *pgraster = NULL;
153 
154  text *formattext = NULL;
155  char *format = NULL;
156  char **options = NULL;
157  text *optiontext = NULL;
158  char *option = NULL;
159  int32_t srid = SRID_UNKNOWN;
160  char *srs = NULL;
161 
162  ArrayType *array;
163  Oid etype;
164  Datum *e;
165  bool *nulls;
166  int16 typlen;
167  bool typbyval;
168  char typalign;
169  int n = 0;
170  int i = 0;
171  int j = 0;
172 
173  uint8_t *gdal = NULL;
174  uint64_t gdal_size = 0;
175  bytea *result = NULL;
176  uint64_t result_size = 0;
177 
178  POSTGIS_RT_DEBUG(3, "RASTER_asGDALRaster: Starting");
179 
180  /* pgraster is null, return null */
181  if (PG_ARGISNULL(0)) PG_RETURN_NULL();
182  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
183 
184  raster = rt_raster_deserialize(pgraster, FALSE);
185  if (!raster) {
186  PG_FREE_IF_COPY(pgraster, 0);
187  elog(ERROR, "RASTER_asGDALRaster: Could not deserialize raster");
188  PG_RETURN_NULL();
189  }
190 
191  /* format is required */
192  if (PG_ARGISNULL(1)) {
193  elog(NOTICE, "Format must be provided");
195  PG_FREE_IF_COPY(pgraster, 0);
196  PG_RETURN_NULL();
197  }
198  else {
199  formattext = PG_GETARG_TEXT_P(1);
200  format = text_to_cstring(formattext);
201  }
202 
203  POSTGIS_RT_DEBUGF(3, "RASTER_asGDALRaster: Arg 1 (format) is %s", format);
204 
205  /* process options */
206  if (!PG_ARGISNULL(2)) {
207  POSTGIS_RT_DEBUG(3, "RASTER_asGDALRaster: Processing Arg 2 (options)");
208  array = PG_GETARG_ARRAYTYPE_P(2);
209  etype = ARR_ELEMTYPE(array);
210  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
211 
212  switch (etype) {
213  case TEXTOID:
214  break;
215  default:
217  PG_FREE_IF_COPY(pgraster, 0);
218  elog(ERROR, "RASTER_asGDALRaster: Invalid data type for options");
219  PG_RETURN_NULL();
220  break;
221  }
222 
223  deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
224  &nulls, &n);
225 
226  if (n) {
227  options = (char **) palloc(sizeof(char *) * (n + 1));
228  if (options == NULL) {
230  PG_FREE_IF_COPY(pgraster, 0);
231  elog(ERROR, "RASTER_asGDALRaster: Could not allocate memory for options");
232  PG_RETURN_NULL();
233  }
234 
235  /* clean each option */
236  for (i = 0, j = 0; i < n; i++) {
237  if (nulls[i]) continue;
238 
239  option = NULL;
240  switch (etype) {
241  case TEXTOID:
242  optiontext = (text *) DatumGetPointer(e[i]);
243  if (NULL == optiontext) break;
244  option = text_to_cstring(optiontext);
245 
246  /* trim string */
247  option = rtpg_trim(option);
248  POSTGIS_RT_DEBUGF(3, "RASTER_asGDALRaster: option is '%s'", option);
249  break;
250  }
251 
252  if (strlen(option)) {
253  options[j] = (char *) palloc(sizeof(char) * (strlen(option) + 1));
254  strcpy(options[j], option);
255  j++;
256  }
257  }
258 
259  if (j > 0) {
260  /* trim allocation */
261  options = repalloc(options, (j + 1) * sizeof(char *));
262 
263  /* add NULL to end */
264  options[j] = NULL;
265 
266  }
267  else {
268  pfree(options);
269  options = NULL;
270  }
271  }
272  }
273 
274  /* process srid */
275  /* NULL srid means use raster's srid */
276  if (PG_ARGISNULL(3))
277  srid = rt_raster_get_srid(raster);
278  else
279  srid = PG_GETARG_INT32(3);
280 
281  /* get srs from srid */
282  if (clamp_srid(srid) != SRID_UNKNOWN) {
283  srs = rtpg_getSR(srid);
284  if (NULL == srs) {
285  if (NULL != options) {
286  for (i = j - 1; i >= 0; i--) pfree(options[i]);
287  pfree(options);
288  }
290  PG_FREE_IF_COPY(pgraster, 0);
291  elog(ERROR, "RASTER_asGDALRaster: Could not find srtext for SRID (%d)", srid);
292  PG_RETURN_NULL();
293  }
294  POSTGIS_RT_DEBUGF(3, "RASTER_asGDALRaster: Arg 3 (srs) is %s", srs);
295  }
296  else
297  srs = NULL;
298 
299  POSTGIS_RT_DEBUG(3, "RASTER_asGDALRaster: Generating GDAL raster");
300  gdal = rt_raster_to_gdal(raster, srs, format, options, &gdal_size);
301 
302  /* free memory */
303  if (NULL != options) {
304  for (i = j - 1; i >= 0; i--) pfree(options[i]);
305  pfree(options);
306  }
307  if (NULL != srs) pfree(srs);
309  PG_FREE_IF_COPY(pgraster, 0);
310 
311  if (!gdal) {
312  elog(ERROR, "RASTER_asGDALRaster: Could not allocate and generate GDAL raster");
313  PG_RETURN_NULL();
314  }
315  POSTGIS_RT_DEBUGF(3, "RASTER_asGDALRaster: GDAL raster generated with %d bytes", (int) gdal_size);
316 
317  /* result is a varlena */
318  result_size = gdal_size + VARHDRSZ;
319  result = (bytea *) palloc(result_size);
320  if (NULL == result) {
321  elog(ERROR, "RASTER_asGDALRaster: Insufficient virtual memory for GDAL raster");
322  PG_RETURN_NULL();
323  }
324  SET_VARSIZE(result, result_size);
325  memcpy(VARDATA(result), gdal, VARSIZE_ANY_EXHDR(result));
326 
327  /* free gdal mem buffer */
328  CPLFree(gdal);
329 
330  POSTGIS_RT_DEBUG(3, "RASTER_asGDALRaster: Returning pointer to GDAL raster");
331  PG_RETURN_POINTER(result);
332 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:262
#define FALSE
Definition: dbfopen.c:72
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:215
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition: lwutil.c:333
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
Definition: rt_raster.c:360
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_raster.c:1720
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:86
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:725
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
char * rtpg_getSR(int32_t srid)
char * rtpg_trim(const char *input)
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:65
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:69
Struct definitions.
Definition: librtcore.h:2403

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.

Here is the call graph for this function: