From 48486b5d7bd9b0a2a94babf77a013f8e4b884266 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Fri, 1 Jun 2018 12:59:28 -0700 Subject: [PATCH] Add --use-source-polygon-winding and --reverse-source-polygon-winding --- CHANGELOG.md | 4 ++++ README.md | 2 ++ geometry.cpp | 18 ++++++++++++++++-- main.cpp | 2 ++ man/tippecanoe.1 | 4 ++++ options.hpp | 2 ++ tests/polygon-winding/in.json | 19 +++++++++++++++++++ tests/polygon-winding/out/-z0.json | 18 ++++++++++++++++++ .../-z0_--reverse-source-polygon-winding.json | 18 ++++++++++++++++++ .../out/-z0_--use-source-polygon-winding.json | 18 ++++++++++++++++++ version.hpp | 2 +- 11 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 tests/polygon-winding/in.json create mode 100644 tests/polygon-winding/out/-z0.json create mode 100644 tests/polygon-winding/out/-z0_--reverse-source-polygon-winding.json create mode 100644 tests/polygon-winding/out/-z0_--use-source-polygon-winding.json diff --git a/CHANGELOG.md b/CHANGELOG.md index f5fcfa8..e70f954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.29.1 + +* Add --use-source-polygon-winding and --reverse-source-polygon-winding + ## 1.29.0 * Add the option to specify layer file, name, and description as JSON diff --git a/README.md b/README.md index b05fb66..d7a68c0 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,8 @@ Example: to retain only major TIGER roads at low zoom levels: ### Trying to correct bad source geometry * `-aw` or `--detect-longitude-wraparound`: Detect when adjacent points within a feature jump to the other side of the world, and try to fix the geometry. + * `-pw` or `--use-source-polygon-winding`: Instead of respecting GeoJSON polygon ring order, use the original polygon winding in the source data to distinguish inner (clockwise) and outer (counterclockwise) polygon rings. + * `-pW` or `--reverse-source-polygon-winding`: Instead of respecting GeoJSON polygon ring order, use the opposite of the original polygon winding in the source data to distinguish inner (counterclockwise) and outer (clockwise) polygon rings. ### Setting or disabling tile size limits diff --git a/geometry.cpp b/geometry.cpp index 980c061..6f69abe 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -19,6 +19,7 @@ #include "projection.hpp" #include "serial.hpp" #include "main.hpp" +#include "options.hpp" static int pnpoly(drawvec &vert, size_t start, size_t nvert, long long testx, long long testy); static int clip(double *x0, double *y0, double *x1, double *y1, double xmin, double ymin, double xmax, double ymax); @@ -912,8 +913,21 @@ drawvec fix_polygon(drawvec &geom) { // Reverse ring if winding order doesn't match // inner/outer expectation - double area = get_area(ring, 0, ring.size()); - if ((area > 0) != outer) { + bool reverse_ring = false; + if (prevent[P_USE_SOURCE_POLYGON_WINDING]) { + // GeoJSON winding is reversed from vector winding + reverse_ring = true; + } else if (prevent[P_REVERSE_SOURCE_POLYGON_WINDING]) { + // GeoJSON winding is reversed from vector winding + reverse_ring = false; + } else { + double area = get_area(ring, 0, ring.size()); + if ((area > 0) != outer) { + reverse_ring = true; + } + } + + if (reverse_ring) { drawvec tmp; for (int a = ring.size() - 1; a >= 0; a--) { tmp.push_back(ring[a]); diff --git a/main.cpp b/main.cpp index 011cf18..1dbe289 100644 --- a/main.cpp +++ b/main.cpp @@ -2552,6 +2552,8 @@ int main(int argc, char **argv) { {"Trying to correct bad source geometry", 0, 0, 0}, {"detect-longitude-wraparound", no_argument, &additional[A_DETECT_WRAPAROUND], 1}, + {"use-source-polygon-winding", no_argument, &prevent[P_USE_SOURCE_POLYGON_WINDING], 1}, + {"reverse-source-polygon-winding", no_argument, &prevent[P_REVERSE_SOURCE_POLYGON_WINDING], 1}, {"Filtering tile contents", 0, 0, 0}, {"prefilter", required_argument, 0, 'C'}, diff --git a/man/tippecanoe.1 b/man/tippecanoe.1 index 1674791..a2d7a09 100644 --- a/man/tippecanoe.1 +++ b/man/tippecanoe.1 @@ -361,6 +361,10 @@ the line or polygon within one tile unit of its proper location. You can probabl .RS .IP \(bu 2 \fB\fC\-aw\fR or \fB\fC\-\-detect\-longitude\-wraparound\fR: Detect when adjacent points within a feature jump to the other side of the world, and try to fix the geometry. +.IP \(bu 2 +\fB\fC\-pw\fR or \fB\fC\-\-use\-source\-polygon\-winding\fR: Instead of respecting GeoJSON polygon ring order, use the original polygon winding in the source data to distinguish inner (clockwise) and outer (counterclockwise) polygon rings. +.IP \(bu 2 +\fB\fC\-pW\fR or \fB\fC\-\-reverse\-source\-polygon\-winding\fR: Instead of respecting GeoJSON polygon ring order, use the opposite of the original polygon winding in the source data to distinguish inner (counterclockwise) and outer (clockwise) polygon rings. .RE .SS Setting or disabling tile size limits .RS diff --git a/options.hpp b/options.hpp index e97dd72..0b113f6 100644 --- a/options.hpp +++ b/options.hpp @@ -35,6 +35,8 @@ #define P_TINY_POLYGON_REDUCTION ((int) 't') #define P_TILE_COMPRESSION ((int) 'C') #define P_TILE_STATS ((int) 'g') +#define P_USE_SOURCE_POLYGON_WINDING ((int) 'w') +#define P_REVERSE_SOURCE_POLYGON_WINDING ((int) 'W') extern int prevent[256]; extern int additional[256]; diff --git a/tests/polygon-winding/in.json b/tests/polygon-winding/in.json new file mode 100644 index 0000000..c736d69 --- /dev/null +++ b/tests/polygon-winding/in.json @@ -0,0 +1,19 @@ + { + "type": "Polygon", + "coordinates": [ + [ + [100.0, 0.0], + [101.0, 0.0], + [101.0, 1.0], + [100.0, 1.0], + [100.0, 0.0] + ], + [ + [100.8, 0.8], + [100.8, 0.2], + [100.2, 0.2], + [100.2, 0.8], + [100.8, 0.8] + ] + ] + } diff --git a/tests/polygon-winding/out/-z0.json b/tests/polygon-winding/out/-z0.json new file mode 100644 index 0000000..c46816a --- /dev/null +++ b/tests/polygon-winding/out/-z0.json @@ -0,0 +1,18 @@ +{ "type": "FeatureCollection", "properties": { +"bounds": "100.000000,0.000000,101.000000,1.000000", +"center": "100.000000,0.000000,0", +"description": "tests/polygon-winding/out/-z0.json.check.mbtiles", +"format": "pbf", +"json": "{\"vector_layers\": [ { \"id\": \"in\", \"description\": \"\", \"minzoom\": 0, \"maxzoom\": 0, \"fields\": {} } ],\"tilestats\": {\"layerCount\": 1,\"layers\": [{\"layer\": \"in\",\"count\": 1,\"geometry\": \"Polygon\",\"attributeCount\": 0,\"attributes\": []}]}}", +"maxzoom": "0", +"minzoom": "0", +"name": "tests/polygon-winding/out/-z0.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": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 100.986328, 1.054628 ], [ 100.986328, 0.000000 ], [ 99.931641, 0.000000 ], [ 99.931641, 1.054628 ], [ 100.986328, 1.054628 ] ], [ [ 100.195312, 0.263671 ], [ 100.722656, 0.263671 ], [ 100.722656, 0.878872 ], [ 100.195312, 0.878872 ], [ 100.195312, 0.263671 ] ] ] } } +] } +] } +] } diff --git a/tests/polygon-winding/out/-z0_--reverse-source-polygon-winding.json b/tests/polygon-winding/out/-z0_--reverse-source-polygon-winding.json new file mode 100644 index 0000000..6e638f1 --- /dev/null +++ b/tests/polygon-winding/out/-z0_--reverse-source-polygon-winding.json @@ -0,0 +1,18 @@ +{ "type": "FeatureCollection", "properties": { +"bounds": "100.000000,0.000000,101.000000,1.000000", +"center": "100.000000,0.000000,0", +"description": "tests/polygon-winding/out/-z0_--reverse-source-polygon-winding.json.check.mbtiles", +"format": "pbf", +"json": "{\"vector_layers\": [ { \"id\": \"in\", \"description\": \"\", \"minzoom\": 0, \"maxzoom\": 0, \"fields\": {} } ],\"tilestats\": {\"layerCount\": 1,\"layers\": [{\"layer\": \"in\",\"count\": 1,\"geometry\": \"Polygon\",\"attributeCount\": 0,\"attributes\": []}]}}", +"maxzoom": "0", +"minzoom": "0", +"name": "tests/polygon-winding/out/-z0_--reverse-source-polygon-winding.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": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 100.722656, 0.878872 ], [ 100.722656, 0.263671 ], [ 100.195312, 0.263671 ], [ 100.195312, 0.878872 ], [ 100.722656, 0.878872 ] ] ] } } +] } +] } +] } diff --git a/tests/polygon-winding/out/-z0_--use-source-polygon-winding.json b/tests/polygon-winding/out/-z0_--use-source-polygon-winding.json new file mode 100644 index 0000000..bb6d8cb --- /dev/null +++ b/tests/polygon-winding/out/-z0_--use-source-polygon-winding.json @@ -0,0 +1,18 @@ +{ "type": "FeatureCollection", "properties": { +"bounds": "100.000000,0.000000,101.000000,1.000000", +"center": "100.000000,0.000000,0", +"description": "tests/polygon-winding/out/-z0_--use-source-polygon-winding.json.check.mbtiles", +"format": "pbf", +"json": "{\"vector_layers\": [ { \"id\": \"in\", \"description\": \"\", \"minzoom\": 0, \"maxzoom\": 0, \"fields\": {} } ],\"tilestats\": {\"layerCount\": 1,\"layers\": [{\"layer\": \"in\",\"count\": 1,\"geometry\": \"Polygon\",\"attributeCount\": 0,\"attributes\": []}]}}", +"maxzoom": "0", +"minzoom": "0", +"name": "tests/polygon-winding/out/-z0_--use-source-polygon-winding.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": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 100.986328, 1.054628 ], [ 100.986328, 0.000000 ], [ 99.931641, 0.000000 ], [ 99.931641, 1.054628 ], [ 100.986328, 1.054628 ] ], [ [ 100.195312, 0.263671 ], [ 100.722656, 0.263671 ], [ 100.722656, 0.878872 ], [ 100.195312, 0.878872 ], [ 100.195312, 0.263671 ] ] ] } } +] } +] } +] } diff --git a/version.hpp b/version.hpp index 83d12f6..a3433c9 100644 --- a/version.hpp +++ b/version.hpp @@ -1,6 +1,6 @@ #ifndef VERSION_HPP #define VERSION_HPP -#define VERSION "tippecanoe v1.29.0\n" +#define VERSION "tippecanoe v1.29.1\n" #endif