PostGIS  2.1.10dev-r@@SVN_REVISION@@
Datum LWGEOM_dump_rings ( PG_FUNCTION_ARGS  )

Definition at line 204 of file lwgeom_dump.c.

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

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

Here is the call graph for this function: