Use bounding box for quick accept/reject before detailed clipping.

This commit is contained in:
Eric Fischer 2014-12-11 13:34:50 -08:00
parent 380550ce85
commit 105dfa73d7
3 changed files with 67 additions and 11 deletions

View File

@ -8,6 +8,7 @@
#include <unistd.h>
#include <math.h>
#include <sqlite3.h>
#include <limits.h>
#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;

View File

@ -15,12 +15,13 @@ struct draw {
typedef std::vector<draw> 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);

27
tile.cc
View File

@ -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);