Trying to clear up point IDs and real vs phantom

This commit is contained in:
Eric Fischer 2018-06-12 14:33:06 -07:00
parent 9e8e0edb99
commit f6830787dd
3 changed files with 34 additions and 17 deletions

View File

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

View File

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

38
vt3.cpp
View File

@ -36,14 +36,14 @@ std::vector<mvt_geometry> clip_lines(std::vector<mvt_geometry> &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;
}