PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ LWGEOM_dump_rings()

Datum LWGEOM_dump_rings ( PG_FUNCTION_ARGS  )

Definition at line 221 of file lwgeom_dump.c.

222 {
223  GSERIALIZED *pglwgeom;
224  LWGEOM *lwgeom;
225  FuncCallContext *funcctx;
226  struct POLYDUMPSTATE *state;
227  TupleDesc tupdesc;
228  HeapTuple tuple;
229  AttInMetadata *attinmeta;
230  MemoryContext oldcontext, newcontext;
231  Datum result;
232  char address[256];
233  char *values[2];
234 
235  if (SRF_IS_FIRSTCALL())
236  {
237  funcctx = SRF_FIRSTCALL_INIT();
238  newcontext = funcctx->multi_call_memory_ctx;
239 
240  oldcontext = MemoryContextSwitchTo(newcontext);
241 
242  pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
243  if ( gserialized_get_type(pglwgeom) != POLYGONTYPE )
244  {
245  elog(ERROR, "Input is not a polygon");
246  }
247 
248  lwgeom = lwgeom_from_gserialized(pglwgeom);
249 
250  /* Create function state */
251  state = lwalloc(sizeof(struct POLYDUMPSTATE));
252  state->poly = lwgeom_as_lwpoly(lwgeom);
253  assert (state->poly);
254  state->ringnum=0;
255 
256  funcctx->user_fctx = state;
257 
258  /*
259  * Build a tuple description for an
260  * geometry_dump tuple
261  */
262  get_call_result_type(fcinfo, 0, &tupdesc);
263  BlessTupleDesc(tupdesc);
264 
265  /*
266  * generate attribute metadata needed later to produce
267  * tuples from raw C strings
268  */
269  attinmeta = TupleDescGetAttInMetadata(tupdesc);
270  funcctx->attinmeta = attinmeta;
271 
272  MemoryContextSwitchTo(oldcontext);
273  }
274 
275  /* stuff done on every call of the function */
276  funcctx = SRF_PERCALL_SETUP();
277  newcontext = funcctx->multi_call_memory_ctx;
278 
279  /* get state */
280  state = funcctx->user_fctx;
281 
282  /* Loop trough polygon rings */
283  while (state->ringnum < state->poly->nrings )
284  {
285  LWPOLY* poly = state->poly;
286  POINTARRAY *ring;
287  LWGEOM* ringgeom;
288 
289  /* Switch to an appropriate memory context for POINTARRAY
290  * cloning and hexwkb allocation */
291  oldcontext = MemoryContextSwitchTo(newcontext);
292 
293  /* We need a copy of input ring here */
294  ring = ptarray_clone_deep(poly->rings[state->ringnum]);
295 
296  /* Construct another polygon with shell only */
297  ringgeom = (LWGEOM*)lwpoly_construct(
298  poly->srid,
299  NULL, /* TODO: could use input bounding box here */
300  1, /* one ring */
301  &ring);
302 
303  /* Write path as ``{ <ringnum> }'' */
304  sprintf(address, "{%d}", state->ringnum);
305 
306  values[0] = address;
307  values[1] = lwgeom_to_hexwkb_buffer(ringgeom, WKB_EXTENDED);
308 
309  MemoryContextSwitchTo(oldcontext);
310 
311  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
312  result = HeapTupleGetDatum(tuple);
313  ++state->ringnum;
314  SRF_RETURN_NEXT(funcctx, result);
315  }
316 
317  SRF_RETURN_DONE(funcctx);
318 
319 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:267
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: gserialized.c:89
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:634
char * lwgeom_to_hexwkb_buffer(const LWGEOM *geom, uint8_t variant)
Definition: lwout_wkb.c:845
#define POLYGONTYPE
Definition: liblwgeom.h:118
#define WKB_EXTENDED
Definition: liblwgeom.h:2148
void * lwalloc(size_t size)
Definition: lwutil.c:227
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:198
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition: lwpoly.c:43
POINTARRAY ** rings
Definition: liblwgeom.h:533
uint32_t nrings
Definition: liblwgeom.h:538
int32_t srid
Definition: liblwgeom.h:534
uint32_t ringnum
Definition: lwgeom_dump.c:216
LWPOLY * poly
Definition: lwgeom_dump.c:217

References gserialized_get_type(), lwalloc(), lwgeom_as_lwpoly(), lwgeom_from_gserialized(), lwgeom_to_hexwkb_buffer(), lwpoly_construct(), LWPOLY::nrings, POLYDUMPSTATE::poly, POLYGONTYPE, ptarray_clone_deep(), result, POLYDUMPSTATE::ringnum, LWPOLY::rings, LWPOLY::srid, and WKB_EXTENDED.

Here is the call graph for this function: