Assign node IDs when edge points are introduced, not in next-zoom prep

This commit is contained in:
Eric Fischer 2018-04-25 14:00:18 +02:00
parent 6052f48d24
commit 6fb308d049
3 changed files with 38 additions and 13 deletions

View File

@ -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++) {

View File

@ -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<drawvec> chop_polygon(std::vector<drawvec> &geoms);

View File

@ -414,6 +414,7 @@ struct partial {
std::set<std::string> 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<partial> &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) {