PostGIS  3.7.0dev-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  MemoryContext oldcontext, newcontext;
81  Datum result;
82  char address[256];
83  char *ptr;
84  int i;
85  char *values[2];
86 
87  if (SRF_IS_FIRSTCALL())
88  {
89  funcctx = SRF_FIRSTCALL_INIT();
90  newcontext = funcctx->multi_call_memory_ctx;
91 
92  oldcontext = MemoryContextSwitchTo(newcontext);
93 
94  pglwgeom = PG_GETARG_GSERIALIZED_P_COPY(0);
95  lwgeom = lwgeom_from_gserialized(pglwgeom);
96 
97  /* Create function state */
98  state = lwalloc(sizeof(GEOMDUMPSTATE));
99  state->root = lwgeom;
100  state->stacklen=0;
101 
102  if ( lwgeom_is_collection(lwgeom) )
103  {
104  /*
105  * Push a GEOMDUMPNODE on the state stack
106  */
107  node = lwalloc(sizeof(GEOMDUMPNODE));
108  node->idx=0;
109  node->geom = lwgeom;
110  PUSH(state, node);
111  }
112 
113  funcctx->user_fctx = state;
114 
115  /*
116  * Build a tuple description for an
117  * geometry_dump tuple
118  */
119  get_call_result_type(fcinfo, 0, &tupdesc);
120  BlessTupleDesc(tupdesc);
121 
122  /*
123  * generate attribute metadata needed later to produce
124  * tuples from raw C strings
125  */
126  funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);;
127 
128  MemoryContextSwitchTo(oldcontext);
129  }
130 
131  /* stuff done on every call of the function */
132  funcctx = SRF_PERCALL_SETUP();
133  newcontext = funcctx->multi_call_memory_ctx;
134 
135  /* get state */
136  state = funcctx->user_fctx;
137 
138  /* Handled simple geometries */
139  if ( ! state->root ) SRF_RETURN_DONE(funcctx);
140  /* Return nothing for empties */
141  if ( lwgeom_is_empty(state->root) ) SRF_RETURN_DONE(funcctx);
142  if ( ! lwgeom_is_collection(state->root) )
143  {
144  values[0] = "{}";
145  values[1] = lwgeom_to_hexwkb_buffer(state->root, WKB_EXTENDED);
146  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
147  result = HeapTupleGetDatum(tuple);
148 
149  state->root = NULL;
150  SRF_RETURN_NEXT(funcctx, result);
151  }
152 
153  while (1)
154  {
155  node = LAST(state);
156  lwcoll = (LWCOLLECTION*)node->geom;
157 
158  if ( node->idx < lwcoll->ngeoms )
159  {
160  lwgeom = lwcoll->geoms[node->idx];
161  if ( ! lwgeom_is_collection(lwgeom) )
162  {
163  /* write address of current geom */
164  ptr=address;
165  *ptr++='{';
166  for (i=0; i<state->stacklen; i++)
167  {
168  if ( i ) ptr += sprintf(ptr, ",");
169  ptr += sprintf(ptr, "%d", state->stack[i]->idx+1);
170  }
171  *ptr++='}';
172  *ptr='\0';
173 
174  break;
175  }
176 
177  /*
178  * It's a collection, increment index
179  * of current node, push a new one on the
180  * stack
181  */
182 
183  if (state->stacklen > MAXDEPTH)
184  elog(ERROR, "Unable to dump overly nested collection.");
185 
186  oldcontext = MemoryContextSwitchTo(newcontext);
187 
188  node = lwalloc(sizeof(GEOMDUMPNODE));
189  node->idx=0;
190  node->geom = lwgeom;
191  PUSH(state, node);
192 
193  MemoryContextSwitchTo(oldcontext);
194 
195  continue;
196  }
197 
198  if ( ! POP(state) ) SRF_RETURN_DONE(funcctx);
199  LAST(state)->idx++;
200  }
201 
202  lwgeom->srid = state->root->srid;
203 
204  values[0] = address;
205  values[1] = lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED);
206  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
207  result = TupleGetDatum(funcctx->slot, tuple);
208  node->idx++;
209  SRF_RETURN_NEXT(funcctx, result);
210 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:267
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:268
char * lwgeom_to_hexwkb_buffer(const LWGEOM *geom, uint8_t variant)
Definition: lwout_wkb.c:845
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM contains sub-geometries or not This basically just checks that the struct ...
Definition: lwgeom.c:1097
#define WKB_EXTENDED
Definition: liblwgeom.h:2209
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define MAXDEPTH
Definition: lwgeom_dump.c:55
#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:199
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:580
LWGEOM ** geoms
Definition: liblwgeom.h:575
int32_t srid
Definition: liblwgeom.h:460

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

Here is the call graph for this function: