PostGIS  3.0.0dev-r@@SVN_REVISION@@

◆ LWGEOM_dump_rings()

Datum LWGEOM_dump_rings ( PG_FUNCTION_ARGS  )

Definition at line 217 of file lwgeom_dump.c.

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.

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