234{
235 FuncCallContext *funcctx;
236
239
241 bool isnull[3] = {0,0,0};
242 Datum tuple_arr[3];
243 HeapTuple tuple;
245
246 if (SRF_IS_FIRSTCALL())
247 {
248 MemoryContext oldcontext;
249 const char *func_name;
250 char gbounds_is_empty;
252 double size;
253 funcctx = SRF_FIRSTCALL_INIT();
254
255
256 gbounds = PG_GETARG_GSERIALIZED_P(1);
257 size = PG_GETARG_FLOAT8(0);
258
260
261
262 if (size <= 0.0 || gbounds_is_empty)
263 {
264 funcctx = SRF_PERCALL_SETUP();
265 SRF_RETURN_DONE(funcctx);
266 }
267
268 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
269
270
271
272
273
274 func_name = get_func_name(fcinfo->flinfo->fn_oid);
275 if (strcmp(func_name, "st_hexagongrid") == 0)
276 {
278 }
279 else if (strcmp(func_name, "st_squaregrid") == 0)
280 {
282 }
283 else
284 {
285 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
286 errmsg("%s called from unsupported functional context '%s'", __func__, func_name)));
287 }
288
289 funcctx->user_fctx = state;
290
291
292 if (get_call_result_type(fcinfo, 0, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE)
293 {
294 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
295 errmsg("set-valued function called in context that cannot accept a set")));
296 }
297
298 BlessTupleDesc(funcctx->tuple_desc);
299 MemoryContextSwitchTo(oldcontext);
300 }
301
302
303 funcctx = SRF_PERCALL_SETUP();
304
305
306 state = funcctx->user_fctx;
307
308
310 {
311 SRF_RETURN_DONE(funcctx);
312 }
313
314
315 tuple_arr[1] = Int32GetDatum(state->
i);
316 tuple_arr[2] = Int32GetDatum(state->
j);
317
318
320 {
323
325 break;
328
330 break;
331 default:
332 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
333 errmsg(
"%s called from with unsupported shape '%d'", __func__, state->
cell_shape)));
334 }
335
336 tuple_arr[0] = PointerGetDatum(geometry_serialize(lwgeom));
338
339
340 tuple = heap_form_tuple(funcctx->tuple_desc, tuple_arr, isnull);
341 result = HeapTupleGetDatum(tuple);
342 SRF_RETURN_NEXT(funcctx,
result);
343}
char result[OUT_DOUBLE_BUFFER_SIZE]
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Read the box from the GSERIALIZED or calculate it if necessary.
static LWGEOM * square(double origin_x, double origin_y, double size, int cell_i, int cell_j, int32_t srid)
static HexagonGridState * hexagon_grid_state(double size, const GBOX *gbox, int32_t srid)
static SquareGridState * square_grid_state(double size, const GBOX *gbox, int32_t srid)
static void square_state_next(SquareGridState *state)
static void hexagon_state_next(HexagonGridState *state)
static LWGEOM * hexagon(double origin_x, double origin_y, double size, int cell_i, int cell_j, int32_t srid)