Add --use-source-polygon-winding and --reverse-source-polygon-winding

This commit is contained in:
Eric Fischer 2018-06-01 12:59:28 -07:00
parent 38bca4a179
commit 48486b5d7b
11 changed files with 104 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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]);

View File

@ -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'},

View File

@ -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

View File

@ -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];

View File

@ -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]
]
]
}

View File

@ -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 ] ] ] } }
] }
] }
] }

View File

@ -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 ] ] ] } }
] }
] }
] }

View File

@ -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 ] ] ] } }
] }
] }
] }

View File

@ -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