35 #include "utils/elog.h" 36 #include "utils/array.h" 37 #include "utils/geo_decls.h" 40 #include "../postgis_config.h" 42 #include "lwgeom_pg.h" 65 #define PUSH(x,y) ((x)->stack[(x)->stacklen++]=(y)) 66 #define LAST(x) ((x)->stack[(x)->stacklen-1]) 67 #define POP(x) (--((x)->stacklen)) 76 FuncCallContext *funcctx;
81 AttInMetadata *attinmeta;
82 MemoryContext oldcontext, newcontext;
89 if (SRF_IS_FIRSTCALL())
91 funcctx = SRF_FIRSTCALL_INIT();
92 newcontext = funcctx->multi_call_memory_ctx;
94 oldcontext = MemoryContextSwitchTo(newcontext);
96 pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
101 state->
root = lwgeom;
115 funcctx->user_fctx = state;
121 get_call_result_type(fcinfo, 0, &tupdesc);
122 BlessTupleDesc(tupdesc);
128 attinmeta = TupleDescGetAttInMetadata(tupdesc);
129 funcctx->attinmeta = attinmeta;
131 MemoryContextSwitchTo(oldcontext);
135 funcctx = SRF_PERCALL_SETUP();
136 newcontext = funcctx->multi_call_memory_ctx;
139 state = funcctx->user_fctx;
142 if ( ! state->
root ) SRF_RETURN_DONE(funcctx);
149 tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
150 result = HeapTupleGetDatum(tuple);
153 SRF_RETURN_NEXT(funcctx, result);
171 if ( i ) ptr += sprintf(ptr,
",");
172 ptr += sprintf(ptr,
"%d", state->
stack[i]->
idx+1);
186 oldcontext = MemoryContextSwitchTo(newcontext);
193 MemoryContextSwitchTo(oldcontext);
198 if ( !
POP(state) ) SRF_RETURN_DONE(funcctx);
206 tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
207 result = TupleGetDatum(funcctx->slot, tuple);
209 SRF_RETURN_NEXT(funcctx, result);
223 FuncCallContext *funcctx;
227 AttInMetadata *attinmeta;
228 MemoryContext oldcontext, newcontext;
233 if (SRF_IS_FIRSTCALL())
235 funcctx = SRF_FIRSTCALL_INIT();
236 newcontext = funcctx->multi_call_memory_ctx;
238 oldcontext = MemoryContextSwitchTo(newcontext);
240 pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
243 elog(ERROR,
"Input is not a polygon");
251 assert (state->
poly);
254 funcctx->user_fctx = state;
260 get_call_result_type(fcinfo, 0, &tupdesc);
261 BlessTupleDesc(tupdesc);
267 attinmeta = TupleDescGetAttInMetadata(tupdesc);
268 funcctx->attinmeta = attinmeta;
270 MemoryContextSwitchTo(oldcontext);
274 funcctx = SRF_PERCALL_SETUP();
275 newcontext = funcctx->multi_call_memory_ctx;
278 state = funcctx->user_fctx;
289 oldcontext = MemoryContextSwitchTo(newcontext);
302 sprintf(address,
"{%d}", state->
ringnum);
307 MemoryContextSwitchTo(oldcontext);
309 tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
310 result = HeapTupleGetDatum(tuple);
312 SRF_RETURN_NEXT(funcctx, result);
315 SRF_RETURN_DONE(funcctx);
332 #if POSTGIS_GEOS_VERSION < 35 334 elog(ERROR,
"The GEOS version this PostGIS binary " 335 "was compiled against (%d) doesn't support " 336 "'%s' function (3.5.0+ required)",
349 FuncCallContext *funcctx;
350 collection_fctx *fctx;
351 MemoryContext oldcontext;
354 if (SRF_IS_FIRSTCALL())
359 int maxvertices = 256;
362 funcctx = SRF_FIRSTCALL_INIT();
367 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
372 gser = PG_GETARG_GSERIALIZED_P(0);
378 if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
379 maxvertices = PG_GETARG_INT32(1);
387 SRF_RETURN_DONE(funcctx);
390 fctx = (collection_fctx *) palloc(
sizeof(collection_fctx));
394 fctx->numgeoms = col->
ngeoms;
398 funcctx->user_fctx = fctx;
399 MemoryContextSwitchTo(oldcontext);
403 funcctx = SRF_PERCALL_SETUP();
404 fctx = funcctx->user_fctx;
406 if (fctx->nextgeom < fctx->numgeoms)
410 SRF_RETURN_NEXT(funcctx, PointerGetDatum(gpart));
415 SRF_RETURN_DONE(funcctx);
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
char * lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Datum LWGEOM_dump(PG_FUNCTION_ARGS)
#define POSTGIS_GEOS_VERSION
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
PG_FUNCTION_INFO_V1(LWGEOM_dump)
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
struct GEOMDUMPSTATE GEOMDUMPSTATE
Datum ST_Subdivide(PG_FUNCTION_ARGS)
LWPOLY * lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Datum LWGEOM_dump_rings(PG_FUNCTION_ARGS)
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
GEOMDUMPNODE * stack[MAXDEPTH]
LWCOLLECTION * lwgeom_subdivide(const LWGEOM *geom, int maxvertices)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
void * lwalloc(size_t size)
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
struct GEOMDUMPNODE_T GEOMDUMPNODE
This library is the generic geometry handling section of PostGIS.