diff --git a/CHANGELOG.md b/CHANGELOG.md index 969fdfc..a8c9544 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +## 1.16.10 + +* Add a tippecanoe-decode option to specify layer names + +## 1.16.9 + +* Clean up layer name handling to fix layer merging crash + +## 1.16.8 + +* Fix some code that could sometimes try to divide by zero +* Add check for $TIPPECANOE_MAX_THREADS environmental variable + +## 1.16.7 + +* Fix area of placeholders for degenerate multipolygons + +## 1.16.6 + +* Upgrade Wagyu to 0.3.0; downgrade C++ requirement to C++ 11 + ## 1.16.5 * Add -z and -Z options to tippecanoe-decode diff --git a/Makefile b/Makefile index dae76ba..142f6aa 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ SHELL = /bin/bash CC := $(CC) CXX := $(CXX) CFLAGS := $(CFLAGS) -CXXFLAGS := $(CXXFLAGS) -std=c++14 +CXXFLAGS := $(CXXFLAGS) -std=c++11 LDFLAGS := $(LDFLAGS) WARNING_FLAGS := -Wall -Wshadow -Wsign-compare RELEASE_FLAGS := -O3 -DNDEBUG @@ -78,7 +78,7 @@ indent: TESTS = $(wildcard tests/*/out/*.json) SPACE = $(NULL) $(NULL) -test: tippecanoe tippecanoe-decode $(addsuffix .check,$(TESTS)) parallel-test pbf-test join-test enumerate-test unit +test: tippecanoe tippecanoe-decode $(addsuffix .check,$(TESTS)) parallel-test pbf-test join-test enumerate-test decode-test unit ./unit # Work around Makefile and filename punctuation limits: _ for space, @ for :, % for / @@ -112,6 +112,13 @@ parallel-test: cmp tests/parallel/linear-file.json tests/parallel/parallel-pipes.json rm tests/parallel/*.mbtiles tests/parallel/*.json +decode-test: + mkdir -p tests/muni/decode + ./tippecanoe -z11 -Z11 -f -o tests/muni/decode/multi.mbtiles tests/muni/*.json + ./tippecanoe-decode -l subway tests/muni/decode/multi.mbtiles > tests/muni/decode/multi.mbtiles.json.check + cmp tests/muni/decode/multi.mbtiles.json.check tests/muni/decode/multi.mbtiles.json + rm -f tests/muni/decode/multi.mbtiles.json.check tests/muni/decode/multi.mbtiles + pbf-test: ./tippecanoe-decode tests/pbf/11-328-791.vector.pbf 11 328 791 > tests/pbf/11-328-791.vector.pbf.out cmp tests/pbf/11-328-791.json tests/pbf/11-328-791.vector.pbf.out diff --git a/README.md b/README.md index b6f2d79..3c4647b 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,12 @@ contain `index`, `sequence`, and `extent` elements, which must be passed through tippecanoe -o countries.mbtiles -z5 -C 'mkdir -p tiles/$1/$2; tee tiles/$1/$2/$3.geojson' ne_10m_admin_0_countries.json ``` +Environment +----------- + +Tippecanoe ordinarily uses as many parallel threads as the operating system claims that CPUs are available. +You can override this number by setting the `TIPPECANOE_MAX_THREADS` environmental variable. + Example ------- @@ -309,7 +315,7 @@ and perhaps make install -Tippecanoe now requires features from the 2014 C++ standard. If your compiler is older than +Tippecanoe now requires features from the 2011 C++ standard. If your compiler is older than that, you will need to install a newer one. On MacOS, updating to the lastest XCode should get you a new enough version of `clang++`. On Linux, you should be able to upgrade `g++` with @@ -435,3 +441,4 @@ resolutions. * -t _projection_: Specify the projection of the output data. Currently supported are EPSG:4326 (WGS84, the default) and EPSG:3857 (Web Mercator). * -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.) diff --git a/decode.cpp b/decode.cpp index 1970256..30efb47 100644 --- a/decode.cpp +++ b/decode.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,7 @@ int minzoom = 0; int maxzoom = 32; -void handle(std::string message, int z, unsigned x, unsigned y, int describe) { +void handle(std::string message, int z, unsigned x, unsigned y, int describe, std::set const &to_decode) { int within = 0; mvt_tile tile; @@ -48,11 +49,16 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) { printf(", \"features\": [\n"); + bool first_layer = true; for (size_t l = 0; l < tile.layers.size(); l++) { mvt_layer &layer = tile.layers[l]; + if (to_decode.size() != 0 && !to_decode.count(layer.name)) { + continue; + } + if (describe) { - if (l != 0) { + if (!first_layer) { printf(",\n"); } @@ -63,6 +69,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) { printf(" }"); printf(", \"features\": [\n"); + first_layer = false; within = 0; } @@ -76,7 +83,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) { printf("] }\n"); } -void decode(char *fname, int z, unsigned x, unsigned y) { +void decode(char *fname, int z, unsigned x, unsigned y, std::set const &to_decode) { sqlite3 *db; int oz = z; unsigned ox = x, oy = y; @@ -91,7 +98,7 @@ void decode(char *fname, int z, unsigned x, unsigned y) { if (strcmp(map, "SQLite format 3") != 0) { if (z >= 0) { std::string s = std::string(map, st.st_size); - handle(s, z, x, y, 1); + handle(s, z, x, y, 1, to_decode); munmap(map, st.st_size); return; } else { @@ -171,7 +178,7 @@ void decode(char *fname, int z, unsigned x, unsigned y) { ty = (1LL << tz) - 1 - ty; const char *s = (const char *) sqlite3_column_blob(stmt, 0); - handle(std::string(s, len), tz, tx, ty, 1); + handle(std::string(s, len), tz, tx, ty, 1, to_decode); } printf("] }\n"); @@ -199,7 +206,7 @@ void decode(char *fname, int z, unsigned x, unsigned y) { fprintf(stderr, "%s: Warning: using tile %d/%u/%u instead of %d/%u/%u\n", fname, z, x, y, oz, ox, oy); } - handle(std::string(s, len), z, x, y, 0); + handle(std::string(s, len), z, x, y, 0, to_decode); handled = 1; } @@ -218,7 +225,7 @@ void decode(char *fname, int z, unsigned x, unsigned y) { } void usage(char **argv) { - fprintf(stderr, "Usage: %s [-t projection] [-Z minzoom] [-z maxzoom] file.mbtiles [zoom x y]\n", argv[0]); + fprintf(stderr, "Usage: %s [-t projection] [-Z minzoom] [-z maxzoom] [-l layer ...] file.mbtiles [zoom x y]\n", argv[0]); exit(EXIT_FAILURE); } @@ -226,8 +233,9 @@ int main(int argc, char **argv) { extern int optind; extern char *optarg; int i; + std::set to_decode; - while ((i = getopt(argc, argv, "t:Z:z:")) != -1) { + while ((i = getopt(argc, argv, "t:Z:z:l:")) != -1) { switch (i) { case 't': set_projection_or_exit(optarg); @@ -241,15 +249,19 @@ int main(int argc, char **argv) { minzoom = atoi(optarg); break; + case 'l': + to_decode.insert(optarg); + break; + default: usage(argv); } } if (argc == optind + 4) { - decode(argv[optind], atoi(argv[optind + 1]), atoi(argv[optind + 2]), atoi(argv[optind + 3])); + decode(argv[optind], atoi(argv[optind + 1]), atoi(argv[optind + 2]), atoi(argv[optind + 3]), to_decode); } else if (argc == optind + 1) { - decode(argv[optind], -1, -1, -1); + decode(argv[optind], -1, -1, -1, to_decode); } else { usage(argv); } diff --git a/geometry.cpp b/geometry.cpp index ca2d763..91a928e 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -10,9 +10,11 @@ #include #include #include -#include +#include +#include #include #include +#include #include "geometry.hpp" #include "projection.hpp" #include "serial.hpp" @@ -166,6 +168,27 @@ double get_area(drawvec &geom, size_t i, size_t j) { return area; } +double get_mp_area(drawvec &geom) { + double ret = 0; + + for (size_t i = 0; i < geom.size(); i++) { + if (geom[i].op == VT_MOVETO) { + size_t j; + + for (j = i + 1; j < geom.size(); j++) { + if (geom[j].op != VT_LINETO) { + break; + } + } + + ret += get_area(geom, i, j); + i = j - 1; + } + } + + return ret; +} + static void decode_clipped(mapbox::geometry::multi_polygon &t, drawvec &out) { out.clear(); @@ -323,29 +346,41 @@ static int pnpoly(drawvec &vert, size_t start, size_t nvert, long long testx, lo } void check_polygon(drawvec &geom, drawvec &before) { - for (size_t i = 0; i + 1 < geom.size(); i++) { - for (size_t j = i + 1; j + 1 < geom.size(); j++) { - if (geom[i + 1].op == VT_LINETO && geom[j + 1].op == VT_LINETO) { - double s1_x = geom[i + 1].x - geom[i + 0].x; - double s1_y = geom[i + 1].y - geom[i + 0].y; - double s2_x = geom[j + 1].x - geom[j + 0].x; - double s2_y = geom[j + 1].y - geom[j + 0].y; + geom = remove_noop(geom, VT_POLYGON, 0); - double s, t; - s = (-s1_y * (geom[i + 0].x - geom[j + 0].x) + s1_x * (geom[i + 0].y - geom[j + 0].y)) / (-s2_x * s1_y + s1_x * s2_y); - t = (s2_x * (geom[i + 0].y - geom[j + 0].y) - s2_y * (geom[i + 0].x - geom[j + 0].x)) / (-s2_x * s1_y + s1_x * s2_y); - - if (t > 0 && t < 1 && s > 0 && s < 1) { - printf("Internal error: self-intersecting polygon. %lld,%lld to %lld,%lld intersects %lld,%lld to %lld,%lld\n", - geom[i + 0].x, geom[i + 0].y, - geom[i + 1].x, geom[i + 1].y, - geom[j + 0].x, geom[j + 0].y, - geom[j + 1].x, geom[j + 1].y); + mapbox::geometry::multi_polygon mp; + for (size_t i = 0; i < geom.size(); i++) { + if (geom[i].op == VT_MOVETO) { + size_t j; + for (j = i + 1; j < geom.size(); j++) { + if (geom[j].op != VT_LINETO) { + break; } } + + if (j >= i + 4) { + mapbox::geometry::linear_ring lr; + + for (size_t k = i; k < j; k++) { + lr.push_back(mapbox::geometry::point(geom[k].x, geom[k].y)); + } + + if (lr.size() >= 3) { + mapbox::geometry::polygon p; + p.push_back(lr); + mp.push_back(p); + } + } + + i = j - 1; } } + mapbox::geometry::multi_polygon mp2 = mapbox::geometry::snap_round(mp, true, true); + if (mp != mp2) { + fprintf(stderr, "Internal error: self-intersecting polygon\n"); + } + size_t outer_start = -1; size_t outer_len = 0; @@ -446,19 +481,19 @@ drawvec simple_clip_poly(drawvec &geom, long long minx, long long miny, long lon ring.push_back(mapbox::geometry::point(geom[k].x, geom[k].y)); } - optional_linear_ring lr = mapbox::geometry::wagyu::quick_clip::quick_lr_clip(ring, bbox); + mapbox::geometry::linear_ring lr = mapbox::geometry::wagyu::quick_clip::quick_lr_clip(ring, bbox); - if (lr) { - for (size_t k = 0; k < lr->size(); k++) { + if (lr.size() > 0) { + for (size_t k = 0; k < lr.size(); k++) { if (k == 0) { - out.push_back(draw(VT_MOVETO, (*lr)[k].x, (*lr)[k].y)); + out.push_back(draw(VT_MOVETO, lr[k].x, lr[k].y)); } else { - out.push_back(draw(VT_LINETO, (*lr)[k].x, (*lr)[k].y)); + out.push_back(draw(VT_LINETO, lr[k].x, lr[k].y)); } } - if (lr->size() > 0 && (*lr)[0] != (*lr)[lr->size() - 1]) { - out.push_back(draw(VT_LINETO, (*lr)[0].x, (*lr)[0].y)); + if (lr.size() > 0 && lr[0] != lr[lr.size() - 1]) { + out.push_back(draw(VT_LINETO, lr[0].x, lr[0].y)); } } diff --git a/geometry.hpp b/geometry.hpp index b8f0bf0..09184bf 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -71,3 +71,4 @@ drawvec fix_polygon(drawvec &geom); std::vector chop_polygon(std::vector &geoms); void check_polygon(drawvec &geom, drawvec &before); double get_area(drawvec &geom, size_t i, size_t j); +double get_mp_area(drawvec &geom); diff --git a/main.cpp b/main.cpp index 866d895..3b8950d 100644 --- a/main.cpp +++ b/main.cpp @@ -122,7 +122,14 @@ void checkdisk(struct reader *r, int nreader) { }; void init_cpus() { - CPUS = sysconf(_SC_NPROCESSORS_ONLN); + const char *TIPPECANOE_MAX_THREADS = getenv("TIPPECANOE_MAX_THREADS"); + + if (TIPPECANOE_MAX_THREADS != NULL) { + CPUS = atoi(TIPPECANOE_MAX_THREADS); + } else { + CPUS = sysconf(_SC_NPROCESSORS_ONLN); + } + if (CPUS < 1) { CPUS = 1; } @@ -414,7 +421,7 @@ void do_read_parallel(char *map, long long len, long long initial_offset, const pja[i].treefile = reader[i].treefile; pja[i].fname = fname; pja[i].basezoom = basezoom; - pja[i].layer = source < nlayers ? source : 0; + pja[i].layer = source; pja[i].droprate = droprate; pja[i].file_bbox = reader[i].file_bbox; pja[i].segment = i; @@ -713,6 +720,9 @@ void radix1(int *geomfds_in, int *indexfds_in, int inputs, int prefix, int split unit = max_unit; } unit = ((unit + page - 1) / page) * page; + if (unit < page) { + unit = page; + } size_t nmerges = (indexpos + unit - 1) / unit; struct mergelist merges[nmerges]; @@ -999,7 +1009,7 @@ void choose_first_zoom(long long *file_bbox, struct reader *reader, unsigned *iz } } -int read_input(std::vector &sources, char *fname, const char *layername, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, std::set *exclude, std::set *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma, long long *file_bbox, const char *prefilter, const char *postfilter) { +int read_input(std::vector &sources, char *fname, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, std::set *exclude, std::set *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma, long long *file_bbox, const char *prefilter, const char *postfilter) { int ret = EXIT_SUCCESS; struct reader reader[CPUS]; @@ -1107,26 +1117,12 @@ int read_input(std::vector &sources, char *fname, const char *layername, initialized[i] = initial_x[i] = initial_y[i] = 0; } - size_t nlayers; - if (layername != NULL) { - nlayers = 1; - } else { - nlayers = sources.size(); - if (nlayers == 0) { - nlayers = 1; - } - } - - std::vector layernames; + size_t nlayers = sources.size(); for (size_t l = 0; l < nlayers; l++) { - if (layername != NULL) { - layernames.push_back(std::string(layername)); - } else { + if (sources[l].layer.size() == 0) { const char *src; - if (sources.size() < 1) { + if (sources[l].file.size() == 0) { src = fname; - } else if (sources[l].layer.size() != 0) { - src = sources[l].layer.c_str(); } else { src = sources[l].file.c_str(); } @@ -1158,7 +1154,7 @@ int read_input(std::vector &sources, char *fname, const char *layername, out.append(trunc, p, 1); } } - layernames.push_back(out); + sources[l].layer = out; if (!quiet) { fprintf(stderr, "For layer %d, using name \"%s\"\n", (int) l, out.c_str()); @@ -1168,25 +1164,21 @@ int read_input(std::vector &sources, char *fname, const char *layername, std::map layermap; for (size_t l = 0; l < nlayers; l++) { - layermap.insert(std::pair(layernames[l], layermap_entry(l))); + layermap.insert(std::pair(sources[l].layer, layermap_entry(l))); } std::vector > layermaps; for (size_t l = 0; l < CPUS; l++) { layermaps.push_back(layermap); } - size_t nsources = sources.size(); - if (nsources == 0) { - nsources = 1; - } - long overall_offset = 0; + size_t nsources = sources.size(); for (size_t source = 0; source < nsources; source++) { std::string reading; int fd; - if (source >= sources.size()) { + if (sources[source].file.size() == 0) { reading = "standard input"; fd = 0; } else { @@ -1198,6 +1190,13 @@ int read_input(std::vector &sources, char *fname, const char *layername, } } + auto a = layermap.find(sources[source].layer); + if (a == layermap.end()) { + fprintf(stderr, "Internal error: couldn't find layer %s", sources[source].layer.c_str()); + exit(EXIT_FAILURE); + } + size_t layer = a->second.id; + struct stat st; char *map = NULL; off_t off = 0; @@ -1216,7 +1215,7 @@ int read_input(std::vector &sources, char *fname, const char *layername, } if (map != NULL && map != MAP_FAILED) { - do_read_parallel(map, st.st_size - off, overall_offset, reading.c_str(), reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, source, nlayers, &layermaps, droprate, initialized, initial_x, initial_y, maxzoom, layernames[source < nlayers ? source : 0], uses_gamma); + do_read_parallel(map, st.st_size - off, overall_offset, reading.c_str(), reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, layer, nlayers, &layermaps, droprate, initialized, initial_x, initial_y, maxzoom, sources[layer].layer, uses_gamma); overall_offset += st.st_size - off; checkdisk(reader, CPUS); @@ -1227,7 +1226,7 @@ int read_input(std::vector &sources, char *fname, const char *layername, } else { FILE *fp = fdopen(fd, "r"); if (fp == NULL) { - perror(sources[source].file.c_str()); + perror(sources[layer].file.c_str()); if (close(fd) != 0) { perror("close source file"); exit(EXIT_FAILURE); @@ -1284,7 +1283,7 @@ int read_input(std::vector &sources, char *fname, const char *layername, } fflush(readfp); - start_parsing(readfd, readfp, initial_offset, ahead, &is_parsing, ¶llel_parser, parser_created, reading.c_str(), reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, source, nlayers, layermaps, droprate, initialized, initial_x, initial_y, maxzoom, layernames[source < nlayers ? source : 0], gamma != 0); + start_parsing(readfd, readfp, initial_offset, ahead, &is_parsing, ¶llel_parser, parser_created, reading.c_str(), reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, layer, nlayers, layermaps, droprate, initialized, initial_x, initial_y, maxzoom, sources[layer].layer, gamma != 0); initial_offset += ahead; overall_offset += ahead; @@ -1321,7 +1320,7 @@ int read_input(std::vector &sources, char *fname, const char *layername, fflush(readfp); if (ahead > 0) { - start_parsing(readfd, readfp, initial_offset, ahead, &is_parsing, ¶llel_parser, parser_created, reading.c_str(), reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, source, nlayers, layermaps, droprate, initialized, initial_x, initial_y, maxzoom, layernames[source < nlayers ? source : 0], gamma != 0); + start_parsing(readfd, readfp, initial_offset, ahead, &is_parsing, ¶llel_parser, parser_created, reading.c_str(), reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, layer, nlayers, layermaps, droprate, initialized, initial_x, initial_y, maxzoom, sources[layer].layer, gamma != 0); if (parser_created) { if (pthread_join(parallel_parser, NULL) != 0) { @@ -1338,7 +1337,7 @@ int read_input(std::vector &sources, char *fname, const char *layername, long long layer_seq = overall_offset; json_pull *jp = json_begin_file(fp); - parse_json(jp, reading.c_str(), &layer_seq, &progress_seq, &reader[0].metapos, &reader[0].geompos, &reader[0].indexpos, exclude, include, exclude_all, reader[0].metafile, reader[0].geomfile, reader[0].indexfile, reader[0].poolfile, reader[0].treefile, fname, basezoom, source < nlayers ? source : 0, droprate, reader[0].file_bbox, 0, &initialized[0], &initial_x[0], &initial_y[0], reader, maxzoom, &layermaps[0], layernames[source < nlayers ? source : 0], uses_gamma); + parse_json(jp, reading.c_str(), &layer_seq, &progress_seq, &reader[0].metapos, &reader[0].geompos, &reader[0].indexpos, exclude, include, exclude_all, reader[0].metafile, reader[0].geomfile, reader[0].indexfile, reader[0].poolfile, reader[0].treefile, fname, basezoom, layer, droprate, reader[0].file_bbox, 0, &initialized[0], &initial_x[0], &initial_y[0], reader, maxzoom, &layermaps[0], sources[layer].layer, uses_gamma); json_end(jp); overall_offset = layer_seq; checkdisk(reader, CPUS); @@ -1880,7 +1879,7 @@ int main(int argc, char **argv) { int i; char *name = NULL; - char *layer = NULL; + char *layername = NULL; char *outdir = NULL; int maxzoom = 14; int minzoom = 0; @@ -1998,7 +1997,7 @@ int main(int argc, char **argv) { break; case 'l': - layer = optarg; + layername = optarg; break; case 'A': @@ -2281,9 +2280,22 @@ int main(int argc, char **argv) { sources.push_back(src); } + if (sources.size() == 0) { + struct source src; + src.layer = ""; + src.file = ""; // standard input + sources.push_back(src); + } + + if (layername != NULL) { + for (size_t a = 0; a < sources.size(); a++) { + sources[a].layer = layername; + } + } + long long file_bbox[4] = {UINT_MAX, UINT_MAX, 0, 0}; - ret = read_input(sources, name ? name : outdir, layer, maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox, prefilter, postfilter); + ret = read_input(sources, name ? name : outdir, maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, &exclude, &include, exclude_all, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox, prefilter, postfilter); mbtiles_close(outdb, argv); diff --git a/man/tippecanoe.1 b/man/tippecanoe.1 index 610faa1..53ba2c4 100644 --- a/man/tippecanoe.1 +++ b/man/tippecanoe.1 @@ -223,6 +223,10 @@ to files in a \fB\fCtiles/z/x/y.geojson\fR directory hierarchy. tippecanoe \-o countries.mbtiles \-z5 \-C 'mkdir \-p tiles/$1/$2; tee tiles/$1/$2/$3.geojson' ne_10m_admin_0_countries.json .fi .RE +.SH Environment +.PP +Tippecanoe ordinarily uses as many parallel threads as the operating system claims that CPUs are available. +You can override this number by setting the \fB\fCTIPPECANOE_MAX_THREADS\fR environmental variable. .SH Example .PP .RS @@ -370,7 +374,7 @@ make install .fi .RE .PP -Tippecanoe now requires features from the 2014 C++ standard. If your compiler is older than +Tippecanoe now requires features from the 2011 C++ standard. If your compiler is older than that, you will need to install a newer one. On MacOS, updating to the lastest XCode should get you a new enough version of \fB\fCclang++\fR\&. On Linux, you should be able to upgrade \fB\fCg++\fR with .PP @@ -515,4 +519,6 @@ resolutions. \-z \fImaxzoom\fP: Specify the highest zoom level to decode from the tileset .IP \(bu 2 \-Z \fIminzoom\fP: Specify the lowest zoom level to decode from the tileset +.IP \(bu 2 +\-l \fIlayer\fP: Decode only layers with the specified names. (Multiple \fB\fC\-l\fR options can be specified.) .RE diff --git a/mapbox/geometry/snap_rounding.hpp b/mapbox/geometry/snap_rounding.hpp new file mode 100644 index 0000000..ca1e9e0 --- /dev/null +++ b/mapbox/geometry/snap_rounding.hpp @@ -0,0 +1,466 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace mapbox { +namespace geometry { + +template +void add_vertical(size_t intermediate, size_t which_end, size_t into, std::vector>> &segments, bool &again, std::vector &nexts) { + again = true; + std::vector> dv; + dv.push_back(segments[intermediate][which_end]); + dv.push_back(segments[into][1]); + segments.push_back(dv); + segments[into][1] = segments[intermediate][which_end]; + nexts.push_back(nexts[into]); + nexts[into] = nexts.size() - 1; +} + +template +void add_horizontal(size_t intermediate, size_t which_end, size_t into, std::vector>> &segments, bool &again, std::vector &nexts) { + again = true; + + T x = segments[intermediate][which_end].x; + T y = segments[intermediate][0].y + + (segments[intermediate][which_end].x - segments[intermediate][0].x) * + (segments[intermediate][1].y - segments[intermediate][0].y) / + (segments[intermediate][1].x - segments[intermediate][0].x); + point d(x, y); + + std::vector> dv; + dv.push_back(d); + dv.push_back(segments[into][1]); + segments.push_back(dv); + segments[into][1] = d; + nexts.push_back(nexts[into]); + nexts[into] = nexts.size() - 1; +} + +template +void warn(std::vector>> &segments, size_t a, size_t b, bool do_warn) { + if (do_warn) { + fprintf(stderr, "%lld,%lld to %lld,%lld intersects %lld,%lld to %lld,%lld\n", + (long long) segments[a][0].x, (long long) segments[a][0].y, + (long long) segments[a][1].x, (long long) segments[a][1].y, + (long long) segments[b][0].x, (long long) segments[b][0].y, + (long long) segments[b][1].x, (long long) segments[b][1].y); + } +} + +template +void check_intersection(std::vector>> &segments, size_t a, size_t b, bool &again, std::vector &nexts, bool do_warn, bool endpoint_ok) { + T s10_x = segments[a][1].x - segments[a][0].x; + T s10_y = segments[a][1].y - segments[a][0].y; + T s32_x = segments[b][1].x - segments[b][0].x; + T s32_y = segments[b][1].y - segments[b][0].y; + + // http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect + T denom = s10_x * s32_y - s32_x * s10_y; + + if (denom == 0) { + // They are parallel or collinear. Find out if they are collinear. + // http://www.cpsc.ucalgary.ca/~marina/papers/Segment_intersection.ps + + T ccw = + segments[a][0].x * segments[a][1].y + + segments[a][1].x * segments[b][0].y + + segments[b][0].x * segments[a][0].y - + segments[a][0].x * segments[b][0].y - + segments[a][1].x * segments[a][0].y - + segments[b][0].x * segments[a][1].y; + + if (ccw == 0) { + if (segments[a][0].x == segments[a][1].x) { + // Vertical + + T amin, amax, bmin, bmax; + if (segments[a][0].y < segments[a][1].y) { + amin = segments[a][0].y; + amax = segments[a][1].y; + } else { + amin = segments[a][1].y; + amax = segments[a][0].y; + } + if (segments[b][0].y < segments[b][1].y) { + bmin = segments[b][0].y; + bmax = segments[b][1].y; + } else { + bmin = segments[b][1].y; + bmax = segments[b][0].y; + } + + // All of these transformations preserve verticality so we can check multiple cases + if (segments[b][0].y > amin && segments[b][0].y < amax) { + // B0 is in A + warn(segments, a, b, do_warn); + add_vertical(b, 0, a, segments, again, nexts); + } + if (segments[b][1].y > amin && segments[b][1].y < amax) { + // B1 is in A + warn(segments, a, b, do_warn); + add_vertical(b, 1, a, segments, again, nexts); + } + if (segments[a][0].y > bmin && segments[a][0].y < bmax) { + // A0 is in B + warn(segments, a, b, do_warn); + add_vertical(a, 0, b, segments, again, nexts); + } + if (segments[a][1].y > bmin && segments[a][1].y < bmax) { + // A1 is in B + warn(segments, a, b, do_warn); + add_vertical(a, 1, b, segments, again, nexts); + } + } else { + // Horizontal or diagonal + + T amin, amax, bmin, bmax; + if (segments[a][0].x < segments[a][1].x) { + amin = segments[a][0].x; + amax = segments[a][1].x; + } else { + amin = segments[a][1].x; + amax = segments[a][0].x; + } + if (segments[b][0].x < segments[b][1].x) { + bmin = segments[b][0].x; + bmax = segments[b][1].x; + } else { + bmin = segments[b][1].x; + bmax = segments[b][0].x; + } + + // Don't check multiples, because rounding may corrupt collinearity + if (segments[b][0].x > amin && segments[b][0].x < amax) { + // B0 is in A + add_horizontal(b, 0, a, segments, again, nexts); + warn(segments, a, b, do_warn); + } else if (segments[b][1].x > amin && segments[b][1].x < amax) { + // B1 is in A + add_horizontal(b, 1, a, segments, again, nexts); + warn(segments, a, b, do_warn); + } else if (segments[a][0].x > bmin && segments[a][0].x < bmax) { + // A0 is in B + warn(segments, a, b, do_warn); + add_horizontal(a, 0, b, segments, again, nexts); + } else if (segments[a][1].x > bmin && segments[a][1].x < bmax) { + // A1 is in B + warn(segments, a, b, do_warn); + add_horizontal(a, 1, b, segments, again, nexts); + } + } + } + } else { + // Neither parallel nor collinear, so may intersect at a single point + + T s02_x = segments[a][0].x - segments[b][0].x; + T s02_y = segments[a][0].y - segments[b][0].y; + + double s = (s10_x * s02_y - s10_y * s02_x) / (long double) denom; + double t = (s32_x * s02_y - s32_y * s02_x) / (long double) denom; + + if (t >= 0 && t <= 1 && s >= 0 && s <= 1) { + T x = (T) round(segments[a][0].x + t * s10_x); + T y = (T) round(segments[a][0].y + t * s10_y); + + if ((t > 0 && t < 1 && s > 0 && s < 1) || !endpoint_ok) { + if (t >= 0 && t <= 1) { + if ((x != segments[a][0].x || y != segments[a][0].y) && (x != segments[a][1].x || y != segments[a][1].y)) { + warn(segments, a, b, do_warn); + // splitting a + std::vector> dv; + dv.push_back(point(x, y)); + dv.push_back(segments[a][1]); + segments.push_back(dv); + segments[a][1] = point(x, y); + nexts.push_back(nexts[a]); + nexts[a] = nexts.size() - 1; + again = true; + } + } + + if (s >= 0 && s <= 1) { + if ((x != segments[b][0].x || y != segments[b][0].y) && (x != segments[b][1].x || y != segments[b][1].y)) { + // splitting b + warn(segments, a, b, do_warn); + std::vector> dv; + dv.push_back(point(x, y)); + dv.push_back(segments[b][1]); + segments.push_back(dv); + segments[b][1] = point(x, y); + nexts.push_back(nexts[b]); + nexts[b] = nexts.size() - 1; + again = true; + } + } + } + } + } +} + +template +void partition(std::vector>> &segs, std::vector &subset, int direction, std::set> &possible) { + std::vector points; + + // List of X or Y midpoints of edges, so we can find the median + + if (direction == 0) { + for (size_t i = 0; i < subset.size(); i++) { + points.push_back((segs[subset[i]][0].x + segs[subset[i]][1].x) / 2); + } + } else { + for (size_t i = 0; i < subset.size(); i++) { + points.push_back((segs[subset[i]][0].y + segs[subset[i]][1].y) / 2); + } + } + + if (points.size() == 0) { + return; + } + + size_t mid = points.size() / 2; + std::nth_element(points.begin(), points.begin() + mid, points.end()); + T median = points[mid]; + + // Partition into sets that are above or below, or to the left or to the right of, the median. + // Segments that cross the median appear in both. + + std::vector one; + std::vector two; + + if (direction == 0) { + for (size_t i = 0; i < subset.size(); i++) { + if (segs[subset[i]][0].x <= median || segs[subset[i]][1].x <= median) { + one.push_back(subset[i]); + } + if (segs[subset[i]][0].x >= median || segs[subset[i]][1].x >= median) { + two.push_back(subset[i]); + } + } + } else { + for (size_t i = 0; i < subset.size(); i++) { + if (segs[subset[i]][0].y <= median || segs[subset[i]][1].y <= median) { + one.push_back(subset[i]); + } + if (segs[subset[i]][0].y >= median || segs[subset[i]][1].y >= median) { + two.push_back(subset[i]); + } + } + } + + if (one.size() >= subset.size() || two.size() >= subset.size()) { + for (size_t i = 0; i < subset.size(); i++) { + for (size_t j = i + 1; j < subset.size(); j++) { + possible.insert(std::pair(subset[i], subset[j])); + } + } + } else { + // By experiment, stopping at 10 is a little faster than either 5 or 20 + + if (one.size() < 10) { + for (size_t i = 0; i < one.size(); i++) { + for (size_t j = i + 1; j < one.size(); j++) { + possible.insert(std::pair(one[i], one[j])); + } + } + } else { + partition(segs, one, !direction, possible); + } + + if (two.size() < 10) { + for (size_t i = 0; i < two.size(); i++) { + for (size_t j = i + 1; j < two.size(); j++) { + possible.insert(std::pair(two[i], two[j])); + } + } + } else { + partition(segs, two, !direction, possible); + } + } +} + +template +std::vector>> intersect_segments(std::vector>> segments, std::vector &nexts, bool do_warn, bool endpoint_ok) { + bool again = true; + + while (again) { + again = false; + + std::set> possible; + + std::vector subset; + for (size_t i = 0; i < segments.size(); i++) { + subset.push_back(i); + } + + partition(segments, subset, 0, possible); + + for (auto it = possible.begin(); it != possible.end(); ++it) { + check_intersection(segments, it->first, it->second, again, nexts, do_warn, endpoint_ok); + } + } + + return segments; +} + +template +linear_ring remove_collinear(linear_ring ring) { + linear_ring out; + + size_t len = ring.size() - 1; // Exclude duplicated last point + for (size_t j = 0; j < len; j++) { + long long ccw = + ring[(j + len - 1) % len].x * ring[(j + len - 0) % len].y + + ring[(j + len - 0) % len].x * ring[(j + len + 1) % len].y + + ring[(j + len + 1) % len].x * ring[(j + len - 1) % len].y - + ring[(j + len - 1) % len].x * ring[(j + len + 1) % len].y - + ring[(j + len - 0) % len].x * ring[(j + len - 1) % len].y - + ring[(j + len + 1) % len].x * ring[(j + len - 0) % len].y; + + if (ccw != 0) { + out.push_back(ring[j]); + } + + if (ring.size() > 0 && ring[0] != ring[ring.size() - 1]) { + ring.push_back(ring[0]); + } + } + + return out; +} + +template +multi_polygon snap_round(multi_polygon geom, bool do_warn, bool endpoint_ok) { + std::vector>> segments; + std::vector nexts; + std::vector> ring_starts; + + // Crunch out any 0-length segments + for (size_t i = 0; i < geom.size(); i++) { + for (size_t j = 0; j < geom[i].size(); j++) { + for (ssize_t k = geom[i][j].size() - 1; k > 0; k--) { + if (geom[i][j][k] == geom[i][j][k - 1]) { + geom[i][j].erase(geom[i][j].begin() + k); + } + } + } + } + + for (size_t i = 0; i < geom.size(); i++) { + ring_starts.push_back(std::vector()); + + for (size_t j = 0; j < geom[i].size(); j++) { + size_t s = geom[i][j].size(); + + if (s > 1) { + ring_starts[i].push_back(segments.size()); + size_t first = nexts.size(); + + for (size_t k = 0; k + 1 < s; k++) { + std::vector> dv; + dv.push_back(geom[i][j][k]); + dv.push_back(geom[i][j][k + 1]); + + segments.push_back(dv); + nexts.push_back(nexts.size() + 1); + } + + // Fabricate a point if ring was not closed + if (geom[i][j][0] != geom[i][j][s - 1]) { + std::vector> dv; + dv.push_back(geom[i][j][s - 1]); + dv.push_back(geom[i][j][0]); + + segments.push_back(dv); + nexts.push_back(nexts.size() + 1); + } + + // Last point of ring points back to first + nexts[nexts.size() - 1] = first; + } + } + } + + segments = intersect_segments(segments, nexts, do_warn, endpoint_ok); + + multi_polygon mp; + for (size_t i = 0; i < ring_starts.size(); i++) { + mp.push_back(polygon()); + + for (size_t j = 0; j < ring_starts[i].size(); j++) { + mp[i].push_back(linear_ring()); + + size_t k = ring_starts[i][j]; + do { + mp[i][j].push_back(segments[k][0]); + k = nexts[k]; + } while (k != ring_starts[i][j]); + + mp[i][j].push_back(segments[ring_starts[i][j]][0]); + } + } + + return mp; +} + +template +multi_line_string snap_round(multi_line_string geom, bool do_warn, bool endpoint_ok) { + std::vector>> segments; + std::vector nexts; + std::vector ring_starts; + + // Crunch out any 0-length segments + for (size_t j = 0; j < geom.size(); j++) { + for (ssize_t k = geom[j].size() - 1; k > 0; k--) { + if (geom[j][k] == geom[j][k - 1]) { + geom[j].erase(geom[j].begin() + k); + } + } + } + + for (size_t j = 0; j < geom.size(); j++) { + size_t s = geom[j].size(); + + if (s > 1) { + ring_starts.push_back(segments.size()); + size_t first = nexts.size(); + + for (size_t k = 0; k + 1 < s; k++) { + std::vector> dv; + dv.push_back(geom[j][k]); + dv.push_back(geom[j][k + 1]); + + segments.push_back(dv); + nexts.push_back(nexts.size() + 1); + } + + // Last point of ring points back to first + nexts[nexts.size() - 1] = first; + } + } + + segments = intersect_segments(segments, nexts, do_warn, endpoint_ok); + + multi_line_string mp; + for (size_t j = 0; j < ring_starts.size(); j++) { + mp.push_back(line_string()); + + size_t k = ring_starts[j]; + size_t last = k; + do { + mp[j].push_back(segments[k][0]); + last = k; + k = nexts[k]; + } while (k != ring_starts[j]); + + mp[j].push_back(segments[last][1]); + } + + return mp; +} +} +} diff --git a/mapbox/geometry/wagyu/quick_clip.hpp b/mapbox/geometry/wagyu/quick_clip.hpp index 9153bef..56506fa 100644 --- a/mapbox/geometry/wagyu/quick_clip.hpp +++ b/mapbox/geometry/wagyu/quick_clip.hpp @@ -5,11 +5,6 @@ #include #include -#include - -template -using optional_linear_ring = std::experimental::optional>; - namespace mapbox { namespace geometry { namespace wagyu { @@ -61,7 +56,7 @@ bool inside(mapbox::geometry::point p, size_t edge, mapbox::geometry::box } template -optional_linear_ring quick_lr_clip(mapbox::geometry::linear_ring const& ring, +mapbox::geometry::linear_ring quick_lr_clip(mapbox::geometry::linear_ring const& ring, mapbox::geometry::box const& b) { mapbox::geometry::linear_ring out = ring; @@ -89,13 +84,14 @@ optional_linear_ring quick_lr_clip(mapbox::geometry::linear_ring const& ri } if (out.size() < 3) { - return optional_linear_ring(); + out.clear(); + return out; } // Close the ring if the first/last point was outside if (out[0] != out[out.size() - 1]) { out.push_back(out[0]); } - return optional_linear_ring(std::move(out)); + return out; } } @@ -107,8 +103,8 @@ mapbox::geometry::multi_polygon clip(mapbox::geometry::polygon const& poly wagyu clipper; for (auto const& lr : poly) { auto new_lr = quick_clip::quick_lr_clip(lr, b); - if (new_lr) { - clipper.add_ring(*new_lr, polygon_type_subject); + if (!new_lr.empty()) { + clipper.add_ring(new_lr, polygon_type_subject); } } clipper.execute(clip_type_union, result, subject_fill_type, fill_type_even_odd); @@ -124,8 +120,8 @@ mapbox::geometry::multi_polygon clip(mapbox::geometry::multi_polygon const for (auto const& poly : mp) { for (auto const& lr : poly) { auto new_lr = quick_clip::quick_lr_clip(lr, b); - if (new_lr) { - clipper.add_ring(*new_lr, polygon_type_subject); + if (!new_lr.empty()) { + clipper.add_ring(new_lr, polygon_type_subject); } } } diff --git a/mapbox/geometry/wagyu/wagyu.hpp b/mapbox/geometry/wagyu/wagyu.hpp index 7c4020f..21fde80 100644 --- a/mapbox/geometry/wagyu/wagyu.hpp +++ b/mapbox/geometry/wagyu/wagyu.hpp @@ -15,6 +15,12 @@ #include #include +#define WAGYU_MAJOR_VERSION 0 +#define WAGYU_MINOR_VERSION 3 +#define WAGYU_PATCH_VERSION 0 + +#define WAGYU_VERSION (WAGYU_MAJOR_VERSION * 100000) + (WAGYU_MINOR_VERSION * 100) + (WAGYU_PATCH_VERSION) + namespace mapbox { namespace geometry { namespace wagyu { diff --git a/tests/islands/in.json b/tests/islands/in.json new file mode 100644 index 0000000..7746b15 --- /dev/null +++ b/tests/islands/in.json @@ -0,0 +1,2 @@ +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http:\/\/en.wikipedia.org\/wiki\/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "name_alt": null, "name_local": null, "type": null, "type_en": null, "code_local": null, "code_hasc": "FM.YA", "note": null, "hasc_maybe": null, "region": null, "region_cod": null, "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "abbrev": null, "postal": null, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "fips_alt": null, "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.5810099999999991, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_region": null, "gn_a1_code": "FM.04", "region_sub": null, "sub_code": null, "gns_level": 1, "gns_lang": null, "gns_adm1": "FM04", "gns_region": null }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 143.920339389000134, 7.354966539000131 ], [ 143.915456576000139, 7.344142971000124 ], [ 143.917979363000057, 7.354803778000161 ], [ 143.917491082000055, 7.359930731000176 ], [ 143.920339389000134, 7.354966539000131 ] ] ], [ [ [ 143.843028191, 7.370550848000121 ], [ 143.834971550000063, 7.367824611000145 ], [ 143.839040561000019, 7.377427476000122 ], [ 143.843841993000211, 7.377468166000114 ], [ 143.843028191, 7.370550848000121 ] ] ], [ [ [ 143.858409050000233, 7.37791575700011 ], [ 143.859385613000228, 7.37213776200015 ], [ 143.855642123000194, 7.373846747000158 ], [ 143.858409050000233, 7.37791575700011 ] ] ], [ [ [ 143.918060743000041, 7.373236395000106 ], [ 143.916107618000098, 7.366563218000138 ], [ 143.914642774000214, 7.367295640000165 ], [ 143.908132358000245, 7.370754299000083 ], [ 143.910411004, 7.379461981000148 ], [ 143.918060743000041, 7.373236395000106 ] ] ], [ [ [ 138.184255405000187, 9.544378973000136 ], [ 138.197520379, 9.539007880000085 ], [ 138.219004754000053, 9.548570054000081 ], [ 138.214121941000172, 9.537054755000142 ], [ 138.202403191000172, 9.521185614000117 ], [ 138.188731316000059, 9.506822007000139 ], [ 138.177989129000053, 9.500189520000077 ], [ 138.164073113000228, 9.504828192000105 ], [ 138.15658613399998, 9.525783596000139 ], [ 138.143809441000059, 9.521307684000178 ], [ 138.134450717000192, 9.511867580000157 ], [ 138.079844597000061, 9.425441799000069 ], [ 138.068125847000061, 9.412054755000071 ], [ 138.063812696000156, 9.436102606000105 ], [ 138.073008660000056, 9.470404364000075 ], [ 138.089121941000116, 9.501166083000143 ], [ 138.105967644000117, 9.514471747000158 ], [ 138.112966342000192, 9.521470445000148 ], [ 138.121267123000081, 9.55487702000012 ], [ 138.126231316, 9.565985419000143 ], [ 138.141123894000174, 9.5743675800001 ], [ 138.147227410000056, 9.567368882000125 ], [ 138.150075717000192, 9.541164455000086 ], [ 138.151866082000055, 9.550848700000145 ], [ 138.154958530000073, 9.560736395000148 ], [ 138.159190300000063, 9.569525458000129 ], [ 138.16439863399998, 9.575873114000146 ], [ 138.173187696000156, 9.582342841000155 ], [ 138.184906446000042, 9.588812567000062 ], [ 138.193614129000053, 9.588853257000054 ], [ 138.19239342500012, 9.575873114000146 ], [ 138.181651238000114, 9.558742580000114 ], [ 138.184255405000187, 9.544378973000136 ] ] ], [ [ [ 140.524668816000059, 9.764471747000115 ], [ 140.515391472, 9.761175848000079 ], [ 140.51417076900006, 9.76780833500014 ], [ 140.521739129000053, 9.774725653000132 ], [ 140.531260613000228, 9.775580145000134 ], [ 140.532888217000078, 9.771918036000088 ], [ 140.524668816000059, 9.764471747000115 ] ] ] ] } }, +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "wikipedia": null, "iso_a2": "KI", "adm0_sr": 5, "name": null, "name_alt": null, "name_local": null, "type": null, "type_en": null, "code_local": null, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "hasc_maybe": null, "region": null, "region_cod": null, "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "abbrev": null, "postal": null, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "fips": null, "fips_alt": null, "woe_id": -99, "woe_label": null, "woe_name": null, "latitude": -4.6896699999999996, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gn_name": null, "gns_id": 0, "gns_name": null, "gn_level": 0, "gn_region": null, "gn_a1_code": "KI.", "region_sub": null, "sub_code": null, "gns_level": 0, "gns_lang": null, "gns_adm1": null, "gns_region": null }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -150.231231248999904, -10.007582289999874 ], [ -150.236154751999948, -10.00986093499985 ], [ -150.24282792899993, -10.005547783999845 ], [ -150.241769985999952, -10.000339450999846 ], [ -150.235585089999887, -10.001234632999839 ], [ -150.231231248999904, -10.007582289999874 ] ] ], [ [ [ -150.206410285999937, -9.955336195999863 ], [ -150.208159959999932, -9.960056247999873 ], [ -150.207793748999904, -9.931817315999893 ], [ -150.20754960799988, -9.932142835999827 ], [ -150.206410285999937, -9.955336195999863 ] ] ], [ [ [ -150.211537238999881, -9.919203382999825 ], [ -150.208526170999846, -9.927260023999864 ], [ -150.212676561999899, -9.923109632999825 ], [ -150.216013149999924, -9.914971612999892 ], [ -150.211537238999881, -9.919203382999825 ] ] ], [ [ [ -155.906809048999946, -5.611993096999825 ], [ -155.899322068999879, -5.616794528999904 ], [ -155.879628058999913, -5.609470309999892 ], [ -155.865061001999891, -5.615166924999883 ], [ -155.859811977999925, -5.625095309999878 ], [ -155.867990688999896, -5.630303643999881 ], [ -155.906442837999919, -5.635349216999899 ], [ -155.92247473899991, -5.629978122999859 ], [ -155.933461066999882, -5.609144789999874 ], [ -155.923898891999897, -5.608086846999825 ], [ -155.914987758999928, -5.609063408999887 ], [ -155.906809048999946, -5.611993096999825 ] ] ], [ [ [ -174.500681118999864, -4.694268487999977 ], [ -174.501535610999866, -4.697360934999963 ], [ -174.512155727999925, -4.691989841999913 ], [ -174.521555141999926, -4.68385182099982 ], [ -174.516713019999855, -4.68425872199991 ], [ -174.506418423999946, -4.689141533999887 ], [ -174.500681118999864, -4.694268487999977 ] ] ], [ [ [ -174.527902798999889, -4.683526299999883 ], [ -174.527658657999922, -4.68385182099982 ], [ -174.533884243999893, -4.680759373 ], [ -174.541737433999856, -4.672784112999864 ], [ -174.540109829999949, -4.672051690999837 ], [ -174.535878058999913, -4.677504164999959 ], [ -174.529286261999943, -4.682712497999873 ], [ -174.527902798999889, -4.683526299999883 ] ] ], [ [ [ -174.501535610999866, -4.687676690999822 ], [ -174.500843878999945, -4.69109465899983 ], [ -174.513986782999893, -4.676202080999872 ], [ -174.528269008999871, -4.667413018999909 ], [ -174.538075324999909, -4.665215752999828 ], [ -174.543405727999868, -4.660251559999864 ], [ -174.538400844999927, -4.656508070999834 ], [ -174.52440344999988, -4.664483330999971 ], [ -174.501535610999866, -4.687676690999822 ] ] ], [ [ [ -171.236520962999862, -4.468519790000016 ], [ -171.249582485999952, -4.469821872999844 ], [ -171.259632941999939, -4.465264580999886 ], [ -171.264027472999913, -4.456312757999868 ], [ -171.259958462999947, -4.444105726999894 ], [ -171.259917772999955, -4.444105726999894 ], [ -171.244984503999916, -4.441338799999841 ], [ -171.233876105999883, -4.448988539999945 ], [ -171.230051235999866, -4.46054452899989 ], [ -171.236520962999862, -4.468519790000016 ] ] ], [ [ [ -171.087269660999908, -3.143161716999856 ], [ -171.092477993999921, -3.145440362999921 ], [ -171.093576626999948, -3.131442966999956 ], [ -171.090036587999862, -3.120863539999917 ], [ -171.08543860599994, -3.111260674999841 ], [ -171.083119269999884, -3.129978122999901 ], [ -171.087269660999908, -3.143161716999856 ] ] ], [ [ [ 174.237478061000132, -0.526543877999899 ], [ 174.245290561000076, -0.529310804999952 ], [ 174.245778842000249, -0.531182549999841 ], [ 174.240896030000187, -0.528252862999821 ], [ 174.236745639000077, -0.529636325999974 ], [ 174.234141472000175, -0.529717705999957 ], [ 174.237478061000132, -0.526543877999899 ] ] ], [ [ [ 173.550466342000192, 0.173895575000103 ], [ 173.542002800000176, 0.171576239000046 ], [ 173.537282748000251, 0.17194245000006 ], [ 173.529714388999906, 0.174343166000099 ], [ 173.525075716999964, 0.178778387000165 ], [ 173.534434441000172, 0.183579820000148 ], [ 173.550466342000192, 0.18105703300013 ], [ 173.550466342000192, 0.173895575000103 ] ] ], [ [ [ 173.413910352000215, 0.2071800800001 ], [ 173.391449415000096, 0.19277578300013 ], [ 173.383148633999923, 0.199571031000147 ], [ 173.377614780000187, 0.214748440000136 ], [ 173.37973066500021, 0.223334052000055 ], [ 173.389170769000231, 0.225775458000086 ], [ 173.398529493000268, 0.223089911000116 ], [ 173.414073113000228, 0.211859442000105 ], [ 173.413910352000215, 0.2071800800001 ] ] ], [ [ [ 173.372894727000158, 0.242092190000108 ], [ 173.368337436000132, 0.2378604190001 ], [ 173.348155144, 0.254380601000079 ], [ 173.347585483000074, 0.263291734000106 ], [ 173.354828321000156, 0.268296617000061 ], [ 173.364349806000263, 0.261623440000093 ], [ 173.371104363, 0.253566799000069 ], [ 173.372894727000158, 0.242092190000108 ] ] ], [ [ [ 173.937103712000095, 0.310003973000093 ], [ 173.933604363000228, 0.308986721000124 ], [ 173.927582227000215, 0.312079169000114 ], [ 173.927093946000213, 0.315537828000032 ], [ 173.930511915000153, 0.318467515000052 ], [ 173.936045769000231, 0.320746161000116 ], [ 173.938975457000168, 0.327622789000117 ], [ 173.940521681000206, 0.340399481000162 ], [ 173.938649935999962, 0.344427802000126 ], [ 173.937754754000167, 0.349391994000172 ], [ 173.937998894000287, 0.357245184000163 ], [ 173.925466342000192, 0.399562893000081 ], [ 173.928314649000214, 0.405829169000114 ], [ 173.93246504000021, 0.401271877000084 ], [ 173.937510613000285, 0.388861395000148 ], [ 173.946950717000135, 0.360337632000054 ], [ 173.947032097000118, 0.322577216000084 ], [ 173.942800326000196, 0.315375067000147 ], [ 173.937103712000095, 0.310003973000093 ] ] ] ] } }, diff --git a/tests/islands/out/-d7_-z7_-pt_-pp.json b/tests/islands/out/-d7_-z7_-pt_-pp.json new file mode 100644 index 0000000..d0afd3e --- /dev/null +++ b/tests/islands/out/-d7_-z7_-pt_-pp.json @@ -0,0 +1,224 @@ +{ "type": "FeatureCollection", "properties": { +"bounds": "-174.543406,-10.009861,174.245779,9.775580", +"center": "172.968750,1.405686,7", +"description": "tests/islands/out/-d7_-z7_-pt_-pp.json.check.mbtiles", +"format": "pbf", +"json": "{\"vector_layers\": [ { \"id\": \"in\", \"description\": \"\", \"minzoom\": 0, \"maxzoom\": 7, \"fields\": {\"OBJECTID_1\": \"Number\", \"adm0_a3\": \"String\", \"adm0_label\": \"Number\", \"adm0_sr\": \"Number\", \"adm1_cod_1\": \"String\", \"adm1_code\": \"String\", \"admin\": \"String\", \"area_sqkm\": \"Number\", \"check_me\": \"Number\", \"code_hasc\": \"String\", \"datarank\": \"Number\", \"diss_me\": \"Number\", \"featurecla\": \"String\", \"fips\": \"String\", \"gadm_level\": \"Number\", \"geonunit\": \"String\", \"gn_a1_code\": \"String\", \"gn_id\": \"Number\", \"gn_level\": \"Number\", \"gn_name\": \"String\", \"gns_adm1\": \"String\", \"gns_id\": \"Number\", \"gns_level\": \"Number\", \"gns_name\": \"String\", \"gu_a3\": \"String\", \"iso_3166_2\": \"String\", \"iso_a2\": \"String\", \"labelrank\": \"Number\", \"latitude\": \"Number\", \"longitude\": \"Number\", \"mapcolor13\": \"Number\", \"mapcolor9\": \"Number\", \"name\": \"String\", \"name_len\": \"Number\", \"note\": \"String\", \"provnum_ne\": \"Number\", \"sameascity\": \"Number\", \"scalerank\": \"Number\", \"sov_a3\": \"String\", \"wikipedia\": \"String\", \"woe_id\": \"Number\", \"woe_label\": \"String\", \"woe_name\": \"String\"} } ] }", +"maxzoom": "7", +"minzoom": "0", +"name": "tests/islands/out/-d7_-z7_-pt_-pp.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": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -43.242188, -3.951941 ], [ -43.154297, -3.951941 ], [ -43.154297, -4.039618 ], [ -43.242188, -4.039618 ], [ -43.242188, -3.951941 ] ] ] } } +, +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http://en.wikipedia.org/wiki/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "code_hasc": "FM.YA", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.58101, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_a1_code": "FM.04", "gns_level": 1, "gns_adm1": "FM04" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 142.294922, 8.320212 ], [ 142.382812, 8.320212 ], [ 142.382812, 8.146243 ], [ 142.294922, 8.146243 ], [ 142.294922, 8.320212 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 1, "x": 0, "y": 1 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -155.917969, -5.572250 ], [ -155.874023, -5.615986 ], [ -155.961914, -5.615986 ], [ -155.917969, -5.572250 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 1, "x": 1, "y": 1 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.199219, -0.483393 ], [ 174.243164, -0.527336 ], [ 174.199219, -0.527336 ], [ 174.199219, -0.483393 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 1, "x": 1, "y": 0 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.199219, -0.483393 ], [ 174.243164, -0.527336 ], [ 174.199219, -0.527336 ], [ 174.199219, -0.483393 ] ] ] } } +, +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http://en.wikipedia.org/wiki/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "code_hasc": "FM.YA", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.58101, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_a1_code": "FM.04", "gns_level": 1, "gns_adm1": "FM04" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 138.164062, 9.622414 ], [ 138.164062, 9.535749 ], [ 138.032227, 9.449062 ], [ 138.164062, 9.622414 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 2, "x": 0, "y": 2 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -155.917969, -5.594118 ], [ -155.874023, -5.615986 ], [ -155.939941, -5.615986 ], [ -155.917969, -5.594118 ] ] ], [ [ [ -174.528809, -4.653080 ], [ -174.506836, -4.674980 ], [ -174.528809, -4.674980 ], [ -174.528809, -4.653080 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 2, "x": 3, "y": 2 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 174.221191, -0.505365 ], [ 174.243164, -0.527336 ], [ 174.221191, -0.527336 ], [ 174.221191, -0.505365 ] ] ], [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.329588 ], [ 173.913574, 0.417477 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 2, "x": 3, "y": 1 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 174.221191, -0.505365 ], [ 174.243164, -0.527336 ], [ 174.221191, -0.527336 ], [ 174.221191, -0.505365 ] ] ], [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.329588 ], [ 173.913574, 0.417477 ] ] ] ] } } +, +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http://en.wikipedia.org/wiki/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "code_hasc": "FM.YA", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.58101, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_a1_code": "FM.04", "gns_level": 1, "gns_adm1": "FM04" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 138.208008, 9.557417 ], [ 138.186035, 9.514079 ], [ 138.142090, 9.535749 ], [ 138.054199, 9.427387 ], [ 138.120117, 9.579084 ], [ 138.142090, 9.557417 ], [ 138.208008, 9.557417 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 3, "x": 0, "y": 4 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -155.917969, -5.615986 ], [ -155.895996, -5.594118 ], [ -155.874023, -5.594118 ], [ -155.874023, -5.615986 ], [ -155.917969, -5.615986 ] ] ], [ [ [ -174.506836, -4.674980 ], [ -174.506836, -4.696879 ], [ -174.528809, -4.674980 ], [ -174.506836, -4.674980 ] ] ], [ [ [ -174.528809, -4.653080 ], [ -174.506836, -4.674980 ], [ -174.550781, -4.653080 ], [ -174.528809, -4.653080 ] ] ], [ [ [ -171.276855, -4.434044 ], [ -171.232910, -4.455951 ], [ -171.276855, -4.455951 ], [ -171.276855, -4.434044 ] ] ], [ [ [ -155.917969, -5.615986 ], [ -155.939941, -5.615986 ], [ -155.939941, -5.594118 ], [ -155.917969, -5.594118 ], [ -155.917969, -5.615986 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 3, "x": 7, "y": 4 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 174.221191, -0.505365 ], [ 174.243164, -0.527336 ], [ 174.221191, -0.527336 ], [ 174.221191, -0.505365 ] ] ], [ [ [ 173.540039, 0.197754 ], [ 173.540039, 0.175781 ], [ 173.518066, 0.175781 ], [ 173.518066, 0.197754 ], [ 173.540039, 0.197754 ] ] ], [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.342285, 0.285643 ], [ 173.364258, 0.263671 ], [ 173.364258, 0.241699 ], [ 173.342285, 0.285643 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.329588 ], [ 173.913574, 0.417477 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 3, "x": 7, "y": 3 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 174.221191, -0.505365 ], [ 174.243164, -0.527336 ], [ 174.221191, -0.527336 ], [ 174.221191, -0.505365 ] ] ], [ [ [ 173.540039, 0.197754 ], [ 173.540039, 0.175781 ], [ 173.518066, 0.175781 ], [ 173.518066, 0.197754 ], [ 173.540039, 0.197754 ] ] ], [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.342285, 0.285643 ], [ 173.364258, 0.263671 ], [ 173.364258, 0.241699 ], [ 173.342285, 0.285643 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.329588 ], [ 173.913574, 0.417477 ] ] ] ] } } +, +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http://en.wikipedia.org/wiki/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "code_hasc": "FM.YA", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.58101, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_a1_code": "FM.04", "gns_level": 1, "gns_adm1": "FM04" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 138.186035, 9.600750 ], [ 138.164062, 9.557417 ], [ 138.208008, 9.557417 ], [ 138.186035, 9.514079 ], [ 138.142090, 9.535749 ], [ 138.076172, 9.427387 ], [ 138.054199, 9.427387 ], [ 138.054199, 9.470736 ], [ 138.120117, 9.557417 ], [ 138.120117, 9.579084 ], [ 138.142090, 9.579084 ], [ 138.186035, 9.600750 ] ] ], [ [ [ 140.515137, 9.795678 ], [ 140.515137, 9.774025 ], [ 140.493164, 9.774025 ], [ 140.515137, 9.795678 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 4, "x": 0, "y": 8 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -174.528809, -4.653080 ], [ -174.506836, -4.674980 ], [ -174.506836, -4.696879 ], [ -174.528809, -4.674980 ], [ -174.528809, -4.653080 ] ] ], [ [ [ -171.254883, -4.434044 ], [ -171.232910, -4.455951 ], [ -171.276855, -4.455951 ], [ -171.276855, -4.434044 ], [ -171.254883, -4.434044 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 4, "x": 1, "y": 8 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -155.917969, -5.615986 ], [ -155.895996, -5.594118 ], [ -155.874023, -5.594118 ], [ -155.874023, -5.615986 ], [ -155.917969, -5.615986 ] ] ], [ [ [ -155.917969, -5.615986 ], [ -155.939941, -5.615986 ], [ -155.939941, -5.594118 ], [ -155.917969, -5.594118 ], [ -155.917969, -5.615986 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 4, "x": 14, "y": 7 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http://en.wikipedia.org/wiki/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "code_hasc": "FM.YA", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.58101, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_a1_code": "FM.04", "gns_level": 1, "gns_adm1": "FM04" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 138.164062, 9.579084 ], [ 138.164062, 9.557417 ], [ 138.208008, 9.557417 ], [ 138.186035, 9.535749 ], [ 138.186035, 9.514079 ], [ 138.164062, 9.514079 ], [ 138.142090, 9.535749 ], [ 138.120117, 9.514079 ], [ 138.076172, 9.427387 ], [ 138.054199, 9.427387 ], [ 138.054199, 9.470736 ], [ 138.076172, 9.514079 ], [ 138.120117, 9.557417 ], [ 138.120117, 9.579084 ], [ 138.164062, 9.579084 ] ] ], [ [ [ 138.186035, 9.579084 ], [ 138.164062, 9.579084 ], [ 138.164062, 9.600750 ], [ 138.186035, 9.600750 ], [ 138.186035, 9.579084 ] ] ], [ [ [ 140.515137, 9.795678 ], [ 140.515137, 9.774025 ], [ 140.493164, 9.774025 ], [ 140.515137, 9.795678 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 4, "x": 15, "y": 8 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 174.221191, -0.505365 ], [ 174.243164, -0.527336 ], [ 174.221191, -0.527336 ], [ 174.221191, -0.505365 ] ] ], [ [ [ 173.540039, 0.197754 ], [ 173.540039, 0.175781 ], [ 173.518066, 0.175781 ], [ 173.518066, 0.197754 ], [ 173.540039, 0.197754 ] ] ], [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.219726 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.342285, 0.285643 ], [ 173.364258, 0.263671 ], [ 173.364258, 0.241699 ], [ 173.342285, 0.263671 ], [ 173.342285, 0.285643 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.373533 ], [ 173.913574, 0.417477 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 4, "x": 15, "y": 7 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 173.540039, 0.197754 ], [ 173.540039, 0.175781 ], [ 173.518066, 0.175781 ], [ 173.518066, 0.197754 ], [ 173.540039, 0.197754 ] ] ], [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.219726 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.342285, 0.285643 ], [ 173.364258, 0.263671 ], [ 173.364258, 0.241699 ], [ 173.342285, 0.263671 ], [ 173.342285, 0.285643 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.373533 ], [ 173.913574, 0.417477 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 5, "x": 0, "y": 16 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -174.528809, -4.653080 ], [ -174.506836, -4.674980 ], [ -174.506836, -4.696879 ], [ -174.528809, -4.674980 ], [ -174.528809, -4.653080 ] ] ], [ [ [ -171.254883, -4.434044 ], [ -171.232910, -4.455951 ], [ -171.276855, -4.455951 ], [ -171.276855, -4.434044 ], [ -171.254883, -4.434044 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 5, "x": 2, "y": 16 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -155.917969, -5.615986 ], [ -155.895996, -5.594118 ], [ -155.874023, -5.594118 ], [ -155.874023, -5.615986 ], [ -155.917969, -5.615986 ] ] ], [ [ [ -155.917969, -5.615986 ], [ -155.939941, -5.615986 ], [ -155.939941, -5.594118 ], [ -155.917969, -5.594118 ], [ -155.917969, -5.615986 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 5, "x": 28, "y": 15 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http://en.wikipedia.org/wiki/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "code_hasc": "FM.YA", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.58101, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_a1_code": "FM.04", "gns_level": 1, "gns_adm1": "FM04" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 138.164062, 9.579084 ], [ 138.164062, 9.557417 ], [ 138.208008, 9.557417 ], [ 138.186035, 9.535749 ], [ 138.186035, 9.514079 ], [ 138.164062, 9.514079 ], [ 138.142090, 9.535749 ], [ 138.120117, 9.514079 ], [ 138.076172, 9.427387 ], [ 138.054199, 9.427387 ], [ 138.054199, 9.470736 ], [ 138.076172, 9.514079 ], [ 138.120117, 9.557417 ], [ 138.120117, 9.579084 ], [ 138.164062, 9.579084 ] ] ], [ [ [ 138.186035, 9.579084 ], [ 138.164062, 9.579084 ], [ 138.164062, 9.600750 ], [ 138.186035, 9.600750 ], [ 138.186035, 9.579084 ] ] ], [ [ [ 140.515137, 9.795678 ], [ 140.515137, 9.774025 ], [ 140.493164, 9.774025 ], [ 140.515137, 9.795678 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 5, "x": 31, "y": 16 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 174.221191, -0.505365 ], [ 174.243164, -0.527336 ], [ 174.221191, -0.527336 ], [ 174.221191, -0.505365 ] ] ], [ [ [ 173.540039, 0.197754 ], [ 173.540039, 0.175781 ], [ 173.518066, 0.175781 ], [ 173.518066, 0.197754 ], [ 173.540039, 0.197754 ] ] ], [ [ [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.219726 ], [ 173.408203, 0.219726 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 5, "x": 31, "y": 15 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 173.540039, 0.197754 ], [ 173.540039, 0.175781 ], [ 173.518066, 0.175781 ], [ 173.518066, 0.197754 ], [ 173.540039, 0.197754 ] ] ], [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.219726 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.342285, 0.285643 ], [ 173.364258, 0.263671 ], [ 173.364258, 0.241699 ], [ 173.342285, 0.263671 ], [ 173.342285, 0.285643 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.373533 ], [ 173.913574, 0.417477 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 6, "x": 0, "y": 32 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -174.528809, -4.653080 ], [ -174.506836, -4.674980 ], [ -174.506836, -4.696879 ], [ -174.528809, -4.674980 ], [ -174.528809, -4.653080 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 6, "x": 1, "y": 32 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -171.254883, -4.434044 ], [ -171.232910, -4.455951 ], [ -171.276855, -4.455951 ], [ -171.276855, -4.434044 ], [ -171.254883, -4.434044 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 6, "x": 4, "y": 33 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -155.917969, -5.615986 ], [ -155.895996, -5.594118 ], [ -155.874023, -5.594118 ], [ -155.874023, -5.615986 ], [ -155.917969, -5.615986 ] ] ], [ [ [ -155.917969, -5.615986 ], [ -155.939941, -5.615986 ], [ -155.939941, -5.594118 ], [ -155.917969, -5.594118 ], [ -155.917969, -5.615986 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 6, "x": 4, "y": 32 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -155.917969, -5.615986 ], [ -155.895996, -5.594118 ], [ -155.874023, -5.594118 ], [ -155.874023, -5.615986 ], [ -155.917969, -5.615986 ] ] ], [ [ [ -155.917969, -5.615986 ], [ -155.939941, -5.615986 ], [ -155.939941, -5.594118 ], [ -155.917969, -5.594118 ], [ -155.917969, -5.615986 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 6, "x": 56, "y": 30 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http://en.wikipedia.org/wiki/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "code_hasc": "FM.YA", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.58101, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_a1_code": "FM.04", "gns_level": 1, "gns_adm1": "FM04" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 138.164062, 9.579084 ], [ 138.164062, 9.557417 ], [ 138.208008, 9.557417 ], [ 138.186035, 9.535749 ], [ 138.186035, 9.514079 ], [ 138.164062, 9.514079 ], [ 138.142090, 9.535749 ], [ 138.120117, 9.514079 ], [ 138.076172, 9.427387 ], [ 138.054199, 9.427387 ], [ 138.054199, 9.470736 ], [ 138.076172, 9.514079 ], [ 138.120117, 9.557417 ], [ 138.120117, 9.579084 ], [ 138.164062, 9.579084 ] ] ], [ [ [ 138.186035, 9.579084 ], [ 138.164062, 9.579084 ], [ 138.164062, 9.600750 ], [ 138.186035, 9.600750 ], [ 138.186035, 9.579084 ] ] ], [ [ [ 140.515137, 9.795678 ], [ 140.515137, 9.774025 ], [ 140.493164, 9.774025 ], [ 140.515137, 9.795678 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 6, "x": 62, "y": 32 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.221191, -0.505365 ], [ 174.243164, -0.527336 ], [ 174.221191, -0.527336 ], [ 174.221191, -0.505365 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 6, "x": 62, "y": 31 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 173.540039, 0.197754 ], [ 173.540039, 0.175781 ], [ 173.518066, 0.175781 ], [ 173.518066, 0.197754 ], [ 173.540039, 0.197754 ] ] ], [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.219726 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.342285, 0.285643 ], [ 173.364258, 0.263671 ], [ 173.364258, 0.241699 ], [ 173.342285, 0.263671 ], [ 173.342285, 0.285643 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.373533 ], [ 173.913574, 0.417477 ] ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 7, "x": 1, "y": 65 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 128 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -174.528809, -4.653080 ], [ -174.506836, -4.674980 ], [ -174.528809, -4.674980 ], [ -174.528809, -4.653080 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 7, "x": 3, "y": 65 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 128 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -171.188965, -3.754634 ], [ -171.166992, -3.754634 ], [ -171.166992, -3.798484 ], [ -171.188965, -3.798484 ], [ -171.188965, -3.754634 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 7, "x": 8, "y": 66 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 128 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -155.917969, -5.594118 ], [ -155.917969, -5.615986 ], [ -155.939941, -5.615986 ], [ -155.939941, -5.594118 ], [ -155.917969, -5.594118 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 7, "x": 8, "y": 65 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 128 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -155.917969, -5.594118 ], [ -155.874023, -5.615986 ], [ -155.939941, -5.615986 ], [ -155.917969, -5.594118 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 7, "x": 113, "y": 60 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 128 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "FSM-4943", "OBJECTID_1": 6464, "diss_me": 4943, "adm1_cod_1": "FSM-4943", "iso_3166_2": "FM-YAP", "wikipedia": "http://en.wikipedia.org/wiki/Yap_State", "iso_a2": "FM", "adm0_sr": 5, "name": "Yap", "code_hasc": "FM.YA", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 10, "datarank": 10, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 scale rank", "name_len": 3, "mapcolor9": 4, "mapcolor13": 13, "fips": "FM04", "woe_id": 2345343, "woe_label": "Yap, FM, Federated States of Micronesia", "woe_name": "Yap", "latitude": 9.58101, "longitude": 138.114, "sov_a3": "FSM", "adm0_a3": "FSM", "adm0_label": 5, "admin": "Federated States of Micronesia", "geonunit": "Federated States of Micronesia", "gu_a3": "FSM", "gn_id": 2081175, "gn_name": "State of Yap", "gns_id": -3741502, "gns_name": "Yap, State of", "gn_level": 1, "gn_a1_code": "FM.04", "gns_level": 1, "gns_adm1": "FM04" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 138.208008, 9.557417 ], [ 138.186035, 9.514079 ], [ 138.142090, 9.535749 ], [ 138.054199, 9.427387 ], [ 138.120117, 9.579084 ], [ 138.142090, 9.557417 ], [ 138.208008, 9.557417 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 7, "x": 125, "y": 64 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 128 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.221191, -0.505365 ], [ 174.243164, -0.527336 ], [ 174.221191, -0.527336 ], [ 174.221191, -0.505365 ] ] ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 7, "x": 125, "y": 63 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 128 }, "features": [ +{ "type": "Feature", "properties": { "adm1_code": "KIR+99?", "OBJECTID_1": 3643, "diss_me": 10097, "adm1_cod_1": "KIR+99?", "iso_3166_2": "KI-", "iso_a2": "KI", "adm0_sr": 5, "code_hasc": "-99", "note": "KIR-99 (Kiribati minor island)", "provnum_ne": 0, "gadm_level": 0, "check_me": 0, "scalerank": 11, "datarank": 11, "area_sqkm": 0, "sameascity": -99, "labelrank": 20, "featurecla": "Admin-1 minor island", "name_len": 0, "mapcolor9": 6, "mapcolor13": 12, "woe_id": -99, "latitude": -4.68967, "longitude": -174.511, "sov_a3": "KIR", "adm0_a3": "KIR", "adm0_label": 7, "admin": "Kiribati", "geonunit": "Kiribati", "gu_a3": "KIR", "gn_id": 0, "gns_id": 0, "gn_level": 0, "gn_a1_code": "KI.", "gns_level": 0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 173.386230, 0.241699 ], [ 173.408203, 0.219726 ], [ 173.386230, 0.197754 ], [ 173.364258, 0.241699 ], [ 173.386230, 0.241699 ] ] ], [ [ [ 173.913574, 0.417477 ], [ 173.935547, 0.395505 ], [ 173.935547, 0.329588 ], [ 173.913574, 0.417477 ] ] ] ] } } +] } +] } +] } diff --git a/tests/muni/decode/multi.mbtiles.json b/tests/muni/decode/multi.mbtiles.json new file mode 100644 index 0000000..6a42a89 --- /dev/null +++ b/tests/muni/decode/multi.mbtiles.json @@ -0,0 +1,63 @@ +{ "type": "FeatureCollection", "properties": { +"bounds": "-122.538670,37.705764,-12.240000,37.836443", +"center": "-122.431641,37.788049,11", +"description": "tests/muni/decode/multi.mbtiles", +"format": "pbf", +"json": "{\"vector_layers\": [ { \"id\": \"muni\", \"description\": \"\", \"minzoom\": 11, \"maxzoom\": 11, \"fields\": {\"name\": \"String\"} }, { \"id\": \"subway\", \"description\": \"\", \"minzoom\": 11, \"maxzoom\": 11, \"fields\": {\"name\": \"String\"} } ] }", +"maxzoom": "11", +"minzoom": "11", +"name": "tests/muni/decode/multi.mbtiles", +"type": "overlay", +"version": "2" +}, "features": [ +{ "type": "FeatureCollection", "properties": { "zoom": 11, "x": 326, "y": 791 }, "features": [ +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 11, "x": 327, "y": 792 }, "features": [ +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 11, "x": 327, "y": 791 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "subway", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "name": "Metro Castro Station/Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.435331, 37.762708 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Castro Station/Downtown" }, "geometry": { "type": "Point", "coordinates": [ -122.435246, 37.762641 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Forest Hill Station/Downtown" }, "geometry": { "type": "Point", "coordinates": [ -122.458634, 37.748356 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Montgomery Station/Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.402158, 37.788794 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Montgomery Station/Downtown" }, "geometry": { "type": "Point", "coordinates": [ -122.401943, 37.788726 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Embarcadero Station/Downtown" }, "geometry": { "type": "Point", "coordinates": [ -122.396579, 37.793033 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Embarcadero Station" }, "geometry": { "type": "Point", "coordinates": [ -122.396450, 37.793168 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Embarcadero Station" }, "geometry": { "type": "Point", "coordinates": [ -122.396407, 37.793168 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Civic Center Station/Downtown" }, "geometry": { "type": "Point", "coordinates": [ -122.412543, 37.780348 ] } } +, +{ "type": "Feature", "properties": { "name": "Van Ness Station Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.419367, 37.775260 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Van Ness Station/Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.419281, 37.775159 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Van Ness Station" }, "geometry": { "type": "Point", "coordinates": [ -122.419195, 37.775091 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Van Ness Station/Downtown" }, "geometry": { "type": "Point", "coordinates": [ -122.419281, 37.775057 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Civic Center Station/Outbd" }, "geometry": { "type": "Point", "coordinates": [ -122.415032, 37.778686 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Civic Center Station/Downtn" }, "geometry": { "type": "Point", "coordinates": [ -122.414818, 37.778551 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Church Station/Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.429323, 37.767356 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Church Station/Downtown" }, "geometry": { "type": "Point", "coordinates": [ -122.429194, 37.767221 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Powell Station/Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.407823, 37.784317 ] } } +, +{ "type": "Feature", "properties": { "name": "Metro Powell Station/Downtown" }, "geometry": { "type": "Point", "coordinates": [ -122.407737, 37.784215 ] } } +] } +] } +, +{ "type": "FeatureCollection", "properties": { "zoom": 11, "x": 954, "y": 791 }, "features": [ +] } +] } diff --git a/tile.cpp b/tile.cpp index 3d6e115..88eca9e 100644 --- a/tile.cpp +++ b/tile.cpp @@ -402,7 +402,7 @@ void *partial_feature_worker(void *v) { double area = 0; if (t == VT_POLYGON) { - area = get_area(geom, 0, geom.size()); + area = get_mp_area(geom); } if ((t == VT_LINE || t == VT_POLYGON) && !(prevent[P_SIMPLIFY] || (z == maxzoom && prevent[P_SIMPLIFY_LOW]) || (z < maxzoom && additional[A_GRID_LOW_ZOOMS]))) { @@ -1706,6 +1706,12 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s } auto l = layers.find(layername); + if (l == layers.end()) { + fprintf(stderr, "Internal error: couldn't find layer %s\n", layername.c_str()); + fprintf(stderr, "segment %d\n", partials[i].segment); + fprintf(stderr, "layer %lld\n", partials[i].layer); + exit(EXIT_FAILURE); + } l->second.push_back(c); } } diff --git a/version.hpp b/version.hpp index 34febff..4d70e23 100644 --- a/version.hpp +++ b/version.hpp @@ -1 +1 @@ -#define VERSION "tippecanoe v1.16.5\n" +#define VERSION "tippecanoe v1.16.10\n"