PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ RASTER_Contour()

Datum RASTER_Contour ( PG_FUNCTION_ARGS  )

Definition at line 456 of file rtpg_gdal.c.

457 {
458  /* For return values */
459  typedef struct gdal_contour_result_t {
460  size_t ncontours;
461  struct rt_contour_t *contours;
462  } gdal_contour_result_t;
463 
464  FuncCallContext *funcctx;
465 
466  if (SRF_IS_FIRSTCALL())
467  {
468  MemoryContext oldcontext;
469  TupleDesc tupdesc;
470  gdal_contour_result_t *result;
471  rt_pgraster *pgraster = NULL;
472 
473  /* For reading the raster */
474  int src_srid = SRID_UNKNOWN;
475  char *src_srs = NULL;
476  rt_raster raster = NULL;
477  int num_bands;
478  int band, rv;
479 
480  /* For reading the levels[] */
481  ArrayType *array;
482  size_t array_size = 0;
483 
484  /* For the level parameters */
485  double level_base = 0.0;
486  double level_interval = 100.0;
487  double *fixed_levels = NULL;
488  size_t fixed_levels_count = 0;
489 
490  /* for the polygonize flag */
491  bool polygonize = false;
492 
493  /* create a function context for cross-call persistence */
494  funcctx = SRF_FIRSTCALL_INIT();
495 
496  /* switch to memory context appropriate for multiple function calls */
497  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
498 
499  /* To carry the output from rt_raster_gdal_contour */
500  result = palloc0(sizeof(gdal_contour_result_t));
501 
502  /* Build a tuple descriptor for our return result */
503  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
504  MemoryContextSwitchTo(oldcontext);
505  ereport(ERROR, (
506  errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
507  errmsg(
508  "function returning record called in context "
509  "that cannot accept type record"
510  )
511  ));
512  }
513  BlessTupleDesc(tupdesc);
514  funcctx->tuple_desc = tupdesc;
515 
516  /* Read the raster */
517  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
518  raster = rt_raster_deserialize(pgraster, FALSE);
519  num_bands = rt_raster_get_num_bands(raster);
520  src_srid = clamp_srid(rt_raster_get_srid(raster));
521  src_srs = rtpg_getSR(src_srid);
522 
523  /* Read the band number */
524  band = PG_GETARG_INT32(1);
525  if (band < 1 || band > num_bands) {
526  elog(ERROR, "%s: band number must be between 1 and %u inclusive", __func__, num_bands);
527  }
528 
529  /* Read the level_interval */
530  level_interval = PG_GETARG_FLOAT8(2);
531 
532  /* Read the level_base */
533  level_base = PG_GETARG_FLOAT8(3);
534 
535  if (level_interval <= 0.0) {
536  elog(ERROR, "%s: level interval must be greater than zero", __func__);
537  }
538 
539  /* Read the polygonize flag */
540  polygonize = PG_GETARG_BOOL(5);
541 
542  /* Read the levels array */
543  array = PG_GETARG_ARRAYTYPE_P(4);
544  array_size = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
545  if (array_size > 0) {
546  Datum value;
547  bool isnull;
548  ArrayIterator iterator = array_create_iterator(array, 0, NULL);
549  fixed_levels = palloc0(array_size * sizeof(double));
550  while (array_iterate(iterator, &value, &isnull))
551  {
552  /* Skip nulls */
553  if (isnull)
554  continue;
555 
556  /* Can out if for some reason we are about to blow memory */
557  if (fixed_levels_count >= array_size)
558  break;
559 
560  fixed_levels[fixed_levels_count++] = DatumGetFloat8(value);
561  }
562  }
563 
564  /* Run the contouring routine */
566  /* input parameters */
567  raster,
568  band,
569  src_srid,
570  src_srs,
571  level_interval,
572  level_base,
573  fixed_levels_count,
574  fixed_levels,
575  polygonize,
576  /* output parameters */
577  &(result->ncontours),
578  &(result->contours)
579  );
580 
581  /* No-op on bad return */
582  if (rv == FALSE) {
583  funcctx = SRF_PERCALL_SETUP();
584  SRF_RETURN_DONE(funcctx);
585  }
586 
587  funcctx->user_fctx = result;
588  funcctx->max_calls = result->ncontours;
589  MemoryContextSwitchTo(oldcontext);
590  }
591 
592  /* stuff done on every call of the function */
593  funcctx = SRF_PERCALL_SETUP();
594 
595  /* do when there is more left to send */
596  if (funcctx->call_cntr < funcctx->max_calls) {
597 
598  HeapTuple tuple;
599  Datum srf_result;
600  Datum values[3] = {0, 0, 0};
601  bool nulls[3] = {0, 0, 0};
602 
603  gdal_contour_result_t *result = funcctx->user_fctx;
604  struct rt_contour_t c = result->contours[funcctx->call_cntr];
605 
606  if (c.geom) {
607  values[0] = PointerGetDatum(c.geom);
608  values[1] = Int32GetDatum(c.id);
609  values[2] = Float8GetDatum(c.elevation);
610  }
611  else {
612  nulls[0] = true;
613  nulls[1] = true;
614  nulls[2] = true;
615  }
616 
617  /* return a tuple */
618  tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
619  srf_result = HeapTupleGetDatum(tuple);
620  SRF_RETURN_NEXT(funcctx, srf_result);
621  }
622  else {
623  SRF_RETURN_DONE(funcctx);
624  }
625 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:267
#define FALSE
Definition: dbfopen.c:72
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:230
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
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:376
int rt_raster_gdal_contour(rt_raster src_raster, int src_band, int src_srid, const char *src_srs, double contour_interval, double contour_base, int fixed_level_count, double *fixed_levels, int polygonize, size_t *ncontours, struct rt_contour_t **contours)
Return palloc'ed list of contours.
Definition: rt_gdal.c:89
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:725
int value
Definition: genraster.py:62
band
Definition: ovdump.py:58
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)
GSERIALIZED * geom
Definition: librtcore.h:1749
double elevation
Definition: librtcore.h:1750
Struct definitions.
Definition: librtcore.h:2396

References ovdump::band, clamp_srid(), rt_contour_t::elevation, FALSE, rt_contour_t::geom, rt_contour_t::id, rtrowdump::raster, result, rt_raster_deserialize(), rt_raster_gdal_contour(), rt_raster_get_num_bands(), rt_raster_get_srid(), rtpg_getSR(), SRID_UNKNOWN, and genraster::value.

Here is the call graph for this function: