27 #include "utils/elog.h"
28 #include "utils/array.h"
29 #include "utils/geo_decls.h"
30 #include "utils/lsyscache.h"
31 #include "catalog/pg_type.h"
34 #include "../postgis_config.h"
35 #include "lwgeom_pg.h"
37 #include "access/htup_details.h"
77 FuncCallContext *funcctx;
78 MemoryContext oldcontext, newcontext;
88 bool isnull[2] = {0,0};
91 if (SRF_IS_FIRSTCALL()) {
92 funcctx = SRF_FIRSTCALL_INIT();
94 newcontext = funcctx->multi_call_memory_ctx;
95 oldcontext = MemoryContextSwitchTo(newcontext);
98 pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
103 MemoryContextSwitchTo(oldcontext);
104 funcctx = SRF_PERCALL_SETUP();
105 SRF_RETURN_DONE(funcctx);
109 state =
lwalloc(
sizeof *state);
110 state->
root = lwgeom;
116 funcctx->user_fctx = state;
129 if (get_call_result_type(fcinfo, 0, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE) {
130 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
131 errmsg(
"set-valued function called in context that cannot accept a set")));
134 BlessTupleDesc(funcctx->tuple_desc);
137 get_typlenbyvalalign(INT4OID, &state->
typlen, &state->
byval, &state->
align);
139 MemoryContextSwitchTo(oldcontext);
143 funcctx = SRF_PERCALL_SETUP();
144 newcontext = funcctx->multi_call_memory_ctx;
147 state = funcctx->user_fctx;
172 switch(lwgeom->
type) {
175 if (state->
pt == 0) {
178 if (state->
pt <= 3) {
236 ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
237 errmsg(
"Invalid Geometry type %d passed to ST_DumpPoints()", lwgeom->
type)));
252 if (--state->
stacklen == 0) SRF_RETURN_DONE(funcctx);
260 pathpt[0] = PointerGetDatum(construct_array(state->
path, state->
pathlen+1,
263 pathpt[1] = PointerGetDatum(geometry_serialize((
LWGEOM*)lwpoint));
265 tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
266 result = HeapTupleGetDatum(tuple);
267 SRF_RETURN_NEXT(funcctx,
result);
277 elog(ERROR,
"Unabled to dump overly nested collection");
280 lwgeom = lwcoll->
geoms[node->
idx++];
295 if (--state->
stacklen == 0) SRF_RETURN_DONE(funcctx);
303 FuncCallContext *funcctx;
304 MemoryContext oldcontext, newcontext;
314 bool isnull[2] = {0, 0};
317 if (SRF_IS_FIRSTCALL())
319 funcctx = SRF_FIRSTCALL_INIT();
321 newcontext = funcctx->multi_call_memory_ctx;
322 oldcontext = MemoryContextSwitchTo(newcontext);
324 pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
330 MemoryContextSwitchTo(oldcontext);
331 funcctx = SRF_PERCALL_SETUP();
332 SRF_RETURN_DONE(funcctx);
336 state =
lwalloc(
sizeof *state);
337 state->
root = lwgeom;
343 funcctx->user_fctx = state;
355 if (get_call_result_type(fcinfo, 0, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE)
358 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
359 errmsg(
"set-valued function called in context that cannot accept a set")));
362 BlessTupleDesc(funcctx->tuple_desc);
365 get_typlenbyvalalign(INT4OID, &state->
typlen, &state->
byval, &state->
align);
367 MemoryContextSwitchTo(oldcontext);
371 funcctx = SRF_PERCALL_SETUP();
372 newcontext = funcctx->multi_call_memory_ctx;
375 state = funcctx->user_fctx;
464 pathpt[0] = PointerGetDatum(construct_array(state->
path,
470 pathpt[1] = PointerGetDatum(geometry_serialize((
LWGEOM *)segment));
472 tuple = heap_form_tuple(funcctx->tuple_desc, pathpt, isnull);
473 result = HeapTupleGetDatum(tuple);
474 SRF_RETURN_NEXT(funcctx,
result);
479 SRF_RETURN_DONE(funcctx);
494 elog(ERROR,
"Unable to dump overly nested collection");
497 lwgeom = lwcoll->
geoms[node->
idx++];
514 SRF_RETURN_DONE(funcctx);
char result[OUT_DOUBLE_BUFFER_SIZE]
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
LWPOINT * lwcircstring_get_lwpoint(const LWCIRCSTRING *circ, uint32_t where)
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
LWTRIANGLE * lwgeom_as_lwtriangle(const LWGEOM *lwgeom)
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
void * lwalloc(size_t size)
LWCIRCSTRING * lwgeom_as_lwcircstring(const LWGEOM *lwgeom)
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
LWPOINT * lwpoint_make(int32_t srid, int hasz, int hasm, const POINT4D *p)
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
This library is the generic geometry handling section of PostGIS.
Datum LWGEOM_dumpsegments(PG_FUNCTION_ARGS)
Datum LWGEOM_dumppoints(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(LWGEOM_dumppoints)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
struct dumpnode stack[MAXDEPTH]