From 6b70e2aebd354d7d360253ecacb633f3f33df66f Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Wed, 25 Apr 2018 14:59:41 +0200 Subject: [PATCH] Tag all LineString crossings of tile boundaries --- geometry.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++-- geometry.hpp | 2 +- tile.cpp | 2 +- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index acc1576..1b1ea6f 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -790,11 +790,66 @@ bool point_within_tile(long long x, long long y, int z) { return x >= 0 && y >= 0 && x < area && y < area; } -drawvec clip_lines(drawvec &geom, int z, long long buffer) { +drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid) { + drawvec out; + + 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; + out.push_back(draw(VT_LINETO, xx, yy, ++*pointid)); + } + } else { + for (long long xx = geom[i].x / width * width + width; xx <= geom[i - 1].x / width * width; xx += width) { + long long yy = (xx - geom[i].x) * (geom[i - 1].y - geom[i].y) / (geom[i - 1].x - geom[i].x) + geom[i].y; + out.push_back(draw(VT_LINETO, xx, yy, ++*pointid)); + } + } + } + } + + out.push_back(geom[i]); + } + + geom = out; + + 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; + out.push_back(draw(VT_LINETO, xx, yy, ++*pointid)); + } + } else { + for (long long yy = geom[i].y / width * width + width; yy <= geom[i - 1].y / width * width; yy += width) { + long long xx = (yy - geom[i].y) * (geom[i - 1].x - geom[i].x) / (geom[i - 1].y - geom[i].y) + geom[i].x; + out.push_back(draw(VT_LINETO, xx, yy, ++*pointid)); + } + } + } + } + + out.push_back(geom[i]); + } + + return out; +} + +drawvec clip_lines(drawvec geom, int z, 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); + min -= buffer * area / 256; area += buffer * area / 256; @@ -974,7 +1029,7 @@ drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, } if (mark_tile_bounds) { - geom = impose_tile_boundaries(geom, area, pointid); + // geom = impose_tile_boundaries(geom, area, pointid); } for (size_t i = 0; i < geom.size(); i++) { diff --git a/geometry.hpp b/geometry.hpp index d3856ad..362367e 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); +drawvec clip_lines(drawvec geom, int z, 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 fd94ce7..f0183dc 100644 --- a/tile.cpp +++ b/tile.cpp @@ -531,7 +531,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); + geoms[g] = clip_lines(geoms[g], z, (*partials)[i].buffer, (*partials)[i].pointid); to_tile_scale(geoms[g], z, line_detail); } }