diff --git a/clip.cpp b/clip.cpp index 33e16722..28ec0aca 100644 --- a/clip.cpp +++ b/clip.cpp @@ -895,13 +895,13 @@ static drawvec simplify_lines_basic(drawvec &geom, int z, int detail, double sim for (size_t i = 0; i < geom.size(); i++) { if (geom[i].op == VT_MOVETO) { - geom[i].necessary = 1; + geom[i].necessary = 127; } else if (geom[i].op == VT_LINETO) { geom[i].necessary = 0; // if this is actually the endpoint, not an intermediate point, // it will be marked as necessary below } else { - geom[i].necessary = 1; + geom[i].necessary = 127; } } @@ -914,8 +914,8 @@ static drawvec simplify_lines_basic(drawvec &geom, int z, int detail, double sim } } - geom[i].necessary = 1; - geom[j - 1].necessary = 1; + geom[i].necessary = 127; + geom[j - 1].necessary = 127; if (j - i > 1) { douglas_peucker(geom, i, j - i, res * simplification, 2, retain, false); diff --git a/geometry.cpp b/geometry.cpp index 30f8fd9e..59aa30aa 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -40,9 +40,11 @@ drawvec decode_geometry(const char **meta, int z, unsigned tx, unsigned ty, long if (d.op == VT_MOVETO || d.op == VT_LINETO) { long long dx, dy; + signed char necessary; deserialize_long_long(meta, &dx); deserialize_long_long(meta, &dy); + deserialize_byte(meta, &necessary); wx += dx * (1 << geometry_scale); wy += dy * (1 << geometry_scale); @@ -62,6 +64,7 @@ drawvec decode_geometry(const char **meta, int z, unsigned tx, unsigned ty, long d.x = wwx; d.y = wwy; + d.necessary = necessary; } out.push_back(d); @@ -224,11 +227,11 @@ drawvec impose_tile_boundaries(const drawvec &geom, long long extent) { if (c > 1) { // clipped if (x1 != geom[i - 1].x || y1 != geom[i - 1].y) { out.emplace_back(VT_LINETO, x1, y1); - out[out.size() - 1].necessary = 1; + out[out.size() - 1].necessary = 127; } if (x2 != geom[i - 0].x || y2 != geom[i - 0].y) { out.emplace_back(VT_LINETO, x2, y2); - out[out.size() - 1].necessary = 1; + out[out.size() - 1].necessary = 127; } } } @@ -245,13 +248,13 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma for (size_t i = 0; i < geom.size(); i++) { if (geom[i].op == VT_MOVETO) { - geom[i].necessary = 1; + geom[i].necessary = 127; } else if (geom[i].op == VT_LINETO) { geom[i].necessary = 0; // if this is actually the endpoint, not an intermediate point, // it will be marked as necessary below } else { - geom[i].necessary = 1; + geom[i].necessary = 127; } if (prevent[P_SIMPLIFY_SHARED_NODES]) { @@ -265,7 +268,7 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma auto pt = std::lower_bound(shared_nodes.begin(), shared_nodes.end(), geom[i]); if (pt != shared_nodes.end() && *pt == geom[i]) { - geom[i].necessary = true; + geom[i].necessary = 127; } if (nodepos > 0) { @@ -281,7 +284,7 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma n.index = encode_quadkey((unsigned) d.x, (unsigned) d.y); if (bsearch(&n, shared_nodes_map, nodepos / sizeof(node), sizeof(node), nodecmp) != NULL) { - geom[i].necessary = true; + geom[i].necessary = 127; } } } @@ -300,8 +303,8 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma } } - geom[i].necessary = 1; - geom[j - 1].necessary = 1; + geom[i].necessary = 127; + geom[j - 1].necessary = 127; // empirical mapping from douglas-peucker simplifications // to visvalingam simplifications that yield similar diff --git a/geometry.hpp b/geometry.hpp index 997842c7..fad6f339 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -27,20 +27,24 @@ struct draw { long long x : 40; signed char op; long long y : 40; + + // 0: not necessary + // 127: always necessary + // other n: necessary at detail n/4 signed char necessary; draw(int nop, long long nx, long long ny) : x(nx), op(nop), y(ny), - necessary(0) { + necessary(127) { } draw() : x(0), op(0), y(0), - necessary(0) { + necessary(127) { } bool operator<(draw const &s) const { diff --git a/serial.cpp b/serial.cpp index bd694ebb..6df96758 100644 --- a/serial.cpp +++ b/serial.cpp @@ -160,6 +160,7 @@ static void write_geometry(drawvec const &dv, std::string &out, long long wx, lo serialize_byte(out, dv[i].op); serialize_long_long(out, dv[i].x - wx); serialize_long_long(out, dv[i].y - wy); + serialize_byte(out, dv[i].necessary); wx = dv[i].x; wy = dv[i].y; } else {