From d45c960c1fe0dbe062a16992c98358bc53600527 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Wed, 25 Apr 2018 16:36:23 +0200 Subject: [PATCH] Shift the coordinate system so the tile boundary marking works right. (Was missing transitions before because division rounds toward zero) --- geometry.cpp | 28 +++++++++++++++++++++------- geometry.hpp | 2 +- tile.cpp | 8 +++++++- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index 1b1ea6f..de68616 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -790,14 +790,24 @@ bool point_within_tile(long long x, long long y, int z) { return x >= 0 && y >= 0 && x < area && y < area; } -drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid) { +drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid, int z, unsigned tx, unsigned ty) { drawvec out; + // shift to word coordinates so tile edge division will work + // even though it rounds toward 0 instead of rounding down + unsigned sx = 0, sy = 0; + if (z != 0) { + sx = tx << (32 - z); + sy = ty << (32 - z); + } + for (size_t i = 0; i < geom.size(); i++) { + geom[i].x += sx; + geom[i].y += sy; + } + for (size_t i = 0; i < geom.size(); i++) { if (geom[i].op == VT_LINETO) { if (geom[i - 1].x / width != geom[i].x / width) { - long long min, max; - if (geom[i - 1].x < geom[i].x) { for (long long xx = geom[i - 1].x / width * width + width; xx <= geom[i].x / width * width; xx += width) { long long yy = (xx - geom[i - 1].x) * (geom[i].y - geom[i - 1].y) / (geom[i].x - geom[i - 1].x) + geom[i - 1].y; @@ -816,12 +826,11 @@ drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid) { } geom = out; + out.clear(); for (size_t i = 0; i < geom.size(); i++) { if (geom[i].op == VT_LINETO) { if (geom[i - 1].y / width != geom[i].y / width) { - long long min, may; - if (geom[i - 1].y < geom[i].y) { for (long long yy = geom[i - 1].y / width * width + width; yy <= geom[i].y / width * width; yy += width) { long long xx = (yy - geom[i - 1].y) * (geom[i].x - geom[i - 1].x) / (geom[i].y - geom[i - 1].y) + geom[i - 1].x; @@ -839,16 +848,21 @@ drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid) { out.push_back(geom[i]); } + for (size_t i = 0; i < out.size(); i++) { + out[i].x -= sx; + out[i].y -= sy; + } + return out; } -drawvec clip_lines(drawvec geom, int z, long long buffer, long long *pointid) { +drawvec clip_lines(drawvec geom, int z, unsigned x, unsigned y, long long buffer, long long *pointid) { drawvec out; long long min = 0; long long area = 1LL << (32 - z); - geom = mark_tile_edges(geom, area, pointid); + geom = mark_tile_edges(geom, area, pointid, z, x, y); min -= buffer * area / 256; area += buffer * area / 256; diff --git a/geometry.hpp b/geometry.hpp index 362367e..983764e 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -74,7 +74,7 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip); drawvec simple_clip_poly(drawvec &geom, int z, int buffer); drawvec close_poly(drawvec &geom); drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double *accum_area); -drawvec clip_lines(drawvec geom, int z, long long buffer, long long *pointid); +drawvec clip_lines(drawvec geom, int z, unsigned x, unsigned y, long long buffer, long long *pointid); drawvec stairstep(drawvec &geom, int z, int detail); bool point_within_tile(long long x, long long y, int z); int quick_check(long long *bbox, int z, long long buffer); diff --git a/tile.cpp b/tile.cpp index f0183dc..2cff223 100644 --- a/tile.cpp +++ b/tile.cpp @@ -401,6 +401,8 @@ struct partial { int segment = 0; bool reduced = 0; int z = 0; + unsigned x; + unsigned y; int line_detail = 0; int maxzoom = 0; double spacing = 0; @@ -480,6 +482,8 @@ void *partial_feature_worker(void *v) { (*partials)[i].geoms.clear(); // avoid keeping two copies in memory signed char t = (*partials)[i].t; int z = (*partials)[i].z; + unsigned x = (*partials)[i].x; + unsigned y = (*partials)[i].y; int line_detail = (*partials)[i].line_detail; int maxzoom = (*partials)[i].maxzoom; @@ -531,7 +535,7 @@ void *partial_feature_worker(void *v) { if (t == VT_LINE) { for (size_t g = 0; g < geoms.size(); g++) { from_tile_scale(geoms[g], z, line_detail); - geoms[g] = clip_lines(geoms[g], z, (*partials)[i].buffer, (*partials)[i].pointid); + geoms[g] = clip_lines(geoms[g], z, x, y, (*partials)[i].buffer, (*partials)[i].pointid); to_tile_scale(geoms[g], z, line_detail); } } @@ -1988,6 +1992,8 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s p.original_seq = sf.seq; p.reduced = reduced; p.z = z; + p.x = tx; + p.y = ty; p.line_detail = line_detail; p.maxzoom = maxzoom; p.keys = sf.keys;