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

◆ ST_AsMVTGeom()

Datum ST_AsMVTGeom ( PG_FUNCTION_ARGS  )

Definition at line 42 of file lwgeom_out_mvt.c.

43{
44#ifndef HAVE_LIBPROTOBUF
45 elog(ERROR, "ST_AsMVTGeom: Compiled without protobuf-c support");
46 PG_RETURN_NULL();
47#else
48 GBOX *bounds = NULL;
49 int32_t extent = 0;
50 int32_t buffer = 0;
51 bool clip_geom = true;
52 GSERIALIZED *geom_in, *geom_out;
53 LWGEOM *lwgeom_in, *lwgeom_out;
54 uint8_t type = 0;
55
56 if (PG_ARGISNULL(0))
57 {
58 PG_RETURN_NULL();
59 }
60
61 if (PG_ARGISNULL(1))
62 {
63 elog(ERROR, "%s: Geometric bounds cannot be null", __func__);
64 PG_RETURN_NULL();
65 }
66 bounds = (GBOX *)PG_GETARG_POINTER(1);
67 if (bounds->xmax - bounds->xmin <= 0 || bounds->ymax - bounds->ymin <= 0)
68 {
69 elog(ERROR, "%s: Geometric bounds are too small", __func__);
70 PG_RETURN_NULL();
71 }
72
73 extent = PG_ARGISNULL(2) ? 4096 : PG_GETARG_INT32(2);
74 if (extent <= 0)
75 {
76 elog(ERROR, "%s: Extent must be greater than 0", __func__);
77 PG_RETURN_NULL();
78 }
79
80 buffer = PG_ARGISNULL(3) ? 256 : PG_GETARG_INT32(3);
81 clip_geom = PG_ARGISNULL(4) ? true : PG_GETARG_BOOL(4);
82
83 geom_in = PG_GETARG_GSERIALIZED_P_COPY(0);
84 type = gserialized_get_type(geom_in);
85
86 /* If possible, peek into the bounding box before deserializing it to discard small geometries
87 * We don't check COLLECTIONTYPE since that might be a collection of points */
88 if (type == LINETYPE || type == POLYGONTYPE || type == MULTILINETYPE || type == MULTIPOLYGONTYPE)
89 {
90 GBOX gserialized_box;
91 /* We only apply the optimization if the bounding box is available */
92 if (gserialized_fast_gbox_p(geom_in, &gserialized_box) == LW_SUCCESS)
93 {
94 /* Shortcut to drop geometries smaller than the resolution */
95 double geom_width = gserialized_box.xmax - gserialized_box.xmin;
96 double geom_height = gserialized_box.ymax - gserialized_box.ymin;
97
98 /* We use half of the square height and width as limit: We use this
99 * and not area so it works properly with lines */
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)
103 {
104 PG_RETURN_NULL();
105 }
106 }
107 }
108
109 lwgeom_in = lwgeom_from_gserialized(geom_in);
110
111 lwgeom_out = mvt_geom(lwgeom_in, bounds, extent, buffer, clip_geom);
112 if (lwgeom_out == NULL)
113 PG_RETURN_NULL();
114
115 geom_out = geometry_serialize(lwgeom_out);
116 lwgeom_free(lwgeom_out);
117 PG_FREE_IF_COPY(geom_in, 0);
118 PG_RETURN_POINTER(geom_out);
119#endif
120}
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)
Definition lwgeom.c:1246
#define MULTILINETYPE
Definition liblwgeom.h:106
#define LINETYPE
Definition liblwgeom.h:103
#define LW_SUCCESS
Definition liblwgeom.h:97
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
#define POLYGONTYPE
Definition liblwgeom.h:104
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.
Definition mvt.c:931
Datum buffer(PG_FUNCTION_ARGS)
double ymax
Definition liblwgeom.h:357
double xmax
Definition liblwgeom.h:355
double ymin
Definition liblwgeom.h:356
double xmin
Definition liblwgeom.h:354

References buffer(), gserialized_fast_gbox_p(), gserialized_get_type(), LINETYPE, LW_SUCCESS, lwgeom_free(), lwgeom_from_gserialized(), MULTILINETYPE, MULTIPOLYGONTYPE, mvt_geom(), POLYGONTYPE, GBOX::xmax, GBOX::xmin, GBOX::ymax, and GBOX::ymin.

Here is the call graph for this function: