PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ LWGEOM_dump_rings()

Datum LWGEOM_dump_rings ( PG_FUNCTION_ARGS  )

Definition at line 218 of file lwgeom_dump.c.

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

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

Here is the call graph for this function: