PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ LWGEOM_dump_rings()

Datum LWGEOM_dump_rings ( PG_FUNCTION_ARGS  )

Definition at line 219 of file lwgeom_dump.c.

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

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: