From 105dfa73d79d752a59ff7bc13942f4a966931ef9 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Thu, 11 Dec 2014 13:34:50 -0800 Subject: [PATCH] Use bounding box for quick accept/reject before detailed clipping. --- geometry.cc | 48 +++++++++++++++++++++++++++++++++++++++++++++++- geometry.hh | 3 ++- tile.cc | 27 ++++++++++++++++++--------- 3 files changed, 67 insertions(+), 11 deletions(-) diff --git a/geometry.cc b/geometry.cc index 8c4ad12..e74e970 100644 --- a/geometry.cc +++ b/geometry.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include "geometry.hh" extern "C" { @@ -16,9 +17,14 @@ extern "C" { #include "projection.h" } -drawvec decode_geometry(char **meta, int z, unsigned tx, unsigned ty, int detail) { +drawvec decode_geometry(char **meta, int z, unsigned tx, unsigned ty, int detail, long long *bbox) { drawvec out; + bbox[0] = LONG_LONG_MAX; + bbox[1] = LONG_LONG_MAX; + bbox[2] = LONG_LONG_MIN; + bbox[3] = LONG_LONG_MIN; + while (1) { draw d; @@ -40,6 +46,19 @@ drawvec decode_geometry(char **meta, int z, unsigned tx, unsigned ty, int detail wwy -= ty << (32 - z); } + if (wwx < bbox[0]) { + bbox[0] = wwx; + } + if (wwy < bbox[1]) { + bbox[1] = wwy; + } + if (wwx > bbox[2]) { + bbox[2] = wwx; + } + if (wwy > bbox[3]) { + bbox[3] = wwy; + } + d.x = wwx; d.y = wwy; } @@ -412,6 +431,33 @@ drawvec clip_point(drawvec &geom, int z, int detail, long long buffer) { return out; } +int quick_check(long long *bbox, int z, int detail, long long buffer) { + long long min = 0; + long long area = 0xFFFFFFFF; + if (z != 0) { + area = 1LL << (32 - z); + + min -= buffer * area / 256; + area += buffer * area / 256; + } + + // bbox entirely outside the tile + if (bbox[0] > area || bbox[1] > area) { + return 0; + } + if (bbox[2] < min || bbox[3] < min) { + return 0; + } + + // bbox entirely within the tile + if (bbox[0] > min && bbox[1] > min && bbox[2] < area && bbox[3] < area) { + return 1; + } + + // some overlap of edge + return 2; +} + drawvec clip_lines(drawvec &geom, int z, int detail, long long buffer) { drawvec out; unsigned i; diff --git a/geometry.hh b/geometry.hh index 9a1487b..d6fd72b 100644 --- a/geometry.hh +++ b/geometry.hh @@ -15,12 +15,13 @@ struct draw { typedef std::vector drawvec; -drawvec decode_geometry(char **meta, int z, unsigned tx, unsigned ty, int detail); +drawvec decode_geometry(char **meta, int z, unsigned tx, unsigned ty, int detail, long long *bbox); void to_tile_scale(drawvec &geom, int z, int detail); drawvec remove_noop(drawvec geom, int type); drawvec clip_point(drawvec &geom, int z, int detail, long long buffer); drawvec clip_poly(drawvec &geom, int z, int detail, int buffer); drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double *accum_area); drawvec clip_lines(drawvec &geom, int z, int detail, long long buffer); +int quick_check(long long *bbox, int z, int detail, long long buffer); drawvec simplify_lines(drawvec &geom, int z, int detail); drawvec reorder_lines(drawvec &geom); diff --git a/tile.cc b/tile.cc index 767eafc..c2cd1bb 100644 --- a/tile.cc +++ b/tile.cc @@ -386,25 +386,34 @@ long long write_tile(char **geoms, char *metabase, unsigned *file_bbox, int z, u long long metastart; deserialize_long_long(geoms, &metastart); char *meta = metabase + metastart; + long long bbox[4]; - drawvec geom = decode_geometry(geoms, z, tx, ty, line_detail); + drawvec geom = decode_geometry(geoms, z, tx, ty, line_detail, bbox); signed char minzoom; deserialize_byte(geoms, &minzoom); + int quick = quick_check(bbox, z, line_detail, buffer); + if (quick == 0) { + continue; + } + #if 0 if (z > i->maxzoom) { continue; } #endif - if (t == VT_LINE) { - geom = clip_lines(geom, z, line_detail, buffer); - } - if (t == VT_POLYGON) { - geom = clip_poly(geom, z, line_detail, buffer); - } - if (t == VT_POINT) { - geom = clip_point(geom, z, line_detail, buffer); + + if (quick != 1) { + if (t == VT_LINE) { + geom = clip_lines(geom, z, line_detail, buffer); + } + if (t == VT_POLYGON) { + geom = clip_poly(geom, z, line_detail, buffer); + } + if (t == VT_POINT) { + geom = clip_point(geom, z, line_detail, buffer); + } } geom = remove_noop(geom, t);