Don't use longitude wraparound detection if it makes a contradictory geometry

This commit is contained in:
Erica Fischer
2023-12-11 11:00:03 -08:00
parent d7bdbe363b
commit 80ac56a0b3
4 changed files with 99 additions and 27 deletions
+2
View File
@@ -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
View File
@@ -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 ] ] ] ] } }
] }
] }
] }