mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 08:25:40 +02:00
Prescan for small deltas before doing proper simplification
This commit is contained in:
@@ -789,14 +789,14 @@ double distance_from_line(long long point_x, long long point_y, long long segA_x
|
|||||||
void douglas_peucker(drawvec &geom, int start, int n, double e, size_t kept, size_t retain, bool prevent_simplify_shared_nodes) {
|
void douglas_peucker(drawvec &geom, int start, int n, double e, size_t kept, size_t retain, bool prevent_simplify_shared_nodes) {
|
||||||
std::stack<int> recursion_stack;
|
std::stack<int> recursion_stack;
|
||||||
|
|
||||||
if (!geom[start + 0].necessary || !geom[start + n - 1].necessary) {
|
if (!(geom[start + 0].necessary > 0) || !(geom[start + n - 1].necessary > 0)) {
|
||||||
fprintf(stderr, "endpoints not marked necessary\n");
|
fprintf(stderr, "endpoints not marked necessary\n");
|
||||||
exit(EXIT_IMPOSSIBLE);
|
exit(EXIT_IMPOSSIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int prev = 0;
|
int prev = 0;
|
||||||
for (int here = 1; here < n; here++) {
|
for (int here = 1; here < n; here++) {
|
||||||
if (geom[start + here].necessary) {
|
if (geom[start + here].necessary > 0) {
|
||||||
recursion_stack.push(prev);
|
recursion_stack.push(prev);
|
||||||
recursion_stack.push(here);
|
recursion_stack.push(here);
|
||||||
prev = here;
|
prev = here;
|
||||||
@@ -829,9 +829,12 @@ void douglas_peucker(drawvec &geom, int start, int n, double e, size_t kept, siz
|
|||||||
if (geom[start + first] < geom[start + second]) {
|
if (geom[start + first] < geom[start + second]) {
|
||||||
farthest_element_index = first;
|
farthest_element_index = first;
|
||||||
for (i = first + 1; i < second; i++) {
|
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;
|
||||||
|
if (geom[start + i].necessary < 0) {
|
||||||
double distance = std::fabs(temp_dist);
|
distance = 0;
|
||||||
|
} else {
|
||||||
|
distance = 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);
|
||||||
|
}
|
||||||
|
|
||||||
if ((distance > e || kept < retain) && (distance > max_distance || (distance == max_distance && geom[start + i] < geom[start + farthest_element_index]))) {
|
if ((distance > e || kept < retain) && (distance > max_distance || (distance == max_distance && geom[start + i] < geom[start + farthest_element_index]))) {
|
||||||
farthest_element_index = i;
|
farthest_element_index = i;
|
||||||
@@ -841,9 +844,12 @@ void douglas_peucker(drawvec &geom, int start, int n, double e, size_t kept, siz
|
|||||||
} else {
|
} else {
|
||||||
farthest_element_index = second;
|
farthest_element_index = second;
|
||||||
for (i = second - 1; i > first; i--) {
|
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;
|
||||||
|
if (geom[start + i].necessary < 0) {
|
||||||
double distance = std::fabs(temp_dist);
|
distance = 0;
|
||||||
|
} else {
|
||||||
|
distance = 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);
|
||||||
|
}
|
||||||
|
|
||||||
if ((distance > e || kept < retain) && (distance > max_distance || (distance == max_distance && geom[start + i] < geom[start + farthest_element_index]))) {
|
if ((distance > e || kept < retain) && (distance > max_distance || (distance == max_distance && geom[start + i] < geom[start + farthest_element_index]))) {
|
||||||
farthest_element_index = i;
|
farthest_element_index = i;
|
||||||
@@ -917,7 +923,7 @@ static drawvec simplify_lines_basic(drawvec &geom, int z, int detail, double sim
|
|||||||
|
|
||||||
size_t out = 0;
|
size_t out = 0;
|
||||||
for (size_t i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].necessary) {
|
if (geom[i].necessary > 0) {
|
||||||
geom[out++] = geom[i];
|
geom[out++] = geom[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-3
@@ -239,6 +239,48 @@ drawvec impose_tile_boundaries(const drawvec &geom, long long extent) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mark_unnecessary(drawvec &geom, size_t start, size_t end, double e) {
|
||||||
|
double ee = e * e;
|
||||||
|
|
||||||
|
if (geom[start] < geom[end]) {
|
||||||
|
size_t last = start;
|
||||||
|
for (size_t i = start + 1; i < end; i++) {
|
||||||
|
long long dx = geom[i].x - geom[last].x;
|
||||||
|
long long dy = geom[i].y - geom[last].y;
|
||||||
|
if (dx * dx + dy * dy < ee) {
|
||||||
|
geom[i].necessary = -1;
|
||||||
|
} else {
|
||||||
|
last = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size_t last = end;
|
||||||
|
for (size_t i = end - 1; i > start; i--) {
|
||||||
|
long long dx = geom[i].x - geom[last].x;
|
||||||
|
long long dy = geom[i].y - geom[last].y;
|
||||||
|
if (dx * dx + dy * dy < ee) {
|
||||||
|
geom[i].necessary = -1;
|
||||||
|
} else {
|
||||||
|
last = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mark_unnecessary(drawvec &geom, double e) {
|
||||||
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
|
if (geom[i].necessary > 0) {
|
||||||
|
for (size_t j = i + 1; j < geom.size(); j++) {
|
||||||
|
if (geom[j].necessary > 0) {
|
||||||
|
mark_unnecessary(geom, i, j, e);
|
||||||
|
i = j - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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, std::string const &shared_nodes_bloom) {
|
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, std::string const &shared_nodes_bloom) {
|
||||||
int res = 1 << (32 - detail - z);
|
int res = 1 << (32 - detail - z);
|
||||||
long long area = 1LL << (32 - z);
|
long long area = 1LL << (32 - z);
|
||||||
@@ -265,7 +307,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]);
|
auto pt = std::lower_bound(shared_nodes.begin(), shared_nodes.end(), geom[i]);
|
||||||
if (pt != shared_nodes.end() && *pt == geom[i]) {
|
if (pt != shared_nodes.end() && *pt == geom[i]) {
|
||||||
geom[i].necessary = true;
|
geom[i].necessary = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodepos > 0) {
|
if (nodepos > 0) {
|
||||||
@@ -284,7 +326,7 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma
|
|||||||
|
|
||||||
if (shared_nodes_bloom[bloom_ix] & bloom_mask) {
|
if (shared_nodes_bloom[bloom_ix] & bloom_mask) {
|
||||||
if (bsearch(&n, shared_nodes_map, nodepos / sizeof(node), sizeof(node), nodecmp) != NULL) {
|
if (bsearch(&n, shared_nodes_map, nodepos / sizeof(node), sizeof(node), nodecmp) != NULL) {
|
||||||
geom[i].necessary = true;
|
geom[i].necessary = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,6 +337,10 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma
|
|||||||
geom = impose_tile_boundaries(geom, area);
|
geom = impose_tile_boundaries(geom, area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!additional[A_VISVALINGAM]) {
|
||||||
|
mark_unnecessary(geom, res * simplification);
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
size_t j;
|
size_t j;
|
||||||
@@ -327,7 +373,7 @@ drawvec simplify_lines(drawvec &geom, int z, int tx, int ty, int detail, bool ma
|
|||||||
|
|
||||||
size_t out = 0;
|
size_t out = 0;
|
||||||
for (size_t i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].necessary) {
|
if (geom[i].necessary > 0) {
|
||||||
geom[out++] = geom[i];
|
geom[out++] = geom[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user