From f6830787dd063869304f07da69338bdda7fc3b94 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Tue, 12 Jun 2018 14:33:06 -0700 Subject: [PATCH] Trying to clear up point IDs and real vs phantom --- mvt.cpp | 8 +++++--- mvt.hpp | 5 +++++ vt3.cpp | 38 ++++++++++++++++++++++++-------------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/mvt.cpp b/mvt.cpp index e882105..2ad0f55 100644 --- a/mvt.cpp +++ b/mvt.cpp @@ -258,7 +258,8 @@ bool mvt_tile::decode(std::string &message, bool &was_compressed) { for (size_t g = 0; g + 1 < geom_ids.size(); g += 2) { off += geom_ids[g]; if (off < feature.geometry.size()) { - feature.geometry[off].id = geom_ids[g + 1]; + feature.geometry[off].id = geom_ids[g + 1] >> 1; + feature.geometry[off].phantom = geom_ids[g + 1] & 1; } else { fprintf(stderr, "Bad offset in feature node IDs\n"); exit(EXIT_FAILURE); @@ -408,10 +409,11 @@ std::string mvt_tile::encode() { size_t off = 0; for (size_t g = 0; g < geom.size(); g++) { - if (geom[g].id != 0) { + unsigned long id = (geom[g].id << 1) || (geom[g].phantom ? 1 : 0); + if (id != 0) { geometry_ids.push_back(g - off); off = g; - geometry_ids.push_back(geom[g].id); + geometry_ids.push_back(id); } } diff --git a/mvt.hpp b/mvt.hpp index f716d8c..197377d 100644 --- a/mvt.hpp +++ b/mvt.hpp @@ -20,6 +20,11 @@ struct mvt_geometry { long long x = 0; long long y = 0; int /* mvt_operation */ op = 0; + + // 0 false: no id + // 0 true: outside, introduced by clipping + // N true: on edge, introduced by clipping + // N false: along or on edge, to be preserved long id = 0; bool phantom = false; diff --git a/vt3.cpp b/vt3.cpp index ca0bc8a..5421e77 100644 --- a/vt3.cpp +++ b/vt3.cpp @@ -36,14 +36,14 @@ std::vector clip_lines(std::vector &geom, long left, int c = clip(&x1, &y1, &x2, &y2, left, top, right, bottom); - if (c > 1) { // clipped + if (c == CLIP_ELIMINATED) { + out.push_back(mvt_geometry(mvt_moveto, geom[i].x, geom[i].y)); + } else if (c == CLIP_OK) { + out.push_back(geom[i]); + } else { out.push_back(mvt_geometry(mvt_moveto, x1, y1)); out.push_back(mvt_geometry(mvt_lineto, x2, y2)); out.push_back(mvt_geometry(mvt_moveto, geom[i].x, geom[i].y)); - } else if (c == 1) { // unchanged - out.push_back(geom[i]); - } else { // clipped away entirely - out.push_back(mvt_geometry(mvt_moveto, geom[i].x, geom[i].y)); } } else { out.push_back(geom[i]); @@ -59,6 +59,11 @@ void split_feature(mvt_layer const &layer, mvt_feature const &feature, std::vect long extent = layer.extent; long nextent = extent / n; + if (nextent * (long) n != extent) { + fprintf(stderr, "Extent %ld doesn't subdivide evenly by %zud\n", extent, n); + exit(EXIT_FAILURE); + } + // Calculate bounding box of feature long minx = LONG_MAX; @@ -138,7 +143,7 @@ void split_feature(mvt_layer const &layer, mvt_feature const &feature, std::vect // segments that cross from one sub-tile to another for (size_t i = 0; i < ogeom.size(); i++) { - if (i > 0 && (floor((double) ogeom[i].x / nextent) != floor((double) ogeom[i - 1].x / nextent))) { + if (i > 0 && ogeom[i].op == mvt_lineto && (floor((double) ogeom[i].x / nextent) != floor((double) ogeom[i - 1].x / nextent))) { long first = floor((double) ogeom[i - 1].x / nextent) * nextent; long second = floor((double) ogeom[i].x / nextent) * nextent; @@ -169,7 +174,7 @@ void split_feature(mvt_layer const &layer, mvt_feature const &feature, std::vect ogeom = ngeom; ngeom.clear(); for (size_t i = 0; i < ogeom.size(); i++) { - if (i > 0 && (floor((double) ogeom[i].y / nextent) != floor((double) ogeom[i - 1].y / nextent))) { + if (i > 0 && ogeom[i].op == mvt_lineto && (floor((double) ogeom[i].y / nextent) != floor((double) ogeom[i - 1].y / nextent))) { long first = (ogeom[i - 1].y / nextent) * nextent; long second = (ogeom[i].y / nextent) * nextent; @@ -195,16 +200,12 @@ void split_feature(mvt_layer const &layer, mvt_feature const &feature, std::vect ngeom.push_back(ogeom[i]); } - // Part 2: Assign (real) point IDs for both ends of any - // segments that travel along a sub-tile edge + // Part 2: Assign (real) point IDs for any points that are on a sub-tile edge for (size_t i = 0; i < ngeom.size(); i++) { - if (i > 0 && ((ngeom[i].x == ngeom[i - 1].x && ngeom[i].x % nextent == 0) || - (ngeom[i].y == ngeom[i - 1].y && ngeom[i].y % nextent == 0))) { + if (ngeom[i].x % nextent == 0 || ngeom[i].y % nextent == 0) { if (ogeom[i].id == 0) { ogeom[i].id = ++pointid; - } - if (ogeom[i - 1].id == 0) { - ogeom[i - 1].id = ++pointid; + ogeom[i].phantom = false; } } } @@ -266,5 +267,14 @@ mvt_tile split_and_merge(mvt_tile tile, int tile_zoom) { } } + // Trim unused features from layers, layers from tiles + + // Write each tile to PBF + // Decode each tile back from PBF + + // Recreate original tile from decoded sub-tiles + + // Verify that the original data has been recreated + return tile; }