Skip to content

Commit

Permalink
Merge pull request #412 from mapbox/polygon-closure
Browse files Browse the repository at this point in the history
Enforce polygon winding and closure rules in tippecanoe-decode
  • Loading branch information
e-n-f authored May 5, 2017
2 parents eab593f + 922bef7 commit 685e1a4
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.17.7

* Enforce polygon winding and closure rules in tippecanoe-decode

## 1.17.6

* Add tile-join options to set name, attribution, description
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,4 @@ resolutions.
* `-z` _maxzoom_: Specify the highest zoom level to decode from the tileset
* `-Z` _minzoom_: Specify the lowest zoom level to decode from the tileset
* `-l` _layer_: Decode only layers with the specified names. (Multiple `-l` options can be specified.)
* `-f`: Decode tiles even if polygon ring order or closure problems are detected
23 changes: 22 additions & 1 deletion decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

int minzoom = 0;
int maxzoom = 32;
bool force = false;

void printq(const char *s) {
putchar('"');
Expand Down Expand Up @@ -261,6 +262,15 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe, st
rings[n].push_back(ops[i]);
}
}

if (i + 1 >= ops.size() || ops[i + 1].op == VT_MOVETO) {
if (ops[i].op != VT_CLOSEPATH) {
fprintf(stderr, "Ring does not end with closepath (ends with %d)\n", ops[i].op);
if (!force) {
exit(EXIT_FAILURE);
}
}
}
}

int outer = 0;
Expand Down Expand Up @@ -290,6 +300,13 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe, st

int state = 0;
for (size_t i = 0; i < rings.size(); i++) {
if (i == 0 && areas[i] < 0) {
fprintf(stderr, "Polygon begins with an inner ring\n");
if (!force) {
exit(EXIT_FAILURE);
}
}

if (areas[i] >= 0) {
if (state != 0) {
// new multipolygon
Expand Down Expand Up @@ -489,7 +506,7 @@ int main(int argc, char **argv) {
int i;
std::set<std::string> to_decode;

while ((i = getopt(argc, argv, "t:Z:z:l:")) != -1) {
while ((i = getopt(argc, argv, "t:Z:z:l:f")) != -1) {
switch (i) {
case 't':
set_projection_or_exit(optarg);
Expand All @@ -507,6 +524,10 @@ int main(int argc, char **argv) {
to_decode.insert(optarg);
break;

case 'f':
force = true;
break;

default:
usage(argv);
}
Expand Down
2 changes: 2 additions & 0 deletions man/tippecanoe.1
Original file line number Diff line number Diff line change
Expand Up @@ -568,4 +568,6 @@ resolutions.
\fB\fC\-Z\fR \fIminzoom\fP: Specify the lowest zoom level to decode from the tileset
.IP \(bu 2
\fB\fC\-l\fR \fIlayer\fP: Decode only layers with the specified names. (Multiple \fB\fC\-l\fR options can be specified.)
.IP \(bu 2
\fB\fC\-f\fR: Decode tiles even if polygon ring order or closure problems are detected
.RE
2 changes: 1 addition & 1 deletion version.hpp
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define VERSION "tippecanoe v1.17.6\n"
#define VERSION "tippecanoe v1.17.7\n"

0 comments on commit 685e1a4

Please sign in to comment.