PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ 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, "Missing libprotobuf-c");
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 */
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.
Definition: gserialized.c:239
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: gserialized.c:89
int gserialized_fast_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Read the box from the GSERIALIZED or return #LWFAILURE if box is unavailable.
Definition: gserialized.c:77
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1138
#define MULTILINETYPE
Definition: liblwgeom.h:120
#define LINETYPE
Definition: liblwgeom.h:117
#define LW_SUCCESS
Definition: liblwgeom.h:111
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:121
#define POLYGONTYPE
Definition: liblwgeom.h:118
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:1176
type
Definition: ovdump.py:42
Datum buffer(PG_FUNCTION_ARGS)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
double ymax
Definition: liblwgeom.h:343
double xmax
Definition: liblwgeom.h:341
double ymin
Definition: liblwgeom.h:342
double xmin
Definition: liblwgeom.h:340

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

Here is the call graph for this function: