PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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.
char * lwgeom_to_hexwkb_buffer(const LWGEOM *geom, uint8_t variant)
Definition lwout_wkb.c:845
void * lwalloc(size_t size)
Definition lwutil.c:227
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:1125
#define WKB_EXTENDED
Definition liblwgeom.h:2212
#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
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
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, 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: