PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ LWGEOM_dump()

Datum LWGEOM_dump ( PG_FUNCTION_ARGS  )

Definition at line 70 of file lwgeom_dump.c.

71 {
72  GSERIALIZED *pglwgeom;
73  LWCOLLECTION *lwcoll;
74  LWGEOM *lwgeom;
75  FuncCallContext *funcctx;
76  GEOMDUMPSTATE *state;
77  GEOMDUMPNODE *node;
78  TupleDesc tupdesc;
79  HeapTuple tuple;
80  AttInMetadata *attinmeta;
81  MemoryContext oldcontext, newcontext;
82  Datum result;
83  char address[256];
84  char *ptr;
85  int i;
86  char *values[2];
87 
88  if (SRF_IS_FIRSTCALL())
89  {
90  funcctx = SRF_FIRSTCALL_INIT();
91  newcontext = funcctx->multi_call_memory_ctx;
92 
93  oldcontext = MemoryContextSwitchTo(newcontext);
94 
95  pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
96  lwgeom = lwgeom_from_gserialized(pglwgeom);
97 
98  /* Create function state */
99  state = lwalloc(sizeof(GEOMDUMPSTATE));
100  state->root = lwgeom;
101  state->stacklen=0;
102 
103  if ( lwgeom_is_collection(lwgeom) )
104  {
105  /*
106  * Push a GEOMDUMPNODE on the state stack
107  */
108  node = lwalloc(sizeof(GEOMDUMPNODE));
109  node->idx=0;
110  node->geom = lwgeom;
111  PUSH(state, node);
112  }
113 
114  funcctx->user_fctx = state;
115 
116  /*
117  * Build a tuple description for an
118  * geometry_dump tuple
119  */
120  get_call_result_type(fcinfo, 0, &tupdesc);
121  BlessTupleDesc(tupdesc);
122 
123  /*
124  * generate attribute metadata needed later to produce
125  * tuples from raw C strings
126  */
127  attinmeta = TupleDescGetAttInMetadata(tupdesc);
128  funcctx->attinmeta = attinmeta;
129 
130  MemoryContextSwitchTo(oldcontext);
131  }
132 
133  /* stuff done on every call of the function */
134  funcctx = SRF_PERCALL_SETUP();
135  newcontext = funcctx->multi_call_memory_ctx;
136 
137  /* get state */
138  state = funcctx->user_fctx;
139 
140  /* Handled simple geometries */
141  if ( ! state->root ) SRF_RETURN_DONE(funcctx);
142  /* Return nothing for empties */
143  if ( lwgeom_is_empty(state->root) ) SRF_RETURN_DONE(funcctx);
144  if ( ! lwgeom_is_collection(state->root) )
145  {
146  values[0] = "{}";
147  values[1] = lwgeom_to_hexwkb(state->root, WKB_EXTENDED, 0);
148  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
149  result = HeapTupleGetDatum(tuple);
150 
151  state->root = NULL;
152  SRF_RETURN_NEXT(funcctx, result);
153  }
154 
155  while (1)
156  {
157  node = LAST(state);
158  lwcoll = (LWCOLLECTION*)node->geom;
159 
160  if ( node->idx < lwcoll->ngeoms )
161  {
162  lwgeom = lwcoll->geoms[node->idx];
163  if ( ! lwgeom_is_collection(lwgeom) )
164  {
165  /* write address of current geom */
166  ptr=address;
167  *ptr++='{';
168  for (i=0; i<state->stacklen; i++)
169  {
170  if ( i ) ptr += sprintf(ptr, ",");
171  ptr += sprintf(ptr, "%d", state->stack[i]->idx+1);
172  }
173  *ptr++='}';
174  *ptr='\0';
175 
176  break;
177  }
178 
179  /*
180  * It's a collection, increment index
181  * of current node, push a new one on the
182  * stack
183  */
184 
185  oldcontext = MemoryContextSwitchTo(newcontext);
186 
187  node = lwalloc(sizeof(GEOMDUMPNODE));
188  node->idx=0;
189  node->geom = lwgeom;
190  PUSH(state, node);
191 
192  MemoryContextSwitchTo(oldcontext);
193 
194  continue;
195  }
196 
197  if ( ! POP(state) ) SRF_RETURN_DONE(funcctx);
198  LAST(state)->idx++;
199  }
200 
201  lwgeom->srid = state->root->srid;
202 
203  values[0] = address;
204  values[1] = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, 0);
205  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
206  result = TupleGetDatum(funcctx->slot, tuple);
207  node->idx++;
208  SRF_RETURN_NEXT(funcctx, result);
209 }
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
Definition: lwgeom.c:1079
#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
#define PUSH(x, y)
Definition: lwgeom_dump.c:64
#define LAST(x)
Definition: lwgeom_dump.c:65
#define POP(x)
Definition: lwgeom_dump.c:66
if(!(yy_init))
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition: lwinline.h:193
uint32_t idx
Definition: lwgeom_dump.c:50
LWGEOM * geom
Definition: lwgeom_dump.c:51
LWGEOM * root
Definition: lwgeom_dump.c:60
GEOMDUMPNODE * stack[MAXDEPTH]
Definition: lwgeom_dump.c:59
uint32_t ngeoms
Definition: liblwgeom.h:566
LWGEOM ** geoms
Definition: liblwgeom.h:561
int32_t srid
Definition: liblwgeom.h:446

References GEOMDUMPNODE_T::geom, LWCOLLECTION::geoms, GEOMDUMPNODE_T::idx, if(), LAST, lwalloc(), lwgeom_from_gserialized(), lwgeom_is_collection(), lwgeom_is_empty(), lwgeom_to_hexwkb(), LWCOLLECTION::ngeoms, POP, PUSH, GEOMDUMPSTATE::root, LWGEOM::srid, GEOMDUMPSTATE::stack, GEOMDUMPSTATE::stacklen, and WKB_EXTENDED.

Here is the call graph for this function: