mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-01-22 04:18:01 +00:00
Simplify lines consistently on opposite sides of tile boundaries
This commit is contained in:
parent
e1e028b865
commit
1f8b6faec8
@ -1,3 +1,7 @@
|
|||||||
|
## 1.6.2
|
||||||
|
|
||||||
|
* Make sure line simplification matches on opposite sides of a tile boundary
|
||||||
|
|
||||||
## 1.6.1
|
## 1.6.1
|
||||||
|
|
||||||
* Use multiple threads for line simplification and polygon cleaning
|
* Use multiple threads for line simplification and polygon cleaning
|
||||||
|
40
geometry.cc
40
geometry.cc
@ -750,8 +750,46 @@ static void douglas_peucker(drawvec &geom, int start, int n, double e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 out;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < geom.size(); i++) {
|
||||||
|
if (i > 0 && geom[i].op == VT_LINETO && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO)) {
|
||||||
|
double x1 = geom[i - 1].x;
|
||||||
|
double y1 = geom[i - 1].y;
|
||||||
|
|
||||||
|
double x2 = geom[i - 0].x;
|
||||||
|
double y2 = geom[i - 0].y;
|
||||||
|
|
||||||
|
int c = clip(&x1, &y1, &x2, &y2, 0, 0, extent, extent);
|
||||||
|
|
||||||
|
if (c > 1) { // clipped
|
||||||
|
if (x1 != geom[i - 1].x || y1 != geom[i - 1].y) {
|
||||||
|
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));
|
||||||
|
out[out.size() - 1].necessary = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.push_back(geom[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
drawvec simplify_lines(drawvec &geom, int z, int detail) {
|
drawvec simplify_lines(drawvec &geom, int z, int detail) {
|
||||||
int res = 1 << (32 - detail - z);
|
int res = 1 << (32 - detail - z);
|
||||||
|
long long area = 0xFFFFFFFF;
|
||||||
|
if (z != 0) {
|
||||||
|
area = 1LL << (32 - z);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (i = 0; i < geom.size(); i++) {
|
||||||
@ -764,6 +802,8 @@ drawvec simplify_lines(drawvec &geom, int z, int detail) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geom = impose_tile_boundaries(geom, area);
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
unsigned j;
|
unsigned j;
|
||||||
|
6
tile.cc
6
tile.cc
@ -493,7 +493,7 @@ void *partial_feature_worker(void *v) {
|
|||||||
|
|
||||||
for (unsigned i = a->task; i < (*partials).size(); i += a->tasks) {
|
for (unsigned i = a->task; i < (*partials).size(); i += a->tasks) {
|
||||||
drawvec geom = (*partials)[i].geom;
|
drawvec geom = (*partials)[i].geom;
|
||||||
(*partials)[i].geom.clear(); // avoid keeping two copies in memory
|
(*partials)[i].geom.clear(); // avoid keeping two copies in memory
|
||||||
signed char t = (*partials)[i].t;
|
signed char t = (*partials)[i].t;
|
||||||
int z = (*partials)[i].z;
|
int z = (*partials)[i].z;
|
||||||
int line_detail = (*partials)[i].line_detail;
|
int line_detail = (*partials)[i].line_detail;
|
||||||
@ -501,7 +501,7 @@ void *partial_feature_worker(void *v) {
|
|||||||
char *additional = (*partials)[i].additional;
|
char *additional = (*partials)[i].additional;
|
||||||
|
|
||||||
if ((t == VT_LINE || t == VT_POLYGON) && !prevent['s' & 0xFF]) {
|
if ((t == VT_LINE || t == VT_POLYGON) && !prevent['s' & 0xFF]) {
|
||||||
if (1 /* !reduced */) { // XXX why did this not simplify if reduced?
|
if (1 /* !reduced */) { // XXX why did this not simplify if reduced?
|
||||||
if (t == VT_LINE) {
|
if (t == VT_LINE) {
|
||||||
geom = remove_noop(geom, t, 32 - z - line_detail);
|
geom = remove_noop(geom, t, 32 - z - line_detail);
|
||||||
}
|
}
|
||||||
@ -845,7 +845,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsi
|
|||||||
// This is serial because decode_meta() unifies duplicates
|
// This is serial because decode_meta() unifies duplicates
|
||||||
for (unsigned i = 0; i < partials.size(); i++) {
|
for (unsigned i = 0; i < partials.size(); i++) {
|
||||||
drawvec geom = partials[i].geom;
|
drawvec geom = partials[i].geom;
|
||||||
partials[i].geom.clear(); // avoid keeping two copies in memory
|
partials[i].geom.clear(); // avoid keeping two copies in memory
|
||||||
long long layer = partials[i].layer;
|
long long layer = partials[i].layer;
|
||||||
char *meta = partials[i].meta;
|
char *meta = partials[i].meta;
|
||||||
signed char t = partials[i].t;
|
signed char t = partials[i].t;
|
||||||
|
Loading…
Reference in New Issue
Block a user