mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-03 08:55:41 +02:00
Don't use longitude wraparound detection if it makes a contradictory geometry
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
* Don't use longitude wraparound detection if it makes a self-contradictory geometry
|
||||
|
||||
# 2.37.1
|
||||
|
||||
* Reduce maximum memory used for vertex sorting
|
||||
|
||||
+76
-27
@@ -314,40 +314,89 @@ serial_feature deserialize_feature(std::string &geoms, unsigned z, unsigned tx,
|
||||
}
|
||||
|
||||
static long long scale_geometry(struct serialization_state *sst, long long *bbox, drawvec &geom) {
|
||||
long long offset = 0;
|
||||
long long prev = 0;
|
||||
bool has_prev = false;
|
||||
double scale = 1.0 / (1 << geometry_scale);
|
||||
|
||||
if (additional[A_DETECT_WRAPAROUND]) {
|
||||
drawvec out;
|
||||
|
||||
for (size_t i = 0; i < geom.size(); i++) {
|
||||
if (geom[i].op == VT_MOVETO) {
|
||||
size_t j = 0;
|
||||
for (j = i + 1; j < geom.size(); j++) {
|
||||
if (geom[j].op != VT_LINETO) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
long long prev_x = geom[i].x;
|
||||
long long offset = 0;
|
||||
bool balanced = true;
|
||||
|
||||
drawvec ring;
|
||||
for (size_t k = i; k < j; k++) {
|
||||
draw op = geom[k];
|
||||
op.x += offset;
|
||||
|
||||
// jumps at least 180° but not exactly 360°,
|
||||
// which in some data sets is an intentional
|
||||
// line across the world
|
||||
if (op.x - prev_x > (1LL << 31) && op.x - prev_x != (1LL << 32)) {
|
||||
if (offset < 0) {
|
||||
// already shifted left, but seems to need another shift left
|
||||
balanced = false;
|
||||
break;
|
||||
}
|
||||
|
||||
offset -= 1LL << 32;
|
||||
op.x -= 1LL << 32;
|
||||
} else if (prev_x - op.x > (1LL << 31) && prev_x - op.x != (1LL << 32)) {
|
||||
if (offset > 0) {
|
||||
// already shifted right, but seems to need another shift right
|
||||
balanced = false;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += 1LL << 32;
|
||||
op.x += 1LL << 32;
|
||||
}
|
||||
|
||||
ring.push_back(op);
|
||||
prev_x = op.x;
|
||||
}
|
||||
|
||||
if (geom[j - 1] == geom[i]) {
|
||||
if (offset != 0) {
|
||||
// first and last points are supposed to be the same
|
||||
// but there is an unresolved antimeridian shift still
|
||||
balanced = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!balanced) {
|
||||
ring.clear();
|
||||
for (size_t k = i; k < j; k++) {
|
||||
ring.push_back(geom[k]);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const &g : ring) {
|
||||
out.push_back(g);
|
||||
}
|
||||
|
||||
i = j - 1;
|
||||
} else if (geom[i].op == VT_CLOSEPATH) {
|
||||
out.push_back(geom[i]);
|
||||
}
|
||||
}
|
||||
|
||||
geom = std::move(out);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < geom.size(); i++) {
|
||||
if (geom[i].op == VT_MOVETO || geom[i].op == VT_LINETO) {
|
||||
long long x = geom[i].x;
|
||||
long long y = geom[i].y;
|
||||
|
||||
if (additional[A_DETECT_WRAPAROUND]) {
|
||||
if (geom[i].op == VT_LINETO) {
|
||||
x += offset;
|
||||
if (has_prev) {
|
||||
// jumps at least 180° but not exactly 360°,
|
||||
// which in some data sets is an intentional
|
||||
// line across the world
|
||||
if (x - prev > (1LL << 31) && x - prev != (1LL << 32)) {
|
||||
offset -= 1LL << 32;
|
||||
x -= 1LL << 32;
|
||||
} else if (prev - x > (1LL << 31) && prev - x != (1LL << 32)) {
|
||||
offset += 1LL << 32;
|
||||
x += 1LL << 32;
|
||||
}
|
||||
}
|
||||
|
||||
has_prev = true;
|
||||
prev = x;
|
||||
} else {
|
||||
offset = 0;
|
||||
prev = x;
|
||||
}
|
||||
}
|
||||
|
||||
if (x < bbox[0]) {
|
||||
bbox[0] = x;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,20 @@
|
||||
{ "type": "FeatureCollection", "properties": {
|
||||
"antimeridian_adjusted_bounds": "-179.084872,-42.586987,179.718436,64.188520",
|
||||
"bounds": "-179.084872,-85.051129,179.718436,64.188520",
|
||||
"center": "0.000000,0.000000,0",
|
||||
"description": "tests/wraparound-gap/out/-z0_--detect-longitude-wraparound.json.check.mbtiles",
|
||||
"format": "pbf",
|
||||
"generator_options": "./tippecanoe -q -a@ -f -o tests/wraparound-gap/out/-z0_--detect-longitude-wraparound.json.check.mbtiles -z0 --detect-longitude-wraparound tests/wraparound-gap/in.json",
|
||||
"json": "{\"vector_layers\":[{\"id\":\"in\",\"description\":\"\",\"minzoom\":0,\"maxzoom\":0,\"fields\":{\"felt:color\":\"String\",\"felt:fillOpacity\":\"Number\",\"felt:id\":\"String\",\"felt:locked\":\"Number\",\"felt:ordering\":\"Number\",\"felt:showArea\":\"Number\",\"felt:strokeOpacity\":\"Number\",\"felt:strokeStyle\":\"String\",\"felt:strokeWidth\":\"Number\",\"felt:type\":\"String\"}}],\"tilestats\":{\"layerCount\":1,\"layers\":[{\"layer\":\"in\",\"count\":1,\"geometry\":\"Polygon\",\"attributeCount\":10,\"attributes\":[{\"attribute\":\"felt:color\",\"count\":1,\"type\":\"string\",\"values\":[\"#C93535\"]},{\"attribute\":\"felt:fillOpacity\",\"count\":1,\"type\":\"number\",\"values\":[0.25],\"min\":0.25,\"max\":0.25},{\"attribute\":\"felt:id\",\"count\":1,\"type\":\"string\",\"values\":[\"fdd67048-a864-48d1-9596-fe332d5e2fd8\"]},{\"attribute\":\"felt:locked\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"felt:ordering\",\"count\":1,\"type\":\"number\",\"values\":[1701884658553581],\"min\":1701884658553581,\"max\":1701884658553581},{\"attribute\":\"felt:showArea\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"felt:strokeOpacity\",\"count\":1,\"type\":\"number\",\"values\":[1],\"min\":1,\"max\":1},{\"attribute\":\"felt:strokeStyle\",\"count\":1,\"type\":\"string\",\"values\":[\"solid\"]},{\"attribute\":\"felt:strokeWidth\",\"count\":1,\"type\":\"number\",\"values\":[2],\"min\":2,\"max\":2},{\"attribute\":\"felt:type\",\"count\":1,\"type\":\"string\",\"values\":[\"Polygon\"]}]}]}}",
|
||||
"maxzoom": "0",
|
||||
"minzoom": "0",
|
||||
"name": "tests/wraparound-gap/out/-z0_--detect-longitude-wraparound.json.check.mbtiles",
|
||||
"type": "overlay",
|
||||
"version": "2"
|
||||
}, "features": [
|
||||
{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [
|
||||
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [
|
||||
{ "type": "Feature", "properties": { "felt:color": "#C93535", "felt:fillOpacity": 0.25, "felt:id": "fdd67048-a864-48d1-9596-fe332d5e2fd8", "felt:locked": 0, "felt:ordering": 1701884658553581, "felt:showArea": 0, "felt:strokeOpacity": 1, "felt:strokeStyle": "solid", "felt:strokeWidth": 2, "felt:type": "Polygon" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -68.730469, 64.206377 ], [ -63.281250, 64.052978 ], [ -60.644531, 63.898731 ], [ -55.371094, 63.391522 ], [ -52.910156, 63.074866 ], [ -50.361328, 62.714462 ], [ -45.615234, 61.856149 ], [ -41.220703, 60.802064 ], [ -37.089844, 59.578851 ], [ -35.156250, 58.904646 ], [ -29.707031, 56.704506 ], [ -24.960938, 54.213861 ], [ -19.511719, 50.569283 ], [ -15.996094, 47.576526 ], [ -10.986328, 42.293564 ], [ -8.349609, 38.959409 ], [ -3.164062, 30.600094 ], [ 0.527344, 22.998852 ], [ 3.779297, 16.888660 ], [ 6.679688, 12.125264 ], [ 10.722656, 4.740675 ], [ 16.435547, -6.751896 ], [ 25.048828, -12.382928 ], [ 37.353516, -19.890723 ], [ 44.824219, -23.966176 ], [ 55.019531, -28.921631 ], [ 64.160156, -32.694866 ], [ 70.927734, -35.029996 ], [ 75.146484, -36.315125 ], [ 82.177734, -38.203655 ], [ 89.472656, -39.774769 ], [ 93.955078, -40.580585 ], [ 98.525391, -41.244772 ], [ 103.183594, -41.771312 ], [ 109.511719, -42.293564 ], [ 115.927734, -42.553080 ], [ 122.431641, -42.553080 ], [ 128.935547, -42.293564 ], [ 133.857422, -41.902277 ], [ 137.197266, -41.508577 ], [ 143.789062, -40.044438 ], [ 145.283203, -39.571822 ], [ 151.171875, -37.439974 ], [ 156.796875, -35.101934 ], [ 166.113281, -30.524413 ], [ 173.671875, -26.194877 ], [ 179.736328, -22.350076 ], [ 179.736328, -85.622069 ], [ -179.121094, -85.622069 ], [ -179.121094, -21.534847 ], [ -157.939453, -6.140555 ], [ -143.437500, 13.838080 ], [ -140.712891, 20.632784 ], [ -137.109375, 28.459033 ], [ -133.593750, 34.597042 ], [ -130.429688, 39.368279 ], [ -128.671875, 41.640078 ], [ -123.662109, 47.040182 ], [ -118.916016, 51.013755 ], [ -117.597656, 51.944265 ], [ -113.291016, 54.622978 ], [ -110.039062, 56.316537 ], [ -106.611328, 57.844751 ], [ -102.832031, 59.265881 ], [ -96.591797, 61.100789 ], [ -92.021484, 62.103883 ], [ -87.187500, 62.955223 ], [ -84.638672, 63.273182 ], [ -79.453125, 63.821288 ], [ -76.816406, 63.975961 ], [ -71.367188, 64.168107 ], [ -68.730469, 64.206377 ] ] ], [ [ [ 187.031250, -17.224758 ], [ 187.031250, -85.622069 ], [ 180.878906, -85.622069 ], [ 180.878906, -21.534847 ], [ 187.031250, -17.224758 ] ] ], [ [ [ -180.263672, -22.350076 ], [ -180.263672, -85.622069 ], [ -187.031250, -85.622069 ], [ -187.031250, -26.588527 ], [ -180.263672, -22.350076 ] ] ] ] } }
|
||||
] }
|
||||
] }
|
||||
] }
|
||||
Reference in New Issue
Block a user