diff --git a/geometry.cpp b/geometry.cpp index 376cc493..30f8fd9e 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -206,101 +205,6 @@ bool point_within_tile(long long x, long long y, int z) { return x >= 0 && y >= 0 && x < area && y < area; } -// https://github.com/Project-OSRM/osrm-backend/blob/733d1384a40f/Algorithms/DouglasePeucker.cpp -static void douglas_peucker(drawvec &geom, int start, int n, double e, size_t kept, size_t retain) { - std::stack recursion_stack; - - if (!geom[start + 0].necessary || !geom[start + n - 1].necessary) { - fprintf(stderr, "endpoints not marked necessary\n"); - exit(EXIT_IMPOSSIBLE); - } - - int prev = 0; - for (int here = 1; here < n; here++) { - if (geom[start + here].necessary) { - recursion_stack.push(prev); - recursion_stack.push(here); - prev = here; - - if (prevent[P_SIMPLIFY_SHARED_NODES]) { - if (retain > 0) { - retain--; - } - } - } - } - // These segments are put on the stack from start to end, - // independent of winding, so note that anything that uses - // "retain" to force it to keep at least N points will - // keep a different set of points when wound one way than - // when wound the other way. - - while (!recursion_stack.empty()) { - // pop next element - int second = recursion_stack.top(); - recursion_stack.pop(); - int first = recursion_stack.top(); - recursion_stack.pop(); - - double max_distance = -1; - int farthest_element_index; - - // find index idx of element with max_distance - int i; - if (geom[start + first] < geom[start + second]) { - farthest_element_index = first; - for (i = first + 1; i < second; i++) { - double temp_dist = distance_from_line(geom[start + i].x, geom[start + i].y, geom[start + first].x, geom[start + first].y, geom[start + second].x, geom[start + second].y); - - double distance = std::fabs(temp_dist); - - if ((distance > e || kept < retain) && (distance > max_distance || (distance == max_distance && geom[start + i] < geom[start + farthest_element_index]))) { - farthest_element_index = i; - max_distance = distance; - } - } - } else { - farthest_element_index = second; - for (i = second - 1; i > first; i--) { - double temp_dist = distance_from_line(geom[start + i].x, geom[start + i].y, geom[start + second].x, geom[start + second].y, geom[start + first].x, geom[start + first].y); - - double distance = std::fabs(temp_dist); - - if ((distance > e || kept < retain) && (distance > max_distance || (distance == max_distance && geom[start + i] < geom[start + farthest_element_index]))) { - farthest_element_index = i; - max_distance = distance; - } - } - } - - if (max_distance >= 0) { - // mark idx as necessary - geom[start + farthest_element_index].necessary = 1; - kept++; - - if (geom[start + first] < geom[start + second]) { - if (1 < farthest_element_index - first) { - recursion_stack.push(first); - recursion_stack.push(farthest_element_index); - } - if (1 < second - farthest_element_index) { - recursion_stack.push(farthest_element_index); - recursion_stack.push(second); - } - } else { - if (1 < second - farthest_element_index) { - recursion_stack.push(farthest_element_index); - recursion_stack.push(second); - } - if (1 < farthest_element_index - first) { - recursion_stack.push(first); - recursion_stack.push(farthest_element_index); - } - } - } - } -} - // 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. @@ -410,7 +314,7 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma if (additional[A_VISVALINGAM]) { visvalingam(geom, i, j, scale, retain); } else { - douglas_peucker(geom, i, j - i, res * simplification, 2, retain); + douglas_peucker(geom, i, j - i, res * simplification, 2, retain, prevent[P_SIMPLIFY_SHARED_NODES]); } } i = j - 1; diff --git a/geometry.hpp b/geometry.hpp index fe4ca441..997842c7 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -80,6 +80,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(const long long *bbox, int z, long long buffer); +void douglas_peucker(drawvec &geom, int start, int n, double e, size_t kept, size_t retain, bool prevent_simplify_shared_nodes); drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool mark_tile_bounds, double simplification, size_t retain, drawvec const &shared_nodes, struct node *shared_nodes_map, size_t nodepos); drawvec reorder_lines(const drawvec &geom); drawvec fix_polygon(const drawvec &geom); diff --git a/tile.cpp b/tile.cpp index 9c0c9e58..84fceccb 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1715,7 +1715,7 @@ long long write_tile(decompressor *geoms, std::atomic *geompos_in, ch struct multiplier_state multiplier_state; size_t multiplier_seq = retain_points_multiplier - 1; - bool drop_rest = false; // are we dropping the remainder of a multiplier cluster whose first point was dropped? + bool drop_rest = false; // are we dropping the remainder of a multiplier cluster whose first point was dropped? bool dropping_by_rate = false; // are we dropping anything by rate in this tile, or keeping it only as part of a multiplier? unsigned long long next_feature_previndex = 0;