From 15a3e313ff31c1c0151a28158a5d71b10cf1a5aa Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Mon, 11 Dec 2023 11:14:26 -0800 Subject: [PATCH] Tolerate polygon rings with insufficiently many points in input (#175) * Tolerate polygon rings with insufficiently many points in input * Fix changelog typo --- CHANGELOG.md | 4 ++++ geometry.cpp | 11 +++++++++-- tests/invalid-linestring/out/-z0.json | 15 +++++++++++++++ tests/invalid-linestring/too-few.json | 1 + tests/invalid-polygon/in.json | 1 + tests/invalid-polygon/out/-z0.json | 15 +++++++++++++++ version.hpp | 2 +- 7 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 tests/invalid-linestring/out/-z0.json create mode 100644 tests/invalid-linestring/too-few.json create mode 100644 tests/invalid-polygon/in.json create mode 100644 tests/invalid-polygon/out/-z0.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 130e3e944..482b28a88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.38.0 + +* Tolerate polygon rings with insuffiently many points in input + # 2.37.1 * Reduce maximum memory used for vertex sorting diff --git a/geometry.cpp b/geometry.cpp index 07ff15290..c4f8ee575 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -642,9 +642,9 @@ drawvec fix_polygon(drawvec &geom) { // A polygon ring must contain at least three points // (and really should contain four). If this one does - // not have enough, avoid a division by zero trying to + // not have any, avoid a division by zero trying to // calculate the centroid below. - if (j - i < 3) { + if (j - i < 1) { i = j - 1; outer = 0; continue; @@ -661,6 +661,13 @@ drawvec fix_polygon(drawvec &geom) { ring.push_back(ring[0]); } + // A polygon ring at this point should contain at least four points. + // Flesh it out with some vertex copies if it doesn't. + + while (ring.size() < 4) { + ring.push_back(ring[0]); + } + // Reverse ring if winding order doesn't match // inner/outer expectation diff --git a/tests/invalid-linestring/out/-z0.json b/tests/invalid-linestring/out/-z0.json new file mode 100644 index 000000000..150fb75a0 --- /dev/null +++ b/tests/invalid-linestring/out/-z0.json @@ -0,0 +1,15 @@ +{ "type": "FeatureCollection", "properties": { +"antimeridian_adjusted_bounds": "1.000000,2.000000,1.000000,2.000000", +"bounds": "1.000000,2.000000,1.000000,2.000000", +"center": "1.000000,2.000000,0", +"description": "tests/invalid-linestring/out/-z0.json.check.mbtiles", +"format": "pbf", +"generator_options": "./tippecanoe -q -a@ -f -o tests/invalid-linestring/out/-z0.json.check.mbtiles -z0 tests/invalid-linestring/too-few.json", +"json": "{\"vector_layers\":[{\"id\":\"toofew\",\"description\":\"\",\"minzoom\":0,\"maxzoom\":0,\"fields\":{}}],\"tilestats\":{\"layerCount\":1,\"layers\":[{\"layer\":\"toofew\",\"count\":1,\"geometry\":\"LineString\",\"attributeCount\":0,\"attributes\":[]}]}}", +"maxzoom": "0", +"minzoom": "0", +"name": "tests/invalid-linestring/out/-z0.json.check.mbtiles", +"type": "overlay", +"version": "2" +}, "features": [ +] } diff --git a/tests/invalid-linestring/too-few.json b/tests/invalid-linestring/too-few.json new file mode 100644 index 000000000..1bfeccd22 --- /dev/null +++ b/tests/invalid-linestring/too-few.json @@ -0,0 +1 @@ +{ "type": "Feature", "properties": {}, "geometry": { "type": "LineString", "coordinates": [ [ 1, 2 ] ] } } diff --git a/tests/invalid-polygon/in.json b/tests/invalid-polygon/in.json new file mode 100644 index 000000000..112a1380e --- /dev/null +++ b/tests/invalid-polygon/in.json @@ -0,0 +1 @@ +{ "type": "Feature", "properties": { "handle": 717, "block": -1, "etype": 13, "space": 0, "layer": "0", "olinetype": "BYLAYER", "linetype": "", "color": "0,0,0,255", "ocolor": 7, "color24": -1, "transparency": 0, "lweight": -1, "linewidth": 0.0, "ltscale": 1.0, "visible": 1, "thickness": 0.0, "ext": null, "name": "SOLID", "solid": 1, "associative": 0, "hstyle": 1, "hpattern": 1, "doubleflag": 0, "angle": 0.0, "scale": 0.0, "deflines": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -135.2329619, -85.526118 ], [ -135.2329619, -85.526118 ] ] ] ] } } diff --git a/tests/invalid-polygon/out/-z0.json b/tests/invalid-polygon/out/-z0.json new file mode 100644 index 000000000..263eb1d39 --- /dev/null +++ b/tests/invalid-polygon/out/-z0.json @@ -0,0 +1,15 @@ +{ "type": "FeatureCollection", "properties": { +"antimeridian_adjusted_bounds": "180.000000,85.051129,-180.000000,-85.051129", +"bounds": "-135.232962,-85.051129,-135.232962,-85.051129", +"center": "-135.232962,-85.051129,0", +"description": "tests/invalid-polygon/out/-z0.json.check.mbtiles", +"format": "pbf", +"generator_options": "./tippecanoe -q -a@ -f -o tests/invalid-polygon/out/-z0.json.check.mbtiles -z0 tests/invalid-polygon/in.json", +"json": "{\"vector_layers\":[{\"id\":\"in\",\"description\":\"\",\"minzoom\":0,\"maxzoom\":0,\"fields\":{\"angle\":\"Number\",\"associative\":\"Number\",\"block\":\"Number\",\"color\":\"String\",\"color24\":\"Number\",\"deflines\":\"Number\",\"doubleflag\":\"Number\",\"etype\":\"Number\",\"handle\":\"Number\",\"hpattern\":\"Number\",\"hstyle\":\"Number\",\"layer\":\"String\",\"linetype\":\"String\",\"linewidth\":\"Number\",\"ltscale\":\"Number\",\"lweight\":\"Number\",\"name\":\"String\",\"ocolor\":\"Number\",\"olinetype\":\"String\",\"scale\":\"Number\",\"solid\":\"Number\",\"space\":\"Number\",\"thickness\":\"Number\",\"transparency\":\"Number\",\"visible\":\"Number\"}}],\"tilestats\":{\"layerCount\":1,\"layers\":[{\"layer\":\"in\",\"count\":1,\"geometry\":\"Polygon\",\"attributeCount\":25,\"attributes\":[{\"attribute\":\"angle\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"associative\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"block\",\"count\":1,\"type\":\"number\",\"values\":[-1],\"min\":-1,\"max\":-1},{\"attribute\":\"color\",\"count\":1,\"type\":\"string\",\"values\":[\"0,0,0,255\"]},{\"attribute\":\"color24\",\"count\":1,\"type\":\"number\",\"values\":[-1],\"min\":-1,\"max\":-1},{\"attribute\":\"deflines\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"doubleflag\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"etype\",\"count\":1,\"type\":\"number\",\"values\":[13],\"min\":13,\"max\":13},{\"attribute\":\"handle\",\"count\":1,\"type\":\"number\",\"values\":[717],\"min\":717,\"max\":717},{\"attribute\":\"hpattern\",\"count\":1,\"type\":\"number\",\"values\":[1],\"min\":1,\"max\":1},{\"attribute\":\"hstyle\",\"count\":1,\"type\":\"number\",\"values\":[1],\"min\":1,\"max\":1},{\"attribute\":\"layer\",\"count\":1,\"type\":\"string\",\"values\":[\"0\"]},{\"attribute\":\"linetype\",\"count\":1,\"type\":\"string\",\"values\":[\"\"]},{\"attribute\":\"linewidth\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"ltscale\",\"count\":1,\"type\":\"number\",\"values\":[1],\"min\":1,\"max\":1},{\"attribute\":\"lweight\",\"count\":1,\"type\":\"number\",\"values\":[-1],\"min\":-1,\"max\":-1},{\"attribute\":\"name\",\"count\":1,\"type\":\"string\",\"values\":[\"SOLID\"]},{\"attribute\":\"ocolor\",\"count\":1,\"type\":\"number\",\"values\":[7],\"min\":7,\"max\":7},{\"attribute\":\"olinetype\",\"count\":1,\"type\":\"string\",\"values\":[\"BYLAYER\"]},{\"attribute\":\"scale\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"solid\",\"count\":1,\"type\":\"number\",\"values\":[1],\"min\":1,\"max\":1},{\"attribute\":\"space\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"thickness\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"transparency\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"visible\",\"count\":1,\"type\":\"number\",\"values\":[1],\"min\":1,\"max\":1}]}]}}", +"maxzoom": "0", +"minzoom": "0", +"name": "tests/invalid-polygon/out/-z0.json.check.mbtiles", +"type": "overlay", +"version": "2" +}, "features": [ +] } diff --git a/version.hpp b/version.hpp index 1fbbe1a5a..709cd9a7b 100644 --- a/version.hpp +++ b/version.hpp @@ -1,6 +1,6 @@ #ifndef VERSION_HPP #define VERSION_HPP -#define VERSION "v2.37.1" +#define VERSION "v2.38.0" #endif