PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ RASTER_asGDALRaster()

Datum RASTER_asGDALRaster ( PG_FUNCTION_ARGS  )

Definition at line 148 of file rtpg_gdal.c.

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

Referenced by RASTER_fromGDALRaster().

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