[postgis-tickets] r15880 - ST_AsMVT / ST_AsMVTGeom refactor to avoid deep clone
bjorn at wololo.org
bjorn at wololo.org
Tue Oct 3 11:39:41 PDT 2017
Author: bjornharrtell
Date: 2017-10-03 11:39:41 -0700 (Tue, 03 Oct 2017)
New Revision: 15880
Modified:
trunk/postgis/lwgeom_out_mvt.c
trunk/postgis/mvt.c
trunk/postgis/mvt.h
Log:
ST_AsMVT / ST_AsMVTGeom refactor to avoid deep clone
Modified: trunk/postgis/lwgeom_out_mvt.c
===================================================================
--- trunk/postgis/lwgeom_out_mvt.c 2017-10-03 10:14:10 UTC (rev 15879)
+++ trunk/postgis/lwgeom_out_mvt.c 2017-10-03 18:39:41 UTC (rev 15880)
@@ -52,7 +52,7 @@
bool clip_geom;
if (PG_ARGISNULL(0))
PG_RETURN_NULL();
- geom_in = PG_GETARG_GSERIALIZED_P(0);
+ geom_in = PG_GETARG_GSERIALIZED_P_COPY(0);
lwgeom_in = lwgeom_from_gserialized(geom_in);
if (PG_ARGISNULL(1))
elog(ERROR, "ST_AsMVTGeom: parameter bounds cannot be null");
Modified: trunk/postgis/mvt.c
===================================================================
--- trunk/postgis/mvt.c 2017-10-03 10:14:10 UTC (rev 15879)
+++ trunk/postgis/mvt.c 2017-10-03 18:39:41 UTC (rev 15880)
@@ -658,12 +658,11 @@
* Makes best effort to keep validity. Might collapse geometry into lower
* dimension.
*/
-LWGEOM *mvt_geom(const LWGEOM *lwgeom, const GBOX *gbox, uint32_t extent, uint32_t buffer,
+LWGEOM *mvt_geom(LWGEOM *lwgeom, const GBOX *gbox, uint32_t extent, uint32_t buffer,
bool clip_geom)
{
AFFINE affine;
gridspec grid;
- LWGEOM *lwgeom_out = NULL;
double width = gbox->xmax - gbox->xmin;
double height = gbox->ymax - gbox->ymin;
double resx = width / extent;
@@ -672,14 +671,14 @@
double fy = -(extent / height);
double buffer_map_xunits = resx * buffer;
double buffer_map_yunits = resy * buffer;
- const GBOX *ggbox;
+ const GBOX *lwgeom_gbox;
POSTGIS_DEBUG(2, "mvt_geom called");
/* Short circuit out on EMPTY */
if (lwgeom_is_empty(lwgeom))
return NULL;
- ggbox = lwgeom_get_bbox(lwgeom);
+ lwgeom_gbox = lwgeom_get_bbox(lwgeom);
if (width == 0 || height == 0)
elog(ERROR, "mvt_geom: bounds width or height cannot be 0");
@@ -689,32 +688,28 @@
if (clip_geom) {
GBOX *bgbox = gbox_copy(gbox);
gbox_expand(bgbox, buffer_map_xunits);
- if (!gbox_overlaps_2d(ggbox, bgbox)) {
+ if (!gbox_overlaps_2d(lwgeom_gbox, bgbox)) {
POSTGIS_DEBUG(3, "mvt_geom: geometry outside clip box");
return NULL;
}
- if (!gbox_contains_2d(bgbox, ggbox)) {
+ if (!gbox_contains_2d(bgbox, lwgeom_gbox)) {
double x0 = bgbox->xmin;
double y0 = bgbox->ymin;
double x1 = bgbox->xmax;
double y1 = bgbox->ymax;
#if POSTGIS_GEOS_VERSION < 35
LWPOLY *lwenv = lwpoly_construct_envelope(0, x0, y0, x1, y1);
- lwgeom_out = lwgeom_intersection(lwgeom, lwpoly_as_lwgeom(lwenv));
+ lwgeom = lwgeom_intersection(lwgeom, lwpoly_as_lwgeom(lwenv));
lwpoly_free(lwenv);
#else
- lwgeom_out = lwgeom_clip_by_rect(lwgeom, x0, y0, x1, y1);
+ lwgeom = lwgeom_clip_by_rect(lwgeom, x0, y0, x1, y1);
#endif
POSTGIS_DEBUG(3, "mvt_geom: no geometry after clip");
- if (lwgeom_out == NULL || lwgeom_is_empty(lwgeom_out))
+ if (lwgeom == NULL || lwgeom_is_empty(lwgeom))
return NULL;
}
}
- /* if no clip output deep clone original to avoid mutation */
- if (lwgeom_out == NULL)
- lwgeom_out = lwgeom_clone_deep(lwgeom);
-
/* transform to tile coordinate space */
memset(&affine, 0, sizeof(affine));
affine.afac = fx;
@@ -722,7 +717,7 @@
affine.ifac = 1;
affine.xoff = -gbox->xmin * fx;
affine.yoff = -gbox->ymax * fy;
- lwgeom_affine(lwgeom_out, &affine);
+ lwgeom_affine(lwgeom, &affine);
/* snap to integer precision, removing duplicate points */
memset(&grid, 0, sizeof(gridspec));
@@ -730,36 +725,34 @@
grid.ipy = 0;
grid.xsize = 1;
grid.ysize = 1;
- lwgeom_out = lwgeom_grid(lwgeom_out, &grid);
+ lwgeom = lwgeom_grid(lwgeom, &grid);
- if (lwgeom_out == NULL || lwgeom_is_empty(lwgeom_out))
+ if (lwgeom == NULL || lwgeom_is_empty(lwgeom))
return NULL;
/* if polygon(s) make valid and force clockwise as per MVT spec */
- if (lwgeom_out->type == POLYGONTYPE ||
- lwgeom_out->type == MULTIPOLYGONTYPE) {
- lwgeom_out = lwgeom_make_valid(lwgeom_out);
- lwgeom_force_clockwise(lwgeom_out);
+ if (lwgeom->type == POLYGONTYPE || lwgeom->type == MULTIPOLYGONTYPE) {
+ lwgeom = lwgeom_make_valid(lwgeom);
+ lwgeom_force_clockwise(lwgeom);
}
/* if geometry collection extract highest dimensional geometry type */
- if (lwgeom_out->type == COLLECTIONTYPE) {
- LWCOLLECTION *lwcoll = lwgeom_as_lwcollection(lwgeom_out);
- lwgeom_out = lwcollection_as_lwgeom(
+ if (lwgeom->type == COLLECTIONTYPE) {
+ LWCOLLECTION *lwcoll = lwgeom_as_lwcollection(lwgeom);
+ lwgeom = lwcollection_as_lwgeom(
lwcollection_extract(lwcoll, max_type(lwcoll)));
- lwgeom_out = lwgeom_homogenize(lwgeom_out);
+ lwgeom = lwgeom_homogenize(lwgeom);
/* if polygon(s) make valid and force clockwise as per MVT spec */
- if (lwgeom_out->type == POLYGONTYPE ||
- lwgeom_out->type == MULTIPOLYGONTYPE) {
- lwgeom_out = lwgeom_make_valid(lwgeom_out);
- lwgeom_force_clockwise(lwgeom_out);
+ if (lwgeom->type == POLYGONTYPE || lwgeom->type == MULTIPOLYGONTYPE) {
+ lwgeom = lwgeom_make_valid(lwgeom);
+ lwgeom_force_clockwise(lwgeom);
}
}
- if (lwgeom_out == NULL || lwgeom_is_empty(lwgeom_out))
+ if (lwgeom == NULL || lwgeom_is_empty(lwgeom))
return NULL;
- return lwgeom_out;
+ return lwgeom;
}
/**
Modified: trunk/postgis/mvt.h
===================================================================
--- trunk/postgis/mvt.h 2017-10-03 10:14:10 UTC (rev 15879)
+++ trunk/postgis/mvt.h 2017-10-03 18:39:41 UTC (rev 15880)
@@ -67,7 +67,7 @@
uint32_t c;
};
-LWGEOM *mvt_geom(const LWGEOM *geom, const GBOX *bounds, uint32_t extent, uint32_t buffer,
+LWGEOM *mvt_geom(LWGEOM *geom, const GBOX *bounds, uint32_t extent, uint32_t buffer,
bool clip_geom);
void mvt_agg_init_context(struct mvt_agg_context *ctx);
void mvt_agg_transfn(struct mvt_agg_context *ctx);
More information about the postgis-tickets
mailing list