From 6fb308d04997facc5f9ecb089fb03a5fbf5a50b9 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Wed, 25 Apr 2018 14:00:18 +0200 Subject: [PATCH] Assign node IDs when edge points are introduced, not in next-zoom prep --- geometry.cpp | 39 ++++++++++++++++++++++++++++++--------- geometry.hpp | 2 +- tile.cpp | 10 +++++++--- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index 94f0d23..acc1576 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -19,6 +19,7 @@ #include "projection.hpp" #include "serial.hpp" #include "main.hpp" +#include "options.hpp" static int pnpoly(drawvec &vert, size_t start, size_t nvert, long long testx, long long testy); static int clip(double *x0, double *y0, double *x1, double *y1, double xmin, double ymin, double xmax, double ymax); @@ -808,13 +809,23 @@ drawvec clip_lines(drawvec &geom, int z, long long buffer) { int c = clip(&x1, &y1, &x2, &y2, min, min, area, area); if (c > 1) { // clipped - out.push_back(draw(VT_MOVETO, x1, y1)); - out.push_back(draw(VT_LINETO, x2, y2)); - out.push_back(draw(VT_MOVETO, geom[i].x, geom[i].y)); + if (x1 == geom[i - 1].x && y1 == geom[i - 1].y) { + out.push_back(draw(VT_MOVETO, x1, y1, geom[i - 1].id)); + } else { + out.push_back(draw(VT_MOVETO, x1, y1)); + } + + if (x2 == geom[i].x && y2 == geom[i].y) { + out.push_back(draw(VT_LINETO, x2, y2, geom[i].id)); + } else { + out.push_back(draw(VT_LINETO, x2, y2)); + } + + out.push_back(draw(VT_MOVETO, geom[i].x, geom[i].y, geom[i].id)); } else if (c == 1) { // unchanged out.push_back(geom[i]); } else { // clipped away entirely - out.push_back(draw(VT_MOVETO, geom[i].x, geom[i].y)); + out.push_back(draw(VT_MOVETO, geom[i].x, geom[i].y, geom[i].id)); } } else { out.push_back(geom[i]); @@ -907,7 +918,7 @@ static void douglas_peucker(drawvec &geom, int start, int n, double e, size_t ke // If any line segment crosses a tile boundary, add a node there // that cannot be simplified away, to prevent the edge of any // feature from jumping abruptly at the tile boundary. -drawvec impose_tile_boundaries(drawvec &geom, long long extent) { +drawvec impose_tile_boundaries(drawvec &geom, long long extent, long long *pointid) { drawvec out; for (size_t i = 0; i < geom.size(); i++) { @@ -922,11 +933,21 @@ drawvec impose_tile_boundaries(drawvec &geom, long long extent) { if (c > 1) { // clipped if (x1 != geom[i - 1].x || y1 != geom[i - 1].y) { - out.push_back(draw(VT_LINETO, x1, y1)); + if (additional[A_JOIN_FEATURES_ACROSS_TILES]) { + out.push_back(draw(VT_LINETO, x1, y1, ++*pointid)); + } else { + out.push_back(draw(VT_LINETO, x1, y1)); + } + out[out.size() - 1].necessary = 1; } if (x2 != geom[i - 0].x || y2 != geom[i - 0].y) { - out.push_back(draw(VT_LINETO, x2, y2)); + if (additional[A_JOIN_FEATURES_ACROSS_TILES]) { + out.push_back(draw(VT_LINETO, x2, y2, ++*pointid)); + } else { + out.push_back(draw(VT_LINETO, x2, y2)); + } + out[out.size() - 1].necessary = 1; } } @@ -938,7 +959,7 @@ drawvec impose_tile_boundaries(drawvec &geom, long long extent) { return out; } -drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain) { +drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain, long long *pointid) { int res = 1 << (32 - detail - z); long long area = 1LL << (32 - z); @@ -953,7 +974,7 @@ drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, } if (mark_tile_bounds) { - geom = impose_tile_boundaries(geom, area); + 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 6446462..d3856ad 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -78,7 +78,7 @@ drawvec clip_lines(drawvec &geom, int z, long long buffer); 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); -drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain); +drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain, long long *pointid); drawvec reorder_lines(drawvec &geom); drawvec fix_polygon(drawvec &geom); std::vector chop_polygon(std::vector &geoms); diff --git a/tile.cpp b/tile.cpp index a4452d7..fd94ce7 100644 --- a/tile.cpp +++ b/tile.cpp @@ -414,6 +414,7 @@ struct partial { std::set need_tilestats; long clipid = 0; int buffer; + long long *pointid; }; struct partial_arg { @@ -503,7 +504,7 @@ void *partial_feature_worker(void *v) { } if (!already_marked) { - drawvec ngeom = simplify_lines(geom, z, line_detail, !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), (*partials)[i].simplification, t == VT_POLYGON ? 4 : 0); + drawvec ngeom = simplify_lines(geom, z, line_detail, !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), (*partials)[i].simplification, t == VT_POLYGON ? 4 : 0, (*partials)[i].pointid); if (t != VT_POLYGON || ngeom.size() >= 3) { geom = ngeom; @@ -964,7 +965,8 @@ bool find_common_edges(std::vector &partials, int z, int line_detail, d } } if (!(prevent[P_SIMPLIFY] || (z == maxzoom && prevent[P_SIMPLIFY_LOW]) || (z < maxzoom && additional[A_GRID_LOW_ZOOMS]))) { - simplified_arcs[ai->second] = simplify_lines(dv, z, line_detail, !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, 4); + long long pid = 0; + simplified_arcs[ai->second] = simplify_lines(dv, z, line_detail, !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, 4, &pid); } else { simplified_arcs[ai->second] = dv; } @@ -2002,6 +2004,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s p.clustered = 0; p.clipid = sf.clipid; p.buffer = buffer; + p.pointid = &sf.pointid; partials.push_back(p); } @@ -2204,8 +2207,9 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s for (size_t x = 0; x < layer_features.size(); x++) { if (layer_features[x].coalesced && layer_features[x].type == VT_LINE) { layer_features[x].geom = remove_noop(layer_features[x].geom, layer_features[x].type, 0); + long long pid = 27; layer_features[x].geom = simplify_lines(layer_features[x].geom, 32, 0, - !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, layer_features[x].type == VT_POLYGON ? 4 : 0); + !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, layer_features[x].type == VT_POLYGON ? 4 : 0, &pid); } if (layer_features[x].type == VT_POLYGON) {