26 #include "utils/builtins.h"
27 #include "executor/spi.h"
28 #include "../postgis_config.h"
29 #include "lwgeom_pg.h"
34 #ifdef HAVE_LIBPROTOBUF
35 #include "vector_tile.pb-c.h"
44 #ifndef HAVE_LIBPROTOBUF
45 elog(ERROR,
"Missing libprotobuf-c");
51 bool clip_geom =
true;
53 LWGEOM *lwgeom_in, *lwgeom_out;
63 elog(ERROR,
"%s: Geometric bounds cannot be null", __func__);
66 bounds = (
GBOX *)PG_GETARG_POINTER(1);
69 elog(ERROR,
"%s: Geometric bounds are too small", __func__);
73 extent = PG_ARGISNULL(2) ? 4096 : PG_GETARG_INT32(2);
76 elog(ERROR,
"%s: Extent must be greater than 0", __func__);
80 buffer = PG_ARGISNULL(3) ? 256 : PG_GETARG_INT32(3);
81 clip_geom = PG_ARGISNULL(4) ? true : PG_GETARG_BOOL(4);
83 geom_in = PG_GETARG_GSERIALIZED_P_COPY(0);
95 double geom_width = gserialized_box.
xmax - gserialized_box.
xmin;
96 double geom_height = gserialized_box.
ymax - gserialized_box.
ymin;
100 double bounds_width = ((bounds->
xmax - bounds->
xmin) / extent) / 2.0;
101 double bounds_height = ((bounds->
ymax - bounds->
ymin) / extent) / 2.0;
102 if (geom_width < bounds_width && geom_height < bounds_height)
111 lwgeom_out =
mvt_geom(lwgeom_in, bounds, extent,
buffer, clip_geom);
112 if (lwgeom_out == NULL)
117 PG_FREE_IF_COPY(geom_in, 0);
118 PG_RETURN_POINTER(geom_out);
128 #ifndef HAVE_LIBPROTOBUF
129 elog(ERROR,
"Missing libprotobuf-c");
132 MemoryContext aggcontext;
136 postgis_initialize_cache(fcinfo);
138 if (!AggCheckCallContext(fcinfo, &aggcontext))
139 elog(ERROR,
"%s called in non-aggregate context", __func__);
140 MemoryContextSwitchTo(aggcontext);
142 if (PG_ARGISNULL(0)) {
143 ctx = palloc(
sizeof(*ctx));
144 ctx->
name =
"default";
145 if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
148 if (PG_NARGS() > 3 && !PG_ARGISNULL(3))
149 ctx->
extent = PG_GETARG_INT32(3);
151 if (PG_NARGS() > 4 && !PG_ARGISNULL(4))
153 if (PG_NARGS() > 5 && !PG_ARGISNULL(5))
162 if (!type_is_rowtype(get_fn_expr_argtype(fcinfo->flinfo, 1)))
163 elog(ERROR,
"%s: parameter row cannot be other than a rowtype", __func__);
164 ctx->
row = PG_GETARG_HEAPTUPLEHEADER(1);
167 PG_FREE_IF_COPY(ctx->
row, 1);
168 PG_RETURN_POINTER(ctx);
178 #ifndef HAVE_LIBPROTOBUF
179 elog(ERROR,
"Missing libprotobuf-c");
184 elog(DEBUG2,
"%s called", __func__);
185 if (!AggCheckCallContext(fcinfo, NULL))
186 elog(ERROR,
"%s called in non-aggregate context", __func__);
190 bytea *emptybuf = palloc(VARHDRSZ);
191 SET_VARSIZE(emptybuf, VARHDRSZ);
192 PG_RETURN_BYTEA_P(emptybuf);
197 PG_RETURN_BYTEA_P(buf);
204 #ifndef HAVE_LIBPROTOBUF
205 elog(ERROR,
"Missing libprotobuf-c");
209 elog(DEBUG2,
"%s called", __func__);
210 if (!AggCheckCallContext(fcinfo, NULL))
211 elog(ERROR,
"%s called in non-aggregate context", __func__);
215 bytea *emptybuf = palloc(VARHDRSZ);
216 SET_VARSIZE(emptybuf, VARHDRSZ);
217 PG_RETURN_BYTEA_P(emptybuf);
229 #ifndef HAVE_LIBPROTOBUF
230 elog(ERROR,
"Missing libprotobuf-c");
233 MemoryContext aggcontext, oldcontext;
235 elog(DEBUG2,
"%s called", __func__);
236 if (!AggCheckCallContext(fcinfo, &aggcontext))
237 elog(ERROR,
"%s called in non-aggregate context", __func__);
239 oldcontext = MemoryContextSwitchTo(aggcontext);
241 MemoryContextSwitchTo(oldcontext);
243 PG_RETURN_POINTER(ctx);
250 #ifndef HAVE_LIBPROTOBUF
251 elog(ERROR,
"Missing libprotobuf-c");
254 MemoryContext aggcontext, oldcontext;
256 elog(DEBUG2,
"%s called", __func__);
257 if (!AggCheckCallContext(fcinfo, &aggcontext))
258 elog(ERROR,
"%s called in non-aggregate context", __func__);
262 oldcontext = MemoryContextSwitchTo(aggcontext);
264 MemoryContextSwitchTo(oldcontext);
265 PG_RETURN_POINTER(ctx);
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
int gserialized_fast_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Read the box from the GSERIALIZED or return #LWFAILURE if box is unavailable.
void lwgeom_free(LWGEOM *geom)
This library is the generic geometry handling section of PostGIS.
Datum ST_AsMVTGeom(PG_FUNCTION_ARGS)
Datum pgis_asmvt_serialfn(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(ST_AsMVTGeom)
Process input parameters to mvt_geom and returned serialized geometry.
Datum pgis_asmvt_finalfn(PG_FUNCTION_ARGS)
Datum pgis_asmvt_transfn(PG_FUNCTION_ARGS)
Datum pgis_asmvt_deserialfn(PG_FUNCTION_ARGS)
Datum pgis_asmvt_combinefn(PG_FUNCTION_ARGS)
mvt_agg_context * mvt_ctx_combine(mvt_agg_context *ctx1, mvt_agg_context *ctx2)
mvt_agg_context * mvt_ctx_deserialize(const bytea *ba)
LWGEOM * mvt_geom(LWGEOM *lwgeom, const GBOX *gbox, uint32_t extent, uint32_t buffer, bool clip_geom)
Transform a geometry into vector tile coordinate space.
bytea * mvt_agg_finalfn(mvt_agg_context *ctx)
Finalize aggregation.
bytea * mvt_ctx_serialize(mvt_agg_context *ctx)
void mvt_agg_init_context(mvt_agg_context *ctx)
Initialize aggregation context.
void mvt_agg_transfn(mvt_agg_context *ctx)
Aggregation step.
Datum buffer(PG_FUNCTION_ARGS)
char * text_to_cstring(const text *textptr)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)