PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ RASTER_Contour()

Datum RASTER_Contour ( PG_FUNCTION_ARGS  )

Definition at line 459 of file rtpg_gdal.c.

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

References clamp_srid(), rt_contour_t::elevation, FALSE, rt_contour_t::geom, rt_contour_t::id, result, rt_raster_deserialize(), rt_raster_gdal_contour(), rt_raster_get_num_bands(), rt_raster_get_srid(), rtpg_getSR(), and SRID_UNKNOWN.

Here is the call graph for this function: