459 typedef struct gdal_contour_result_t {
462 } gdal_contour_result_t;
464 FuncCallContext *funcctx;
466 if (SRF_IS_FIRSTCALL())
468 MemoryContext oldcontext;
470 gdal_contour_result_t *
result;
475 char *src_srs = NULL;
482 size_t array_size = 0;
485 double level_base = 0.0;
486 double level_interval = 100.0;
487 double *fixed_levels = NULL;
488 size_t fixed_levels_count = 0;
491 bool polygonize =
false;
494 funcctx = SRF_FIRSTCALL_INIT();
497 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
500 result = palloc0(
sizeof(gdal_contour_result_t));
503 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
504 MemoryContextSwitchTo(oldcontext);
506 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
508 "function returning record called in context "
509 "that cannot accept type record"
513 BlessTupleDesc(tupdesc);
514 funcctx->tuple_desc = tupdesc;
517 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
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);
530 level_interval = PG_GETARG_FLOAT8(2);
533 level_base = PG_GETARG_FLOAT8(3);
535 if (level_interval <= 0.0) {
536 elog(ERROR,
"%s: level interval must be greater than zero", __func__);
540 polygonize = PG_GETARG_BOOL(5);
543 array = PG_GETARG_ARRAYTYPE_P(4);
544 array_size = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
545 if (array_size > 0) {
548 ArrayIterator iterator = array_create_iterator(array, 0, NULL);
549 fixed_levels = palloc0(array_size *
sizeof(
double));
550 while (array_iterate(iterator, &
value, &isnull))
557 if (fixed_levels_count >= array_size)
560 fixed_levels[fixed_levels_count++] = DatumGetFloat8(
value);
583 funcctx = SRF_PERCALL_SETUP();
584 SRF_RETURN_DONE(funcctx);
587 funcctx->user_fctx =
result;
588 funcctx->max_calls =
result->ncontours;
589 MemoryContextSwitchTo(oldcontext);
593 funcctx = SRF_PERCALL_SETUP();
596 if (funcctx->call_cntr < funcctx->max_calls) {
600 Datum values[3] = {0, 0, 0};
601 bool nulls[3] = {0, 0, 0};
603 gdal_contour_result_t *
result = funcctx->user_fctx;
607 values[0] = PointerGetDatum(c.
geom);
608 values[1] = Int32GetDatum(c.
id);
618 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
619 srf_result = HeapTupleGetDatum(tuple);
620 SRF_RETURN_NEXT(funcctx, srf_result);
623 SRF_RETURN_DONE(funcctx);
char result[OUT_DOUBLE_BUFFER_SIZE]
#define SRID_UNKNOWN
Unknown SRID value.
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...
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
uint16_t rt_raster_get_num_bands(rt_raster raster)
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.
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
char * rtpg_getSR(int32_t srid)