PostGIS 3.0.6dev-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 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.
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
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
#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:193
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, 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: