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

◆ ST_ShapeGrid()

Datum ST_ShapeGrid ( PG_FUNCTION_ARGS  )

Definition at line 233 of file lwgeom_generate_grid.c.

234{
235 FuncCallContext *funcctx;
236
237 GSERIALIZED *gbounds;
238 GeometryGridState *state;
239
240 LWGEOM *lwgeom;
241 bool isnull[3] = {0,0,0}; /* needed to say no value is null */
242 Datum tuple_arr[3]; /* used to construct the composite return value */
243 HeapTuple tuple;
244 Datum result; /* the actual composite return value */
245
246 if (SRF_IS_FIRSTCALL())
247 {
248 MemoryContext oldcontext;
249 const char *func_name;
250 char gbounds_is_empty;
251 GBOX bounds;
252 double size;
253 funcctx = SRF_FIRSTCALL_INIT();
254
255 /* Get a local copy of the bounds we are going to fill with shapes */
256 gbounds = PG_GETARG_GSERIALIZED_P(1);
257 size = PG_GETARG_FLOAT8(0);
258
259 gbounds_is_empty = (gserialized_get_gbox_p(gbounds, &bounds) == LW_FAILURE);
260
261 /* quick opt-out if we get nonsensical inputs */
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 * Support both hexagon and square grids with one function,
272 * by checking the calling signature up front.
273 */
274 func_name = get_func_name(fcinfo->flinfo->fn_oid);
275 if (strcmp(func_name, "st_hexagongrid") == 0)
276 {
277 state = (GeometryGridState*)hexagon_grid_state(size, &bounds, gserialized_get_srid(gbounds));
278 }
279 else if (strcmp(func_name, "st_squaregrid") == 0)
280 {
281 state = (GeometryGridState*)square_grid_state(size, &bounds, gserialized_get_srid(gbounds));
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 /* get tuple description for return type */
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 /* stuff done on every call of the function */
303 funcctx = SRF_PERCALL_SETUP();
304
305 /* get state */
306 state = funcctx->user_fctx;
307
308 /* Stop when we've used up all the grid squares */
309 if (state->done)
310 {
311 SRF_RETURN_DONE(funcctx);
312 }
313
314 /* Store grid cell coordinates */
315 tuple_arr[1] = Int32GetDatum(state->i);
316 tuple_arr[2] = Int32GetDatum(state->j);
317
318 /* Generate geometry */
319 switch (state->cell_shape)
320 {
321 case SHAPE_HEXAGON:
322 lwgeom = hexagon(0.0, 0.0, state->size, state->i, state->j, state->srid);
323 /* Increment to next cell */
325 break;
326 case SHAPE_SQUARE:
327 lwgeom = square(0.0, 0.0, state->size, state->i, state->j, state->srid);
328 /* Increment to next cell */
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));
337 lwfree(lwgeom);
338
339 /* Form tuple and return */
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]
Definition cu_print.c:267
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.
Definition gserialized.c:94
#define LW_FAILURE
Definition liblwgeom.h:96
void lwfree(void *mem)
Definition lwutil.c:248
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)
@ SHAPE_SQUARE
@ SHAPE_HEXAGON
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)

References GeometryGridState::cell_shape, HexagonGridState::cell_shape, GeometryGridState::done, gserialized_get_gbox_p(), gserialized_get_srid(), hexagon(), hexagon_grid_state(), hexagon_state_next(), GeometryGridState::i, HexagonGridState::i, GeometryGridState::j, HexagonGridState::j, LW_FAILURE, lwfree(), result, SHAPE_HEXAGON, SHAPE_SQUARE, GeometryGridState::size, HexagonGridState::size, square(), square_grid_state(), square_state_next(), GeometryGridState::srid, and HexagonGridState::srid.

Here is the call graph for this function: