From aaad2e3af8f7b4b7a997fc6fef60d0430939eb31 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Mon, 18 Nov 2024 16:12:33 -0800 Subject: [PATCH 01/24] Plumb a clip bounding box around through overzoom --- clip.cpp | 10 ++++++---- geometry.hpp | 18 ++++++++++++++++-- main.hpp | 12 ------------ overzoom.cpp | 18 +++++++++++++++++- tile-join.cpp | 3 ++- 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/clip.cpp b/clip.cpp index 06d29c12..eb4a2b66 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1087,7 +1087,8 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int n std::vector const &unidecode_data, double simplification, double tiny_polygon_size, std::vector const &bins, std::string const &bin_by_id_list, - std::string const &accumulate_numeric, size_t feature_limit) { + std::string const &accumulate_numeric, size_t feature_limit, + std::vector const &clipbboxes) { std::vector decoded; for (auto const &t : tiles) { @@ -1113,7 +1114,7 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int n decoded.push_back(out); } - return overzoom(decoded, nz, nx, ny, detail_or_unspecified, buffer, keep, exclude, exclude_prefix, do_compress, next_overzoomed_tiles, demultiply, filter, preserve_input_order, attribute_accum, unidecode_data, simplification, tiny_polygon_size, bins, bin_by_id_list, accumulate_numeric, feature_limit); + return overzoom(decoded, nz, nx, ny, detail_or_unspecified, buffer, keep, exclude, exclude_prefix, do_compress, next_overzoomed_tiles, demultiply, filter, preserve_input_order, attribute_accum, unidecode_data, simplification, tiny_polygon_size, bins, bin_by_id_list, accumulate_numeric, feature_limit, clipbboxes); } // like a minimal serial_feature, but with mvt_feature-style attributes @@ -1776,7 +1777,8 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int std::vector const &unidecode_data, double simplification, double tiny_polygon_size, std::vector const &bins, std::string const &bin_by_id_list, - std::string const &accumulate_numeric, size_t feature_limit) { + std::string const &accumulate_numeric, size_t feature_limit, + std::vector const &clipbboxes) { mvt_tile outtile; key_pool key_pool; @@ -2003,7 +2005,7 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int detail_or_unspecified, buffer, keep, exclude, exclude_prefix, false, NULL, demultiply, filter, preserve_input_order, attribute_accum, unidecode_data, simplification, tiny_polygon_size, bins, bin_by_id_list, accumulate_numeric, - 1); + 1, clipbboxes); if (child.size() > 0) { next_overzoomed_tiles->emplace_back(nx * 2 + x, ny * 2 + y); } diff --git a/geometry.hpp b/geometry.hpp index 7d8d81f0..2284ab95 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -115,6 +115,18 @@ struct source_tile { int y; }; +struct clipbbox { + double lon1; + double lat1; + double lon2; + double lat2; + + long long minx; + long long miny; + long long maxx; + long long maxy; +}; + std::string overzoom(std::vector const &tiles, int nz, int nx, int ny, int detail, int buffer, std::set const &keep, @@ -127,7 +139,8 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int std::vector const &unidecode_data, double simplification, double tiny_polygon_size, std::vector const &bins, std::string const &bin_by_id_list, - std::string const &accumulate_numeric, size_t feature_limit); + std::string const &accumulate_numeric, size_t feature_limit, + std::vector const &clipbboxes); std::string overzoom(std::vector const &tiles, int nz, int nx, int ny, int detail, int buffer, @@ -141,7 +154,8 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int n std::vector const &unidecode_data, double simplification, double tiny_polygon_size, std::vector const &bins, std::string const &bin_by_id_list, - std::string const &accumulate_numeric, size_t feature_limit); + std::string const &accumulate_numeric, size_t feature_limit, + std::vector const &clipbboxes); draw center_of_mass_mp(const drawvec &dv); diff --git a/main.hpp b/main.hpp index cc28df3c..714af5c3 100644 --- a/main.hpp +++ b/main.hpp @@ -24,18 +24,6 @@ struct index { } }; -struct clipbbox { - double lon1; - double lat1; - double lon2; - double lat2; - - long long minx; - long long miny; - long long maxx; - long long maxy; -}; - extern std::vector clipbboxes; void checkdisk(std::vector *r); diff --git a/overzoom.cpp b/overzoom.cpp index 37fdbaeb..514c7669 100644 --- a/overzoom.cpp +++ b/overzoom.cpp @@ -10,6 +10,7 @@ #include "attribute.hpp" #include "text.hpp" #include "read_json.hpp" +#include "projection.hpp" extern char *optarg; extern int optind; @@ -29,6 +30,7 @@ std::string accumulate_numeric; std::set keep; std::set exclude; std::vector exclude_prefix; +std::vector clipbboxes; void usage(char **argv) { fprintf(stderr, "Usage: %s -o newtile.pbf.gz tile.pbf.gz oz/ox/oy nz/nx/ny\n", argv[0]); @@ -67,7 +69,9 @@ int main(int argc, char **argv) { {"assign-to-bins", required_argument, 0, 'b' & 0x1F}, {"bin-by-id-list", required_argument, 0, 'c' & 0x1F}, {"accumulate-numeric-attributes", required_argument, 0, 'a' & 0x1F}, + {"numeric-attributes", required_argument, 0, 'a' & 0x1F}, {"no-tile-compression", no_argument, 0, 'd' & 0x1F}, + {"clip-bounding-box", required_argument, 0, 'k' & 0x1F}, {0, 0, 0, 0}, }; @@ -158,6 +162,18 @@ int main(int argc, char **argv) { do_compress = false; break; + case 'k' & 0x1F: + clipbbox clip; + if (sscanf(optarg, "%lf,%lf,%lf,%lf", &clip.lon1, &clip.lat1, &clip.lon2, &clip.lat2) == 4) { + projection->project(clip.lon1, clip.lat1, 32, &clip.minx, &clip.maxy); + projection->project(clip.lon2, clip.lat2, 32, &clip.maxx, &clip.miny); + clipbboxes.push_back(clip); + } else { + fprintf(stderr, "%s: Can't parse bounding box --clip-bounding-box=%s\n", argv[0], optarg); + exit(EXIT_ARGS); + } + break; + default: fprintf(stderr, "Unrecognized flag -%c\n", i); usage(argv); @@ -262,7 +278,7 @@ int main(int argc, char **argv) { its.push_back(std::move(t)); } - std::string out = overzoom(its, nz, nx, ny, detail, buffer, keep, exclude, exclude_prefix, do_compress, NULL, demultiply, json_filter, preserve_input_order, attribute_accum, unidecode_data, simplification, tiny_polygon_size, bins, bin_by_id_list, accumulate_numeric, SIZE_MAX); + std::string out = overzoom(its, nz, nx, ny, detail, buffer, keep, exclude, exclude_prefix, do_compress, NULL, demultiply, json_filter, preserve_input_order, attribute_accum, unidecode_data, simplification, tiny_polygon_size, bins, bin_by_id_list, accumulate_numeric, SIZE_MAX, clipbboxes); FILE *f = fopen(outfile, "wb"); if (f == NULL) { diff --git a/tile-join.cpp b/tile-join.cpp index 3fa3d412..6d8d2523 100644 --- a/tile-join.cpp +++ b/tile-join.cpp @@ -716,7 +716,8 @@ struct tileset_reader { std::set(), std::set(), std::vector(), false, &next_overzoomed_tiles, false, NULL, false, std::unordered_map(), unidecode_data, 0, 0, - std::vector(), "", "", SIZE_MAX); + std::vector(), "", "", SIZE_MAX, + std::vector()); return ret; } From 1afe03ed96635c7467fd37ba05cd8d497e253fb9 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Mon, 18 Nov 2024 21:34:53 -0800 Subject: [PATCH 02/24] Actually do some clipping --- clip.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/clip.cpp b/clip.cpp index eb4a2b66..a0ad12c7 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1318,28 +1318,55 @@ static bool feature_out(std::vector const &features, mvt_layer &ou std::vector const &exclude_prefix, std::unordered_map const &attribute_accum, std::string const &accumulate_numeric, - key_pool &key_pool, int buffer, bool include_nonaggregate) { + key_pool &key_pool, int buffer, bool include_nonaggregate, + std::vector const &clipbboxes, int nz, int nx, int ny) { // Add geometry to output feature drawvec geom = features[0].geom; - if (buffer >= 0) { - int t = features[0].t; + int t = features[0].t; + + bool fix_polygons = false; + if ((buffer >= 0 || clipbboxes.size() > 0) && t == VT_POLYGON) { + fix_polygons = true; + } + + if (fix_polygons) { + handle_closepath_from_mvt(geom); + } + if (buffer >= 0) { if (t == VT_LINE) { geom = clip_lines(geom, 32 - outlayer.detail(), buffer); } else if (t == VT_POLYGON) { drawvec dv; - handle_closepath_from_mvt(geom); geom = simple_clip_poly(geom, 32 - outlayer.detail(), buffer, dv, false); } else if (t == VT_POINT) { geom = clip_point(geom, 32 - outlayer.detail(), buffer); } geom = remove_noop(geom, t, 0); - if (t == VT_POLYGON) { - geom = clean_or_clip_poly(geom, 0, 0, false, false); - geom = close_poly(geom); + } + + if (clipbboxes.size() != 0) { + long long dx = (long long) nx << (32 - nz); + long long dy = (long long) ny << (32 - nz); + + for (auto &c : clipbboxes) { + if (t == VT_POLYGON) { + geom = simple_clip_poly(geom, c.minx - dx, c.miny - dy, c.maxx - dx, c.maxy - dy, false); + } else if (t == VT_LINE) { + geom = clip_lines(geom, c.minx - dx, c.miny - dy, c.maxx - dx, c.maxy - dy); + } else if (t == VT_POINT) { + geom = clip_point(geom, c.minx - dx, c.miny - dy, c.maxx - dx, c.maxy - dy); + } } + + geom = remove_noop(geom, t, 0); + } + + if (fix_polygons) { + geom = clean_or_clip_poly(geom, 0, 0, false, false); + geom = close_poly(geom); } mvt_feature outfeature; @@ -1578,7 +1605,7 @@ mvt_tile assign_to_bins(mvt_tile &features, std::set keep, std::set exclude, std::vector exclude_prefix, - int buffer) { + int buffer, std::vector const &clipbboxes) { std::vector events; key_pool key_pool; @@ -1741,7 +1768,8 @@ mvt_tile assign_to_bins(mvt_tile &features, if (outfeatures[i].size() > 1) { if (feature_out(outfeatures[i], outlayer, keep, exclude, exclude_prefix, attribute_accum, - accumulate_numeric, key_pool, buffer, true)) { + accumulate_numeric, key_pool, buffer, true, + clipbboxes, z, x, y)) { mvt_feature &nfeature = outlayer.features.back(); mvt_value val; val.type = mvt_uint; @@ -1838,8 +1866,22 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int } } + // Clip to user-specified bounding boxes. + // But don't clip here if we are binning, because we need to bin points in the buffer + if (bins.size() == 0) { + for (auto &c : clipbboxes) { + if (t == VT_POLYGON) { + geom = simple_clip_poly(geom, c.minx, c.miny, c.maxx, c.maxy, false); + } else if (t == VT_LINE) { + geom = clip_lines(geom, c.minx, c.miny, c.maxx, c.maxy); + } else if (t == VT_POINT) { + geom = clip_point(geom, c.minx, c.miny, c.maxx, c.maxy); + } + } + } + // Now offset from world coordinates to output tile coordinates, - // but retain world scale, because that is what tippecanoe clipping expects + // but retain world scale, because that is what tippecanoe zoom-oriented clipping expects long long outtilesize = 1LL << (32 - nz); // destination tile size in world coordinates for (auto &g : geom) { @@ -1905,7 +1947,7 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int if (flush_multiplier_cluster) { if (pending_tile_features.size() > 0) { - feature_out(pending_tile_features, *outlayer, keep, exclude, exclude_prefix, attribute_accum, accumulate_numeric, key_pool, -1, bins.size() == 0); + feature_out(pending_tile_features, *outlayer, keep, exclude, exclude_prefix, attribute_accum, accumulate_numeric, key_pool, -1, bins.size() == 0, std::vector(), nz, nx, ny); if (outlayer->features.size() >= feature_limit) { break; } @@ -1965,7 +2007,7 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int } if (pending_tile_features.size() > 0) { - feature_out(pending_tile_features, *outlayer, keep, exclude, exclude_prefix, attribute_accum, accumulate_numeric, key_pool, -1, bins.size() == 0); + feature_out(pending_tile_features, *outlayer, keep, exclude, exclude_prefix, attribute_accum, accumulate_numeric, key_pool, -1, bins.size() == 0, std::vector(), nz, nx, ny); pending_tile_features.clear(); if (outlayer->features.size() >= feature_limit) { break; @@ -2017,7 +2059,7 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int if (bins.size() > 0) { outtile = assign_to_bins(outtile, bins, bin_by_id_list, nz, nx, ny, attribute_accum, accumulate_numeric, - keep, exclude, exclude_prefix, buffer); + keep, exclude, exclude_prefix, buffer, clipbboxes); } for (ssize_t i = outtile.layers.size() - 1; i >= 0; i--) { From 08f9d0d71de616353dea018da2684bc9c7f092ab Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Mon, 18 Nov 2024 21:43:35 -0800 Subject: [PATCH 03/24] Add a test --- Makefile | 5 ++ main.cpp | 3 + tests/pbf/countries-0-0-0-clip.pbf.out.json | 73 +++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 tests/pbf/countries-0-0-0-clip.pbf.out.json diff --git a/Makefile b/Makefile index be1b08ce..b0b6ae6c 100644 --- a/Makefile +++ b/Makefile @@ -362,6 +362,11 @@ overzoom-test: tippecanoe-overzoom ./tippecanoe-decode tests/pbf/countries-0-0-0.pbf.out 0 0 0 > tests/pbf/countries-0-0-0.pbf.out.json.check cmp tests/pbf/countries-0-0-0.pbf.out.json.check tests/pbf/countries-0-0-0.pbf.out.json rm tests/pbf/countries-0-0-0.pbf.out tests/pbf/countries-0-0-0.pbf.out.json.check + # Clipping to bounding box + ./tippecanoe-overzoom --clip-bounding-box 5,5,25.7,50 -o tests/pbf/countries-0-0-0-clip.pbf.out tests/pbf/countries-0-0-0.pbf 0/0/0 0/0/0 + ./tippecanoe-decode tests/pbf/countries-0-0-0-clip.pbf.out 0 0 0 > tests/pbf/countries-0-0-0-clip.pbf.out.json.check + cmp tests/pbf/countries-0-0-0-clip.pbf.out.json.check tests/pbf/countries-0-0-0-clip.pbf.out.json + rm tests/pbf/countries-0-0-0-clip.pbf.out tests/pbf/countries-0-0-0-clip.pbf.out.json.check # Binning ./tippecanoe-overzoom -o tests/pbf/bin-11-327-791.pbf.out --assign-to-bins tests/pbf/sf-zips.json tests/pbf/muni-11-327-791.pbf 11/327/791 11/327/791 ./tippecanoe-decode tests/pbf/bin-11-327-791.pbf.out 11 327 791 > tests/pbf/bin-11-327-791.pbf.out.json.check diff --git a/main.cpp b/main.cpp index 6a5e09e7..0d0a9ed3 100644 --- a/main.cpp +++ b/main.cpp @@ -2380,6 +2380,9 @@ std::pair read_input(std::vector &sources, char *fname, i double want = nearby_ft / 2; maxzoom = ceil(log(360 / (.00000274 * want)) / log(2) - full_detail); + if (maxzoom < 0) { + maxzoom = 0; + } if (!quiet) { fprintf(stderr, "Choosing a maxzoom of -z%d for features typically %d feet (%d meters) apart, ", diff --git a/tests/pbf/countries-0-0-0-clip.pbf.out.json b/tests/pbf/countries-0-0-0-clip.pbf.out.json new file mode 100644 index 00000000..49922160 --- /dev/null +++ b/tests/pbf/countries-0-0-0-clip.pbf.out.json @@ -0,0 +1,73 @@ +{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 12.392578, 50.007739 ], [ 12.392578, 49.951220 ], [ 12.480469, 49.553726 ], [ 13.007812, 49.325122 ], [ 13.623047, 48.864715 ], [ 13.271484, 48.400032 ], [ 12.919922, 48.283193 ], [ 13.007812, 47.635784 ], [ 12.919922, 47.457809 ], [ 12.656250, 47.694974 ], [ 12.128906, 47.694974 ], [ 11.425781, 47.517201 ], [ 10.546875, 47.576526 ], [ 10.371094, 47.279229 ], [ 9.931641, 47.576526 ], [ 9.580078, 47.517201 ], [ 8.525391, 47.813155 ], [ 8.349609, 47.635784 ], [ 7.470703, 47.635784 ], [ 7.558594, 48.341646 ], [ 8.085938, 49.037868 ], [ 6.679688, 49.210420 ], [ 6.152344, 49.439557 ], [ 6.240234, 49.894634 ], [ 6.152344, 50.007739 ], [ 12.392578, 50.007739 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 5.800781, 50.007739 ], [ 5.712891, 49.553726 ], [ 5.009766, 49.894634 ], [ 5.009766, 50.007739 ], [ 5.800781, 50.007739 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 6.152344, 50.007739 ], [ 6.240234, 49.894634 ], [ 6.152344, 49.439557 ], [ 5.888672, 49.439557 ], [ 5.712891, 49.553726 ], [ 5.800781, 50.007739 ], [ 6.152344, 50.007739 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 9.404297, 43.004647 ], [ 9.580078, 42.163403 ], [ 9.228516, 41.376809 ], [ 8.789062, 41.574361 ], [ 8.525391, 42.228517 ], [ 8.789062, 42.617791 ], [ 9.404297, 43.004647 ] ] ], [ [ [ 5.009766, 49.894634 ], [ 5.712891, 49.553726 ], [ 5.888672, 49.439557 ], [ 6.152344, 49.439557 ], [ 6.679688, 49.210420 ], [ 8.085938, 49.037868 ], [ 7.558594, 48.341646 ], [ 7.470703, 47.635784 ], [ 7.207031, 47.457809 ], [ 6.767578, 47.517201 ], [ 6.767578, 47.279229 ], [ 6.064453, 46.739861 ], [ 6.064453, 46.255847 ], [ 6.503906, 46.437857 ], [ 6.855469, 46.012224 ], [ 6.767578, 45.706179 ], [ 7.119141, 45.336702 ], [ 6.767578, 45.026950 ], [ 7.031250, 44.276671 ], [ 7.558594, 44.150681 ], [ 7.470703, 43.707594 ], [ 6.503906, 43.133061 ], [ 5.009766, 43.325178 ], [ 5.009766, 49.894634 ] ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 8.525391, 47.813155 ], [ 9.580078, 47.517201 ], [ 9.667969, 47.338823 ], [ 9.492188, 47.100045 ], [ 9.931641, 46.920255 ], [ 10.458984, 46.920255 ], [ 10.371094, 46.498392 ], [ 9.931641, 46.316584 ], [ 9.140625, 46.437857 ], [ 8.964844, 46.012224 ], [ 8.525391, 46.012224 ], [ 8.349609, 46.134170 ], [ 7.734375, 45.828799 ], [ 7.294922, 45.767523 ], [ 6.855469, 46.012224 ], [ 6.503906, 46.437857 ], [ 6.064453, 46.255847 ], [ 6.064453, 46.739861 ], [ 6.767578, 47.279229 ], [ 6.767578, 47.517201 ], [ 7.207031, 47.457809 ], [ 7.470703, 47.635784 ], [ 8.349609, 47.635784 ], [ 8.525391, 47.813155 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 23.115234, 50.007739 ], [ 22.500000, 49.496675 ], [ 22.763672, 49.037868 ], [ 22.587891, 49.095452 ], [ 21.621094, 49.496675 ], [ 20.917969, 49.325122 ], [ 20.390625, 49.439557 ], [ 19.863281, 49.210420 ], [ 19.335938, 49.553726 ], [ 18.896484, 49.439557 ], [ 18.896484, 49.496675 ], [ 18.369141, 50.007739 ], [ 23.115234, 50.007739 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.292969, 49.037868 ], [ 15.996094, 48.748945 ], [ 16.523438, 48.806863 ], [ 16.962891, 48.574790 ], [ 16.875000, 48.458352 ], [ 16.962891, 48.107431 ], [ 16.875000, 47.694974 ], [ 16.347656, 47.694974 ], [ 16.523438, 47.517201 ], [ 16.171875, 46.860191 ], [ 15.996094, 46.679594 ], [ 15.117188, 46.679594 ], [ 14.589844, 46.437857 ], [ 13.798828, 46.498392 ], [ 12.392578, 46.739861 ], [ 12.128906, 47.100045 ], [ 11.162109, 46.920255 ], [ 11.074219, 46.739861 ], [ 10.458984, 46.920255 ], [ 9.931641, 46.920255 ], [ 9.492188, 47.100045 ], [ 9.667969, 47.338823 ], [ 9.580078, 47.517201 ], [ 9.931641, 47.576526 ], [ 10.371094, 47.279229 ], [ 10.546875, 47.576526 ], [ 11.425781, 47.517201 ], [ 12.128906, 47.694974 ], [ 12.656250, 47.694974 ], [ 12.919922, 47.457809 ], [ 13.007812, 47.635784 ], [ 12.919922, 48.283193 ], [ 13.271484, 48.400032 ], [ 13.623047, 48.864715 ], [ 14.326172, 48.574790 ], [ 14.941406, 48.980217 ], [ 15.292969, 49.037868 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 18.369141, 50.007739 ], [ 18.896484, 49.496675 ], [ 18.544922, 49.496675 ], [ 18.369141, 49.325122 ], [ 18.193359, 49.267805 ], [ 18.105469, 49.037868 ], [ 17.929688, 48.980217 ], [ 17.929688, 48.922499 ], [ 17.578125, 48.806863 ], [ 17.138672, 48.806863 ], [ 16.962891, 48.574790 ], [ 16.523438, 48.806863 ], [ 15.996094, 48.748945 ], [ 15.292969, 49.037868 ], [ 14.941406, 48.980217 ], [ 14.326172, 48.574790 ], [ 13.623047, 48.864715 ], [ 13.007812, 49.325122 ], [ 12.480469, 49.553726 ], [ 12.392578, 49.951220 ], [ 12.392578, 50.007739 ], [ 18.369141, 50.007739 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.347656, 46.860191 ], [ 16.523438, 46.498392 ], [ 15.732422, 46.255847 ], [ 15.644531, 45.828799 ], [ 15.292969, 45.706179 ], [ 15.292969, 45.460131 ], [ 14.941406, 45.460131 ], [ 14.589844, 45.644768 ], [ 14.414062, 45.460131 ], [ 13.710938, 45.521744 ], [ 13.974609, 45.583290 ], [ 13.710938, 46.012224 ], [ 13.798828, 46.498392 ], [ 14.589844, 46.437857 ], [ 15.117188, 46.679594 ], [ 15.996094, 46.679594 ], [ 16.171875, 46.860191 ], [ 16.347656, 46.860191 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 19.335938, 49.553726 ], [ 19.863281, 49.210420 ], [ 20.390625, 49.439557 ], [ 20.917969, 49.325122 ], [ 21.621094, 49.496675 ], [ 22.587891, 49.095452 ], [ 22.324219, 48.806863 ], [ 22.060547, 48.400032 ], [ 21.884766, 48.341646 ], [ 20.830078, 48.632909 ], [ 20.478516, 48.574790 ], [ 20.214844, 48.341646 ], [ 19.775391, 48.224673 ], [ 19.687500, 48.283193 ], [ 19.160156, 48.107431 ], [ 18.808594, 48.107431 ], [ 18.720703, 47.872144 ], [ 17.841797, 47.754098 ], [ 17.490234, 47.872144 ], [ 16.962891, 48.107431 ], [ 16.875000, 48.458352 ], [ 17.138672, 48.806863 ], [ 17.578125, 48.806863 ], [ 17.929688, 48.922499 ], [ 17.929688, 48.980217 ], [ 18.105469, 49.037868 ], [ 18.193359, 49.267805 ], [ 18.369141, 49.325122 ], [ 18.544922, 49.496675 ], [ 18.896484, 49.496675 ], [ 18.896484, 49.439557 ], [ 19.335938, 49.553726 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.523438, 46.498392 ], [ 16.875000, 46.377254 ], [ 17.666016, 45.951150 ], [ 18.457031, 45.767523 ], [ 18.808594, 45.890008 ], [ 19.072266, 45.521744 ], [ 19.423828, 45.213004 ], [ 18.984375, 44.840291 ], [ 18.544922, 45.089036 ], [ 17.841797, 45.089036 ], [ 16.962891, 45.213004 ], [ 16.523438, 45.213004 ], [ 16.347656, 45.026950 ], [ 15.996094, 45.213004 ], [ 15.732422, 44.840291 ], [ 16.259766, 44.339565 ], [ 16.435547, 44.024422 ], [ 16.875000, 43.644026 ], [ 17.314453, 43.452919 ], [ 17.666016, 43.004647 ], [ 18.544922, 42.617791 ], [ 18.457031, 42.488302 ], [ 17.490234, 42.875964 ], [ 16.962891, 43.197167 ], [ 15.996094, 43.516689 ], [ 15.205078, 44.213710 ], [ 15.380859, 44.339565 ], [ 14.941406, 44.715514 ], [ 14.941406, 45.089036 ], [ 14.238281, 45.213004 ], [ 13.974609, 44.777936 ], [ 13.623047, 45.151053 ], [ 13.710938, 45.460131 ], [ 13.710938, 45.521744 ], [ 14.414062, 45.460131 ], [ 14.589844, 45.644768 ], [ 14.941406, 45.460131 ], [ 15.292969, 45.460131 ], [ 15.292969, 45.706179 ], [ 15.644531, 45.828799 ], [ 15.732422, 46.255847 ], [ 16.523438, 46.498392 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.962891, 45.213004 ], [ 17.841797, 45.089036 ], [ 18.544922, 45.089036 ], [ 18.984375, 44.840291 ], [ 19.335938, 44.840291 ], [ 19.160156, 44.402392 ], [ 19.599609, 44.024422 ], [ 19.423828, 43.580391 ], [ 19.072266, 43.452919 ], [ 18.720703, 43.197167 ], [ 18.544922, 42.617791 ], [ 17.666016, 43.004647 ], [ 17.314453, 43.452919 ], [ 16.875000, 43.644026 ], [ 16.435547, 44.024422 ], [ 16.259766, 44.339565 ], [ 15.732422, 44.840291 ], [ 15.996094, 45.213004 ], [ 16.347656, 45.026950 ], [ 16.523438, 45.213004 ], [ 16.962891, 45.213004 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 19.248047, 43.516689 ], [ 19.511719, 43.325178 ], [ 19.599609, 43.197167 ], [ 19.951172, 43.133061 ], [ 20.302734, 42.875964 ], [ 20.214844, 42.811522 ], [ 20.039062, 42.617791 ], [ 19.775391, 42.488302 ], [ 19.775391, 42.682435 ], [ 19.335938, 42.163403 ], [ 19.335938, 41.902277 ], [ 19.160156, 41.967659 ], [ 18.896484, 42.293564 ], [ 18.457031, 42.488302 ], [ 18.544922, 42.617791 ], [ 18.720703, 43.197167 ], [ 19.072266, 43.452919 ], [ 19.248047, 43.516689 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 20.830078, 43.261206 ], [ 20.917969, 43.133061 ], [ 21.181641, 43.068888 ], [ 21.269531, 42.940339 ], [ 21.445312, 42.875964 ], [ 21.621094, 42.682435 ], [ 21.796875, 42.682435 ], [ 21.533203, 42.293564 ], [ 21.533203, 42.228517 ], [ 21.357422, 42.228517 ], [ 20.742188, 42.032974 ], [ 20.742188, 41.836828 ], [ 20.566406, 41.836828 ], [ 20.566406, 42.228517 ], [ 20.302734, 42.293564 ], [ 20.039062, 42.617791 ], [ 20.214844, 42.811522 ], [ 20.478516, 42.875964 ], [ 20.654297, 43.197167 ], [ 20.830078, 43.261206 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 19.775391, 42.682435 ], [ 19.775391, 42.488302 ], [ 20.039062, 42.617791 ], [ 20.302734, 42.293564 ], [ 20.566406, 42.228517 ], [ 20.566406, 41.836828 ], [ 20.478516, 41.508577 ], [ 20.566406, 41.112469 ], [ 21.005859, 40.847060 ], [ 21.005859, 40.580585 ], [ 20.654297, 40.446947 ], [ 20.654297, 40.111689 ], [ 20.126953, 39.639538 ], [ 19.951172, 39.707187 ], [ 19.951172, 39.909736 ], [ 19.423828, 40.245992 ], [ 19.335938, 40.713956 ], [ 19.423828, 41.376809 ], [ 19.511719, 41.705729 ], [ 19.335938, 41.902277 ], [ 19.335938, 42.163403 ], [ 19.775391, 42.682435 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 20.302734, 42.875964 ], [ 19.951172, 43.133061 ], [ 19.599609, 43.197167 ], [ 19.511719, 43.325178 ], [ 19.248047, 43.516689 ], [ 19.423828, 43.580391 ], [ 19.599609, 44.024422 ], [ 19.160156, 44.402392 ], [ 19.335938, 44.840291 ], [ 18.984375, 44.840291 ], [ 19.423828, 45.213004 ], [ 19.072266, 45.521744 ], [ 18.808594, 45.890008 ], [ 19.599609, 46.195042 ], [ 20.214844, 46.134170 ], [ 20.742188, 45.706179 ], [ 20.917969, 45.398450 ], [ 21.445312, 45.151053 ], [ 21.533203, 44.777936 ], [ 22.148438, 44.465151 ], [ 22.500000, 44.715514 ], [ 22.675781, 44.590467 ], [ 22.500000, 44.402392 ], [ 22.675781, 44.213710 ], [ 22.412109, 44.024422 ], [ 22.500000, 43.644026 ], [ 23.027344, 43.197167 ], [ 22.587891, 42.875964 ], [ 22.412109, 42.553080 ], [ 22.587891, 42.488302 ], [ 22.412109, 42.293564 ], [ 21.884766, 42.293564 ], [ 21.533203, 42.228517 ], [ 21.533203, 42.293564 ], [ 21.796875, 42.682435 ], [ 21.621094, 42.682435 ], [ 21.445312, 42.875964 ], [ 21.269531, 42.940339 ], [ 21.181641, 43.068888 ], [ 20.917969, 43.133061 ], [ 20.830078, 43.261206 ], [ 20.654297, 43.197167 ], [ 20.478516, 42.875964 ], [ 20.302734, 42.875964 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 25.664062, 50.007739 ], [ 25.664062, 47.931066 ], [ 25.224609, 47.872144 ], [ 24.873047, 47.754098 ], [ 24.433594, 47.989922 ], [ 23.730469, 47.989922 ], [ 23.115234, 48.107431 ], [ 22.675781, 47.872144 ], [ 22.675781, 48.166085 ], [ 22.060547, 48.400032 ], [ 22.324219, 48.806863 ], [ 22.587891, 49.095452 ], [ 22.763672, 49.037868 ], [ 22.500000, 49.496675 ], [ 23.115234, 50.007739 ], [ 25.664062, 50.007739 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 20.830078, 48.632909 ], [ 21.884766, 48.341646 ], [ 22.060547, 48.400032 ], [ 22.675781, 48.166085 ], [ 22.675781, 47.872144 ], [ 22.060547, 47.694974 ], [ 21.621094, 46.980252 ], [ 21.005859, 46.316584 ], [ 20.214844, 46.134170 ], [ 19.599609, 46.195042 ], [ 18.808594, 45.890008 ], [ 18.457031, 45.767523 ], [ 17.666016, 45.951150 ], [ 16.875000, 46.377254 ], [ 16.523438, 46.498392 ], [ 16.347656, 46.860191 ], [ 16.171875, 46.860191 ], [ 16.523438, 47.517201 ], [ 16.347656, 47.694974 ], [ 16.875000, 47.694974 ], [ 16.962891, 48.107431 ], [ 17.490234, 47.872144 ], [ 17.841797, 47.754098 ], [ 18.720703, 47.872144 ], [ 18.808594, 48.107431 ], [ 19.160156, 48.107431 ], [ 19.687500, 48.283193 ], [ 19.775391, 48.224673 ], [ 20.214844, 48.341646 ], [ 20.478516, 48.574790 ], [ 20.830078, 48.632909 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 23.730469, 35.675147 ], [ 24.257812, 35.389050 ], [ 25.048828, 35.460670 ], [ 25.664062, 35.389050 ], [ 25.664062, 34.957995 ], [ 24.697266, 34.885931 ], [ 24.697266, 35.101934 ], [ 23.554688, 35.245619 ], [ 23.730469, 35.675147 ] ] ], [ [ [ 24.521484, 41.574361 ], [ 25.224609, 41.244772 ], [ 25.664062, 41.310824 ], [ 25.664062, 40.847060 ], [ 25.488281, 40.847060 ], [ 24.960938, 40.979898 ], [ 23.730469, 40.713956 ], [ 24.433594, 40.111689 ], [ 23.906250, 39.977120 ], [ 23.378906, 39.977120 ], [ 22.851562, 40.446947 ], [ 22.587891, 40.245992 ], [ 22.851562, 39.639538 ], [ 23.378906, 39.164141 ], [ 22.939453, 38.959409 ], [ 23.554688, 38.479395 ], [ 23.994141, 38.203655 ], [ 24.082031, 37.649034 ], [ 23.115234, 37.926868 ], [ 23.378906, 37.439974 ], [ 22.763672, 37.300275 ], [ 23.115234, 36.456636 ], [ 22.500000, 36.385913 ], [ 21.708984, 36.879621 ], [ 21.269531, 37.649034 ], [ 21.093750, 38.341656 ], [ 20.214844, 39.368279 ], [ 20.126953, 39.639538 ], [ 20.654297, 40.111689 ], [ 20.654297, 40.446947 ], [ 21.005859, 40.580585 ], [ 21.005859, 40.847060 ], [ 21.708984, 40.913513 ], [ 22.060547, 41.178654 ], [ 22.587891, 41.112469 ], [ 22.763672, 41.310824 ], [ 23.730469, 41.310824 ], [ 24.521484, 41.574361 ] ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 22.675781, 44.213710 ], [ 22.939453, 43.834527 ], [ 23.291016, 43.897892 ], [ 24.082031, 43.771094 ], [ 25.576172, 43.707594 ], [ 25.664062, 43.771094 ], [ 25.664062, 41.310824 ], [ 25.224609, 41.244772 ], [ 24.521484, 41.574361 ], [ 23.730469, 41.310824 ], [ 22.939453, 41.310824 ], [ 22.851562, 41.967659 ], [ 22.412109, 42.293564 ], [ 22.587891, 42.488302 ], [ 22.412109, 42.553080 ], [ 22.587891, 42.875964 ], [ 23.027344, 43.197167 ], [ 22.500000, 43.644026 ], [ 22.412109, 44.024422 ], [ 22.675781, 44.213710 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 23.115234, 48.107431 ], [ 23.730469, 47.989922 ], [ 24.433594, 47.989922 ], [ 24.873047, 47.754098 ], [ 25.224609, 47.872144 ], [ 25.664062, 47.931066 ], [ 25.664062, 43.771094 ], [ 25.576172, 43.707594 ], [ 24.082031, 43.771094 ], [ 23.291016, 43.897892 ], [ 22.939453, 43.834527 ], [ 22.675781, 44.213710 ], [ 22.500000, 44.402392 ], [ 22.675781, 44.590467 ], [ 22.500000, 44.715514 ], [ 22.148438, 44.465151 ], [ 21.533203, 44.777936 ], [ 21.445312, 45.151053 ], [ 20.917969, 45.398450 ], [ 20.742188, 45.706179 ], [ 20.214844, 46.134170 ], [ 21.005859, 46.316584 ], [ 21.621094, 46.980252 ], [ 22.060547, 47.694974 ], [ 22.675781, 47.872144 ], [ 23.115234, 48.107431 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 9.492188, 37.370157 ], [ 10.195312, 37.230328 ], [ 10.195312, 36.738884 ], [ 10.986328, 37.090240 ], [ 11.074219, 36.879621 ], [ 10.634766, 36.385913 ], [ 10.634766, 35.960223 ], [ 10.898438, 35.675147 ], [ 10.810547, 34.813803 ], [ 10.107422, 34.307144 ], [ 10.371094, 33.797409 ], [ 10.898438, 33.797409 ], [ 11.074219, 33.284620 ], [ 11.513672, 33.137551 ], [ 11.425781, 32.398516 ], [ 10.986328, 32.101190 ], [ 10.634766, 31.728167 ], [ 9.931641, 31.353637 ], [ 10.019531, 30.977609 ], [ 9.931641, 30.524413 ], [ 9.492188, 30.297018 ], [ 9.052734, 32.101190 ], [ 8.437500, 32.472695 ], [ 8.437500, 32.768800 ], [ 7.646484, 33.358062 ], [ 7.558594, 34.089061 ], [ 8.173828, 34.669359 ], [ 8.349609, 35.460670 ], [ 8.261719, 36.456636 ], [ 8.437500, 36.949892 ], [ 9.492188, 37.370157 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 7.294922, 37.090240 ], [ 7.734375, 36.879621 ], [ 8.437500, 36.949892 ], [ 8.261719, 36.456636 ], [ 8.349609, 35.460670 ], [ 8.173828, 34.669359 ], [ 7.558594, 34.089061 ], [ 7.646484, 33.358062 ], [ 8.437500, 32.768800 ], [ 8.437500, 32.472695 ], [ 9.052734, 32.101190 ], [ 9.492188, 30.297018 ], [ 9.843750, 29.458731 ], [ 9.843750, 28.921631 ], [ 9.667969, 28.149503 ], [ 9.755859, 27.683528 ], [ 9.667969, 27.137368 ], [ 9.755859, 26.509905 ], [ 9.316406, 26.115986 ], [ 9.931641, 25.403585 ], [ 9.931641, 24.926295 ], [ 10.283203, 24.367114 ], [ 10.810547, 24.527135 ], [ 11.601562, 24.126702 ], [ 12.041016, 23.483401 ], [ 8.613281, 21.534847 ], [ 5.712891, 19.642588 ], [ 5.009766, 19.394068 ], [ 5.009766, 36.809285 ], [ 5.361328, 36.738884 ], [ 6.240234, 37.090240 ], [ 7.294922, 37.090240 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 15.556641, 38.203655 ], [ 15.117188, 37.439974 ], [ 15.292969, 37.160317 ], [ 15.117188, 36.597889 ], [ 14.326172, 37.020098 ], [ 13.798828, 37.090240 ], [ 12.392578, 37.579413 ], [ 12.568359, 38.134557 ], [ 13.710938, 38.065392 ], [ 14.765625, 38.134557 ], [ 15.556641, 38.203655 ] ] ], [ [ [ 12.128906, 47.100045 ], [ 12.392578, 46.739861 ], [ 13.798828, 46.498392 ], [ 13.710938, 46.012224 ], [ 13.974609, 45.583290 ], [ 13.183594, 45.706179 ], [ 12.304688, 45.398450 ], [ 12.392578, 44.902578 ], [ 12.304688, 44.590467 ], [ 12.568359, 44.087585 ], [ 13.535156, 43.580391 ], [ 14.062500, 42.747012 ], [ 15.117188, 41.967659 ], [ 15.908203, 41.967659 ], [ 16.171875, 41.771312 ], [ 15.908203, 41.508577 ], [ 16.787109, 41.178654 ], [ 17.490234, 40.847060 ], [ 18.369141, 40.380028 ], [ 18.457031, 40.178873 ], [ 18.281250, 39.842286 ], [ 17.753906, 40.245992 ], [ 16.875000, 40.446947 ], [ 16.435547, 39.774769 ], [ 17.138672, 39.436193 ], [ 17.050781, 38.891033 ], [ 16.611328, 38.822591 ], [ 16.083984, 37.996163 ], [ 15.644531, 37.926868 ], [ 15.644531, 38.203655 ], [ 15.908203, 38.754083 ], [ 16.083984, 38.959409 ], [ 15.732422, 39.571822 ], [ 15.380859, 40.044438 ], [ 15.029297, 40.178873 ], [ 14.677734, 40.580585 ], [ 14.062500, 40.780541 ], [ 13.623047, 41.178654 ], [ 12.919922, 41.244772 ], [ 12.128906, 41.705729 ], [ 11.162109, 42.358544 ], [ 10.546875, 42.940339 ], [ 10.195312, 43.897892 ], [ 9.667969, 44.024422 ], [ 8.876953, 44.339565 ], [ 8.437500, 44.213710 ], [ 7.822266, 43.771094 ], [ 7.470703, 43.707594 ], [ 7.558594, 44.150681 ], [ 7.031250, 44.276671 ], [ 6.767578, 45.026950 ], [ 7.119141, 45.336702 ], [ 6.767578, 45.706179 ], [ 6.855469, 46.012224 ], [ 7.294922, 45.767523 ], [ 7.734375, 45.828799 ], [ 8.349609, 46.134170 ], [ 8.525391, 46.012224 ], [ 8.964844, 46.012224 ], [ 9.140625, 46.437857 ], [ 9.931641, 46.316584 ], [ 10.371094, 46.498392 ], [ 10.458984, 46.920255 ], [ 11.074219, 46.739861 ], [ 11.162109, 46.920255 ], [ 12.128906, 47.100045 ] ] ], [ [ [ 9.228516, 41.178654 ], [ 9.843750, 40.513799 ], [ 9.667969, 39.164141 ], [ 9.228516, 39.232253 ], [ 8.789062, 38.891033 ], [ 8.437500, 39.164141 ], [ 8.349609, 40.380028 ], [ 8.173828, 40.979898 ], [ 8.701172, 40.913513 ], [ 9.228516, 41.178654 ] ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 22.412109, 42.293564 ], [ 22.851562, 41.967659 ], [ 22.939453, 41.310824 ], [ 22.763672, 41.310824 ], [ 22.587891, 41.112469 ], [ 22.060547, 41.178654 ], [ 21.708984, 40.913513 ], [ 21.005859, 40.847060 ], [ 20.566406, 41.112469 ], [ 20.478516, 41.508577 ], [ 20.566406, 41.836828 ], [ 20.742188, 41.836828 ], [ 20.742188, 42.032974 ], [ 21.357422, 42.228517 ], [ 21.533203, 42.228517 ], [ 21.884766, 42.293564 ], [ 22.412109, 42.293564 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 11.513672, 33.137551 ], [ 12.656250, 32.768800 ], [ 13.095703, 32.842674 ], [ 13.886719, 32.694866 ], [ 15.205078, 32.249974 ], [ 15.732422, 31.353637 ], [ 16.611328, 31.203405 ], [ 18.017578, 30.751278 ], [ 19.072266, 30.297018 ], [ 19.599609, 30.524413 ], [ 20.039062, 30.977609 ], [ 19.863281, 31.728167 ], [ 20.126953, 32.249974 ], [ 20.830078, 32.694866 ], [ 21.533203, 32.842674 ], [ 22.939453, 32.620870 ], [ 23.203125, 32.175612 ], [ 23.642578, 32.175612 ], [ 23.906250, 32.026706 ], [ 24.960938, 31.877558 ], [ 25.136719, 31.578535 ], [ 24.785156, 31.052934 ], [ 24.960938, 30.675715 ], [ 24.697266, 30.069094 ], [ 24.960938, 29.228890 ], [ 24.960938, 19.973349 ], [ 23.818359, 19.973349 ], [ 23.818359, 19.559790 ], [ 19.863281, 21.534847 ], [ 15.820312, 23.402765 ], [ 14.853516, 22.836946 ], [ 14.150391, 22.512557 ], [ 13.623047, 23.079732 ], [ 12.041016, 23.483401 ], [ 11.601562, 24.126702 ], [ 10.810547, 24.527135 ], [ 10.283203, 24.367114 ], [ 9.931641, 24.926295 ], [ 9.931641, 25.403585 ], [ 9.316406, 26.115986 ], [ 9.755859, 26.509905 ], [ 9.667969, 27.137368 ], [ 9.755859, 27.683528 ], [ 9.667969, 28.149503 ], [ 9.843750, 28.921631 ], [ 9.843750, 29.458731 ], [ 9.492188, 30.297018 ], [ 9.931641, 30.524413 ], [ 10.019531, 30.977609 ], [ 9.931641, 31.353637 ], [ 10.634766, 31.728167 ], [ 10.986328, 32.101190 ], [ 11.425781, 32.398516 ], [ 11.513672, 33.137551 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 12.041016, 23.483401 ], [ 13.623047, 23.079732 ], [ 14.150391, 22.512557 ], [ 14.853516, 22.836946 ], [ 15.117188, 21.289374 ], [ 15.468750, 21.043491 ], [ 15.468750, 20.715015 ], [ 15.908203, 20.385825 ], [ 15.644531, 19.973349 ], [ 15.292969, 17.895114 ], [ 15.205078, 16.636192 ], [ 13.974609, 15.707663 ], [ 13.535156, 14.349548 ], [ 13.974609, 14.008696 ], [ 13.974609, 13.325485 ], [ 14.589844, 13.325485 ], [ 14.501953, 12.897489 ], [ 14.238281, 12.811801 ], [ 14.150391, 12.468760 ], [ 13.974609, 12.468760 ], [ 13.359375, 13.581921 ], [ 13.095703, 13.581921 ], [ 12.304688, 13.068777 ], [ 11.513672, 13.325485 ], [ 10.986328, 13.410994 ], [ 10.722656, 13.239945 ], [ 10.107422, 13.239945 ], [ 9.492188, 12.811801 ], [ 9.052734, 12.811801 ], [ 7.822266, 13.325485 ], [ 7.294922, 13.068777 ], [ 6.855469, 13.154376 ], [ 6.416016, 13.496473 ], [ 5.449219, 13.838080 ], [ 5.009766, 13.838080 ], [ 5.009766, 19.394068 ], [ 5.712891, 19.642588 ], [ 8.613281, 21.534847 ], [ 12.041016, 23.483401 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 5.449219, 13.838080 ], [ 6.416016, 13.496473 ], [ 6.855469, 13.154376 ], [ 7.294922, 13.068777 ], [ 7.822266, 13.325485 ], [ 9.052734, 12.811801 ], [ 9.492188, 12.811801 ], [ 10.107422, 13.239945 ], [ 10.722656, 13.239945 ], [ 10.986328, 13.410994 ], [ 11.513672, 13.325485 ], [ 12.304688, 13.068777 ], [ 13.095703, 13.581921 ], [ 13.359375, 13.581921 ], [ 13.974609, 12.468760 ], [ 14.150391, 12.468760 ], [ 14.589844, 12.125264 ], [ 14.414062, 11.609193 ], [ 13.535156, 10.833306 ], [ 13.271484, 10.141932 ], [ 13.183594, 9.622414 ], [ 12.919922, 9.449062 ], [ 12.744141, 8.754795 ], [ 12.216797, 8.320212 ], [ 12.041016, 7.798079 ], [ 11.865234, 7.362467 ], [ 11.777344, 7.013668 ], [ 11.074219, 6.664608 ], [ 10.458984, 7.013668 ], [ 10.107422, 7.013668 ], [ 9.492188, 6.489983 ], [ 9.228516, 6.402648 ], [ 8.789062, 5.441022 ], [ 8.613281, 5.003394 ], [ 5.273438, 5.003394 ], [ 5.009766, 5.615986 ], [ 5.009766, 13.838080 ], [ 5.449219, 13.838080 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 14.501953, 12.897489 ], [ 14.853516, 12.211180 ], [ 14.941406, 11.523088 ], [ 14.941406, 10.919618 ], [ 15.468750, 9.968851 ], [ 14.941406, 9.968851 ], [ 14.589844, 9.882275 ], [ 14.150391, 10.055403 ], [ 13.974609, 9.535749 ], [ 14.501953, 8.928487 ], [ 14.941406, 8.754795 ], [ 15.468750, 7.710992 ], [ 15.292969, 7.449624 ], [ 14.765625, 6.402648 ], [ 14.501953, 6.227934 ], [ 14.501953, 5.441022 ], [ 14.589844, 5.003394 ], [ 8.613281, 5.003394 ], [ 8.789062, 5.441022 ], [ 9.228516, 6.402648 ], [ 9.492188, 6.489983 ], [ 10.107422, 7.013668 ], [ 10.458984, 7.013668 ], [ 11.074219, 6.664608 ], [ 11.777344, 7.013668 ], [ 11.865234, 7.362467 ], [ 12.041016, 7.798079 ], [ 12.216797, 8.320212 ], [ 12.744141, 8.754795 ], [ 12.919922, 9.449062 ], [ 13.183594, 9.622414 ], [ 13.271484, 10.141932 ], [ 13.535156, 10.833306 ], [ 14.414062, 11.609193 ], [ 14.589844, 12.125264 ], [ 14.150391, 12.468760 ], [ 14.238281, 12.811801 ], [ 14.501953, 12.897489 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 22.851562, 11.178402 ], [ 22.939453, 10.746969 ], [ 23.554688, 10.055403 ], [ 23.554688, 9.709057 ], [ 23.378906, 9.275622 ], [ 23.466797, 8.928487 ], [ 23.818359, 8.667918 ], [ 24.609375, 8.233237 ], [ 25.136719, 7.798079 ], [ 25.136719, 7.536764 ], [ 25.664062, 7.013668 ], [ 25.664062, 5.266008 ], [ 25.312500, 5.178482 ], [ 25.136719, 5.003394 ], [ 24.609375, 5.003394 ], [ 24.433594, 5.090944 ], [ 24.169922, 5.003394 ], [ 14.589844, 5.003394 ], [ 14.501953, 5.441022 ], [ 14.501953, 6.227934 ], [ 14.765625, 6.402648 ], [ 15.292969, 7.449624 ], [ 16.083984, 7.536764 ], [ 16.259766, 7.710992 ], [ 16.435547, 7.710992 ], [ 16.699219, 7.536764 ], [ 17.929688, 7.885147 ], [ 18.369141, 8.320212 ], [ 18.896484, 8.667918 ], [ 18.808594, 9.015302 ], [ 19.072266, 9.102097 ], [ 20.039062, 9.015302 ], [ 21.005859, 9.449062 ], [ 21.708984, 10.574222 ], [ 22.236328, 11.005904 ], [ 22.851562, 11.178402 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 25.664062, 31.578535 ], [ 25.664062, 22.024546 ], [ 24.960938, 22.024546 ], [ 24.960938, 29.228890 ], [ 24.697266, 30.069094 ], [ 24.960938, 30.675715 ], [ 24.785156, 31.052934 ], [ 25.136719, 31.578535 ], [ 25.664062, 31.578535 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 15.820312, 23.402765 ], [ 19.863281, 21.534847 ], [ 23.818359, 19.559790 ], [ 23.906250, 15.623037 ], [ 23.027344, 15.707663 ], [ 22.587891, 14.944785 ], [ 22.324219, 14.349548 ], [ 22.500000, 14.093957 ], [ 22.148438, 13.752725 ], [ 22.324219, 13.410994 ], [ 22.060547, 12.983148 ], [ 21.972656, 12.554564 ], [ 22.324219, 12.640338 ], [ 22.500000, 12.297068 ], [ 22.500000, 11.695273 ], [ 22.851562, 11.350797 ], [ 22.851562, 11.178402 ], [ 22.236328, 11.005904 ], [ 21.708984, 10.574222 ], [ 21.005859, 9.449062 ], [ 20.039062, 9.015302 ], [ 19.072266, 9.102097 ], [ 18.808594, 9.015302 ], [ 18.896484, 8.667918 ], [ 18.369141, 8.320212 ], [ 17.929688, 7.885147 ], [ 16.699219, 7.536764 ], [ 16.435547, 7.710992 ], [ 16.259766, 7.710992 ], [ 16.083984, 7.536764 ], [ 15.292969, 7.449624 ], [ 15.468750, 7.710992 ], [ 14.941406, 8.754795 ], [ 14.501953, 8.928487 ], [ 13.974609, 9.535749 ], [ 14.150391, 10.055403 ], [ 14.589844, 9.882275 ], [ 14.941406, 9.968851 ], [ 15.468750, 9.968851 ], [ 14.941406, 10.919618 ], [ 14.941406, 11.523088 ], [ 14.853516, 12.211180 ], [ 14.501953, 12.897489 ], [ 14.589844, 13.325485 ], [ 13.974609, 13.325485 ], [ 13.974609, 14.008696 ], [ 13.535156, 14.349548 ], [ 13.974609, 15.707663 ], [ 15.205078, 16.636192 ], [ 15.292969, 17.895114 ], [ 15.644531, 19.973349 ], [ 15.908203, 20.385825 ], [ 15.468750, 20.715015 ], [ 15.468750, 21.043491 ], [ 15.117188, 21.289374 ], [ 14.853516, 22.836946 ], [ 15.820312, 23.402765 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 25.664062, 22.024546 ], [ 25.664062, 10.401378 ], [ 25.048828, 10.314919 ], [ 24.785156, 9.795678 ], [ 24.521484, 8.928487 ], [ 24.169922, 8.754795 ], [ 23.906250, 8.581021 ], [ 23.818359, 8.667918 ], [ 23.466797, 8.928487 ], [ 23.378906, 9.275622 ], [ 23.554688, 9.709057 ], [ 23.554688, 10.055403 ], [ 22.939453, 10.746969 ], [ 22.851562, 11.178402 ], [ 22.851562, 11.350797 ], [ 22.500000, 11.695273 ], [ 22.500000, 12.297068 ], [ 22.324219, 12.640338 ], [ 21.972656, 12.554564 ], [ 22.060547, 12.983148 ], [ 22.324219, 13.410994 ], [ 22.148438, 13.752725 ], [ 22.500000, 14.093957 ], [ 22.324219, 14.349548 ], [ 22.587891, 14.944785 ], [ 23.027344, 15.707663 ], [ 23.906250, 15.623037 ], [ 23.818359, 19.559790 ], [ 23.818359, 19.973349 ], [ 24.960938, 19.973349 ], [ 24.960938, 22.024546 ], [ 25.664062, 22.024546 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 25.664062, 10.401378 ], [ 25.664062, 7.013668 ], [ 25.136719, 7.536764 ], [ 25.136719, 7.798079 ], [ 24.609375, 8.233237 ], [ 23.906250, 8.581021 ], [ 24.169922, 8.754795 ], [ 24.521484, 8.928487 ], [ 24.785156, 9.795678 ], [ 25.048828, 10.314919 ], [ 25.664062, 10.401378 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 24.433594, 5.090944 ], [ 24.609375, 5.003394 ], [ 24.169922, 5.003394 ], [ 24.433594, 5.090944 ] ] ], [ [ [ 25.136719, 5.003394 ], [ 25.312500, 5.178482 ], [ 25.664062, 5.266008 ], [ 25.664062, 5.003394 ], [ 25.136719, 5.003394 ] ] ] ] } } +] } +] } From 30e5a5ce9b3fb9495c322e8739dc2f7a2468c18d Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Tue, 19 Nov 2024 09:19:44 -0800 Subject: [PATCH 04/24] Fix post-binning clipping --- Makefile | 5 ++ clip.cpp | 18 +++++-- tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json | 53 +++++++++++++++++++++ 3 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json diff --git a/Makefile b/Makefile index b0b6ae6c..57c81d1d 100644 --- a/Makefile +++ b/Makefile @@ -396,6 +396,11 @@ overzoom-test: tippecanoe-overzoom ./tippecanoe-decode tests/pbf/0-0-0-pop-0-0-0.pbf.out 0 0 0 > tests/pbf/0-0-0-pop-0-0-0.pbf.out.json.check cmp tests/pbf/0-0-0-pop-0-0-0.pbf.out.json.check tests/pbf/0-0-0-pop-0-0-0.pbf.out.json rm tests/pbf/0-0-0-pop-0-0-0.pbf.out tests/pbf/0-0-0-pop-0-0-0.pbf.out.json.check + # Binning, clipping to bounding box + ./tippecanoe-overzoom --clip-bounding-box 88,67.5,138,78 -o tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out --accumulate-numeric-attributes=tippecanoe --assign-to-bins tests/pbf/h3-1-1-0.geojson tests/pbf/0-0-0.pbf 1/1/0 1/1/0 + ./tippecanoe-decode tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out 1 1 0 > tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json.check + cmp tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json.check tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json + rm tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json.check # Verify fix for crash ./tippecanoe-overzoom '-o' tests/10188-crash/out.pbf '-t' '3/2/2' '--assign-to-bins' 'tests/10188-crash/bins.json' '--bin-by-id-list' 'felt:bin_features' '-b5' 'tests/10188-crash/2-0-0.pbf' '2/0/0' rm tests/10188-crash/out.pbf diff --git a/clip.cpp b/clip.cpp index a0ad12c7..e6975a03 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1348,16 +1348,26 @@ static bool feature_out(std::vector const &features, mvt_layer &ou } if (clipbboxes.size() != 0) { + // bounding box is in world coordinates at world scale + // feature is in local coordinates at tile scale + long long dx = (long long) nx << (32 - nz); long long dy = (long long) ny << (32 - nz); + double scale = (double) outlayer.extent / (1LL << (32 - nz)); + + for (auto const &c : clipbboxes) { + clipbbox local; + local.minx = std::llround((c.minx - dx) * scale); + local.miny = std::llround((c.miny - dy) * scale); + local.maxx = std::llround((c.maxx - dx) * scale); + local.maxy = std::llround((c.maxy - dy) * scale); - for (auto &c : clipbboxes) { if (t == VT_POLYGON) { - geom = simple_clip_poly(geom, c.minx - dx, c.miny - dy, c.maxx - dx, c.maxy - dy, false); + geom = simple_clip_poly(geom, local.minx, local.miny, local.maxx, local.maxy, false); } else if (t == VT_LINE) { - geom = clip_lines(geom, c.minx - dx, c.miny - dy, c.maxx - dx, c.maxy - dy); + geom = clip_lines(geom, local.minx, local.miny, local.maxx, local.maxy); } else if (t == VT_POINT) { - geom = clip_point(geom, c.minx - dx, c.miny - dy, c.maxx - dx, c.maxy - dy); + geom = clip_point(geom, local.minx, local.miny, local.maxx, local.maxy); } } diff --git a/tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json b/tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json new file mode 100644 index 00000000..b49113b7 --- /dev/null +++ b/tests/pbf/0-0-0-pop-1-1-0-clip.pbf.out.json @@ -0,0 +1,53 @@ +{ "type": "FeatureCollection", "properties": { "zoom": 1, "x": 1, "y": 0 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "ne_10m_admin_0_countries", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "bin": "820acffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 1, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 1, "tippecanoe:max:LABELRANK": 2, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 2, "tippecanoe:count:ADM0_DIF": 1, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 1, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 2, "tippecanoe:count:GEOU_DIF": 1, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 1, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 1, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 1, "tippecanoe:max:MAPCOLOR7": 5, "tippecanoe:min:MAPCOLOR7": 5, "tippecanoe:sum:MAPCOLOR7": 5, "tippecanoe:count:MAPCOLOR8": 1, "tippecanoe:max:MAPCOLOR8": 2, "tippecanoe:min:MAPCOLOR8": 2, "tippecanoe:sum:MAPCOLOR8": 2, "tippecanoe:count:MAPCOLOR9": 1, "tippecanoe:max:MAPCOLOR9": 7, "tippecanoe:min:MAPCOLOR9": 7, "tippecanoe:sum:MAPCOLOR9": 7, "tippecanoe:count:MAPCOLOR13": 1, "tippecanoe:max:MAPCOLOR13": 3, "tippecanoe:min:MAPCOLOR13": 3, "tippecanoe:sum:MAPCOLOR13": 3, "tippecanoe:count:POP_EST": 1, "tippecanoe:max:POP_EST": 52573973, "tippecanoe:min:POP_EST": 52573973, "tippecanoe:sum:POP_EST": 52573973, "tippecanoe:count:POP_RANK": 1, "tippecanoe:max:POP_RANK": 16, "tippecanoe:min:POP_RANK": 16, "tippecanoe:sum:POP_RANK": 16, "tippecanoe:count:POP_YEAR": 1, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 2019, "tippecanoe:count:GDP_MD": 1, "tippecanoe:max:GDP_MD": 95503, "tippecanoe:min:GDP_MD": 95503, "tippecanoe:sum:GDP_MD": 95503, "tippecanoe:count:GDP_YEAR": 1, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 2019, "tippecanoe:count:WOE_ID": 1, "tippecanoe:max:WOE_ID": 23424863, "tippecanoe:min:WOE_ID": 23424863, "tippecanoe:sum:WOE_ID": 23424863, "tippecanoe:count:WOE_ID_EH": 1, "tippecanoe:max:WOE_ID_EH": 23424863, "tippecanoe:min:WOE_ID_EH": 23424863, "tippecanoe:sum:WOE_ID_EH": 23424863, "tippecanoe:count:ADM0_A3_UN": 1, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -99, "tippecanoe:count:ADM0_A3_WB": 1, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -99, "tippecanoe:count:NAME_LEN": 1, "tippecanoe:max:NAME_LEN": 5, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 5, "tippecanoe:count:LONG_LEN": 1, "tippecanoe:max:LONG_LEN": 5, "tippecanoe:min:LONG_LEN": 5, "tippecanoe:sum:LONG_LEN": 5, "tippecanoe:count:ABBREV_LEN": 1, "tippecanoe:max:ABBREV_LEN": 4, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 4, "tippecanoe:count:TINY": 1, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -99, "tippecanoe:count:HOMEPART": 1, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 1, "tippecanoe:count:MIN_ZOOM": 1, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 1, "tippecanoe:max:MIN_LABEL": 1.7, "tippecanoe:min:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_LABEL": 1.7, "tippecanoe:count:MAX_LABEL": 1, "tippecanoe:max:MAX_LABEL": 6.7, "tippecanoe:min:MAX_LABEL": 6.7, "tippecanoe:sum:MAX_LABEL": 6.7, "tippecanoe:count:LABEL_X": 1, "tippecanoe:max:LABEL_X": 37.907632, "tippecanoe:min:LABEL_X": 37.907632, "tippecanoe:sum:LABEL_X": 37.907632, "tippecanoe:count:LABEL_Y": 1, "tippecanoe:max:LABEL_Y": 0.549043, "tippecanoe:min:LABEL_Y": 0.549043, "tippecanoe:sum:LABEL_Y": 0.549043, "tippecanoe:count:NE_ID": 1, "tippecanoe:max:NE_ID": 1159320971, "tippecanoe:min:NE_ID": 1159320971, "tippecanoe:sum:NE_ID": 1159320971, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 2, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 5, "tippecanoe:mean:MAPCOLOR8": 2, "tippecanoe:mean:MAPCOLOR9": 7, "tippecanoe:mean:MAPCOLOR13": 3, "tippecanoe:mean:POP_EST": 52573973, "tippecanoe:mean:POP_RANK": 16, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 95503, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424863, "tippecanoe:mean:WOE_ID_EH": 23424863, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 5, "tippecanoe:mean:LONG_LEN": 5, "tippecanoe:mean:ABBREV_LEN": 4, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 1.7, "tippecanoe:mean:MAX_LABEL": 6.7, "tippecanoe:mean:LABEL_X": 37.907632, "tippecanoe:mean:LABEL_Y": 0.549043, "tippecanoe:mean:NE_ID": 1159320971, "tippecanoe:count": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 111.093750, 67.776025 ], [ 115.751953, 67.759398 ], [ 116.103516, 67.491751 ], [ 110.742188, 67.491751 ], [ 111.093750, 67.776025 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "82009ffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 6, "tippecanoe:max:scalerank": 6, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 16, "tippecanoe:count:LABELRANK": 6, "tippecanoe:max:LABELRANK": 6, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 25, "tippecanoe:count:ADM0_DIF": 6, "tippecanoe:max:ADM0_DIF": 1, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 4, "tippecanoe:count:LEVEL": 6, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 12, "tippecanoe:count:GEOU_DIF": 6, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 6, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 6, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 6, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 2, "tippecanoe:sum:MAPCOLOR7": 27, "tippecanoe:count:MAPCOLOR8": 6, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 24, "tippecanoe:count:MAPCOLOR9": 6, "tippecanoe:max:MAPCOLOR9": 6, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 24, "tippecanoe:count:MAPCOLOR13": 6, "tippecanoe:max:MAPCOLOR13": 12, "tippecanoe:min:MAPCOLOR13": 2, "tippecanoe:sum:MAPCOLOR13": 31, "tippecanoe:count:POP_EST": 6, "tippecanoe:max:POP_EST": 66834405, "tippecanoe:min:POP_EST": 48678, "tippecanoe:sum:POP_EST": 83455958, "tippecanoe:count:POP_RANK": 6, "tippecanoe:max:POP_RANK": 16, "tippecanoe:min:POP_RANK": 7, "tippecanoe:sum:POP_RANK": 65, "tippecanoe:count:POP_YEAR": 6, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 12114, "tippecanoe:count:GDP_MD": 6, "tippecanoe:max:GDP_MD": 2829108, "tippecanoe:min:GDP_MD": 3116, "tippecanoe:sum:GDP_MD": 3764975, "tippecanoe:count:GDP_YEAR": 6, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2015, "tippecanoe:sum:GDP_YEAR": 12108, "tippecanoe:count:WOE_ID": 6, "tippecanoe:max:WOE_ID": 23424847, "tippecanoe:min:WOE_ID": -90, "tippecanoe:sum:WOE_ID": 117123960, "tippecanoe:count:WOE_ID_EH": 6, "tippecanoe:max:WOE_ID_EH": 23424975, "tippecanoe:min:WOE_ID_EH": 23424757, "tippecanoe:sum:WOE_ID_EH": 140549025, "tippecanoe:count:ADM0_A3_UN": 6, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -594, "tippecanoe:count:ADM0_A3_WB": 6, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -594, "tippecanoe:count:NAME_LEN": 6, "tippecanoe:max:NAME_LEN": 14, "tippecanoe:min:NAME_LEN": 7, "tippecanoe:sum:NAME_LEN": 57, "tippecanoe:count:LONG_LEN": 6, "tippecanoe:max:LONG_LEN": 14, "tippecanoe:min:LONG_LEN": 7, "tippecanoe:sum:LONG_LEN": 61, "tippecanoe:count:ABBREV_LEN": 6, "tippecanoe:max:ABBREV_LEN": 10, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 34, "tippecanoe:count:TINY": 6, "tippecanoe:max:TINY": 3, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -492, "tippecanoe:count:HOMEPART": 6, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": -99, "tippecanoe:sum:HOMEPART": -294, "tippecanoe:count:MIN_ZOOM": 6, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 6, "tippecanoe:max:MIN_LABEL": 5, "tippecanoe:min:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_LABEL": 22.7, "tippecanoe:count:MAX_LABEL": 6, "tippecanoe:max:MAX_LABEL": 10, "tippecanoe:min:MAX_LABEL": 6.7, "tippecanoe:sum:MAX_LABEL": 52.7, "tippecanoe:count:LABEL_X": 6, "tippecanoe:max:LABEL_X": 4.800448, "tippecanoe:min:LABEL_X": -7.798588, "tippecanoe:sum:LABEL_X": -19.26472, "tippecanoe:count:LABEL_Y": 6, "tippecanoe:max:LABEL_Y": 62.185604, "tippecanoe:min:LABEL_Y": 49.463533, "tippecanoe:sum:LABEL_Y": 324.136827, "tippecanoe:count:NE_ID": 6, "tippecanoe:max:NE_ID": 1159320877, "tippecanoe:min:NE_ID": 1159320389, "tippecanoe:sum:NE_ID": 6955923964, "tippecanoe:mean:scalerank": 2.6666666666666667, "tippecanoe:mean:LABELRANK": 4.166666666666667, "tippecanoe:mean:ADM0_DIF": 0.6666666666666666, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 4.5, "tippecanoe:mean:MAPCOLOR8": 4, "tippecanoe:mean:MAPCOLOR9": 4, "tippecanoe:mean:MAPCOLOR13": 5.166666666666667, "tippecanoe:mean:POP_EST": 13909326.333333334, "tippecanoe:mean:POP_RANK": 10.833333333333334, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 627495.8333333334, "tippecanoe:mean:GDP_YEAR": 2018, "tippecanoe:mean:WOE_ID": 19520660, "tippecanoe:mean:WOE_ID_EH": 23424837.5, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 9.5, "tippecanoe:mean:LONG_LEN": 10.166666666666666, "tippecanoe:mean:ABBREV_LEN": 5.666666666666667, "tippecanoe:mean:TINY": -82, "tippecanoe:mean:HOMEPART": -49, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3.783333333333333, "tippecanoe:mean:MAX_LABEL": 8.783333333333334, "tippecanoe:mean:LABEL_X": -3.210786666666667, "tippecanoe:mean:LABEL_Y": 54.0228045, "tippecanoe:mean:NE_ID": 1159320660.6666668, "tippecanoe:count": 6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 94.877930, 77.998190 ], [ 95.537109, 77.888038 ], [ 94.130859, 76.163993 ], [ 87.978516, 75.530136 ], [ 87.978516, 77.998190 ], [ 94.877930, 77.998190 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820aeffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 5, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 5, "tippecanoe:max:LABELRANK": 3, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 14, "tippecanoe:count:ADM0_DIF": 5, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 5, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 10, "tippecanoe:count:GEOU_DIF": 5, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 5, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 5, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 5, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 19, "tippecanoe:count:MAPCOLOR8": 5, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 2, "tippecanoe:sum:MAPCOLOR8": 18, "tippecanoe:count:MAPCOLOR9": 5, "tippecanoe:max:MAPCOLOR9": 6, "tippecanoe:min:MAPCOLOR9": 2, "tippecanoe:sum:MAPCOLOR9": 18, "tippecanoe:count:MAPCOLOR13": 5, "tippecanoe:max:MAPCOLOR13": 10, "tippecanoe:min:MAPCOLOR13": 2, "tippecanoe:sum:MAPCOLOR13": 28, "tippecanoe:count:POP_EST": 5, "tippecanoe:max:POP_EST": 86790567, "tippecanoe:min:POP_EST": 11062113, "tippecanoe:sum:POP_EST": 212754687, "tippecanoe:count:POP_RANK": 5, "tippecanoe:max:POP_RANK": 16, "tippecanoe:min:POP_RANK": 14, "tippecanoe:sum:POP_RANK": 75, "tippecanoe:count:POP_YEAR": 5, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 10095, "tippecanoe:count:GDP_MD": 5, "tippecanoe:max:GDP_MD": 63177, "tippecanoe:min:GDP_MD": 10354, "tippecanoe:sum:GDP_MD": 171094, "tippecanoe:count:GDP_YEAR": 5, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2015, "tippecanoe:sum:GDP_YEAR": 10091, "tippecanoe:count:WOE_ID": 5, "tippecanoe:max:WOE_ID": 23424974, "tippecanoe:min:WOE_ID": -99, "tippecanoe:sum:WOE_ID": 93699565, "tippecanoe:count:WOE_ID_EH": 5, "tippecanoe:max:WOE_ID_EH": 23424974, "tippecanoe:min:WOE_ID_EH": -99, "tippecanoe:sum:WOE_ID_EH": 93699565, "tippecanoe:count:ADM0_A3_UN": 5, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -495, "tippecanoe:count:ADM0_A3_WB": 5, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -495, "tippecanoe:count:NAME_LEN": 5, "tippecanoe:max:NAME_LEN": 15, "tippecanoe:min:NAME_LEN": 6, "tippecanoe:sum:NAME_LEN": 43, "tippecanoe:count:LONG_LEN": 5, "tippecanoe:max:LONG_LEN": 32, "tippecanoe:min:LONG_LEN": 6, "tippecanoe:sum:LONG_LEN": 63, "tippecanoe:count:ABBREV_LEN": 5, "tippecanoe:max:ABBREV_LEN": 7, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 26, "tippecanoe:count:TINY": 5, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -495, "tippecanoe:count:HOMEPART": 5, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 5, "tippecanoe:count:MIN_ZOOM": 5, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 5, "tippecanoe:max:MIN_LABEL": 3, "tippecanoe:min:MIN_LABEL": 2, "tippecanoe:sum:MIN_LABEL": 14, "tippecanoe:count:MAX_LABEL": 5, "tippecanoe:max:MAX_LABEL": 8, "tippecanoe:min:MAX_LABEL": 7, "tippecanoe:sum:MAX_LABEL": 39, "tippecanoe:count:LABEL_X": 5, "tippecanoe:max:LABEL_X": 34.959183, "tippecanoe:min:LABEL_X": 23.458829, "tippecanoe:sum:LABEL_X": 151.860612, "tippecanoe:count:LABEL_Y": 5, "tippecanoe:max:LABEL_Y": 7.230477, "tippecanoe:min:LABEL_Y": -6.051866, "tippecanoe:sum:LABEL_Y": -0.6041630000000007, "tippecanoe:count:NE_ID": 5, "tippecanoe:max:NE_ID": 1159321343, "tippecanoe:min:NE_ID": 1159320513, "tippecanoe:sum:NE_ID": 5796605647, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 2.8, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3.8, "tippecanoe:mean:MAPCOLOR8": 3.6, "tippecanoe:mean:MAPCOLOR9": 3.6, "tippecanoe:mean:MAPCOLOR13": 5.6, "tippecanoe:mean:POP_EST": 42550937.4, "tippecanoe:mean:POP_RANK": 15, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 34218.8, "tippecanoe:mean:GDP_YEAR": 2018.2, "tippecanoe:mean:WOE_ID": 18739913, "tippecanoe:mean:WOE_ID_EH": 18739913, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 8.6, "tippecanoe:mean:LONG_LEN": 12.6, "tippecanoe:mean:ABBREV_LEN": 5.2, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 2.8, "tippecanoe:mean:MAX_LABEL": 7.8, "tippecanoe:mean:LABEL_X": 30.372122400000003, "tippecanoe:mean:LABEL_Y": -0.12083260000000014, "tippecanoe:mean:NE_ID": 1159321129.4, "tippecanoe:count": 5 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 108.413086, 69.224997 ], [ 111.093750, 67.776025 ], [ 110.742188, 67.491751 ], [ 102.216797, 67.491751 ], [ 103.579102, 69.021414 ], [ 108.413086, 69.224997 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820527fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 2, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 2, "tippecanoe:max:LABELRANK": 3, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 6, "tippecanoe:count:ADM0_DIF": 2, "tippecanoe:max:ADM0_DIF": 1, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 1, "tippecanoe:count:LEVEL": 2, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 4, "tippecanoe:count:GEOU_DIF": 2, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 2, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 2, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 2, "tippecanoe:max:MAPCOLOR7": 5, "tippecanoe:min:MAPCOLOR7": 4, "tippecanoe:sum:MAPCOLOR7": 9, "tippecanoe:count:MAPCOLOR8": 2, "tippecanoe:max:MAPCOLOR8": 3, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 4, "tippecanoe:count:MAPCOLOR9": 2, "tippecanoe:max:MAPCOLOR9": 8, "tippecanoe:min:MAPCOLOR9": 4, "tippecanoe:sum:MAPCOLOR9": 12, "tippecanoe:count:MAPCOLOR13": 2, "tippecanoe:max:MAPCOLOR13": 12, "tippecanoe:min:MAPCOLOR13": 6, "tippecanoe:sum:MAPCOLOR13": 18, "tippecanoe:count:POP_EST": 2, "tippecanoe:max:POP_EST": 5520314, "tippecanoe:min:POP_EST": 5347896, "tippecanoe:sum:POP_EST": 10868210, "tippecanoe:count:POP_RANK": 2, "tippecanoe:max:POP_RANK": 13, "tippecanoe:min:POP_RANK": 13, "tippecanoe:sum:POP_RANK": 26, "tippecanoe:count:POP_YEAR": 2, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 4038, "tippecanoe:count:GDP_MD": 2, "tippecanoe:max:GDP_MD": 403336, "tippecanoe:min:GDP_MD": 269296, "tippecanoe:sum:GDP_MD": 672632, "tippecanoe:count:GDP_YEAR": 2, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 4038, "tippecanoe:count:WOE_ID": 2, "tippecanoe:max:WOE_ID": 23424812, "tippecanoe:min:WOE_ID": -90, "tippecanoe:sum:WOE_ID": 23424722, "tippecanoe:count:WOE_ID_EH": 2, "tippecanoe:max:WOE_ID_EH": 23424910, "tippecanoe:min:WOE_ID_EH": 23424812, "tippecanoe:sum:WOE_ID_EH": 46849722, "tippecanoe:count:ADM0_A3_UN": 2, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -198, "tippecanoe:count:ADM0_A3_WB": 2, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -198, "tippecanoe:count:NAME_LEN": 2, "tippecanoe:max:NAME_LEN": 7, "tippecanoe:min:NAME_LEN": 6, "tippecanoe:sum:NAME_LEN": 13, "tippecanoe:count:LONG_LEN": 2, "tippecanoe:max:LONG_LEN": 7, "tippecanoe:min:LONG_LEN": 6, "tippecanoe:sum:LONG_LEN": 13, "tippecanoe:count:ABBREV_LEN": 2, "tippecanoe:max:ABBREV_LEN": 4, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 8, "tippecanoe:count:TINY": 2, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -198, "tippecanoe:count:HOMEPART": 2, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 2, "tippecanoe:count:MIN_ZOOM": 2, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 2, "tippecanoe:max:MIN_LABEL": 3, "tippecanoe:min:MIN_LABEL": 3, "tippecanoe:sum:MIN_LABEL": 6, "tippecanoe:count:MAX_LABEL": 2, "tippecanoe:max:MAX_LABEL": 8, "tippecanoe:min:MAX_LABEL": 7, "tippecanoe:sum:MAX_LABEL": 15, "tippecanoe:count:LABEL_X": 2, "tippecanoe:max:LABEL_X": 27.276449, "tippecanoe:min:LABEL_X": 9.679975, "tippecanoe:sum:LABEL_X": 36.956424, "tippecanoe:count:LABEL_Y": 2, "tippecanoe:max:LABEL_Y": 63.252361, "tippecanoe:min:LABEL_Y": 61.357092, "tippecanoe:sum:LABEL_Y": 124.609453, "tippecanoe:count:NE_ID": 2, "tippecanoe:max:NE_ID": 1159321109, "tippecanoe:min:NE_ID": 1159320623, "tippecanoe:sum:NE_ID": 2318641732, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 3, "tippecanoe:mean:ADM0_DIF": 0.5, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 4.5, "tippecanoe:mean:MAPCOLOR8": 2, "tippecanoe:mean:MAPCOLOR9": 6, "tippecanoe:mean:MAPCOLOR13": 9, "tippecanoe:mean:POP_EST": 5434105, "tippecanoe:mean:POP_RANK": 13, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 336316, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 11712361, "tippecanoe:mean:WOE_ID_EH": 23424861, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 6.5, "tippecanoe:mean:LONG_LEN": 6.5, "tippecanoe:mean:ABBREV_LEN": 4, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3, "tippecanoe:mean:MAX_LABEL": 7.5, "tippecanoe:mean:LABEL_X": 18.478212, "tippecanoe:mean:LABEL_Y": 62.3047265, "tippecanoe:mean:NE_ID": 1159320866, "tippecanoe:count": 2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 97.558594, 77.998190 ], [ 95.537109, 77.888038 ], [ 94.877930, 77.998190 ], [ 97.558594, 77.998190 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a0ffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 4, "tippecanoe:max:scalerank": 3, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 3, "tippecanoe:count:LABELRANK": 4, "tippecanoe:max:LABELRANK": 6, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 16, "tippecanoe:count:ADM0_DIF": 4, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 4, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 8, "tippecanoe:count:GEOU_DIF": 4, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 4, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 4, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 4, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 14, "tippecanoe:count:MAPCOLOR8": 4, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 11, "tippecanoe:count:MAPCOLOR9": 4, "tippecanoe:max:MAPCOLOR9": 5, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 15, "tippecanoe:count:MAPCOLOR13": 4, "tippecanoe:max:MAPCOLOR13": 8, "tippecanoe:min:MAPCOLOR13": 2, "tippecanoe:sum:MAPCOLOR13": 22, "tippecanoe:count:POP_EST": 4, "tippecanoe:max:POP_EST": 200963599, "tippecanoe:min:POP_EST": 215056, "tippecanoe:sum:POP_EST": 204707220, "tippecanoe:count:POP_RANK": 4, "tippecanoe:max:POP_RANK": 17, "tippecanoe:min:POP_RANK": 10, "tippecanoe:sum:POP_RANK": 51, "tippecanoe:count:POP_YEAR": 4, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 8076, "tippecanoe:count:GDP_MD": 4, "tippecanoe:max:GDP_MD": 448120, "tippecanoe:min:GDP_MD": 418, "tippecanoe:sum:GDP_MD": 476438, "tippecanoe:count:GDP_YEAR": 4, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 8076, "tippecanoe:count:WOE_ID": 4, "tippecanoe:max:WOE_ID": 23424966, "tippecanoe:min:WOE_ID": 23424804, "tippecanoe:sum:WOE_ID": 93699500, "tippecanoe:count:WOE_ID_EH": 4, "tippecanoe:max:WOE_ID_EH": 23424966, "tippecanoe:min:WOE_ID_EH": 23424804, "tippecanoe:sum:WOE_ID_EH": 93699500, "tippecanoe:count:ADM0_A3_UN": 4, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -396, "tippecanoe:count:ADM0_A3_WB": 4, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -396, "tippecanoe:count:NAME_LEN": 4, "tippecanoe:max:NAME_LEN": 21, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 43, "tippecanoe:count:LONG_LEN": 4, "tippecanoe:max:LONG_LEN": 21, "tippecanoe:min:LONG_LEN": 5, "tippecanoe:sum:LONG_LEN": 50, "tippecanoe:count:ABBREV_LEN": 4, "tippecanoe:max:ABBREV_LEN": 7, "tippecanoe:min:ABBREV_LEN": 5, "tippecanoe:sum:ABBREV_LEN": 24, "tippecanoe:count:TINY": 4, "tippecanoe:max:TINY": 3, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -192, "tippecanoe:count:HOMEPART": 4, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 4, "tippecanoe:count:MIN_ZOOM": 4, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 4, "tippecanoe:max:MIN_LABEL": 5, "tippecanoe:min:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_LABEL": 13.7, "tippecanoe:count:MAX_LABEL": 4, "tippecanoe:max:MAX_LABEL": 10, "tippecanoe:min:MAX_LABEL": 6.7, "tippecanoe:sum:MAX_LABEL": 33.7, "tippecanoe:count:LABEL_X": 4, "tippecanoe:max:LABEL_X": 11.835939, "tippecanoe:min:LABEL_X": 7.021, "tippecanoe:sum:LABEL_X": 35.350359, "tippecanoe:count:LABEL_Y": 4, "tippecanoe:max:LABEL_Y": 9.439799, "tippecanoe:min:LABEL_Y": -0.437739, "tippecanoe:sum:LABEL_Y": 12.30596, "tippecanoe:count:NE_ID": 4, "tippecanoe:max:NE_ID": 1159321273, "tippecanoe:min:NE_ID": 1159320693, "tippecanoe:sum:NE_ID": 4637283856, "tippecanoe:mean:scalerank": 0.75, "tippecanoe:mean:LABELRANK": 4, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3.5, "tippecanoe:mean:MAPCOLOR8": 2.75, "tippecanoe:mean:MAPCOLOR9": 3.75, "tippecanoe:mean:MAPCOLOR13": 5.5, "tippecanoe:mean:POP_EST": 51176805, "tippecanoe:mean:POP_RANK": 12.75, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 119109.5, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424875, "tippecanoe:mean:WOE_ID_EH": 23424875, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 10.75, "tippecanoe:mean:LONG_LEN": 12.5, "tippecanoe:mean:ABBREV_LEN": 6, "tippecanoe:mean:TINY": -48, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3.425, "tippecanoe:mean:MAX_LABEL": 8.425, "tippecanoe:mean:LABEL_X": 8.83758975, "tippecanoe:mean:LABEL_Y": 3.07649, "tippecanoe:mean:NE_ID": 1159320964, "tippecanoe:count": 4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 94.526367, 68.236823 ], [ 96.635742, 67.491751 ], [ 90.307617, 67.491751 ], [ 90.351562, 67.676085 ], [ 94.526367, 68.236823 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a67fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 2, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 2, "tippecanoe:max:LABELRANK": 7, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 10, "tippecanoe:count:ADM0_DIF": 2, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 2, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 4, "tippecanoe:count:GEOU_DIF": 2, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 2, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 2, "tippecanoe:max:BRK_DIFF": 1, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 1, "tippecanoe:count:MAPCOLOR7": 2, "tippecanoe:max:MAPCOLOR7": 4, "tippecanoe:min:MAPCOLOR7": 2, "tippecanoe:sum:MAPCOLOR7": 6, "tippecanoe:count:MAPCOLOR8": 2, "tippecanoe:max:MAPCOLOR8": 7, "tippecanoe:min:MAPCOLOR8": 2, "tippecanoe:sum:MAPCOLOR8": 9, "tippecanoe:count:MAPCOLOR9": 2, "tippecanoe:max:MAPCOLOR9": 4, "tippecanoe:min:MAPCOLOR9": 3, "tippecanoe:sum:MAPCOLOR9": 7, "tippecanoe:count:MAPCOLOR13": 2, "tippecanoe:max:MAPCOLOR13": 9, "tippecanoe:min:MAPCOLOR13": 4, "tippecanoe:sum:MAPCOLOR13": 13, "tippecanoe:count:POP_EST": 2, "tippecanoe:max:POP_EST": 36471769, "tippecanoe:min:POP_EST": 603253, "tippecanoe:sum:POP_EST": 37075022, "tippecanoe:count:POP_RANK": 2, "tippecanoe:max:POP_RANK": 15, "tippecanoe:min:POP_RANK": 11, "tippecanoe:sum:POP_RANK": 26, "tippecanoe:count:POP_YEAR": 2, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2017, "tippecanoe:sum:POP_YEAR": 4036, "tippecanoe:count:GDP_MD": 2, "tippecanoe:max:GDP_MD": 119700, "tippecanoe:min:GDP_MD": 907, "tippecanoe:sum:GDP_MD": 120607, "tippecanoe:count:GDP_YEAR": 2, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2007, "tippecanoe:sum:GDP_YEAR": 4026, "tippecanoe:count:WOE_ID": 2, "tippecanoe:max:WOE_ID": 23424990, "tippecanoe:min:WOE_ID": 23424893, "tippecanoe:sum:WOE_ID": 46849883, "tippecanoe:count:WOE_ID_EH": 2, "tippecanoe:max:WOE_ID_EH": 23424990, "tippecanoe:min:WOE_ID_EH": 23424893, "tippecanoe:sum:WOE_ID_EH": 46849883, "tippecanoe:count:ADM0_A3_UN": 2, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -198, "tippecanoe:count:ADM0_A3_WB": 2, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -198, "tippecanoe:count:NAME_LEN": 2, "tippecanoe:max:NAME_LEN": 9, "tippecanoe:min:NAME_LEN": 7, "tippecanoe:sum:NAME_LEN": 16, "tippecanoe:count:LONG_LEN": 2, "tippecanoe:max:LONG_LEN": 14, "tippecanoe:min:LONG_LEN": 7, "tippecanoe:sum:LONG_LEN": 21, "tippecanoe:count:ABBREV_LEN": 2, "tippecanoe:max:ABBREV_LEN": 7, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 11, "tippecanoe:count:TINY": 2, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -198, "tippecanoe:count:HOMEPART": 2, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 2, "tippecanoe:count:MIN_ZOOM": 2, "tippecanoe:max:MIN_ZOOM": 4.7, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 4.7, "tippecanoe:count:MIN_LABEL": 2, "tippecanoe:max:MIN_LABEL": 6, "tippecanoe:min:MIN_LABEL": 2.7, "tippecanoe:sum:MIN_LABEL": 8.7, "tippecanoe:count:MAX_LABEL": 2, "tippecanoe:max:MAX_LABEL": 11, "tippecanoe:min:MAX_LABEL": 8, "tippecanoe:sum:MAX_LABEL": 19, "tippecanoe:count:LABEL_X": 2, "tippecanoe:max:LABEL_X": -7.187296, "tippecanoe:min:LABEL_X": -12.630304, "tippecanoe:sum:LABEL_X": -19.8176, "tippecanoe:count:LABEL_Y": 2, "tippecanoe:max:LABEL_Y": 31.650723, "tippecanoe:min:LABEL_Y": 23.967592, "tippecanoe:sum:LABEL_Y": 55.618314999999999, "tippecanoe:count:NE_ID": 2, "tippecanoe:max:NE_ID": 1159321223, "tippecanoe:min:NE_ID": 1159321035, "tippecanoe:sum:NE_ID": 2318642258, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 5, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0.5, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 4.5, "tippecanoe:mean:MAPCOLOR9": 3.5, "tippecanoe:mean:MAPCOLOR13": 6.5, "tippecanoe:mean:POP_EST": 18537511, "tippecanoe:mean:POP_RANK": 13, "tippecanoe:mean:POP_YEAR": 2018, "tippecanoe:mean:GDP_MD": 60303.5, "tippecanoe:mean:GDP_YEAR": 2013, "tippecanoe:mean:WOE_ID": 23424941.5, "tippecanoe:mean:WOE_ID_EH": 23424941.5, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 8, "tippecanoe:mean:LONG_LEN": 10.5, "tippecanoe:mean:ABBREV_LEN": 5.5, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 2.35, "tippecanoe:mean:MIN_LABEL": 4.35, "tippecanoe:mean:MAX_LABEL": 9.5, "tippecanoe:mean:LABEL_X": -9.9088, "tippecanoe:mean:LABEL_Y": 27.809157499999999, "tippecanoe:mean:NE_ID": 1159321129, "tippecanoe:count": 2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 87.978516, 73.640171 ], [ 92.197266, 72.724958 ], [ 91.450195, 71.031249 ], [ 87.978516, 70.524897 ], [ 87.978516, 73.640171 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a2ffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 3, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 3, "tippecanoe:max:LABELRANK": 4, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 11, "tippecanoe:count:ADM0_DIF": 3, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 3, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 6, "tippecanoe:count:GEOU_DIF": 3, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 3, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 3, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 3, "tippecanoe:max:MAPCOLOR7": 4, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 7, "tippecanoe:count:MAPCOLOR8": 3, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 3, "tippecanoe:sum:MAPCOLOR8": 13, "tippecanoe:count:MAPCOLOR9": 3, "tippecanoe:max:MAPCOLOR9": 4, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 8, "tippecanoe:count:MAPCOLOR13": 3, "tippecanoe:max:MAPCOLOR13": 9, "tippecanoe:min:MAPCOLOR13": 3, "tippecanoe:sum:MAPCOLOR13": 19, "tippecanoe:count:POP_EST": 3, "tippecanoe:max:POP_EST": 25716544, "tippecanoe:min:POP_EST": 4937374, "tippecanoe:sum:POP_EST": 38467133, "tippecanoe:count:POP_RANK": 3, "tippecanoe:max:POP_RANK": 15, "tippecanoe:min:POP_RANK": 12, "tippecanoe:sum:POP_RANK": 40, "tippecanoe:count:POP_YEAR": 3, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 6057, "tippecanoe:count:GDP_MD": 3, "tippecanoe:max:GDP_MD": 58539, "tippecanoe:min:GDP_MD": 3070, "tippecanoe:sum:GDP_MD": 65730, "tippecanoe:count:GDP_YEAR": 3, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 6057, "tippecanoe:count:WOE_ID": 3, "tippecanoe:max:WOE_ID": 23424946, "tippecanoe:min:WOE_ID": 23424854, "tippecanoe:sum:WOE_ID": 70274676, "tippecanoe:count:WOE_ID_EH": 3, "tippecanoe:max:WOE_ID_EH": 23424946, "tippecanoe:min:WOE_ID_EH": 23424854, "tippecanoe:sum:WOE_ID_EH": 70274676, "tippecanoe:count:ADM0_A3_UN": 3, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -297, "tippecanoe:count:ADM0_A3_WB": 3, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -297, "tippecanoe:count:NAME_LEN": 3, "tippecanoe:max:NAME_LEN": 13, "tippecanoe:min:NAME_LEN": 7, "tippecanoe:sum:NAME_LEN": 32, "tippecanoe:count:LONG_LEN": 3, "tippecanoe:max:LONG_LEN": 13, "tippecanoe:min:LONG_LEN": 7, "tippecanoe:sum:LONG_LEN": 32, "tippecanoe:count:ABBREV_LEN": 3, "tippecanoe:max:ABBREV_LEN": 7, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 15, "tippecanoe:count:TINY": 3, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -297, "tippecanoe:count:HOMEPART": 3, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 3, "tippecanoe:count:MIN_ZOOM": 3, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 3, "tippecanoe:max:MIN_LABEL": 4, "tippecanoe:min:MIN_LABEL": 2.5, "tippecanoe:sum:MIN_LABEL": 10.5, "tippecanoe:count:MAX_LABEL": 3, "tippecanoe:max:MAX_LABEL": 9, "tippecanoe:min:MAX_LABEL": 8, "tippecanoe:sum:MAX_LABEL": 26, "tippecanoe:count:LABEL_X": 3, "tippecanoe:max:LABEL_X": -5.568618, "tippecanoe:min:LABEL_X": -11.763677, "tippecanoe:sum:LABEL_X": -26.792673999999999, "tippecanoe:count:LABEL_Y": 3, "tippecanoe:max:LABEL_Y": 8.617449, "tippecanoe:min:LABEL_Y": 6.447177, "tippecanoe:sum:LABEL_Y": 22.556016, "tippecanoe:count:NE_ID": 3, "tippecanoe:max:NE_ID": 1159321251, "tippecanoe:min:NE_ID": 1159320507, "tippecanoe:sum:NE_ID": 3477962773, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 3.6666666666666667, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 2.3333333333333337, "tippecanoe:mean:MAPCOLOR8": 4.333333333333333, "tippecanoe:mean:MAPCOLOR9": 2.6666666666666667, "tippecanoe:mean:MAPCOLOR13": 6.333333333333333, "tippecanoe:mean:POP_EST": 12822377.666666666, "tippecanoe:mean:POP_RANK": 13.333333333333334, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 21910, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424892, "tippecanoe:mean:WOE_ID_EH": 23424892, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 10.666666666666666, "tippecanoe:mean:LONG_LEN": 10.666666666666666, "tippecanoe:mean:ABBREV_LEN": 5, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3.5, "tippecanoe:mean:MAX_LABEL": 8.666666666666666, "tippecanoe:mean:LABEL_X": -8.930891333333334, "tippecanoe:mean:LABEL_Y": 7.518672, "tippecanoe:mean:NE_ID": 1159320924.3333333, "tippecanoe:count": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 87.978516, 68.334376 ], [ 90.351562, 67.676085 ], [ 90.307617, 67.491751 ], [ 87.978516, 67.491751 ], [ 87.978516, 68.334376 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a6ffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 9, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 9, "tippecanoe:max:LABELRANK": 6, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 41, "tippecanoe:count:ADM0_DIF": 9, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 9, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 18, "tippecanoe:count:GEOU_DIF": 9, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 9, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 9, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 9, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 27, "tippecanoe:count:MAPCOLOR8": 9, "tippecanoe:max:MAPCOLOR8": 7, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 32, "tippecanoe:count:MAPCOLOR9": 9, "tippecanoe:max:MAPCOLOR9": 8, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 33, "tippecanoe:count:MAPCOLOR13": 9, "tippecanoe:max:MAPCOLOR13": 12, "tippecanoe:min:MAPCOLOR13": 2, "tippecanoe:sum:MAPCOLOR13": 53, "tippecanoe:count:POP_EST": 9, "tippecanoe:max:POP_EST": 60297396, "tippecanoe:min:POP_EST": 38019, "tippecanoe:sum:POP_EST": 129744004, "tippecanoe:count:POP_RANK": 9, "tippecanoe:max:POP_RANK": 16, "tippecanoe:min:POP_RANK": 7, "tippecanoe:sum:POP_RANK": 108, "tippecanoe:count:POP_YEAR": 9, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 18171, "tippecanoe:count:GDP_MD": 9, "tippecanoe:max:GDP_MD": 2003576, "tippecanoe:min:GDP_MD": 3154, "tippecanoe:sum:GDP_MD": 3072017, "tippecanoe:count:GDP_YEAR": 9, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2018, "tippecanoe:sum:GDP_YEAR": 18170, "tippecanoe:count:WOE_ID": 9, "tippecanoe:max:WOE_ID": 23424967, "tippecanoe:min:WOE_ID": 23424740, "tippecanoe:sum:WOE_ID": 210823727, "tippecanoe:count:WOE_ID_EH": 9, "tippecanoe:max:WOE_ID_EH": 23424967, "tippecanoe:min:WOE_ID_EH": 23424740, "tippecanoe:sum:WOE_ID_EH": 210823727, "tippecanoe:count:ADM0_A3_UN": 9, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -891, "tippecanoe:count:ADM0_A3_WB": 9, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -891, "tippecanoe:count:NAME_LEN": 9, "tippecanoe:max:NAME_LEN": 16, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 84, "tippecanoe:count:LONG_LEN": 9, "tippecanoe:max:LONG_LEN": 22, "tippecanoe:min:LONG_LEN": 5, "tippecanoe:sum:LONG_LEN": 90, "tippecanoe:count:ABBREV_LEN": 9, "tippecanoe:max:ABBREV_LEN": 6, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 41, "tippecanoe:count:TINY": 9, "tippecanoe:max:TINY": 6, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -578, "tippecanoe:count:HOMEPART": 9, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 9, "tippecanoe:count:MIN_ZOOM": 9, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 9, "tippecanoe:max:MIN_LABEL": 5.7, "tippecanoe:min:MIN_LABEL": 2, "tippecanoe:sum:MIN_LABEL": 36.7, "tippecanoe:count:MAX_LABEL": 9, "tippecanoe:max:MAX_LABEL": 10, "tippecanoe:min:MAX_LABEL": 6.8, "tippecanoe:sum:MAX_LABEL": 77.8, "tippecanoe:count:LABEL_X": 9, "tippecanoe:max:LABEL_X": 18.06841, "tippecanoe:min:LABEL_X": 1.539409, "tippecanoe:sum:LABEL_X": 80.51718399999999, "tippecanoe:count:LABEL_Y": 9, "tippecanoe:max:LABEL_Y": 49.733732, "tippecanoe:min:LABEL_Y": 27.397406, "tippecanoe:sum:LABEL_Y": 382.08085600000006, "tippecanoe:count:NE_ID": 9, "tippecanoe:max:NE_ID": 1159321327, "tippecanoe:min:NE_ID": 1159320327, "tippecanoe:sum:NE_ID": 10433887383, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 4.555555555555555, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 3.5555555555555555, "tippecanoe:mean:MAPCOLOR9": 3.6666666666666667, "tippecanoe:mean:MAPCOLOR13": 5.888888888888889, "tippecanoe:mean:POP_EST": 14416000.444444444, "tippecanoe:mean:POP_RANK": 12, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 341335.22222222227, "tippecanoe:mean:GDP_YEAR": 2018.888888888889, "tippecanoe:mean:WOE_ID": 23424858.555555557, "tippecanoe:mean:WOE_ID_EH": 23424858.555555557, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 9.333333333333334, "tippecanoe:mean:LONG_LEN": 10, "tippecanoe:mean:ABBREV_LEN": 4.555555555555555, "tippecanoe:mean:TINY": -64.22222222222223, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 4.077777777777778, "tippecanoe:mean:MAX_LABEL": 8.644444444444444, "tippecanoe:mean:LABEL_X": 8.946353777777777, "tippecanoe:mean:LABEL_Y": 42.45342844444445, "tippecanoe:mean:NE_ID": 1159320820.3333333, "tippecanoe:count": 9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 94.130859, 76.163993 ], [ 99.272461, 74.959392 ], [ 97.734375, 73.264704 ], [ 92.197266, 72.724958 ], [ 87.978516, 73.640171 ], [ 87.978516, 75.530136 ], [ 94.130859, 76.163993 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820487fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 1, "tippecanoe:max:scalerank": 3, "tippecanoe:min:scalerank": 3, "tippecanoe:sum:scalerank": 3, "tippecanoe:count:LABELRANK": 1, "tippecanoe:max:LABELRANK": 6, "tippecanoe:min:LABELRANK": 6, "tippecanoe:sum:LABELRANK": 6, "tippecanoe:count:ADM0_DIF": 1, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 1, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 2, "tippecanoe:count:GEOU_DIF": 1, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 1, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 1, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 1, "tippecanoe:max:MAPCOLOR7": 5, "tippecanoe:min:MAPCOLOR7": 5, "tippecanoe:sum:MAPCOLOR7": 5, "tippecanoe:count:MAPCOLOR8": 1, "tippecanoe:max:MAPCOLOR8": 3, "tippecanoe:min:MAPCOLOR8": 3, "tippecanoe:sum:MAPCOLOR8": 3, "tippecanoe:count:MAPCOLOR9": 1, "tippecanoe:max:MAPCOLOR9": 7, "tippecanoe:min:MAPCOLOR9": 7, "tippecanoe:sum:MAPCOLOR9": 7, "tippecanoe:count:MAPCOLOR13": 1, "tippecanoe:max:MAPCOLOR13": 3, "tippecanoe:min:MAPCOLOR13": 3, "tippecanoe:sum:MAPCOLOR13": 3, "tippecanoe:count:POP_EST": 1, "tippecanoe:max:POP_EST": 5703569, "tippecanoe:min:POP_EST": 5703569, "tippecanoe:sum:POP_EST": 5703569, "tippecanoe:count:POP_RANK": 1, "tippecanoe:max:POP_RANK": 13, "tippecanoe:min:POP_RANK": 13, "tippecanoe:sum:POP_RANK": 13, "tippecanoe:count:POP_YEAR": 1, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 2019, "tippecanoe:count:GDP_MD": 1, "tippecanoe:max:GDP_MD": 372062, "tippecanoe:min:GDP_MD": 372062, "tippecanoe:sum:GDP_MD": 372062, "tippecanoe:count:GDP_YEAR": 1, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 2019, "tippecanoe:count:WOE_ID": 1, "tippecanoe:max:WOE_ID": 23424948, "tippecanoe:min:WOE_ID": 23424948, "tippecanoe:sum:WOE_ID": 23424948, "tippecanoe:count:WOE_ID_EH": 1, "tippecanoe:max:WOE_ID_EH": 23424948, "tippecanoe:min:WOE_ID_EH": 23424948, "tippecanoe:sum:WOE_ID_EH": 23424948, "tippecanoe:count:ADM0_A3_UN": 1, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -99, "tippecanoe:count:ADM0_A3_WB": 1, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -99, "tippecanoe:count:NAME_LEN": 1, "tippecanoe:max:NAME_LEN": 9, "tippecanoe:min:NAME_LEN": 9, "tippecanoe:sum:NAME_LEN": 9, "tippecanoe:count:LONG_LEN": 1, "tippecanoe:max:LONG_LEN": 9, "tippecanoe:min:LONG_LEN": 9, "tippecanoe:sum:LONG_LEN": 9, "tippecanoe:count:ABBREV_LEN": 1, "tippecanoe:max:ABBREV_LEN": 5, "tippecanoe:min:ABBREV_LEN": 5, "tippecanoe:sum:ABBREV_LEN": 5, "tippecanoe:count:TINY": 1, "tippecanoe:max:TINY": 3, "tippecanoe:min:TINY": 3, "tippecanoe:sum:TINY": 3, "tippecanoe:count:HOMEPART": 1, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 1, "tippecanoe:count:MIN_ZOOM": 1, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 1, "tippecanoe:max:MIN_LABEL": 4, "tippecanoe:min:MIN_LABEL": 4, "tippecanoe:sum:MIN_LABEL": 4, "tippecanoe:count:MAX_LABEL": 1, "tippecanoe:max:MAX_LABEL": 9, "tippecanoe:min:MAX_LABEL": 9, "tippecanoe:sum:MAX_LABEL": 9, "tippecanoe:count:LABEL_X": 1, "tippecanoe:max:LABEL_X": 103.816925, "tippecanoe:min:LABEL_X": 103.816925, "tippecanoe:sum:LABEL_X": 103.816925, "tippecanoe:count:LABEL_Y": 1, "tippecanoe:max:LABEL_Y": 1.366587, "tippecanoe:min:LABEL_Y": 1.366587, "tippecanoe:sum:LABEL_Y": 1.366587, "tippecanoe:count:NE_ID": 1, "tippecanoe:max:NE_ID": 1159321247, "tippecanoe:min:NE_ID": 1159321247, "tippecanoe:sum:NE_ID": 1159321247, "tippecanoe:mean:scalerank": 3, "tippecanoe:mean:LABELRANK": 6, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 5, "tippecanoe:mean:MAPCOLOR8": 3, "tippecanoe:mean:MAPCOLOR9": 7, "tippecanoe:mean:MAPCOLOR13": 3, "tippecanoe:mean:POP_EST": 5703569, "tippecanoe:mean:POP_RANK": 13, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 372062, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424948, "tippecanoe:mean:WOE_ID_EH": 23424948, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 9, "tippecanoe:mean:LONG_LEN": 9, "tippecanoe:mean:ABBREV_LEN": 5, "tippecanoe:mean:TINY": 3, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 4, "tippecanoe:mean:MAX_LABEL": 9, "tippecanoe:mean:LABEL_X": 103.816925, "tippecanoe:mean:LABEL_Y": 1.366587, "tippecanoe:mean:NE_ID": 1159321247, "tippecanoe:count": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 137.988281, 67.759398 ], [ 137.988281, 67.491751 ], [ 137.197266, 67.491751 ], [ 137.197266, 67.542167 ], [ 137.988281, 67.759398 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a77fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 4, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 4, "tippecanoe:max:LABELRANK": 6, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 17, "tippecanoe:count:ADM0_DIF": 4, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 4, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 8, "tippecanoe:count:GEOU_DIF": 4, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 4, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 4, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 4, "tippecanoe:max:MAPCOLOR7": 5, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 11, "tippecanoe:count:MAPCOLOR8": 4, "tippecanoe:max:MAPCOLOR8": 3, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 7, "tippecanoe:count:MAPCOLOR9": 4, "tippecanoe:max:MAPCOLOR9": 5, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 11, "tippecanoe:count:MAPCOLOR13": 4, "tippecanoe:max:MAPCOLOR13": 12, "tippecanoe:min:MAPCOLOR13": 4, "tippecanoe:sum:MAPCOLOR13": 32, "tippecanoe:count:POP_EST": 4, "tippecanoe:max:POP_EST": 30417856, "tippecanoe:min:POP_EST": 8082366, "tippecanoe:sum:POP_EST": 70622751, "tippecanoe:count:POP_RANK": 4, "tippecanoe:max:POP_RANK": 15, "tippecanoe:min:POP_RANK": 13, "tippecanoe:sum:POP_RANK": 57, "tippecanoe:count:POP_YEAR": 4, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 8076, "tippecanoe:count:GDP_MD": 4, "tippecanoe:max:GDP_MD": 66983, "tippecanoe:min:GDP_MD": 5490, "tippecanoe:sum:GDP_MD": 102853, "tippecanoe:count:GDP_YEAR": 4, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 8076, "tippecanoe:count:WOE_ID": 4, "tippecanoe:max:WOE_ID": 23424978, "tippecanoe:min:WOE_ID": 23424764, "tippecanoe:sum:WOE_ID": 93699531, "tippecanoe:count:WOE_ID_EH": 4, "tippecanoe:max:WOE_ID_EH": 23424978, "tippecanoe:min:WOE_ID_EH": 23424764, "tippecanoe:sum:WOE_ID_EH": 93699531, "tippecanoe:count:ADM0_A3_UN": 4, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -396, "tippecanoe:count:ADM0_A3_WB": 4, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -396, "tippecanoe:count:NAME_LEN": 4, "tippecanoe:max:NAME_LEN": 12, "tippecanoe:min:NAME_LEN": 4, "tippecanoe:sum:NAME_LEN": 26, "tippecanoe:count:LONG_LEN": 4, "tippecanoe:max:LONG_LEN": 12, "tippecanoe:min:LONG_LEN": 4, "tippecanoe:sum:LONG_LEN": 26, "tippecanoe:count:ABBREV_LEN": 4, "tippecanoe:max:ABBREV_LEN": 5, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 18, "tippecanoe:count:TINY": 4, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -396, "tippecanoe:count:HOMEPART": 4, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 4, "tippecanoe:count:MIN_ZOOM": 4, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 4, "tippecanoe:max:MIN_LABEL": 5, "tippecanoe:min:MIN_LABEL": 2.7, "tippecanoe:sum:MIN_LABEL": 14.7, "tippecanoe:count:MAX_LABEL": 4, "tippecanoe:max:MAX_LABEL": 10, "tippecanoe:min:MAX_LABEL": 8, "tippecanoe:sum:MAX_LABEL": 35, "tippecanoe:count:LABEL_X": 4, "tippecanoe:max:LABEL_X": 2.352018, "tippecanoe:min:LABEL_X": -1.36388, "tippecanoe:sum:LABEL_X": 1.0093100000000004, "tippecanoe:count:LABEL_Y": 4, "tippecanoe:max:LABEL_Y": 12.673048, "tippecanoe:min:LABEL_Y": 7.717639, "tippecanoe:sum:LABEL_Y": 39.522682, "tippecanoe:count:NE_ID": 4, "tippecanoe:max:NE_ID": 1159321303, "tippecanoe:min:NE_ID": 1159320399, "tippecanoe:sum:NE_ID": 4637282900, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 4.25, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 2.75, "tippecanoe:mean:MAPCOLOR8": 1.75, "tippecanoe:mean:MAPCOLOR9": 2.75, "tippecanoe:mean:MAPCOLOR13": 8, "tippecanoe:mean:POP_EST": 17655687.75, "tippecanoe:mean:POP_RANK": 14.25, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 25713.25, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424882.75, "tippecanoe:mean:WOE_ID_EH": 23424882.75, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 6.5, "tippecanoe:mean:LONG_LEN": 6.5, "tippecanoe:mean:ABBREV_LEN": 4.5, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3.675, "tippecanoe:mean:MAX_LABEL": 8.75, "tippecanoe:mean:LABEL_X": 0.2523275000000001, "tippecanoe:mean:LABEL_Y": 9.8806705, "tippecanoe:mean:NE_ID": 1159320725, "tippecanoe:count": 4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 91.450195, 71.031249 ], [ 95.405273, 69.900118 ], [ 94.526367, 68.236823 ], [ 90.351562, 67.676085 ], [ 87.978516, 68.334376 ], [ 87.978516, 70.524897 ], [ 91.450195, 71.031249 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820417fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 1, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 1, "tippecanoe:max:LABELRANK": 4, "tippecanoe:min:LABELRANK": 4, "tippecanoe:sum:LABELRANK": 4, "tippecanoe:count:ADM0_DIF": 1, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 1, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 2, "tippecanoe:count:GEOU_DIF": 1, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 1, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 1, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 1, "tippecanoe:max:MAPCOLOR7": 1, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 1, "tippecanoe:count:MAPCOLOR8": 1, "tippecanoe:max:MAPCOLOR8": 1, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 1, "tippecanoe:count:MAPCOLOR9": 1, "tippecanoe:max:MAPCOLOR9": 1, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 1, "tippecanoe:count:MAPCOLOR13": 1, "tippecanoe:max:MAPCOLOR13": 9, "tippecanoe:min:MAPCOLOR13": 9, "tippecanoe:sum:MAPCOLOR13": 9, "tippecanoe:count:POP_EST": 1, "tippecanoe:max:POP_EST": 7169455, "tippecanoe:min:POP_EST": 7169455, "tippecanoe:sum:POP_EST": 7169455, "tippecanoe:count:POP_RANK": 1, "tippecanoe:max:POP_RANK": 13, "tippecanoe:min:POP_RANK": 13, "tippecanoe:sum:POP_RANK": 13, "tippecanoe:count:POP_YEAR": 1, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 2019, "tippecanoe:count:GDP_MD": 1, "tippecanoe:max:GDP_MD": 18173, "tippecanoe:min:GDP_MD": 18173, "tippecanoe:sum:GDP_MD": 18173, "tippecanoe:count:GDP_YEAR": 1, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 2019, "tippecanoe:count:WOE_ID": 1, "tippecanoe:max:WOE_ID": 23424872, "tippecanoe:min:WOE_ID": 23424872, "tippecanoe:sum:WOE_ID": 23424872, "tippecanoe:count:WOE_ID_EH": 1, "tippecanoe:max:WOE_ID_EH": 23424872, "tippecanoe:min:WOE_ID_EH": 23424872, "tippecanoe:sum:WOE_ID_EH": 23424872, "tippecanoe:count:ADM0_A3_UN": 1, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -99, "tippecanoe:count:ADM0_A3_WB": 1, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -99, "tippecanoe:count:NAME_LEN": 1, "tippecanoe:max:NAME_LEN": 4, "tippecanoe:min:NAME_LEN": 4, "tippecanoe:sum:NAME_LEN": 4, "tippecanoe:count:LONG_LEN": 1, "tippecanoe:max:LONG_LEN": 7, "tippecanoe:min:LONG_LEN": 7, "tippecanoe:sum:LONG_LEN": 7, "tippecanoe:count:ABBREV_LEN": 1, "tippecanoe:max:ABBREV_LEN": 4, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 4, "tippecanoe:count:TINY": 1, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -99, "tippecanoe:count:HOMEPART": 1, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 1, "tippecanoe:count:MIN_ZOOM": 1, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 1, "tippecanoe:max:MIN_LABEL": 4, "tippecanoe:min:MIN_LABEL": 4, "tippecanoe:sum:MIN_LABEL": 4, "tippecanoe:count:MAX_LABEL": 1, "tippecanoe:max:MAX_LABEL": 9, "tippecanoe:min:MAX_LABEL": 9, "tippecanoe:sum:MAX_LABEL": 9, "tippecanoe:count:LABEL_X": 1, "tippecanoe:max:LABEL_X": 102.533912, "tippecanoe:min:LABEL_X": 102.533912, "tippecanoe:sum:LABEL_X": 102.533912, "tippecanoe:count:LABEL_Y": 1, "tippecanoe:max:LABEL_Y": 19.431821, "tippecanoe:min:LABEL_Y": 19.431821, "tippecanoe:sum:LABEL_Y": 19.431821, "tippecanoe:count:NE_ID": 1, "tippecanoe:max:NE_ID": 1159321011, "tippecanoe:min:NE_ID": 1159321011, "tippecanoe:sum:NE_ID": 1159321011, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 4, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 1, "tippecanoe:mean:MAPCOLOR8": 1, "tippecanoe:mean:MAPCOLOR9": 1, "tippecanoe:mean:MAPCOLOR13": 9, "tippecanoe:mean:POP_EST": 7169455, "tippecanoe:mean:POP_RANK": 13, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 18173, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424872, "tippecanoe:mean:WOE_ID_EH": 23424872, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 4, "tippecanoe:mean:LONG_LEN": 7, "tippecanoe:mean:ABBREV_LEN": 4, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 4, "tippecanoe:mean:MAX_LABEL": 9, "tippecanoe:mean:LABEL_X": 102.533912, "tippecanoe:mean:LABEL_Y": 19.431821, "tippecanoe:mean:NE_ID": 1159321011, "tippecanoe:count": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 137.988281, 73.578167 ], [ 137.988281, 70.757966 ], [ 135.703125, 71.074056 ], [ 134.692383, 72.842021 ], [ 137.988281, 73.578167 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "8204a7fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 3, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 3, "tippecanoe:max:LABELRANK": 3, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 8, "tippecanoe:count:ADM0_DIF": 3, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 3, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 6, "tippecanoe:count:GEOU_DIF": 3, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 3, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 3, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 3, "tippecanoe:max:MAPCOLOR7": 3, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 6, "tippecanoe:count:MAPCOLOR8": 3, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 2, "tippecanoe:sum:MAPCOLOR8": 11, "tippecanoe:count:MAPCOLOR9": 3, "tippecanoe:max:MAPCOLOR9": 8, "tippecanoe:min:MAPCOLOR9": 2, "tippecanoe:sum:MAPCOLOR9": 15, "tippecanoe:count:MAPCOLOR13": 3, "tippecanoe:max:MAPCOLOR13": 13, "tippecanoe:min:MAPCOLOR13": 1, "tippecanoe:sum:MAPCOLOR13": 16, "tippecanoe:count:POP_EST": 3, "tippecanoe:max:POP_EST": 1366417754, "tippecanoe:min:POP_EST": 54045420, "tippecanoe:sum:POP_EST": 1490088756, "tippecanoe:count:POP_RANK": 3, "tippecanoe:max:POP_RANK": 18, "tippecanoe:min:POP_RANK": 16, "tippecanoe:sum:POP_RANK": 50, "tippecanoe:count:POP_YEAR": 3, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 6057, "tippecanoe:count:GDP_MD": 3, "tippecanoe:max:GDP_MD": 2868929, "tippecanoe:min:GDP_MD": 76085, "tippecanoe:sum:GDP_MD": 3488562, "tippecanoe:count:GDP_YEAR": 3, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 6057, "tippecanoe:count:WOE_ID": 3, "tippecanoe:max:WOE_ID": 23424960, "tippecanoe:min:WOE_ID": 23424763, "tippecanoe:sum:WOE_ID": 70274571, "tippecanoe:count:WOE_ID_EH": 3, "tippecanoe:max:WOE_ID_EH": 23424960, "tippecanoe:min:WOE_ID_EH": 23424763, "tippecanoe:sum:WOE_ID_EH": 70274571, "tippecanoe:count:ADM0_A3_UN": 3, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -297, "tippecanoe:count:ADM0_A3_WB": 3, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -297, "tippecanoe:count:NAME_LEN": 3, "tippecanoe:max:NAME_LEN": 8, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 20, "tippecanoe:count:LONG_LEN": 3, "tippecanoe:max:LONG_LEN": 8, "tippecanoe:min:LONG_LEN": 5, "tippecanoe:sum:LONG_LEN": 20, "tippecanoe:count:ABBREV_LEN": 3, "tippecanoe:max:ABBREV_LEN": 5, "tippecanoe:min:ABBREV_LEN": 5, "tippecanoe:sum:ABBREV_LEN": 15, "tippecanoe:count:TINY": 3, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -297, "tippecanoe:count:HOMEPART": 3, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 3, "tippecanoe:count:MIN_ZOOM": 3, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 3, "tippecanoe:max:MIN_LABEL": 3, "tippecanoe:min:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_LABEL": 7.4, "tippecanoe:count:MAX_LABEL": 3, "tippecanoe:max:MAX_LABEL": 8, "tippecanoe:min:MAX_LABEL": 6.7, "tippecanoe:sum:MAX_LABEL": 22.7, "tippecanoe:count:LABEL_X": 3, "tippecanoe:max:LABEL_X": 101.073198, "tippecanoe:min:LABEL_X": 79.358105, "tippecanoe:sum:LABEL_X": 276.2358, "tippecanoe:count:LABEL_Y": 3, "tippecanoe:max:LABEL_Y": 22.686852, "tippecanoe:min:LABEL_Y": 15.45974, "tippecanoe:sum:LABEL_Y": 59.72044699999999, "tippecanoe:count:NE_ID": 3, "tippecanoe:max:NE_ID": 1159321305, "tippecanoe:min:NE_ID": 1159320847, "tippecanoe:sum:NE_ID": 3477963219, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 2.6666666666666667, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 2, "tippecanoe:mean:MAPCOLOR8": 3.6666666666666667, "tippecanoe:mean:MAPCOLOR9": 5, "tippecanoe:mean:MAPCOLOR13": 5.333333333333333, "tippecanoe:mean:POP_EST": 496696252, "tippecanoe:mean:POP_RANK": 16.666666666666669, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 1162854, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424857, "tippecanoe:mean:WOE_ID_EH": 23424857, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 6.666666666666667, "tippecanoe:mean:LONG_LEN": 6.666666666666667, "tippecanoe:mean:ABBREV_LEN": 5, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 2.466666666666667, "tippecanoe:mean:MAX_LABEL": 7.566666666666666, "tippecanoe:mean:LABEL_X": 92.0786, "tippecanoe:mean:LABEL_Y": 19.906815666666664, "tippecanoe:mean:NE_ID": 1159321073, "tippecanoe:count": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 135.703125, 71.074056 ], [ 137.988281, 70.757966 ], [ 137.988281, 67.759398 ], [ 137.197266, 67.542167 ], [ 132.758789, 68.155209 ], [ 131.660156, 69.900118 ], [ 135.703125, 71.074056 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820427fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 1, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 1, "tippecanoe:max:LABELRANK": 3, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 3, "tippecanoe:count:ADM0_DIF": 1, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 1, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 2, "tippecanoe:count:GEOU_DIF": 1, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 1, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 1, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 1, "tippecanoe:max:MAPCOLOR7": 3, "tippecanoe:min:MAPCOLOR7": 3, "tippecanoe:sum:MAPCOLOR7": 3, "tippecanoe:count:MAPCOLOR8": 1, "tippecanoe:max:MAPCOLOR8": 5, "tippecanoe:min:MAPCOLOR8": 5, "tippecanoe:sum:MAPCOLOR8": 5, "tippecanoe:count:MAPCOLOR9": 1, "tippecanoe:max:MAPCOLOR9": 5, "tippecanoe:min:MAPCOLOR9": 5, "tippecanoe:sum:MAPCOLOR9": 5, "tippecanoe:count:MAPCOLOR13": 1, "tippecanoe:max:MAPCOLOR13": 6, "tippecanoe:min:MAPCOLOR13": 6, "tippecanoe:sum:MAPCOLOR13": 6, "tippecanoe:count:POP_EST": 1, "tippecanoe:max:POP_EST": 3225167, "tippecanoe:min:POP_EST": 3225167, "tippecanoe:sum:POP_EST": 3225167, "tippecanoe:count:POP_RANK": 1, "tippecanoe:max:POP_RANK": 12, "tippecanoe:min:POP_RANK": 12, "tippecanoe:sum:POP_RANK": 12, "tippecanoe:count:POP_YEAR": 1, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 2019, "tippecanoe:count:GDP_MD": 1, "tippecanoe:max:GDP_MD": 13996, "tippecanoe:min:GDP_MD": 13996, "tippecanoe:sum:GDP_MD": 13996, "tippecanoe:count:GDP_YEAR": 1, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 2019, "tippecanoe:count:WOE_ID": 1, "tippecanoe:max:WOE_ID": 23424887, "tippecanoe:min:WOE_ID": 23424887, "tippecanoe:sum:WOE_ID": 23424887, "tippecanoe:count:WOE_ID_EH": 1, "tippecanoe:max:WOE_ID_EH": 23424887, "tippecanoe:min:WOE_ID_EH": 23424887, "tippecanoe:sum:WOE_ID_EH": 23424887, "tippecanoe:count:ADM0_A3_UN": 1, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -99, "tippecanoe:count:ADM0_A3_WB": 1, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -99, "tippecanoe:count:NAME_LEN": 1, "tippecanoe:max:NAME_LEN": 8, "tippecanoe:min:NAME_LEN": 8, "tippecanoe:sum:NAME_LEN": 8, "tippecanoe:count:LONG_LEN": 1, "tippecanoe:max:LONG_LEN": 8, "tippecanoe:min:LONG_LEN": 8, "tippecanoe:sum:LONG_LEN": 8, "tippecanoe:count:ABBREV_LEN": 1, "tippecanoe:max:ABBREV_LEN": 5, "tippecanoe:min:ABBREV_LEN": 5, "tippecanoe:sum:ABBREV_LEN": 5, "tippecanoe:count:TINY": 1, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -99, "tippecanoe:count:HOMEPART": 1, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 1, "tippecanoe:count:MIN_ZOOM": 1, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 1, "tippecanoe:max:MIN_LABEL": 3, "tippecanoe:min:MIN_LABEL": 3, "tippecanoe:sum:MIN_LABEL": 3, "tippecanoe:count:MAX_LABEL": 1, "tippecanoe:max:MAX_LABEL": 7, "tippecanoe:min:MAX_LABEL": 7, "tippecanoe:sum:MAX_LABEL": 7, "tippecanoe:count:LABEL_X": 1, "tippecanoe:max:LABEL_X": 104.150405, "tippecanoe:min:LABEL_X": 104.150405, "tippecanoe:sum:LABEL_X": 104.150405, "tippecanoe:count:LABEL_Y": 1, "tippecanoe:max:LABEL_Y": 45.997488, "tippecanoe:min:LABEL_Y": 45.997488, "tippecanoe:sum:LABEL_Y": 45.997488, "tippecanoe:count:NE_ID": 1, "tippecanoe:max:NE_ID": 1159321071, "tippecanoe:min:NE_ID": 1159321071, "tippecanoe:sum:NE_ID": 1159321071, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 3, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 5, "tippecanoe:mean:MAPCOLOR9": 5, "tippecanoe:mean:MAPCOLOR13": 6, "tippecanoe:mean:POP_EST": 3225167, "tippecanoe:mean:POP_RANK": 12, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 13996, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424887, "tippecanoe:mean:WOE_ID_EH": 23424887, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 8, "tippecanoe:mean:LONG_LEN": 8, "tippecanoe:mean:ABBREV_LEN": 5, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3, "tippecanoe:mean:MAX_LABEL": 7, "tippecanoe:mean:LABEL_X": 104.150405, "tippecanoe:mean:LABEL_Y": 45.997488, "tippecanoe:mean:NE_ID": 1159321071, "tippecanoe:count": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 137.988281, 77.998190 ], [ 137.988281, 75.845169 ], [ 132.011719, 76.382969 ], [ 130.209961, 77.998190 ], [ 137.988281, 77.998190 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "82058ffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 6, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 6, "tippecanoe:max:LABELRANK": 5, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 21, "tippecanoe:count:ADM0_DIF": 6, "tippecanoe:max:ADM0_DIF": 1, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 1, "tippecanoe:count:LEVEL": 6, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 12, "tippecanoe:count:GEOU_DIF": 6, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 6, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 6, "tippecanoe:max:BRK_DIFF": 1, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 1, "tippecanoe:count:MAPCOLOR7": 6, "tippecanoe:max:MAPCOLOR7": 5, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 18, "tippecanoe:count:MAPCOLOR8": 6, "tippecanoe:max:MAPCOLOR8": 7, "tippecanoe:min:MAPCOLOR8": 2, "tippecanoe:sum:MAPCOLOR8": 27, "tippecanoe:count:MAPCOLOR9": 6, "tippecanoe:max:MAPCOLOR9": 7, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 23, "tippecanoe:count:MAPCOLOR13": 6, "tippecanoe:max:MAPCOLOR13": 12, "tippecanoe:min:MAPCOLOR13": -99, "tippecanoe:sum:MAPCOLOR13": -65, "tippecanoe:count:POP_EST": 6, "tippecanoe:max:POP_EST": 1397715000, "tippecanoe:min:POP_EST": 6000, "tippecanoe:sum:POP_EST": 1600424416, "tippecanoe:count:POP_RANK": 6, "tippecanoe:max:POP_RANK": 18, "tippecanoe:min:POP_RANK": 5, "tippecanoe:sum:POP_RANK": 80, "tippecanoe:count:POP_YEAR": 6, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2013, "tippecanoe:sum:POP_YEAR": 12108, "tippecanoe:count:GDP_MD": 6, "tippecanoe:max:GDP_MD": 14342903, "tippecanoe:min:GDP_MD": 15, "tippecanoe:sum:GDP_MD": 15209543, "tippecanoe:count:GDP_YEAR": 6, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2013, "tippecanoe:sum:GDP_YEAR": 12108, "tippecanoe:count:WOE_ID": 6, "tippecanoe:max:WOE_ID": 23424954, "tippecanoe:min:WOE_ID": 23424759, "tippecanoe:sum:WOE_ID": 140549103, "tippecanoe:count:WOE_ID_EH": 6, "tippecanoe:max:WOE_ID_EH": 23424954, "tippecanoe:min:WOE_ID_EH": 23424759, "tippecanoe:sum:WOE_ID_EH": 140549103, "tippecanoe:count:ADM0_A3_UN": 6, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -594, "tippecanoe:count:ADM0_A3_WB": 6, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -594, "tippecanoe:count:NAME_LEN": 6, "tippecanoe:max:NAME_LEN": 15, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 47, "tippecanoe:count:LONG_LEN": 6, "tippecanoe:max:LONG_LEN": 15, "tippecanoe:min:LONG_LEN": 5, "tippecanoe:sum:LONG_LEN": 47, "tippecanoe:count:ABBREV_LEN": 6, "tippecanoe:max:ABBREV_LEN": 7, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 32, "tippecanoe:count:TINY": 6, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -594, "tippecanoe:count:HOMEPART": 6, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 6, "tippecanoe:count:MIN_ZOOM": 6, "tippecanoe:max:MIN_ZOOM": 5, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 5, "tippecanoe:count:MIN_LABEL": 6, "tippecanoe:max:MIN_LABEL": 6.5, "tippecanoe:min:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_LABEL": 20.2, "tippecanoe:count:MAX_LABEL": 6, "tippecanoe:max:MAX_LABEL": 9.5, "tippecanoe:min:MAX_LABEL": 5.7, "tippecanoe:sum:MAX_LABEL": 47.2, "tippecanoe:count:LABEL_X": 6, "tippecanoe:max:LABEL_X": 106.337289, "tippecanoe:min:LABEL_X": 19.01705, "tippecanoe:sum:LABEL_X": 465.849063, "tippecanoe:count:LABEL_Y": 6, "tippecanoe:max:LABEL_Y": 65.85918, "tippecanoe:min:LABEL_Y": 24.214956, "tippecanoe:sum:LABEL_Y": 213.74752999999999, "tippecanoe:count:NE_ID": 6, "tippecanoe:max:NE_ID": 1159321287, "tippecanoe:min:NE_ID": 1159320407, "tippecanoe:sum:NE_ID": 6955924702, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 3.5, "tippecanoe:mean:ADM0_DIF": 0.16666666666666667, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0.16666666666666667, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 4.5, "tippecanoe:mean:MAPCOLOR9": 3.8333333333333337, "tippecanoe:mean:MAPCOLOR13": -10.833333333333334, "tippecanoe:mean:POP_EST": 266737402.66666667, "tippecanoe:mean:POP_RANK": 13.333333333333334, "tippecanoe:mean:POP_YEAR": 2018, "tippecanoe:mean:GDP_MD": 2534923.8333333337, "tippecanoe:mean:GDP_YEAR": 2018, "tippecanoe:mean:WOE_ID": 23424850.5, "tippecanoe:mean:WOE_ID_EH": 23424850.5, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 7.833333333333333, "tippecanoe:mean:LONG_LEN": 7.833333333333333, "tippecanoe:mean:ABBREV_LEN": 5.333333333333333, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0.8333333333333334, "tippecanoe:mean:MIN_LABEL": 3.3666666666666669, "tippecanoe:mean:MAX_LABEL": 7.866666666666667, "tippecanoe:mean:LABEL_X": 77.6415105, "tippecanoe:mean:LABEL_Y": 35.62458833333333, "tippecanoe:mean:NE_ID": 1159320783.6666668, "tippecanoe:count": 6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 128.803711, 73.378215 ], [ 134.692383, 72.842021 ], [ 135.703125, 71.074056 ], [ 131.660156, 69.900118 ], [ 126.562500, 70.348318 ], [ 124.760742, 72.046840 ], [ 128.803711, 73.378215 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820517fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 3, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 3, "tippecanoe:max:LABELRANK": 6, "tippecanoe:min:LABELRANK": 5, "tippecanoe:sum:LABELRANK": 16, "tippecanoe:count:ADM0_DIF": 3, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 3, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 6, "tippecanoe:count:GEOU_DIF": 3, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 3, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 3, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 3, "tippecanoe:max:MAPCOLOR7": 5, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 9, "tippecanoe:count:MAPCOLOR8": 3, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 8, "tippecanoe:count:MAPCOLOR9": 3, "tippecanoe:max:MAPCOLOR9": 5, "tippecanoe:min:MAPCOLOR9": 2, "tippecanoe:sum:MAPCOLOR9": 10, "tippecanoe:count:MAPCOLOR13": 3, "tippecanoe:max:MAPCOLOR13": 10, "tippecanoe:min:MAPCOLOR13": 2, "tippecanoe:sum:MAPCOLOR13": 20, "tippecanoe:count:POP_EST": 3, "tippecanoe:max:POP_EST": 10023318, "tippecanoe:min:POP_EST": 2957731, "tippecanoe:sum:POP_EST": 16701431, "tippecanoe:count:POP_RANK": 3, "tippecanoe:max:POP_RANK": 14, "tippecanoe:min:POP_RANK": 12, "tippecanoe:sum:POP_RANK": 38, "tippecanoe:count:POP_YEAR": 3, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 6057, "tippecanoe:count:GDP_MD": 3, "tippecanoe:max:GDP_MD": 48047, "tippecanoe:min:GDP_MD": 13672, "tippecanoe:sum:GDP_MD": 79196, "tippecanoe:count:GDP_YEAR": 3, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 6057, "tippecanoe:count:WOE_ID": 3, "tippecanoe:max:WOE_ID": 23424823, "tippecanoe:min:WOE_ID": 23424741, "tippecanoe:sum:WOE_ID": 70274307, "tippecanoe:count:WOE_ID_EH": 3, "tippecanoe:max:WOE_ID_EH": 23424823, "tippecanoe:min:WOE_ID_EH": 23424741, "tippecanoe:sum:WOE_ID_EH": 70274307, "tippecanoe:count:ADM0_A3_UN": 3, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -297, "tippecanoe:count:ADM0_A3_WB": 3, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -297, "tippecanoe:count:NAME_LEN": 3, "tippecanoe:max:NAME_LEN": 10, "tippecanoe:min:NAME_LEN": 7, "tippecanoe:sum:NAME_LEN": 24, "tippecanoe:count:LONG_LEN": 3, "tippecanoe:max:LONG_LEN": 10, "tippecanoe:min:LONG_LEN": 7, "tippecanoe:sum:LONG_LEN": 24, "tippecanoe:count:ABBREV_LEN": 3, "tippecanoe:max:ABBREV_LEN": 4, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 12, "tippecanoe:count:TINY": 3, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -297, "tippecanoe:count:HOMEPART": 3, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 3, "tippecanoe:count:MIN_ZOOM": 3, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 3, "tippecanoe:max:MIN_LABEL": 5, "tippecanoe:min:MIN_LABEL": 4, "tippecanoe:sum:MIN_LABEL": 13, "tippecanoe:count:MAX_LABEL": 3, "tippecanoe:max:MAX_LABEL": 10, "tippecanoe:min:MAX_LABEL": 9, "tippecanoe:sum:MAX_LABEL": 28, "tippecanoe:count:LABEL_X": 3, "tippecanoe:max:LABEL_X": 47.210994, "tippecanoe:min:LABEL_X": 43.735724, "tippecanoe:sum:LABEL_X": 135.74728199999999, "tippecanoe:count:LABEL_Y": 3, "tippecanoe:max:LABEL_Y": 41.870087, "tippecanoe:min:LABEL_Y": 40.402387, "tippecanoe:sum:LABEL_Y": 122.731551, "tippecanoe:count:NE_ID": 3, "tippecanoe:max:NE_ID": 1159320779, "tippecanoe:min:NE_ID": 1159320333, "tippecanoe:sum:NE_ID": 3477961493, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 5.333333333333333, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 2.6666666666666667, "tippecanoe:mean:MAPCOLOR9": 3.3333333333333337, "tippecanoe:mean:MAPCOLOR13": 6.666666666666667, "tippecanoe:mean:POP_EST": 5567143.666666667, "tippecanoe:mean:POP_RANK": 12.666666666666666, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 26398.666666666668, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424769, "tippecanoe:mean:WOE_ID_EH": 23424769, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 8, "tippecanoe:mean:LONG_LEN": 8, "tippecanoe:mean:ABBREV_LEN": 4, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 4.333333333333333, "tippecanoe:mean:MAX_LABEL": 9.333333333333334, "tippecanoe:mean:LABEL_X": 45.24909399999999, "tippecanoe:mean:LABEL_Y": 40.910517, "tippecanoe:mean:NE_ID": 1159320497.6666668, "tippecanoe:count": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 116.630859, 76.980149 ], [ 119.926758, 75.375605 ], [ 116.235352, 73.885918 ], [ 109.863281, 73.861506 ], [ 105.952148, 75.297735 ], [ 108.808594, 76.930555 ], [ 116.630859, 76.980149 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "8205affffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 7, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 7, "tippecanoe:max:LABELRANK": 5, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 25, "tippecanoe:count:ADM0_DIF": 7, "tippecanoe:max:ADM0_DIF": 1, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 1, "tippecanoe:count:LEVEL": 7, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 14, "tippecanoe:count:GEOU_DIF": 7, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 7, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 7, "tippecanoe:max:BRK_DIFF": 1, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 1, "tippecanoe:count:MAPCOLOR7": 7, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 2, "tippecanoe:sum:MAPCOLOR7": 26, "tippecanoe:count:MAPCOLOR8": 7, "tippecanoe:max:MAPCOLOR8": 7, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 27, "tippecanoe:count:MAPCOLOR9": 7, "tippecanoe:max:MAPCOLOR9": 8, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 32, "tippecanoe:count:MAPCOLOR13": 7, "tippecanoe:max:MAPCOLOR13": 11, "tippecanoe:min:MAPCOLOR13": 1, "tippecanoe:sum:MAPCOLOR13": 43, "tippecanoe:count:POP_EST": 7, "tippecanoe:max:POP_EST": 216565318, "tippecanoe:min:POP_EST": 36175, "tippecanoe:sum:POP_EST": 309943904, "tippecanoe:count:POP_RANK": 7, "tippecanoe:max:POP_RANK": 17, "tippecanoe:min:POP_RANK": 7, "tippecanoe:sum:POP_RANK": 93, "tippecanoe:count:POP_YEAR": 7, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2009, "tippecanoe:sum:POP_YEAR": 14123, "tippecanoe:count:GDP_MD": 7, "tippecanoe:max:GDP_MD": 278221, "tippecanoe:min:GDP_MD": 596, "tippecanoe:sum:GDP_MD": 413360, "tippecanoe:count:GDP_YEAR": 7, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2013, "tippecanoe:sum:GDP_YEAR": 14126, "tippecanoe:count:WOE_ID": 7, "tippecanoe:max:WOE_ID": 23424980, "tippecanoe:min:WOE_ID": -90, "tippecanoe:sum:WOE_ID": 140549348, "tippecanoe:count:WOE_ID_EH": 7, "tippecanoe:max:WOE_ID_EH": 23424980, "tippecanoe:min:WOE_ID_EH": 20070177, "tippecanoe:sum:WOE_ID_EH": 160619615, "tippecanoe:count:ADM0_A3_UN": 7, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -693, "tippecanoe:count:ADM0_A3_WB": 7, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -693, "tippecanoe:count:NAME_LEN": 7, "tippecanoe:max:NAME_LEN": 12, "tippecanoe:min:NAME_LEN": 8, "tippecanoe:sum:NAME_LEN": 69, "tippecanoe:count:LONG_LEN": 7, "tippecanoe:max:LONG_LEN": 19, "tippecanoe:min:LONG_LEN": 8, "tippecanoe:sum:LONG_LEN": 80, "tippecanoe:count:ABBREV_LEN": 7, "tippecanoe:max:ABBREV_LEN": 6, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 31, "tippecanoe:count:TINY": 7, "tippecanoe:max:TINY": 5, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -589, "tippecanoe:count:HOMEPART": 7, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": -99, "tippecanoe:sum:HOMEPART": -93, "tippecanoe:count:MIN_ZOOM": 7, "tippecanoe:max:MIN_ZOOM": 5, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 5, "tippecanoe:count:MIN_LABEL": 7, "tippecanoe:max:MIN_LABEL": 6, "tippecanoe:min:MIN_LABEL": 2.7, "tippecanoe:sum:MIN_LABEL": 24.7, "tippecanoe:count:MAX_LABEL": 7, "tippecanoe:max:MAX_LABEL": 9.5, "tippecanoe:min:MAX_LABEL": 7, "tippecanoe:sum:MAX_LABEL": 56.5, "tippecanoe:count:LABEL_X": 7, "tippecanoe:max:LABEL_X": 74.532637, "tippecanoe:min:LABEL_X": 58.676647, "tippecanoe:sum:LABEL_X": 468.22810400000005, "tippecanoe:count:LABEL_Y": 7, "tippecanoe:max:LABEL_Y": 45.978332, "tippecanoe:min:LABEL_Y": 29.328389, "tippecanoe:sum:LABEL_Y": 270.888207, "tippecanoe:count:NE_ID": 7, "tippecanoe:max:NE_ID": 1159321405, "tippecanoe:min:NE_ID": 1159320319, "tippecanoe:sum:NE_ID": 8115247435, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 3.5714285714285718, "tippecanoe:mean:ADM0_DIF": 0.14285714285714286, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0.14285714285714286, "tippecanoe:mean:MAPCOLOR7": 3.7142857142857146, "tippecanoe:mean:MAPCOLOR8": 3.857142857142857, "tippecanoe:mean:MAPCOLOR9": 4.571428571428571, "tippecanoe:mean:MAPCOLOR13": 6.142857142857143, "tippecanoe:mean:POP_EST": 44277700.571428578, "tippecanoe:mean:POP_RANK": 13.285714285714287, "tippecanoe:mean:POP_YEAR": 2017.5714285714287, "tippecanoe:mean:GDP_MD": 59051.42857142857, "tippecanoe:mean:GDP_YEAR": 2018, "tippecanoe:mean:WOE_ID": 20078478.285714289, "tippecanoe:mean:WOE_ID_EH": 22945659.285714289, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 9.857142857142858, "tippecanoe:mean:LONG_LEN": 11.428571428571429, "tippecanoe:mean:ABBREV_LEN": 4.428571428571429, "tippecanoe:mean:TINY": -84.14285714285714, "tippecanoe:mean:HOMEPART": -13.285714285714287, "tippecanoe:mean:MIN_ZOOM": 0.7142857142857143, "tippecanoe:mean:MIN_LABEL": 3.5285714285714286, "tippecanoe:mean:MAX_LABEL": 8.071428571428572, "tippecanoe:mean:LABEL_X": 66.88972914285715, "tippecanoe:mean:LABEL_Y": 38.69831528571429, "tippecanoe:mean:NE_ID": 1159321062.142857, "tippecanoe:count": 7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 119.926758, 75.375605 ], [ 126.870117, 75.095633 ], [ 128.803711, 73.378215 ], [ 124.760742, 72.046840 ], [ 118.959961, 72.289067 ], [ 116.235352, 73.885918 ], [ 119.926758, 75.375605 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "8205b7fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 4, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 4, "tippecanoe:max:LABELRANK": 5, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 15, "tippecanoe:count:ADM0_DIF": 4, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 4, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 8, "tippecanoe:count:GEOU_DIF": 4, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 4, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 4, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 4, "tippecanoe:max:MAPCOLOR7": 5, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 13, "tippecanoe:count:MAPCOLOR8": 4, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 2, "tippecanoe:sum:MAPCOLOR8": 15, "tippecanoe:count:MAPCOLOR9": 4, "tippecanoe:max:MAPCOLOR9": 5, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 13, "tippecanoe:count:MAPCOLOR13": 4, "tippecanoe:max:MAPCOLOR13": 13, "tippecanoe:min:MAPCOLOR13": 2, "tippecanoe:sum:MAPCOLOR13": 34, "tippecanoe:count:POP_EST": 4, "tippecanoe:max:POP_EST": 112078730, "tippecanoe:min:POP_EST": 973560, "tippecanoe:sum:POP_EST": 147310371, "tippecanoe:count:POP_RANK": 4, "tippecanoe:max:POP_RANK": 17, "tippecanoe:min:POP_RANK": 11, "tippecanoe:sum:POP_RANK": 56, "tippecanoe:count:POP_YEAR": 4, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2014, "tippecanoe:sum:POP_YEAR": 8071, "tippecanoe:count:GDP_MD": 4, "tippecanoe:max:GDP_MD": 95912, "tippecanoe:min:GDP_MD": 3324, "tippecanoe:sum:GDP_MD": 139653, "tippecanoe:count:GDP_YEAR": 4, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2013, "tippecanoe:sum:GDP_YEAR": 8070, "tippecanoe:count:WOE_ID": 4, "tippecanoe:max:WOE_ID": 23425002, "tippecanoe:min:WOE_ID": -99, "tippecanoe:sum:WOE_ID": 70274508, "tippecanoe:count:WOE_ID_EH": 4, "tippecanoe:max:WOE_ID_EH": 23425002, "tippecanoe:min:WOE_ID_EH": -99, "tippecanoe:sum:WOE_ID_EH": 70274508, "tippecanoe:count:ADM0_A3_UN": 4, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -396, "tippecanoe:count:ADM0_A3_WB": 4, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -396, "tippecanoe:count:NAME_LEN": 4, "tippecanoe:max:NAME_LEN": 10, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 31, "tippecanoe:count:LONG_LEN": 4, "tippecanoe:max:LONG_LEN": 10, "tippecanoe:min:LONG_LEN": 5, "tippecanoe:sum:LONG_LEN": 31, "tippecanoe:count:ABBREV_LEN": 4, "tippecanoe:max:ABBREV_LEN": 6, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 18, "tippecanoe:count:TINY": 4, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -396, "tippecanoe:count:HOMEPART": 4, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 4, "tippecanoe:count:MIN_ZOOM": 4, "tippecanoe:max:MIN_ZOOM": 4, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 4, "tippecanoe:count:MIN_LABEL": 4, "tippecanoe:max:MIN_LABEL": 4.5, "tippecanoe:min:MIN_LABEL": 2, "tippecanoe:sum:MIN_LABEL": 13.5, "tippecanoe:count:MAX_LABEL": 4, "tippecanoe:max:MAX_LABEL": 9, "tippecanoe:min:MAX_LABEL": 7, "tippecanoe:sum:MAX_LABEL": 33, "tippecanoe:count:LABEL_X": 4, "tippecanoe:max:LABEL_X": 46.731595, "tippecanoe:min:LABEL_X": 39.0886, "tippecanoe:sum:LABEL_X": 174.193403, "tippecanoe:count:LABEL_Y": 4, "tippecanoe:max:LABEL_Y": 15.328226, "tippecanoe:min:LABEL_Y": 8.032795, "tippecanoe:sum:LABEL_Y": 44.781253, "tippecanoe:count:NE_ID": 4, "tippecanoe:max:NE_ID": 1159321425, "tippecanoe:min:NE_ID": 1159320541, "tippecanoe:sum:NE_ID": 4637283842, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 3.75, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3.25, "tippecanoe:mean:MAPCOLOR8": 3.75, "tippecanoe:mean:MAPCOLOR9": 3.25, "tippecanoe:mean:MAPCOLOR13": 8.5, "tippecanoe:mean:POP_EST": 36827592.75, "tippecanoe:mean:POP_RANK": 14, "tippecanoe:mean:POP_YEAR": 2017.75, "tippecanoe:mean:GDP_MD": 34913.25, "tippecanoe:mean:GDP_YEAR": 2017.5, "tippecanoe:mean:WOE_ID": 17568627, "tippecanoe:mean:WOE_ID_EH": 17568627, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 7.75, "tippecanoe:mean:LONG_LEN": 7.75, "tippecanoe:mean:ABBREV_LEN": 4.5, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 1, "tippecanoe:mean:MIN_LABEL": 3.375, "tippecanoe:mean:MAX_LABEL": 8.25, "tippecanoe:mean:LABEL_X": 43.54835075, "tippecanoe:mean:LABEL_Y": 11.19531325, "tippecanoe:mean:NE_ID": 1159320960.5, "tippecanoe:count": 4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 115.927734, 70.801366 ], [ 118.300781, 69.224997 ], [ 115.751953, 67.759398 ], [ 111.093750, 67.776025 ], [ 108.413086, 69.224997 ], [ 110.566406, 70.801366 ], [ 115.927734, 70.801366 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a4ffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 18, "tippecanoe:max:scalerank": 3, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 6, "tippecanoe:count:LABELRANK": 18, "tippecanoe:max:LABELRANK": 9, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 86, "tippecanoe:count:ADM0_DIF": 18, "tippecanoe:max:ADM0_DIF": 1, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 3, "tippecanoe:count:LEVEL": 18, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 36, "tippecanoe:count:GEOU_DIF": 18, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 18, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 18, "tippecanoe:max:BRK_DIFF": 1, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 2, "tippecanoe:count:MAPCOLOR7": 18, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 65, "tippecanoe:count:MAPCOLOR8": 18, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 52, "tippecanoe:count:MAPCOLOR9": 18, "tippecanoe:max:MAPCOLOR9": 8, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 74, "tippecanoe:count:MAPCOLOR13": 18, "tippecanoe:max:MAPCOLOR13": 12, "tippecanoe:min:MAPCOLOR13": -99, "tippecanoe:sum:MAPCOLOR13": 10, "tippecanoe:count:POP_EST": 18, "tippecanoe:max:POP_EST": 100388073, "tippecanoe:min:POP_EST": 7850, "tippecanoe:sum:POP_EST": 286398180, "tippecanoe:count:POP_RANK": 18, "tippecanoe:max:POP_RANK": 17, "tippecanoe:min:POP_RANK": 5, "tippecanoe:sum:POP_RANK": 218, "tippecanoe:count:POP_YEAR": 18, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2013, "tippecanoe:sum:POP_YEAR": 36334, "tippecanoe:count:GDP_MD": 18, "tippecanoe:max:GDP_MD": 761425, "tippecanoe:min:GDP_MD": 280, "tippecanoe:sum:GDP_MD": 2142290, "tippecanoe:count:GDP_YEAR": 18, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2013, "tippecanoe:sum:GDP_YEAR": 36323, "tippecanoe:count:WOE_ID": 18, "tippecanoe:max:WOE_ID": 28289408, "tippecanoe:min:WOE_ID": -99, "tippecanoe:sum:WOE_ID": 282607218, "tippecanoe:count:WOE_ID_EH": 18, "tippecanoe:max:WOE_ID_EH": 29389201, "tippecanoe:min:WOE_ID_EH": -99, "tippecanoe:sum:WOE_ID_EH": 378916586, "tippecanoe:count:ADM0_A3_UN": 18, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -1782, "tippecanoe:count:ADM0_A3_WB": 18, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -1782, "tippecanoe:count:NAME_LEN": 18, "tippecanoe:max:NAME_LEN": 23, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 151, "tippecanoe:count:LONG_LEN": 18, "tippecanoe:max:LONG_LEN": 23, "tippecanoe:min:LONG_LEN": 5, "tippecanoe:sum:LONG_LEN": 157, "tippecanoe:count:ABBREV_LEN": 18, "tippecanoe:max:ABBREV_LEN": 7, "tippecanoe:min:ABBREV_LEN": 0, "tippecanoe:sum:ABBREV_LEN": 80, "tippecanoe:count:TINY": 18, "tippecanoe:max:TINY": 4, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -1577, "tippecanoe:count:HOMEPART": 18, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": -99, "tippecanoe:sum:HOMEPART": -182, "tippecanoe:count:MIN_ZOOM": 18, "tippecanoe:max:MIN_ZOOM": 7, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 14, "tippecanoe:count:MIN_LABEL": 18, "tippecanoe:max:MIN_LABEL": 7.7, "tippecanoe:min:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_LABEL": 77.30000000000001, "tippecanoe:count:MAX_LABEL": 18, "tippecanoe:max:MAX_LABEL": 11, "tippecanoe:min:MAX_LABEL": 6.7, "tippecanoe:sum:MAX_LABEL": 161.7, "tippecanoe:count:LABEL_X": 18, "tippecanoe:max:LABEL_X": 35.992892, "tippecanoe:min:LABEL_X": 16.37241, "tippecanoe:sum:LABEL_X": 501.7997449999999, "tippecanoe:count:LABEL_Y": 18, "tippecanoe:max:LABEL_Y": 49.724739, "tippecanoe:min:LABEL_Y": 26.186173, "tippecanoe:sum:LABEL_Y": 692.236434, "tippecanoe:count:NE_ID": 18, "tippecanoe:max:NE_ID": 1159321345, "tippecanoe:min:NE_ID": 1159320325, "tippecanoe:sum:NE_ID": 20867775124, "tippecanoe:mean:scalerank": 0.3333333333333333, "tippecanoe:mean:LABELRANK": 4.777777777777778, "tippecanoe:mean:ADM0_DIF": 0.16666666666666667, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0.1111111111111111, "tippecanoe:mean:MAPCOLOR7": 3.611111111111111, "tippecanoe:mean:MAPCOLOR8": 2.888888888888889, "tippecanoe:mean:MAPCOLOR9": 4.111111111111111, "tippecanoe:mean:MAPCOLOR13": 0.5555555555555556, "tippecanoe:mean:POP_EST": 15911010, "tippecanoe:mean:POP_RANK": 12.11111111111111, "tippecanoe:mean:POP_YEAR": 2018.5555555555557, "tippecanoe:mean:GDP_MD": 119016.11111111111, "tippecanoe:mean:GDP_YEAR": 2017.9444444444444, "tippecanoe:mean:WOE_ID": 15700401, "tippecanoe:mean:WOE_ID_EH": 21050921.444444445, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 8.38888888888889, "tippecanoe:mean:LONG_LEN": 8.722222222222222, "tippecanoe:mean:ABBREV_LEN": 4.444444444444445, "tippecanoe:mean:TINY": -87.61111111111112, "tippecanoe:mean:HOMEPART": -10.11111111111111, "tippecanoe:mean:MIN_ZOOM": 0.7777777777777778, "tippecanoe:mean:MIN_LABEL": 4.294444444444445, "tippecanoe:mean:MAX_LABEL": 8.983333333333333, "tippecanoe:mean:LABEL_X": 27.877763611111108, "tippecanoe:mean:LABEL_Y": 38.45757966666667, "tippecanoe:mean:NE_ID": 1159320840.2222224, "tippecanoe:count": 18 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 105.952148, 75.297735 ], [ 109.863281, 73.861506 ], [ 107.402344, 72.248917 ], [ 101.777344, 71.992578 ], [ 97.734375, 73.264704 ], [ 99.272461, 74.959392 ], [ 105.952148, 75.297735 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "8205a7fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 8, "tippecanoe:max:scalerank": 5, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 5, "tippecanoe:count:LABELRANK": 8, "tippecanoe:max:LABELRANK": 6, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 29, "tippecanoe:count:ADM0_DIF": 8, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 8, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 16, "tippecanoe:count:GEOU_DIF": 8, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 8, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 8, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 8, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 24, "tippecanoe:count:MAPCOLOR8": 8, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 26, "tippecanoe:count:MAPCOLOR9": 8, "tippecanoe:max:MAPCOLOR9": 6, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 24, "tippecanoe:count:MAPCOLOR13": 8, "tippecanoe:max:MAPCOLOR13": 13, "tippecanoe:min:MAPCOLOR13": 1, "tippecanoe:sum:MAPCOLOR13": 46, "tippecanoe:count:POP_EST": 8, "tippecanoe:max:POP_EST": 82913906, "tippecanoe:min:POP_EST": 1641172, "tippecanoe:sum:POP_EST": 192344368, "tippecanoe:count:POP_RANK": 8, "tippecanoe:max:POP_RANK": 16, "tippecanoe:min:POP_RANK": 12, "tippecanoe:sum:POP_RANK": 110, "tippecanoe:count:POP_YEAR": 8, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 16152, "tippecanoe:count:GDP_MD": 8, "tippecanoe:max:GDP_MD": 792966, "tippecanoe:min:GDP_MD": 38574, "tippecanoe:sum:GDP_MD": 1973427, "tippecanoe:count:GDP_YEAR": 8, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2015, "tippecanoe:sum:GDP_YEAR": 16147, "tippecanoe:count:WOE_ID": 8, "tippecanoe:max:WOE_ID": 23424956, "tippecanoe:min:WOE_ID": 23424753, "tippecanoe:sum:WOE_ID": 187399013, "tippecanoe:count:WOE_ID_EH": 8, "tippecanoe:max:WOE_ID_EH": 23424956, "tippecanoe:min:WOE_ID_EH": 23424753, "tippecanoe:sum:WOE_ID_EH": 187399013, "tippecanoe:count:ADM0_A3_UN": 8, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -792, "tippecanoe:count:ADM0_A3_WB": 8, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -792, "tippecanoe:count:NAME_LEN": 8, "tippecanoe:max:NAME_LEN": 12, "tippecanoe:min:NAME_LEN": 4, "tippecanoe:sum:NAME_LEN": 49, "tippecanoe:count:LONG_LEN": 8, "tippecanoe:max:LONG_LEN": 12, "tippecanoe:min:LONG_LEN": 4, "tippecanoe:sum:LONG_LEN": 49, "tippecanoe:count:ABBREV_LEN": 8, "tippecanoe:max:ABBREV_LEN": 5, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 37, "tippecanoe:count:TINY": 8, "tippecanoe:max:TINY": 2, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -691, "tippecanoe:count:HOMEPART": 8, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 8, "tippecanoe:count:MIN_ZOOM": 8, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 8, "tippecanoe:max:MIN_LABEL": 5, "tippecanoe:min:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_LABEL": 27.2, "tippecanoe:count:MAX_LABEL": 8, "tippecanoe:max:MAX_LABEL": 10, "tippecanoe:min:MAX_LABEL": 6.7, "tippecanoe:sum:MAX_LABEL": 66.2, "tippecanoe:count:LABEL_X": 8, "tippecanoe:max:LABEL_X": 54.931495, "tippecanoe:min:LABEL_X": 36.375991, "tippecanoe:sum:LABEL_X": 366.559003, "tippecanoe:count:LABEL_Y": 8, "tippecanoe:max:LABEL_Y": 35.006636, "tippecanoe:min:LABEL_Y": 23.806908, "tippecanoe:sum:LABEL_Y": 235.585807, "tippecanoe:count:NE_ID": 8, "tippecanoe:max:NE_ID": 1159321295, "tippecanoe:min:NE_ID": 1159320413, "tippecanoe:sum:NE_ID": 9274567842, "tippecanoe:mean:scalerank": 0.625, "tippecanoe:mean:LABELRANK": 3.625, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 3.25, "tippecanoe:mean:MAPCOLOR9": 3, "tippecanoe:mean:MAPCOLOR13": 5.75, "tippecanoe:mean:POP_EST": 24043046, "tippecanoe:mean:POP_RANK": 13.75, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 246678.375, "tippecanoe:mean:GDP_YEAR": 2018.375, "tippecanoe:mean:WOE_ID": 23424876.625, "tippecanoe:mean:WOE_ID_EH": 23424876.625, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 6.125, "tippecanoe:mean:LONG_LEN": 6.125, "tippecanoe:mean:ABBREV_LEN": 4.625, "tippecanoe:mean:TINY": -86.375, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3.4, "tippecanoe:mean:MAX_LABEL": 8.275, "tippecanoe:mean:LABEL_X": 45.819875375, "tippecanoe:mean:LABEL_Y": 29.448225875, "tippecanoe:mean:NE_ID": 1159320980.25, "tippecanoe:count": 8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 116.235352, 73.885918 ], [ 118.959961, 72.289067 ], [ 115.927734, 70.801366 ], [ 110.566406, 70.801366 ], [ 107.402344, 72.248917 ], [ 109.863281, 73.861506 ], [ 116.235352, 73.885918 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820537fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 15, "tippecanoe:max:scalerank": 3, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 3, "tippecanoe:count:LABELRANK": 15, "tippecanoe:max:LABELRANK": 6, "tippecanoe:min:LABELRANK": 2, "tippecanoe:sum:LABELRANK": 67, "tippecanoe:count:ADM0_DIF": 15, "tippecanoe:max:ADM0_DIF": 1, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 3, "tippecanoe:count:LEVEL": 15, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 1, "tippecanoe:sum:LEVEL": 29, "tippecanoe:count:GEOU_DIF": 15, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 15, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 15, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 15, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 47, "tippecanoe:count:MAPCOLOR8": 15, "tippecanoe:max:MAPCOLOR8": 7, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 49, "tippecanoe:count:MAPCOLOR9": 15, "tippecanoe:max:MAPCOLOR9": 6, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 51, "tippecanoe:count:MAPCOLOR13": 15, "tippecanoe:max:MAPCOLOR13": 13, "tippecanoe:min:MAPCOLOR13": 1, "tippecanoe:sum:MAPCOLOR13": 114, "tippecanoe:count:POP_EST": 15, "tippecanoe:max:POP_EST": 83132799, "tippecanoe:min:POP_EST": 29884, "tippecanoe:sum:POP_EST": 217744098, "tippecanoe:count:POP_RANK": 15, "tippecanoe:max:POP_RANK": 16, "tippecanoe:min:POP_RANK": 7, "tippecanoe:sum:POP_RANK": 193, "tippecanoe:count:POP_YEAR": 15, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 30285, "tippecanoe:count:GDP_MD": 15, "tippecanoe:max:GDP_MD": 3861123, "tippecanoe:min:GDP_MD": 1563, "tippecanoe:sum:GDP_MD": 6399941, "tippecanoe:count:GDP_YEAR": 15, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2016, "tippecanoe:sum:GDP_YEAR": 30282, "tippecanoe:count:WOE_ID": 15, "tippecanoe:max:WOE_ID": 23424933, "tippecanoe:min:WOE_ID": -90, "tippecanoe:sum:WOE_ID": 317100741, "tippecanoe:count:WOE_ID_EH": 15, "tippecanoe:max:WOE_ID_EH": 23424933, "tippecanoe:min:WOE_ID_EH": 12577865, "tippecanoe:sum:WOE_ID_EH": 340525702, "tippecanoe:count:ADM0_A3_UN": 15, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -1485, "tippecanoe:count:ADM0_A3_WB": 15, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -1485, "tippecanoe:count:NAME_LEN": 15, "tippecanoe:max:NAME_LEN": 10, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 107, "tippecanoe:count:LONG_LEN": 15, "tippecanoe:max:LONG_LEN": 14, "tippecanoe:min:LONG_LEN": 6, "tippecanoe:sum:LONG_LEN": 122, "tippecanoe:count:ABBREV_LEN": 15, "tippecanoe:max:ABBREV_LEN": 5, "tippecanoe:min:ABBREV_LEN": 3, "tippecanoe:sum:ABBREV_LEN": 63, "tippecanoe:count:TINY": 15, "tippecanoe:max:TINY": 5, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -1381, "tippecanoe:count:HOMEPART": 15, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": -99, "tippecanoe:sum:HOMEPART": -85, "tippecanoe:count:MIN_ZOOM": 15, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 15, "tippecanoe:max:MIN_LABEL": 5, "tippecanoe:min:MIN_LABEL": 1.7, "tippecanoe:sum:MIN_LABEL": 51.900000000000009, "tippecanoe:count:MAX_LABEL": 15, "tippecanoe:max:MAX_LABEL": 10, "tippecanoe:min:MAX_LABEL": 6.7, "tippecanoe:sum:MAX_LABEL": 125.7, "tippecanoe:count:LABEL_X": 15, "tippecanoe:max:LABEL_X": 68.685548, "tippecanoe:min:LABEL_X": 9.018163, "tippecanoe:sum:LABEL_X": 352.04201299999996, "tippecanoe:count:LABEL_Y": 15, "tippecanoe:max:LABEL_Y": 60.156467, "tippecanoe:min:LABEL_Y": 45.733237, "tippecanoe:sum:LABEL_Y": 779.237302, "tippecanoe:count:NE_ID": 15, "tippecanoe:max:NE_ID": 1159321283, "tippecanoe:min:NE_ID": 1159320379, "tippecanoe:sum:NE_ID": 17389812239, "tippecanoe:mean:scalerank": 0.2, "tippecanoe:mean:LABELRANK": 4.466666666666667, "tippecanoe:mean:ADM0_DIF": 0.2, "tippecanoe:mean:LEVEL": 1.9333333333333334, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3.1333333333333335, "tippecanoe:mean:MAPCOLOR8": 3.2666666666666668, "tippecanoe:mean:MAPCOLOR9": 3.4, "tippecanoe:mean:MAPCOLOR13": 7.6, "tippecanoe:mean:POP_EST": 14516273.2, "tippecanoe:mean:POP_RANK": 12.866666666666668, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 426662.73333333336, "tippecanoe:mean:GDP_YEAR": 2018.8, "tippecanoe:mean:WOE_ID": 21140049.4, "tippecanoe:mean:WOE_ID_EH": 22701713.466666666, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 7.133333333333334, "tippecanoe:mean:LONG_LEN": 8.133333333333333, "tippecanoe:mean:ABBREV_LEN": 4.2, "tippecanoe:mean:TINY": -92.06666666666666, "tippecanoe:mean:HOMEPART": -5.666666666666667, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3.4600000000000006, "tippecanoe:mean:MAX_LABEL": 8.38, "tippecanoe:mean:LABEL_X": 23.46946753333333, "tippecanoe:mean:LABEL_Y": 51.949153466666668, "tippecanoe:mean:NE_ID": 1159320815.9333335, "tippecanoe:count": 15 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 105.029297, 77.998190 ], [ 108.808594, 76.930555 ], [ 105.952148, 75.297735 ], [ 99.272461, 74.959392 ], [ 94.130859, 76.163993 ], [ 95.537109, 77.888038 ], [ 97.558594, 77.998190 ], [ 105.029297, 77.998190 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a47fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 4, "tippecanoe:max:scalerank": 5, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 5, "tippecanoe:count:LABELRANK": 4, "tippecanoe:max:LABELRANK": 5, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 14, "tippecanoe:count:ADM0_DIF": 4, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 4, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 8, "tippecanoe:count:GEOU_DIF": 4, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 4, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 4, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 4, "tippecanoe:max:MAPCOLOR7": 6, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 12, "tippecanoe:count:MAPCOLOR8": 4, "tippecanoe:max:MAPCOLOR8": 5, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 12, "tippecanoe:count:MAPCOLOR9": 4, "tippecanoe:max:MAPCOLOR9": 8, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 14, "tippecanoe:count:MAPCOLOR13": 4, "tippecanoe:max:MAPCOLOR13": 13, "tippecanoe:min:MAPCOLOR13": 6, "tippecanoe:sum:MAPCOLOR13": 38, "tippecanoe:count:POP_EST": 4, "tippecanoe:max:POP_EST": 23310715, "tippecanoe:min:POP_EST": 502653, "tippecanoe:sum:POP_EST": 46537696, "tippecanoe:count:POP_RANK": 4, "tippecanoe:max:POP_RANK": 15, "tippecanoe:min:POP_RANK": 11, "tippecanoe:sum:POP_RANK": 53, "tippecanoe:count:POP_YEAR": 4, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 8076, "tippecanoe:count:GDP_MD": 4, "tippecanoe:max:GDP_MD": 52091, "tippecanoe:min:GDP_MD": 11314, "tippecanoe:sum:GDP_MD": 91305, "tippecanoe:count:GDP_YEAR": 4, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 8076, "tippecanoe:count:WOE_ID": 4, "tippecanoe:max:WOE_ID": 23424906, "tippecanoe:min:WOE_ID": 23424777, "tippecanoe:sum:WOE_ID": 93699462, "tippecanoe:count:WOE_ID_EH": 4, "tippecanoe:max:WOE_ID_EH": 23424906, "tippecanoe:min:WOE_ID_EH": 23424777, "tippecanoe:sum:WOE_ID_EH": 93699462, "tippecanoe:count:ADM0_A3_UN": 4, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -396, "tippecanoe:count:ADM0_A3_WB": 4, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -396, "tippecanoe:count:NAME_LEN": 4, "tippecanoe:max:NAME_LEN": 5, "tippecanoe:min:NAME_LEN": 4, "tippecanoe:sum:NAME_LEN": 19, "tippecanoe:count:LONG_LEN": 4, "tippecanoe:max:LONG_LEN": 5, "tippecanoe:min:LONG_LEN": 4, "tippecanoe:sum:LONG_LEN": 19, "tippecanoe:count:ABBREV_LEN": 4, "tippecanoe:max:ABBREV_LEN": 5, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 19, "tippecanoe:count:TINY": 4, "tippecanoe:max:TINY": 3, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -294, "tippecanoe:count:HOMEPART": 4, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 4, "tippecanoe:count:MIN_ZOOM": 4, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 4, "tippecanoe:max:MIN_LABEL": 4, "tippecanoe:min:MIN_LABEL": 3, "tippecanoe:sum:MIN_LABEL": 13, "tippecanoe:count:MAX_LABEL": 4, "tippecanoe:max:MAX_LABEL": 9, "tippecanoe:min:MAX_LABEL": 8, "tippecanoe:sum:MAX_LABEL": 33, "tippecanoe:count:LABEL_X": 4, "tippecanoe:max:LABEL_X": 18.645041, "tippecanoe:min:LABEL_X": 9.504356, "tippecanoe:sum:LABEL_X": 60.593417, "tippecanoe:count:LABEL_Y": 4, "tippecanoe:max:LABEL_Y": 35.892886, "tippecanoe:min:LABEL_Y": 15.142959, "tippecanoe:sum:LABEL_Y": 95.12098399999999, "tippecanoe:count:NE_ID": 4, "tippecanoe:max:NE_ID": 1159321301, "tippecanoe:min:NE_ID": 1159321017, "tippecanoe:sum:NE_ID": 4637284470, "tippecanoe:mean:scalerank": 1.25, "tippecanoe:mean:LABELRANK": 3.5, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 3, "tippecanoe:mean:MAPCOLOR9": 3.5, "tippecanoe:mean:MAPCOLOR13": 9.5, "tippecanoe:mean:POP_EST": 11634424, "tippecanoe:mean:POP_RANK": 13.25, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 22826.25, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424865.5, "tippecanoe:mean:WOE_ID_EH": 23424865.5, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 4.75, "tippecanoe:mean:LONG_LEN": 4.75, "tippecanoe:mean:ABBREV_LEN": 4.75, "tippecanoe:mean:TINY": -73.5, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3.25, "tippecanoe:mean:MAX_LABEL": 8.25, "tippecanoe:mean:LABEL_X": 15.14835425, "tippecanoe:mean:LABEL_Y": 23.780245999999999, "tippecanoe:mean:NE_ID": 1159321117.5, "tippecanoe:count": 4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 97.734375, 73.264704 ], [ 101.777344, 71.992578 ], [ 100.239258, 70.333533 ], [ 95.405273, 69.900118 ], [ 91.450195, 71.031249 ], [ 92.197266, 72.724958 ], [ 97.734375, 73.264704 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a5ffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 3, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 3, "tippecanoe:max:LABELRANK": 8, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 15, "tippecanoe:count:ADM0_DIF": 3, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 3, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 6, "tippecanoe:count:GEOU_DIF": 3, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 3, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 3, "tippecanoe:max:BRK_DIFF": 1, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 1, "tippecanoe:count:MAPCOLOR7": 3, "tippecanoe:max:MAPCOLOR7": 3, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 6, "tippecanoe:count:MAPCOLOR8": 3, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 8, "tippecanoe:count:MAPCOLOR9": 3, "tippecanoe:max:MAPCOLOR9": 4, "tippecanoe:min:MAPCOLOR9": 2, "tippecanoe:sum:MAPCOLOR9": 8, "tippecanoe:count:MAPCOLOR13": 3, "tippecanoe:max:MAPCOLOR13": 12, "tippecanoe:min:MAPCOLOR13": 1, "tippecanoe:sum:MAPCOLOR13": 18, "tippecanoe:count:POP_EST": 3, "tippecanoe:max:POP_EST": 42813238, "tippecanoe:min:POP_EST": 0, "tippecanoe:sum:POP_EST": 48894434, "tippecanoe:count:POP_RANK": 3, "tippecanoe:max:POP_RANK": 15, "tippecanoe:min:POP_RANK": 1, "tippecanoe:sum:POP_RANK": 29, "tippecanoe:count:POP_YEAR": 3, "tippecanoe:max:POP_YEAR": 2020, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 6058, "tippecanoe:count:GDP_MD": 3, "tippecanoe:max:GDP_MD": 30513, "tippecanoe:min:GDP_MD": 0, "tippecanoe:sum:GDP_MD": 32578, "tippecanoe:count:GDP_YEAR": 3, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2011, "tippecanoe:sum:GDP_YEAR": 6049, "tippecanoe:count:WOE_ID": 3, "tippecanoe:max:WOE_ID": 23424806, "tippecanoe:min:WOE_ID": -99, "tippecanoe:sum:WOE_ID": 23424617, "tippecanoe:count:WOE_ID_EH": 3, "tippecanoe:max:WOE_ID_EH": 23424952, "tippecanoe:min:WOE_ID_EH": -99, "tippecanoe:sum:WOE_ID_EH": 46849659, "tippecanoe:count:ADM0_A3_UN": 3, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -297, "tippecanoe:count:ADM0_A3_WB": 3, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -297, "tippecanoe:count:NAME_LEN": 3, "tippecanoe:max:NAME_LEN": 9, "tippecanoe:min:NAME_LEN": 5, "tippecanoe:sum:NAME_LEN": 21, "tippecanoe:count:LONG_LEN": 3, "tippecanoe:max:LONG_LEN": 9, "tippecanoe:min:LONG_LEN": 5, "tippecanoe:sum:LONG_LEN": 21, "tippecanoe:count:ABBREV_LEN": 3, "tippecanoe:max:ABBREV_LEN": 8, "tippecanoe:min:ABBREV_LEN": 5, "tippecanoe:sum:ABBREV_LEN": 18, "tippecanoe:count:TINY": 3, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -297, "tippecanoe:count:HOMEPART": 3, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": -99, "tippecanoe:sum:HOMEPART": -97, "tippecanoe:count:MIN_ZOOM": 3, "tippecanoe:max:MIN_ZOOM": 7, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 7, "tippecanoe:count:MIN_LABEL": 3, "tippecanoe:max:MIN_LABEL": 7, "tippecanoe:min:MIN_LABEL": 2.5, "tippecanoe:sum:MIN_LABEL": 13.5, "tippecanoe:count:MAX_LABEL": 3, "tippecanoe:max:MAX_LABEL": 9, "tippecanoe:min:MAX_LABEL": 8, "tippecanoe:sum:MAX_LABEL": 26, "tippecanoe:count:LABEL_X": 3, "tippecanoe:max:LABEL_X": 38.285566, "tippecanoe:min:LABEL_X": 29.260657, "tippecanoe:sum:LABEL_X": 101.219651, "tippecanoe:count:LABEL_Y": 3, "tippecanoe:max:LABEL_Y": 21.860442, "tippecanoe:min:LABEL_Y": 15.787401, "tippecanoe:sum:LABEL_Y": 53.978589, "tippecanoe:count:NE_ID": 3, "tippecanoe:max:NE_ID": 1729635091, "tippecanoe:min:NE_ID": 1159320581, "tippecanoe:sum:NE_ID": 4048276901, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 5, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0.3333333333333333, "tippecanoe:mean:MAPCOLOR7": 2, "tippecanoe:mean:MAPCOLOR8": 2.6666666666666667, "tippecanoe:mean:MAPCOLOR9": 2.6666666666666667, "tippecanoe:mean:MAPCOLOR13": 6, "tippecanoe:mean:POP_EST": 16298144.666666666, "tippecanoe:mean:POP_RANK": 9.666666666666666, "tippecanoe:mean:POP_YEAR": 2019.3333333333333, "tippecanoe:mean:GDP_MD": 10859.333333333334, "tippecanoe:mean:GDP_YEAR": 2016.3333333333333, "tippecanoe:mean:WOE_ID": 7808205.666666667, "tippecanoe:mean:WOE_ID_EH": 15616553, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 7, "tippecanoe:mean:LONG_LEN": 7, "tippecanoe:mean:ABBREV_LEN": 6, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": -32.333333333333339, "tippecanoe:mean:MIN_ZOOM": 2.3333333333333337, "tippecanoe:mean:MIN_LABEL": 4.5, "tippecanoe:mean:MAX_LABEL": 8.666666666666666, "tippecanoe:mean:LABEL_X": 33.739883666666667, "tippecanoe:mean:LABEL_Y": 17.992863, "tippecanoe:mean:NE_ID": 1349425633.6666668, "tippecanoe:count": 3 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 107.402344, 72.248917 ], [ 110.566406, 70.801366 ], [ 108.413086, 69.224997 ], [ 103.579102, 69.021414 ], [ 100.239258, 70.333533 ], [ 101.777344, 71.992578 ], [ 107.402344, 72.248917 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820a57fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 2, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 2, "tippecanoe:max:LABELRANK": 4, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 7, "tippecanoe:count:ADM0_DIF": 2, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 2, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 4, "tippecanoe:count:GEOU_DIF": 2, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 2, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 2, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 2, "tippecanoe:max:MAPCOLOR7": 5, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 6, "tippecanoe:count:MAPCOLOR8": 2, "tippecanoe:max:MAPCOLOR8": 6, "tippecanoe:min:MAPCOLOR8": 4, "tippecanoe:sum:MAPCOLOR8": 10, "tippecanoe:count:MAPCOLOR9": 2, "tippecanoe:max:MAPCOLOR9": 6, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 7, "tippecanoe:count:MAPCOLOR13": 2, "tippecanoe:max:MAPCOLOR13": 9, "tippecanoe:min:MAPCOLOR13": 3, "tippecanoe:sum:MAPCOLOR13": 12, "tippecanoe:count:POP_EST": 2, "tippecanoe:max:POP_EST": 25876380, "tippecanoe:min:POP_EST": 4745185, "tippecanoe:sum:POP_EST": 30621565, "tippecanoe:count:POP_RANK": 2, "tippecanoe:max:POP_RANK": 15, "tippecanoe:min:POP_RANK": 12, "tippecanoe:sum:POP_RANK": 27, "tippecanoe:count:POP_YEAR": 2, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 4038, "tippecanoe:count:GDP_MD": 2, "tippecanoe:max:GDP_MD": 39007, "tippecanoe:min:GDP_MD": 2220, "tippecanoe:sum:GDP_MD": 41227, "tippecanoe:count:GDP_YEAR": 2, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 4038, "tippecanoe:count:WOE_ID": 2, "tippecanoe:max:WOE_ID": 23424792, "tippecanoe:min:WOE_ID": 23424785, "tippecanoe:sum:WOE_ID": 46849577, "tippecanoe:count:WOE_ID_EH": 2, "tippecanoe:max:WOE_ID_EH": 23424792, "tippecanoe:min:WOE_ID_EH": 23424785, "tippecanoe:sum:WOE_ID_EH": 46849577, "tippecanoe:count:ADM0_A3_UN": 2, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -198, "tippecanoe:count:ADM0_A3_WB": 2, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -198, "tippecanoe:count:NAME_LEN": 2, "tippecanoe:max:NAME_LEN": 20, "tippecanoe:min:NAME_LEN": 8, "tippecanoe:sum:NAME_LEN": 28, "tippecanoe:count:LONG_LEN": 2, "tippecanoe:max:LONG_LEN": 24, "tippecanoe:min:LONG_LEN": 8, "tippecanoe:sum:LONG_LEN": 32, "tippecanoe:count:ABBREV_LEN": 2, "tippecanoe:max:ABBREV_LEN": 6, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 10, "tippecanoe:count:TINY": 2, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -198, "tippecanoe:count:HOMEPART": 2, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 2, "tippecanoe:count:MIN_ZOOM": 2, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 2, "tippecanoe:max:MIN_LABEL": 4, "tippecanoe:min:MIN_LABEL": 3, "tippecanoe:sum:MIN_LABEL": 7, "tippecanoe:count:MAX_LABEL": 2, "tippecanoe:max:MAX_LABEL": 9, "tippecanoe:min:MAX_LABEL": 8, "tippecanoe:sum:MAX_LABEL": 17, "tippecanoe:count:LABEL_X": 2, "tippecanoe:max:LABEL_X": 20.906897, "tippecanoe:min:LABEL_X": 12.473488, "tippecanoe:sum:LABEL_X": 33.380385000000007, "tippecanoe:count:LABEL_Y": 2, "tippecanoe:max:LABEL_Y": 6.989681, "tippecanoe:min:LABEL_Y": 4.585041, "tippecanoe:sum:LABEL_Y": 11.574722000000002, "tippecanoe:count:NE_ID": 2, "tippecanoe:max:NE_ID": 1159320509, "tippecanoe:min:NE_ID": 1159320463, "tippecanoe:sum:NE_ID": 2318640972, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 3.5, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 5, "tippecanoe:mean:MAPCOLOR9": 3.5, "tippecanoe:mean:MAPCOLOR13": 6, "tippecanoe:mean:POP_EST": 15310782.5, "tippecanoe:mean:POP_RANK": 13.5, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 20613.5, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424788.5, "tippecanoe:mean:WOE_ID_EH": 23424788.5, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 14, "tippecanoe:mean:LONG_LEN": 16, "tippecanoe:mean:ABBREV_LEN": 5, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3.5, "tippecanoe:mean:MAX_LABEL": 8.5, "tippecanoe:mean:LABEL_X": 16.690192500000003, "tippecanoe:mean:LABEL_Y": 5.787361000000001, "tippecanoe:mean:NE_ID": 1159320486, "tippecanoe:count": 2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 100.239258, 70.333533 ], [ 103.579102, 69.021414 ], [ 102.216797, 67.491751 ], [ 96.635742, 67.491751 ], [ 94.526367, 68.236823 ], [ 95.405273, 69.900118 ], [ 100.239258, 70.333533 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "82059ffffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 1, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 1, "tippecanoe:max:LABELRANK": 3, "tippecanoe:min:LABELRANK": 3, "tippecanoe:sum:LABELRANK": 3, "tippecanoe:count:ADM0_DIF": 1, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 1, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 2, "tippecanoe:count:GEOU_DIF": 1, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 1, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 1, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 1, "tippecanoe:max:MAPCOLOR7": 3, "tippecanoe:min:MAPCOLOR7": 3, "tippecanoe:sum:MAPCOLOR7": 3, "tippecanoe:count:MAPCOLOR8": 1, "tippecanoe:max:MAPCOLOR8": 5, "tippecanoe:min:MAPCOLOR8": 5, "tippecanoe:sum:MAPCOLOR8": 5, "tippecanoe:count:MAPCOLOR9": 1, "tippecanoe:max:MAPCOLOR9": 4, "tippecanoe:min:MAPCOLOR9": 4, "tippecanoe:sum:MAPCOLOR9": 4, "tippecanoe:count:MAPCOLOR13": 1, "tippecanoe:max:MAPCOLOR13": 9, "tippecanoe:min:MAPCOLOR13": 9, "tippecanoe:sum:MAPCOLOR13": 9, "tippecanoe:count:POP_EST": 1, "tippecanoe:max:POP_EST": 21803000, "tippecanoe:min:POP_EST": 21803000, "tippecanoe:sum:POP_EST": 21803000, "tippecanoe:count:POP_RANK": 1, "tippecanoe:max:POP_RANK": 15, "tippecanoe:min:POP_RANK": 15, "tippecanoe:sum:POP_RANK": 15, "tippecanoe:count:POP_YEAR": 1, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 2019, "tippecanoe:count:GDP_MD": 1, "tippecanoe:max:GDP_MD": 84008, "tippecanoe:min:GDP_MD": 84008, "tippecanoe:sum:GDP_MD": 84008, "tippecanoe:count:GDP_YEAR": 1, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 2019, "tippecanoe:count:WOE_ID": 1, "tippecanoe:max:WOE_ID": 23424778, "tippecanoe:min:WOE_ID": 23424778, "tippecanoe:sum:WOE_ID": 23424778, "tippecanoe:count:WOE_ID_EH": 1, "tippecanoe:max:WOE_ID_EH": 23424778, "tippecanoe:min:WOE_ID_EH": 23424778, "tippecanoe:sum:WOE_ID_EH": 23424778, "tippecanoe:count:ADM0_A3_UN": 1, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -99, "tippecanoe:count:ADM0_A3_WB": 1, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -99, "tippecanoe:count:NAME_LEN": 1, "tippecanoe:max:NAME_LEN": 9, "tippecanoe:min:NAME_LEN": 9, "tippecanoe:sum:NAME_LEN": 9, "tippecanoe:count:LONG_LEN": 1, "tippecanoe:max:LONG_LEN": 9, "tippecanoe:min:LONG_LEN": 9, "tippecanoe:sum:LONG_LEN": 9, "tippecanoe:count:ABBREV_LEN": 1, "tippecanoe:max:ABBREV_LEN": 6, "tippecanoe:min:ABBREV_LEN": 6, "tippecanoe:sum:ABBREV_LEN": 6, "tippecanoe:count:TINY": 1, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -99, "tippecanoe:count:HOMEPART": 1, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 1, "tippecanoe:count:MIN_ZOOM": 1, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 1, "tippecanoe:max:MIN_LABEL": 3, "tippecanoe:min:MIN_LABEL": 3, "tippecanoe:sum:MIN_LABEL": 3, "tippecanoe:count:MAX_LABEL": 1, "tippecanoe:max:MAX_LABEL": 8, "tippecanoe:min:MAX_LABEL": 8, "tippecanoe:sum:MAX_LABEL": 8, "tippecanoe:count:LABEL_X": 1, "tippecanoe:max:LABEL_X": 80.704823, "tippecanoe:min:LABEL_X": 80.704823, "tippecanoe:sum:LABEL_X": 80.704823, "tippecanoe:count:LABEL_Y": 1, "tippecanoe:max:LABEL_Y": 7.581097, "tippecanoe:min:LABEL_Y": 7.581097, "tippecanoe:sum:LABEL_Y": 7.581097, "tippecanoe:count:NE_ID": 1, "tippecanoe:max:NE_ID": 1159321025, "tippecanoe:min:NE_ID": 1159321025, "tippecanoe:sum:NE_ID": 1159321025, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 3, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 3, "tippecanoe:mean:MAPCOLOR8": 5, "tippecanoe:mean:MAPCOLOR9": 4, "tippecanoe:mean:MAPCOLOR13": 9, "tippecanoe:mean:POP_EST": 21803000, "tippecanoe:mean:POP_RANK": 15, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 84008, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424778, "tippecanoe:mean:WOE_ID_EH": 23424778, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 9, "tippecanoe:mean:LONG_LEN": 9, "tippecanoe:mean:ABBREV_LEN": 6, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 3, "tippecanoe:mean:MAX_LABEL": 8, "tippecanoe:mean:LABEL_X": 80.704823, "tippecanoe:mean:LABEL_Y": 7.581097, "tippecanoe:mean:NE_ID": 1159321025, "tippecanoe:count": 1 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 126.562500, 70.348318 ], [ 131.660156, 69.900118 ], [ 132.758789, 68.155209 ], [ 130.869141, 67.491751 ], [ 124.804688, 67.491751 ], [ 123.266602, 69.005675 ], [ 126.562500, 70.348318 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin": "820587fffffffff", "felt:h3_level": 2, "tippecanoe:count:scalerank": 2, "tippecanoe:max:scalerank": 0, "tippecanoe:min:scalerank": 0, "tippecanoe:sum:scalerank": 0, "tippecanoe:count:LABELRANK": 2, "tippecanoe:max:LABELRANK": 4, "tippecanoe:min:LABELRANK": 4, "tippecanoe:sum:LABELRANK": 8, "tippecanoe:count:ADM0_DIF": 2, "tippecanoe:max:ADM0_DIF": 0, "tippecanoe:min:ADM0_DIF": 0, "tippecanoe:sum:ADM0_DIF": 0, "tippecanoe:count:LEVEL": 2, "tippecanoe:max:LEVEL": 2, "tippecanoe:min:LEVEL": 2, "tippecanoe:sum:LEVEL": 4, "tippecanoe:count:GEOU_DIF": 2, "tippecanoe:max:GEOU_DIF": 0, "tippecanoe:min:GEOU_DIF": 0, "tippecanoe:sum:GEOU_DIF": 0, "tippecanoe:count:SU_DIF": 2, "tippecanoe:max:SU_DIF": 0, "tippecanoe:min:SU_DIF": 0, "tippecanoe:sum:SU_DIF": 0, "tippecanoe:count:BRK_DIFF": 2, "tippecanoe:max:BRK_DIFF": 0, "tippecanoe:min:BRK_DIFF": 0, "tippecanoe:sum:BRK_DIFF": 0, "tippecanoe:count:MAPCOLOR7": 2, "tippecanoe:max:MAPCOLOR7": 2, "tippecanoe:min:MAPCOLOR7": 1, "tippecanoe:sum:MAPCOLOR7": 3, "tippecanoe:count:MAPCOLOR8": 2, "tippecanoe:max:MAPCOLOR8": 4, "tippecanoe:min:MAPCOLOR8": 1, "tippecanoe:sum:MAPCOLOR8": 5, "tippecanoe:count:MAPCOLOR9": 2, "tippecanoe:max:MAPCOLOR9": 3, "tippecanoe:min:MAPCOLOR9": 1, "tippecanoe:sum:MAPCOLOR9": 4, "tippecanoe:count:MAPCOLOR13": 2, "tippecanoe:max:MAPCOLOR13": 6, "tippecanoe:min:MAPCOLOR13": 3, "tippecanoe:sum:MAPCOLOR13": 9, "tippecanoe:count:POP_EST": 2, "tippecanoe:max:POP_EST": 9770529, "tippecanoe:min:POP_EST": 4974986, "tippecanoe:sum:POP_EST": 14745515, "tippecanoe:count:POP_RANK": 2, "tippecanoe:max:POP_RANK": 13, "tippecanoe:min:POP_RANK": 12, "tippecanoe:sum:POP_RANK": 25, "tippecanoe:count:POP_YEAR": 2, "tippecanoe:max:POP_YEAR": 2019, "tippecanoe:min:POP_YEAR": 2019, "tippecanoe:sum:POP_YEAR": 4038, "tippecanoe:count:GDP_MD": 2, "tippecanoe:max:GDP_MD": 421142, "tippecanoe:min:GDP_MD": 76331, "tippecanoe:sum:GDP_MD": 497473, "tippecanoe:count:GDP_YEAR": 2, "tippecanoe:max:GDP_YEAR": 2019, "tippecanoe:min:GDP_YEAR": 2019, "tippecanoe:sum:GDP_YEAR": 4038, "tippecanoe:count:WOE_ID": 2, "tippecanoe:max:WOE_ID": 23424898, "tippecanoe:min:WOE_ID": 23424738, "tippecanoe:sum:WOE_ID": 46849636, "tippecanoe:count:WOE_ID_EH": 2, "tippecanoe:max:WOE_ID_EH": 23424898, "tippecanoe:min:WOE_ID_EH": 23424738, "tippecanoe:sum:WOE_ID_EH": 46849636, "tippecanoe:count:ADM0_A3_UN": 2, "tippecanoe:max:ADM0_A3_UN": -99, "tippecanoe:min:ADM0_A3_UN": -99, "tippecanoe:sum:ADM0_A3_UN": -198, "tippecanoe:count:ADM0_A3_WB": 2, "tippecanoe:max:ADM0_A3_WB": -99, "tippecanoe:min:ADM0_A3_WB": -99, "tippecanoe:sum:ADM0_A3_WB": -198, "tippecanoe:count:NAME_LEN": 2, "tippecanoe:max:NAME_LEN": 20, "tippecanoe:min:NAME_LEN": 4, "tippecanoe:sum:NAME_LEN": 24, "tippecanoe:count:LONG_LEN": 2, "tippecanoe:max:LONG_LEN": 20, "tippecanoe:min:LONG_LEN": 4, "tippecanoe:sum:LONG_LEN": 24, "tippecanoe:count:ABBREV_LEN": 2, "tippecanoe:max:ABBREV_LEN": 6, "tippecanoe:min:ABBREV_LEN": 4, "tippecanoe:sum:ABBREV_LEN": 10, "tippecanoe:count:TINY": 2, "tippecanoe:max:TINY": -99, "tippecanoe:min:TINY": -99, "tippecanoe:sum:TINY": -198, "tippecanoe:count:HOMEPART": 2, "tippecanoe:max:HOMEPART": 1, "tippecanoe:min:HOMEPART": 1, "tippecanoe:sum:HOMEPART": 2, "tippecanoe:count:MIN_ZOOM": 2, "tippecanoe:max:MIN_ZOOM": 0, "tippecanoe:min:MIN_ZOOM": 0, "tippecanoe:sum:MIN_ZOOM": 0, "tippecanoe:count:MIN_LABEL": 2, "tippecanoe:max:MIN_LABEL": 4, "tippecanoe:min:MIN_LABEL": 4, "tippecanoe:sum:MIN_LABEL": 8, "tippecanoe:count:MAX_LABEL": 2, "tippecanoe:max:MAX_LABEL": 9, "tippecanoe:min:MAX_LABEL": 9, "tippecanoe:sum:MAX_LABEL": 18, "tippecanoe:count:LABEL_X": 2, "tippecanoe:max:LABEL_X": 57.336553, "tippecanoe:min:LABEL_X": 54.547256, "tippecanoe:sum:LABEL_X": 111.883809, "tippecanoe:count:LABEL_Y": 2, "tippecanoe:max:LABEL_Y": 23.466285, "tippecanoe:min:LABEL_Y": 22.120427, "tippecanoe:sum:LABEL_Y": 45.586712, "tippecanoe:count:NE_ID": 2, "tippecanoe:max:NE_ID": 1159321151, "tippecanoe:min:NE_ID": 1159320329, "tippecanoe:sum:NE_ID": 2318641480, "tippecanoe:mean:scalerank": 0, "tippecanoe:mean:LABELRANK": 4, "tippecanoe:mean:ADM0_DIF": 0, "tippecanoe:mean:LEVEL": 2, "tippecanoe:mean:GEOU_DIF": 0, "tippecanoe:mean:SU_DIF": 0, "tippecanoe:mean:BRK_DIFF": 0, "tippecanoe:mean:MAPCOLOR7": 1.5, "tippecanoe:mean:MAPCOLOR8": 2.5, "tippecanoe:mean:MAPCOLOR9": 2, "tippecanoe:mean:MAPCOLOR13": 4.5, "tippecanoe:mean:POP_EST": 7372757.5, "tippecanoe:mean:POP_RANK": 12.5, "tippecanoe:mean:POP_YEAR": 2019, "tippecanoe:mean:GDP_MD": 248736.5, "tippecanoe:mean:GDP_YEAR": 2019, "tippecanoe:mean:WOE_ID": 23424818, "tippecanoe:mean:WOE_ID_EH": 23424818, "tippecanoe:mean:ADM0_A3_UN": -99, "tippecanoe:mean:ADM0_A3_WB": -99, "tippecanoe:mean:NAME_LEN": 12, "tippecanoe:mean:LONG_LEN": 12, "tippecanoe:mean:ABBREV_LEN": 5, "tippecanoe:mean:TINY": -99, "tippecanoe:mean:HOMEPART": 1, "tippecanoe:mean:MIN_ZOOM": 0, "tippecanoe:mean:MIN_LABEL": 4, "tippecanoe:mean:MAX_LABEL": 9, "tippecanoe:mean:LABEL_X": 55.9419045, "tippecanoe:mean:LABEL_Y": 22.793356, "tippecanoe:mean:NE_ID": 1159320740, "tippecanoe:count": 2 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 118.959961, 72.289067 ], [ 124.760742, 72.046840 ], [ 126.562500, 70.348318 ], [ 123.266602, 69.005675 ], [ 118.300781, 69.224997 ], [ 115.927734, 70.801366 ], [ 118.959961, 72.289067 ] ] ] } } +] } +] } From 0a4f6fe546d94b53ce57605c01c04b8b28136a84 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Thu, 21 Nov 2024 15:44:46 -0800 Subject: [PATCH 05/24] Factoring out geometry parsing from feature parsing --- geojson.cpp | 2 +- plugin.cpp | 2 +- read_json.cpp | 252 ++++++++++++++++++++++++++------------------------ read_json.hpp | 2 +- 4 files changed, 134 insertions(+), 124 deletions(-) diff --git a/geojson.cpp b/geojson.cpp index dae22ec3..3798d14b 100644 --- a/geojson.cpp +++ b/geojson.cpp @@ -199,7 +199,7 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom } drawvec dv; - parse_geometry(t, coordinates, dv, VT_MOVETO, sst->fname, sst->line, feature); + parse_coordinates(t, coordinates, dv, VT_MOVETO, sst->fname, sst->line, feature); serial_feature sf; sf.layer = layer; diff --git a/plugin.cpp b/plugin.cpp index 856bb14b..cfe06593 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -223,7 +223,7 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std:: } drawvec dv; - parse_geometry(t, coordinates, dv, VT_MOVETO, "Filter output", jp->line, j); + parse_coordinates(t, coordinates, dv, VT_MOVETO, "Filter output", jp->line, j); if (mb_geometry[t] == VT_POLYGON) { dv = fix_polygon(dv, false, false); } diff --git a/read_json.cpp b/read_json.cpp index c439f265..bf5a5e3f 100644 --- a/read_json.cpp +++ b/read_json.cpp @@ -53,7 +53,7 @@ void json_context(json_object *j) { free(s); // stringify } -void parse_geometry(int t, json_object *j, drawvec &out, int op, const char *fname, int line, json_object *feature) { +void parse_coordinates(int t, json_object *j, drawvec &out, int op, const char *fname, int line, json_object *feature) { if (j == NULL || j->type != JSON_ARRAY) { fprintf(stderr, "%s:%d: expected array for geometry type %d: ", fname, line, t); json_context(feature); @@ -72,7 +72,7 @@ void parse_geometry(int t, json_object *j, drawvec &out, int op, const char *fna } } - parse_geometry(within, j->value.array.array[i], out, op, fname, line, feature); + parse_coordinates(within, j->value.array.array[i], out, op, fname, line, feature); } } else { if (j->value.array.length >= 2 && j->value.array.array[0]->type == JSON_NUMBER && j->value.array.array[1]->type == JSON_NUMBER) { @@ -178,6 +178,126 @@ static std::vector to_feature(drawvec &geom) { return out; } +std::pair parse_geometry(json_object *geometry, json_pull *jp, json_object *j, + int z, int x, int y, int extent, bool fix_longitudes) { + json_object *geometry_type = json_hash_get(geometry, "type"); + if (geometry_type == NULL) { + fprintf(stderr, "Filter output:%d: null geometry (additional not reported): ", jp->line); + json_context(j); + exit(EXIT_JSON); + } + + if (geometry_type->type != JSON_STRING) { + fprintf(stderr, "Filter output:%d: geometry type is not a string: ", jp->line); + json_context(j); + exit(EXIT_JSON); + } + + json_object *coordinates = json_hash_get(geometry, "coordinates"); + if (coordinates == NULL || coordinates->type != JSON_ARRAY) { + fprintf(stderr, "Filter output:%d: geometry without coordinates array: ", jp->line); + json_context(j); + exit(EXIT_JSON); + } + + int t; + for (t = 0; t < GEOM_TYPES; t++) { + if (strcmp(geometry_type->value.string.string, geometry_names[t]) == 0) { + break; + } + } + if (t >= GEOM_TYPES) { + fprintf(stderr, "Filter output:%d: Can't handle geometry type %s: ", jp->line, geometry_type->value.string.string); + json_context(j); + exit(EXIT_JSON); + } + + drawvec dv; + parse_coordinates(t, coordinates, dv, VT_MOVETO, "Filter output", jp->line, j); + + // handle longitude wraparound + // + // this is supposed to be data for a single tile, + // so any jump from the left hand side edge of the world + // to the right edge, or vice versa, is unexpected, + // so move it to the other side. + + if (fix_longitudes && mb_geometry[t] == VT_POLYGON) { + const long long quarter_world = 1LL << 30; + const long long world = 1LL << 32; + + bool copy_to_left = false; + bool copy_to_right = false; + + for (size_t i = 0; i < dv.size(); i++) { + // is this vertex on a different side of the world + // than the first vertex? then shift this one to match + if (i > 0) { + if ((dv[0].x < quarter_world) && (dv[i].x > 3 * quarter_world)) { + dv[i].x -= world; + } + if ((dv[0].x > 3 * quarter_world) && (dv[i].x < quarter_world)) { + dv[i].x += world; + } + } + + // does it stick off the edge of the world? + // then we need another copy on the other side of the world + if (dv[i].x < 0) { + copy_to_right = true; + } + if (dv[i].x > world) { + copy_to_left = true; + } + } + + if (copy_to_left) { + size_t n = dv.size(); + for (size_t i = 0; i < n; i++) { + dv.emplace_back(dv[i].op, dv[i].x - world, (long long) dv[i].y); + } + } + if (copy_to_right) { + size_t n = dv.size(); + for (size_t i = 0; i < n; i++) { + dv.emplace_back(dv[i].op, dv[i].x + world, (long long) dv[i].y); + } + } + } + + if (mb_geometry[t] == VT_POLYGON) { + dv = fix_polygon(dv, false, false); + } + + // Offset and scale geometry from global to tile + for (size_t i = 0; i < dv.size(); i++) { + long long scale = 1LL << (32 - z); + + // offset to tile + dv[i].x -= scale * x; + dv[i].y -= scale * y; + + // scale to tile + dv[i].x = std::round(dv[i].x * extent / (double) scale); + dv[i].y = std::round(dv[i].y * extent / (double) scale); + } + + if (mb_geometry[t] == VT_POLYGON) { + // don't try scaling up because we may have coordinates + // on the other side of the world + dv = clean_or_clip_poly(dv, z, 256, true, false); + if (dv.size() < 3) { + dv.clear(); + } + } + dv = remove_noop(dv, mb_geometry[t], 0); + if (mb_geometry[t] == VT_POLYGON) { + dv = close_poly(dv); + } + + return std::pair(t, dv); +} + std::vector parse_layers(FILE *fp, int z, unsigned x, unsigned y, int extent, bool fix_longitudes) { std::map ret; std::shared_ptr tile_stringpool = std::make_shared(); @@ -208,14 +328,6 @@ std::vector parse_layers(FILE *fp, int z, unsigned x, unsigned y, int continue; } - json_object *geometry = json_hash_get(j, "geometry"); - if (geometry == NULL) { - fprintf(stderr, "Filter output:%d: filtered feature with no geometry: ", jp->line); - json_context(j); - json_free(j); - exit(EXIT_JSON); - } - json_object *properties = json_hash_get(j, "properties"); if (properties == NULL || (properties->type != JSON_HASH && properties->type != JSON_NULL)) { fprintf(stderr, "Filter output:%d: feature without properties hash: ", jp->line); @@ -224,38 +336,6 @@ std::vector parse_layers(FILE *fp, int z, unsigned x, unsigned y, int exit(EXIT_JSON); } - json_object *geometry_type = json_hash_get(geometry, "type"); - if (geometry_type == NULL) { - fprintf(stderr, "Filter output:%d: null geometry (additional not reported): ", jp->line); - json_context(j); - exit(EXIT_JSON); - } - - if (geometry_type->type != JSON_STRING) { - fprintf(stderr, "Filter output:%d: geometry type is not a string: ", jp->line); - json_context(j); - exit(EXIT_JSON); - } - - json_object *coordinates = json_hash_get(geometry, "coordinates"); - if (coordinates == NULL || coordinates->type != JSON_ARRAY) { - fprintf(stderr, "Filter output:%d: feature without coordinates array: ", jp->line); - json_context(j); - exit(EXIT_JSON); - } - - int t; - for (t = 0; t < GEOM_TYPES; t++) { - if (strcmp(geometry_type->value.string.string, geometry_names[t]) == 0) { - break; - } - } - if (t >= GEOM_TYPES) { - fprintf(stderr, "Filter output:%d: Can't handle geometry type %s: ", jp->line, geometry_type->value.string.string); - json_context(j); - exit(EXIT_JSON); - } - std::string layername = "unknown"; json_object *tippecanoe = json_hash_get(j, "tippecanoe"); json_object *layer = NULL; @@ -276,88 +356,18 @@ std::vector parse_layers(FILE *fp, int z, unsigned x, unsigned y, int } auto l = ret.find(layername); - drawvec dv; - parse_geometry(t, coordinates, dv, VT_MOVETO, "Filter output", jp->line, j); - - // handle longitude wraparound - // - // this is supposed to be data for a single tile, - // so any jump from the left hand side edge of the world - // to the right edge, or vice versa, is unexpected, - // so move it to the other side. - - if (fix_longitudes && mb_geometry[t] == VT_POLYGON) { - const long long quarter_world = 1LL << 30; - const long long world = 1LL << 32; - - bool copy_to_left = false; - bool copy_to_right = false; - - for (size_t i = 0; i < dv.size(); i++) { - // is this vertex on a different side of the world - // than the first vertex? then shift this one to match - if (i > 0) { - if ((dv[0].x < quarter_world) && (dv[i].x > 3 * quarter_world)) { - dv[i].x -= world; - } - if ((dv[0].x > 3 * quarter_world) && (dv[i].x < quarter_world)) { - dv[i].x += world; - } - } - - // does it stick off the edge of the world? - // then we need another copy on the other side of the world - if (dv[i].x < 0) { - copy_to_right = true; - } - if (dv[i].x > world) { - copy_to_left = true; - } - } - - if (copy_to_left) { - size_t n = dv.size(); - for (size_t i = 0; i < n; i++) { - dv.emplace_back(dv[i].op, dv[i].x - world, (long long) dv[i].y); - } - } - if (copy_to_right) { - size_t n = dv.size(); - for (size_t i = 0; i < n; i++) { - dv.emplace_back(dv[i].op, dv[i].x + world, (long long) dv[i].y); - } - } - } - - if (mb_geometry[t] == VT_POLYGON) { - dv = fix_polygon(dv, false, false); + json_object *geometry = json_hash_get(j, "geometry"); + if (geometry == NULL) { + fprintf(stderr, "Filter output:%d: filtered feature with no geometry: ", jp->line); + json_context(j); + json_free(j); + exit(EXIT_JSON); } - // Offset and scale geometry from global to tile - for (size_t i = 0; i < dv.size(); i++) { - long long scale = 1LL << (32 - z); - - // offset to tile - dv[i].x -= scale * x; - dv[i].y -= scale * y; + std::pair parsed_geometry = parse_geometry(geometry, jp, j, z, x, y, extent, fix_longitudes); - // scale to tile - dv[i].x = std::round(dv[i].x * extent / (double) scale); - dv[i].y = std::round(dv[i].y * extent / (double) scale); - } - - if (mb_geometry[t] == VT_POLYGON) { - // don't try scaling up because we may have coordinates - // on the other side of the world - dv = clean_or_clip_poly(dv, z, 256, true, false); - if (dv.size() < 3) { - dv.clear(); - } - } - dv = remove_noop(dv, mb_geometry[t], 0); - if (mb_geometry[t] == VT_POLYGON) { - dv = close_poly(dv); - } + int t = parsed_geometry.first; + drawvec &dv = parsed_geometry.second; if (dv.size() > 0) { mvt_feature feature; diff --git a/read_json.hpp b/read_json.hpp index 487329c6..84e0853b 100644 --- a/read_json.hpp +++ b/read_json.hpp @@ -11,7 +11,7 @@ extern int geometry_within[GEOM_TYPES]; extern int mb_geometry[GEOM_TYPES]; void json_context(json_object *j); -void parse_geometry(int t, json_object *j, drawvec &out, int op, const char *fname, int line, json_object *feature); +void parse_coordinates(int t, json_object *j, drawvec &out, int op, const char *fname, int line, json_object *feature); std::vector parse_layers(FILE *fp, int z, unsigned x, unsigned y, int extent, bool fix_longitudes); serial_val stringify_value(json_object *value, const char *reading, int line, json_object *feature); From f9ec00d50d57c0e2915db459b095d4093059d986 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Thu, 21 Nov 2024 16:32:00 -0800 Subject: [PATCH 06/24] Accept a clip polygon argument to tippecanoe-overzoom --- Makefile | 6 +++--- clip.cpp | 37 +++++++++++++++++++++++++++++++++++++ geometry.hpp | 4 ++++ overzoom.cpp | 10 +++++++++- read_json.cpp | 2 +- read_json.hpp | 2 ++ 6 files changed, 56 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 57c81d1d..d267e077 100644 --- a/Makefile +++ b/Makefile @@ -68,16 +68,16 @@ tippecanoe-enumerate: enumerate.o tippecanoe-decode: decode.o projection.o mvt.o write_json.o text.o jsonpull/jsonpull.o dirtiles.o pmtiles_file.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -tile-join: tile-join.o projection.o mbtiles.o mvt.o memfile.o dirtiles.o jsonpull/jsonpull.o text.o evaluator.o csv.o write_json.o pmtiles_file.o clip.o attribute.o thread.o +tile-join: tile-join.o projection.o mbtiles.o mvt.o memfile.o dirtiles.o jsonpull/jsonpull.o text.o evaluator.o csv.o write_json.o pmtiles_file.o clip.o attribute.o thread.o read_json.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread tippecanoe-json-tool: jsontool.o jsonpull/jsonpull.o csv.o text.o geojson-loop.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread -unit: unit.o text.o sort.o mvt.o projection.o clip.o attribute.o jsonpull/jsonpull.o evaluator.o +unit: unit.o text.o sort.o mvt.o projection.o clip.o attribute.o jsonpull/jsonpull.o evaluator.o read_json.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread -tippecanoe-overzoom: overzoom.o mvt.o clip.o evaluator.o jsonpull/jsonpull.o text.o attribute.o read_json.o projection.o +tippecanoe-overzoom: overzoom.o mvt.o clip.o evaluator.o jsonpull/jsonpull.o text.o attribute.o read_json.o projection.o read_json.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread -include $(wildcard *.d) diff --git a/clip.cpp b/clip.cpp index e6975a03..7e2a1f3c 100644 --- a/clip.cpp +++ b/clip.cpp @@ -13,6 +13,7 @@ #include "serial.hpp" #include "attribute.hpp" #include "projection.hpp" +#include "read_json.hpp" static std::vector> clip_poly1(std::vector> &geom, long long minx, long long miny, long long maxx, long long maxy, @@ -1075,6 +1076,42 @@ bool pnpoly_mp(std::vector const &geom, long long x, long long y) return found; } +clipbbox parse_clip_poly(std::string arg) { + json_pull *jp = json_begin_string(arg.c_str()); + json_object *j = json_read_tree(jp); + if (j->type != JSON_HASH) { + fprintf(stderr, "Expected JSON geometry object, not %s\n", arg.c_str()); + } + + std::pair parsed_geometry = parse_geometry(j, jp, j, 0, 0, 0, 1LL << 32, false); + json_end(jp); + + clipbbox out; + out.minx = LLONG_MAX; + out.miny = LLONG_MAX; + out.maxx = LLONG_MIN; + out.maxy = LLONG_MIN; + for (auto const &d : parsed_geometry.second) { + if (d.op == VT_MOVETO || d.op == VT_LINETO) { + if (d.x < out.minx) { + out.minx = d.x; + } + if (d.y < out.miny) { + out.miny = d.y; + } + if (d.x > out.maxx) { + out.maxx = d.x; + } + if (d.y > out.maxy) { + out.maxy = d.y; + } + } + } + out.dv = std::move(parsed_geometry.second); + + return out; +} + std::string overzoom(std::vector const &tiles, int nz, int nx, int ny, int detail_or_unspecified, int buffer, std::set const &keep, diff --git a/geometry.hpp b/geometry.hpp index 2284ab95..45161f3b 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -125,6 +125,8 @@ struct clipbbox { long long miny; long long maxx; long long maxy; + + drawvec dv; // empty, or arbitrary clipping polygon }; std::string overzoom(std::vector const &tiles, int nz, int nx, int ny, @@ -162,4 +164,6 @@ draw center_of_mass_mp(const drawvec &dv); void get_quadkey_bounds(long long xmin, long long ymin, long long xmax, long long ymax, unsigned long long *start, unsigned long long *end); +clipbbox parse_clip_poly(std::string arg); + #endif diff --git a/overzoom.cpp b/overzoom.cpp index 514c7669..63822d0f 100644 --- a/overzoom.cpp +++ b/overzoom.cpp @@ -72,6 +72,7 @@ int main(int argc, char **argv) { {"numeric-attributes", required_argument, 0, 'a' & 0x1F}, {"no-tile-compression", no_argument, 0, 'd' & 0x1F}, {"clip-bounding-box", required_argument, 0, 'k' & 0x1F}, + {"clip-polygon", required_argument, 0, 'l' & 0x1F}, {0, 0, 0, 0}, }; @@ -162,7 +163,7 @@ int main(int argc, char **argv) { do_compress = false; break; - case 'k' & 0x1F: + case 'k' & 0x1F: { clipbbox clip; if (sscanf(optarg, "%lf,%lf,%lf,%lf", &clip.lon1, &clip.lat1, &clip.lon2, &clip.lat2) == 4) { projection->project(clip.lon1, clip.lat1, 32, &clip.minx, &clip.maxy); @@ -173,6 +174,13 @@ int main(int argc, char **argv) { exit(EXIT_ARGS); } break; + } + + case 'l' & 0x1F: { + clipbbox clip = parse_clip_poly(optarg); + clipbboxes.push_back(clip); + break; + } default: fprintf(stderr, "Unrecognized flag -%c\n", i); diff --git a/read_json.cpp b/read_json.cpp index bf5a5e3f..a77fe4be 100644 --- a/read_json.cpp +++ b/read_json.cpp @@ -179,7 +179,7 @@ static std::vector to_feature(drawvec &geom) { } std::pair parse_geometry(json_object *geometry, json_pull *jp, json_object *j, - int z, int x, int y, int extent, bool fix_longitudes) { + int z, int x, int y, long long extent, bool fix_longitudes) { json_object *geometry_type = json_hash_get(geometry, "type"); if (geometry_type == NULL) { fprintf(stderr, "Filter output:%d: null geometry (additional not reported): ", jp->line); diff --git a/read_json.hpp b/read_json.hpp index 84e0853b..6323c497 100644 --- a/read_json.hpp +++ b/read_json.hpp @@ -12,6 +12,8 @@ extern int mb_geometry[GEOM_TYPES]; void json_context(json_object *j); void parse_coordinates(int t, json_object *j, drawvec &out, int op, const char *fname, int line, json_object *feature); +std::pair parse_geometry(json_object *geometry, json_pull *jp, json_object *j, + int z, int x, int y, long long extent, bool fix_longitudes); std::vector parse_layers(FILE *fp, int z, unsigned x, unsigned y, int extent, bool fix_longitudes); serial_val stringify_value(json_object *value, const char *reading, int line, json_object *feature); From 9c4c95295fa4cc6d98ef5d12ea99e69beffee6b0 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 22 Nov 2024 10:29:05 -0800 Subject: [PATCH 07/24] Progress in the direction of polygon clipping --- clip.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ read_json.cpp | 4 +-- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/clip.cpp b/clip.cpp index 7e2a1f3c..09795dd6 100644 --- a/clip.cpp +++ b/clip.cpp @@ -386,6 +386,71 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try return ret; } +drawvec clip_poly(drawvec &geom, drawvec const &bounds) { + printf("initial: %zu\n", geom.size()); + geom = remove_noop(geom, VT_POLYGON, 0); + mapbox::geometry::multi_polygon result; + + { + mapbox::geometry::wagyu::wagyu wagyu; + + for (size_t i = 0; i < geom.size(); i++) { + if (geom[i].op == VT_MOVETO) { + mapbox::geometry::linear_ring lr; + lr.push_back(mapbox::geometry::point(geom[i].x, geom[i].y)); + + size_t j; + for (j = i + 1; j < geom.size(); j++) { + if (geom[j].op != VT_LINETO) { + break; + } + lr.push_back(mapbox::geometry::point(geom[j].x, geom[j].y)); + } + + if (lr.size() >= 4) { + wagyu.add_ring(lr); + } + + i = j - 1; + } + } + + for (size_t i = 0; i < bounds.size(); i++) { + if (bounds[i].op == VT_MOVETO) { + mapbox::geometry::linear_ring lr; + lr.push_back(mapbox::geometry::point(bounds[i].x, bounds[i].y)); + + size_t j; + for (j = i + 1; j < bounds.size(); j++) { + if (bounds[j].op != VT_LINETO) { + break; + } + lr.push_back(mapbox::geometry::point(bounds[j].x, bounds[j].y)); + } + + if (lr.size() >= 4) { + wagyu.add_ring(lr, mapbox::geometry::wagyu::polygon_type_clip); + } + + i = j - 1; + } + } + + try { + result.clear(); + wagyu.execute(mapbox::geometry::wagyu::clip_type_union, result, mapbox::geometry::wagyu::fill_type_positive, mapbox::geometry::wagyu::fill_type_positive); + } catch (std::runtime_error &e) { + fprintf(stderr, "Internal error: Polygon clipping failed\n"); + exit(EXIT_IMPOSSIBLE); + } + } + + drawvec ret; + decode_clipped(result, ret, 1); + printf("after: %zu\n", ret.size()); + return ret; +} + void to_tile_scale(drawvec &geom, int z, int detail) { if (32 - detail - z < 0) { for (size_t i = 0; i < geom.size(); i++) { @@ -1093,6 +1158,7 @@ clipbbox parse_clip_poly(std::string arg) { out.maxy = LLONG_MIN; for (auto const &d : parsed_geometry.second) { if (d.op == VT_MOVETO || d.op == VT_LINETO) { + printf("%lld,%lld\n", d.x, d.y); if (d.x < out.minx) { out.minx = d.x; } @@ -1914,11 +1980,16 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int } // Clip to user-specified bounding boxes. + // Bounding box clip first, to reduce complexity of the full clip. // But don't clip here if we are binning, because we need to bin points in the buffer if (bins.size() == 0) { for (auto &c : clipbboxes) { if (t == VT_POLYGON) { + printf("clip to %lld,%lld %lld,%lld\n", c.minx, c.miny, c.maxx, c.maxy); geom = simple_clip_poly(geom, c.minx, c.miny, c.maxx, c.maxy, false); + if (c.dv.size() > 0) { + geom = clip_poly(geom, c.dv); + } } else if (t == VT_LINE) { geom = clip_lines(geom, c.minx, c.miny, c.maxx, c.maxy); } else if (t == VT_POINT) { diff --git a/read_json.cpp b/read_json.cpp index a77fe4be..2a95e4d3 100644 --- a/read_json.cpp +++ b/read_json.cpp @@ -278,8 +278,8 @@ std::pair parse_geometry(json_object *geometry, json_pull *jp, jso dv[i].y -= scale * y; // scale to tile - dv[i].x = std::round(dv[i].x * extent / (double) scale); - dv[i].y = std::round(dv[i].y * extent / (double) scale); + dv[i].x = std::round(dv[i].x * (extent / (double) scale)); + dv[i].y = std::round(dv[i].y * (extent / (double) scale)); } if (mb_geometry[t] == VT_POLYGON) { From 3ffc04a0b211d527da818106d0c6ece230f334f6 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 22 Nov 2024 10:34:13 -0800 Subject: [PATCH 08/24] Fix the wagyu flags. We need intersection, not union --- clip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clip.cpp b/clip.cpp index 09795dd6..38c0e328 100644 --- a/clip.cpp +++ b/clip.cpp @@ -438,7 +438,7 @@ drawvec clip_poly(drawvec &geom, drawvec const &bounds) { try { result.clear(); - wagyu.execute(mapbox::geometry::wagyu::clip_type_union, result, mapbox::geometry::wagyu::fill_type_positive, mapbox::geometry::wagyu::fill_type_positive); + wagyu.execute(mapbox::geometry::wagyu::clip_type_intersection, result, mapbox::geometry::wagyu::fill_type_positive, mapbox::geometry::wagyu::fill_type_positive); } catch (std::runtime_error &e) { fprintf(stderr, "Internal error: Polygon clipping failed\n"); exit(EXIT_IMPOSSIBLE); From baba6d382d4fe05fe2d7992119458c3ff33cf846 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 22 Nov 2024 10:38:01 -0800 Subject: [PATCH 09/24] Remove debug spew --- clip.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/clip.cpp b/clip.cpp index 38c0e328..be3cedaf 100644 --- a/clip.cpp +++ b/clip.cpp @@ -387,7 +387,6 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try } drawvec clip_poly(drawvec &geom, drawvec const &bounds) { - printf("initial: %zu\n", geom.size()); geom = remove_noop(geom, VT_POLYGON, 0); mapbox::geometry::multi_polygon result; @@ -447,7 +446,6 @@ drawvec clip_poly(drawvec &geom, drawvec const &bounds) { drawvec ret; decode_clipped(result, ret, 1); - printf("after: %zu\n", ret.size()); return ret; } @@ -1158,7 +1156,6 @@ clipbbox parse_clip_poly(std::string arg) { out.maxy = LLONG_MIN; for (auto const &d : parsed_geometry.second) { if (d.op == VT_MOVETO || d.op == VT_LINETO) { - printf("%lld,%lld\n", d.x, d.y); if (d.x < out.minx) { out.minx = d.x; } @@ -1985,9 +1982,8 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int if (bins.size() == 0) { for (auto &c : clipbboxes) { if (t == VT_POLYGON) { - printf("clip to %lld,%lld %lld,%lld\n", c.minx, c.miny, c.maxx, c.maxy); geom = simple_clip_poly(geom, c.minx, c.miny, c.maxx, c.maxy, false); - if (c.dv.size() > 0) { + if (c.dv.size() > 0 && geom.size() > 0) { geom = clip_poly(geom, c.dv); } } else if (t == VT_LINE) { From 0170dd8bea98f937519d0bc698f2ba3718e5988e Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 22 Nov 2024 10:53:30 -0800 Subject: [PATCH 10/24] Clip points to polygon bounds too --- clip.cpp | 34 ++++++++++++++++++++++++++++++++++ geometry.hpp | 1 + 2 files changed, 35 insertions(+) diff --git a/clip.cpp b/clip.cpp index be3cedaf..7bc95082 100644 --- a/clip.cpp +++ b/clip.cpp @@ -449,6 +449,16 @@ drawvec clip_poly(drawvec &geom, drawvec const &bounds) { return ret; } +drawvec clip_point_poly(drawvec &geom, drawvec const &bounds) { + drawvec out; + for (auto const &p : geom) { + if (pnpoly_mp(bounds, p.x, p.y)) { + out.push_back(p); + } + } + return out; +} + void to_tile_scale(drawvec &geom, int z, int detail) { if (32 - detail - z < 0) { for (size_t i = 0; i < geom.size(); i++) { @@ -1139,6 +1149,27 @@ bool pnpoly_mp(std::vector const &geom, long long x, long long y) return found; } +bool pnpoly_mp(drawvec const &geom, long long x, long long y) { + // assumes rings are properly nested, so inside a hole matches twice + bool found = false; + + 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; + } + } + + found ^= pnpoly(geom, i, j - i, x, y); + i = j - 1; + } + } + + return found; +} + clipbbox parse_clip_poly(std::string arg) { json_pull *jp = json_begin_string(arg.c_str()); json_object *j = json_read_tree(jp); @@ -1990,6 +2021,9 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int geom = clip_lines(geom, c.minx, c.miny, c.maxx, c.maxy); } else if (t == VT_POINT) { geom = clip_point(geom, c.minx, c.miny, c.maxx, c.maxy); + if (c.dv.size() > 0 && geom.size() > 0) { + geom = clip_point_poly(geom, c.dv); + } } } } diff --git a/geometry.hpp b/geometry.hpp index 45161f3b..bc616058 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -99,6 +99,7 @@ drawvec clip_lines(drawvec &geom, long long x1, long long y1, long long x2, long drawvec clip_point(drawvec &geom, long long x1, long long y1, long long x2, long long y2); void visvalingam(drawvec &ls, size_t start, size_t end, double threshold, size_t retain); int pnpoly(const drawvec &vert, size_t start, size_t nvert, long long testx, long long testy); +bool pnpoly_mp(drawvec const &geom, long long x, long long y); double distance_from_line(long long point_x, long long point_y, long long segA_x, long long segA_y, long long segB_x, long long segB_y); struct input_tile { From f82a868e88b7b643ac54731fcac069bb783a4076 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 22 Nov 2024 15:12:58 -0800 Subject: [PATCH 11/24] Copy the geometric binning code to serve as intersection-finding code --- clip.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/clip.cpp b/clip.cpp index 7bc95082..4b87ee25 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1934,6 +1934,75 @@ mvt_tile assign_to_bins(mvt_tile &features, return ret; } +drawvec clip_lines(drawvec const &geom, drawvec const ®ion) { + std::vector events; + + if (region.size() == 0) { + return drawvec(); + } + + // Index region segments + for (size_t i = 1; i < region.size(); i++) { + if (region[i].op == VT_LINETO) { + long long xmin = std::min(region[i - 1].x, region[i].x); + long long ymin = std::min(region[i - 1].y, region[i].y); + long long xmax = std::max(region[i - 1].x, region[i].x); + long long ymax = std::max(region[i - 1].y, region[i].y); + unsigned long long start, end; + + get_quadkey_bounds(xmin, ymin, xmax, ymax, &start, &end); + events.emplace_back(start, index_event::ENTER, i, 0, xmin, ymin, xmax, ymax); + events.emplace_back(end, index_event::EXIT, i, 0, xmin, ymin, xmax, ymax); + } + } + + // Index linestring segments + for (size_t i = 1; i < geom.size(); i++) { + if (geom[i].op == VT_LINETO) { + long long xmin = std::min(geom[i - 1].x, geom[i].x); + long long ymin = std::min(geom[i - 1].y, geom[i].y); + long long xmax = std::max(geom[i - 1].x, geom[i].x); + long long ymax = std::max(geom[i - 1].y, geom[i].y); + unsigned long long start, end; + + get_quadkey_bounds(xmin, ymin, xmax, ymax, &start, &end); + events.emplace_back(start, index_event::CHECK, i, 0, xmin, ymin, xmax, ymax); + } + } + + std::sort(events.begin(), events.end()); + std::set active; + + for (auto &e : events) { + if (e.kind == index_event::ENTER) { + active_bin a(e.layer, e.feature); + a.xmin = e.xmin; + a.ymin = e.ymin; + a.xmax = e.xmax; + a.ymax = e.ymax; + + active.insert(std::move(a)); + } else if (e.kind == index_event::CHECK) { + for (auto const &a : active) { + if (bbox_intersects(e.xmin, e.ymin, e.xmax, e.ymax, + a.xmin, a.ymin, a.xmax, a.ymax)) { + // compare + } + } + } else /* EXIT */ { + auto const &found = active.find({e.layer, e.feature}); + if (found != active.end()) { + active.erase(found); + } else { + fprintf(stderr, "event mismatch: can't happen\n"); + exit(EXIT_IMPOSSIBLE); + } + } + } + + return drawvec(); +} + std::string overzoom(std::vector const &tiles, int nz, int nx, int ny, int detail_or_unspecified, int buffer, std::set const &keep, From 159b04fa8eb59cd52a4c0efc445cf79001635134 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 22 Nov 2024 20:50:21 -0800 Subject: [PATCH 12/24] Add clipper2 for linestring clipping --- Makefile | 4 +- clipper2/LICENSE | 23 + clipper2/include/clipper2/clipper.core.h | 1080 ++++++ clipper2/include/clipper2/clipper.engine.h | 641 ++++ clipper2/include/clipper2/clipper.export.h | 827 +++++ clipper2/include/clipper2/clipper.h | 769 ++++ clipper2/include/clipper2/clipper.minkowski.h | 120 + clipper2/include/clipper2/clipper.offset.h | 124 + clipper2/include/clipper2/clipper.rectclip.h | 82 + clipper2/include/clipper2/clipper.version.h | 6 + clipper2/src/clipper.engine.cpp | 3155 +++++++++++++++++ 11 files changed, 6829 insertions(+), 2 deletions(-) create mode 100644 clipper2/LICENSE create mode 100644 clipper2/include/clipper2/clipper.core.h create mode 100644 clipper2/include/clipper2/clipper.engine.h create mode 100644 clipper2/include/clipper2/clipper.export.h create mode 100644 clipper2/include/clipper2/clipper.h create mode 100644 clipper2/include/clipper2/clipper.minkowski.h create mode 100644 clipper2/include/clipper2/clipper.offset.h create mode 100644 clipper2/include/clipper2/clipper.rectclip.h create mode 100644 clipper2/include/clipper2/clipper.version.h create mode 100644 clipper2/src/clipper.engine.cpp diff --git a/Makefile b/Makefile index d267e077..c336b90c 100644 --- a/Makefile +++ b/Makefile @@ -56,10 +56,10 @@ PG= H = $(wildcard *.h) $(wildcard *.hpp) C = $(wildcard *.c) $(wildcard *.cpp) -INCLUDES = -I/usr/local/include -I. +INCLUDES = -I/usr/local/include -I. -Iclipper2/include LIBS = -L/usr/local/lib -tippecanoe: geojson.o jsonpull/jsonpull.o tile.o pool.o mbtiles.o geometry.o projection.o memfile.o mvt.o serial.o main.o text.o dirtiles.o pmtiles_file.o plugin.o read_json.o write_json.o geobuf.o flatgeobuf.o evaluator.o geocsv.o csv.o geojson-loop.o json_logger.o visvalingam.o compression.o clip.o sort.o attribute.o thread.o shared_borders.o +tippecanoe: geojson.o jsonpull/jsonpull.o tile.o pool.o mbtiles.o geometry.o projection.o memfile.o mvt.o serial.o main.o text.o dirtiles.o pmtiles_file.o plugin.o read_json.o write_json.o geobuf.o flatgeobuf.o evaluator.o geocsv.o csv.o geojson-loop.o json_logger.o visvalingam.o compression.o clip.o sort.o attribute.o thread.o shared_borders.o clipper2/src/clipper.engine.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread tippecanoe-enumerate: enumerate.o diff --git a/clipper2/LICENSE b/clipper2/LICENSE new file mode 100644 index 00000000..36b7cd93 --- /dev/null +++ b/clipper2/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/clipper2/include/clipper2/clipper.core.h b/clipper2/include/clipper2/clipper.core.h new file mode 100644 index 00000000..624de903 --- /dev/null +++ b/clipper2/include/clipper2/clipper.core.h @@ -0,0 +1,1080 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 12 May 2024 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2024 * +* Purpose : Core Clipper Library structures and functions * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_CORE_H +#define CLIPPER_CORE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "clipper2/clipper.version.h" + +namespace Clipper2Lib +{ + +#if (defined(__cpp_exceptions) && __cpp_exceptions) || (defined(__EXCEPTIONS) && __EXCEPTIONS) + + class Clipper2Exception : public std::exception { + public: + explicit Clipper2Exception(const char* description) : + m_descr(description) {} + virtual const char* what() const noexcept override { return m_descr.c_str(); } + private: + std::string m_descr; + }; + + static const char* precision_error = + "Precision exceeds the permitted range"; + static const char* range_error = + "Values exceed permitted range"; + static const char* scale_error = + "Invalid scale (either 0 or too large)"; + static const char* non_pair_error = + "There must be 2 values for each coordinate"; + static const char* undefined_error = + "There is an undefined error in Clipper2"; +#endif + + // error codes (2^n) + const int precision_error_i = 1; // non-fatal + const int scale_error_i = 2; // non-fatal + const int non_pair_error_i = 4; // non-fatal + const int undefined_error_i = 32; // fatal + const int range_error_i = 64; + +#ifndef PI + static const double PI = 3.141592653589793238; +#endif + +#ifdef CLIPPER2_MAX_DECIMAL_PRECISION + const int CLIPPER2_MAX_DEC_PRECISION = CLIPPER2_MAX_DECIMAL_PRECISION; +#else + const int CLIPPER2_MAX_DEC_PRECISION = 8; // see Discussions #564 +#endif + + static const int64_t MAX_COORD = INT64_MAX >> 2; + static const int64_t MIN_COORD = -MAX_COORD; + static const int64_t INVALID = INT64_MAX; + const double max_coord = static_cast(MAX_COORD); + const double min_coord = static_cast(MIN_COORD); + + static const double MAX_DBL = (std::numeric_limits::max)(); + + static void DoError([[maybe_unused]] int error_code) + { +#if (defined(__cpp_exceptions) && __cpp_exceptions) || (defined(__EXCEPTIONS) && __EXCEPTIONS) + switch (error_code) + { + case precision_error_i: + throw Clipper2Exception(precision_error); + case scale_error_i: + throw Clipper2Exception(scale_error); + case non_pair_error_i: + throw Clipper2Exception(non_pair_error); + case undefined_error_i: + throw Clipper2Exception(undefined_error); + case range_error_i: + throw Clipper2Exception(range_error); + // Should never happen, but adding this to stop a compiler warning + default: + throw Clipper2Exception("Unknown error"); + } +#else + ++error_code; // only to stop compiler warning +#endif + } + + // can we call std::round on T? (default false) (#824) + template + struct is_round_invocable : std::false_type {}; + + template + struct is_round_invocable()))>> : std::true_type {}; + + + //By far the most widely used filling rules for polygons are EvenOdd + //and NonZero, sometimes called Alternate and Winding respectively. + //https://en.wikipedia.org/wiki/Nonzero-rule + enum class FillRule { EvenOdd, NonZero, Positive, Negative }; + +#ifdef USINGZ + using z_type = int64_t; +#endif + + // Point ------------------------------------------------------------------------ + + template + struct Point { + T x; + T y; +#ifdef USINGZ + z_type z; + + template + inline void Init(const T2 x_ = 0, const T2 y_ = 0, const z_type z_ = 0) + { + if constexpr (std::is_integral_v && + is_round_invocable::value && !std::is_integral_v) + { + x = static_cast(std::round(x_)); + y = static_cast(std::round(y_)); + z = z_; + } + else + { + x = static_cast(x_); + y = static_cast(y_); + z = z_; + } + } + + explicit Point() : x(0), y(0), z(0) {}; + + template + Point(const T2 x_, const T2 y_, const z_type z_ = 0) + { + Init(x_, y_); + z = z_; + } + + template + explicit Point(const Point& p) + { + Init(p.x, p.y, p.z); + } + + template + explicit Point(const Point& p, z_type z_) + { + Init(p.x, p.y, z_); + } + + Point operator * (const double scale) const + { + return Point(x * scale, y * scale, z); + } + + void SetZ(const z_type z_value) { z = z_value; } + + friend std::ostream& operator<<(std::ostream& os, const Point& point) + { + os << point.x << "," << point.y << "," << point.z; + return os; + } + +#else + + template + inline void Init(const T2 x_ = 0, const T2 y_ = 0) + { + if constexpr (std::is_integral_v && + is_round_invocable::value && !std::is_integral_v) + { + x = static_cast(std::round(x_)); + y = static_cast(std::round(y_)); + } + else + { + x = static_cast(x_); + y = static_cast(y_); + } + } + + explicit Point() : x(0), y(0) {}; + + template + Point(const T2 x_, const T2 y_) { Init(x_, y_); } + + template + explicit Point(const Point& p) { Init(p.x, p.y); } + + Point operator * (const double scale) const + { + return Point(x * scale, y * scale); + } + + friend std::ostream& operator<<(std::ostream& os, const Point& point) + { + os << point.x << "," << point.y; + return os; + } +#endif + + friend bool operator==(const Point& a, const Point& b) + { + return a.x == b.x && a.y == b.y; + } + + friend bool operator!=(const Point& a, const Point& b) + { + return !(a == b); + } + + inline Point operator-() const + { + return Point(-x, -y); + } + + inline Point operator+(const Point& b) const + { + return Point(x + b.x, y + b.y); + } + + inline Point operator-(const Point& b) const + { + return Point(x - b.x, y - b.y); + } + + inline void Negate() { x = -x; y = -y; } + + }; + + //nb: using 'using' here (instead of typedef) as they can be used in templates + using Point64 = Point; + using PointD = Point; + + template + using Path = std::vector>; + template + using Paths = std::vector>; + + using Path64 = Path; + using PathD = Path; + using Paths64 = std::vector< Path64>; + using PathsD = std::vector< PathD>; + + static const Point64 InvalidPoint64 = Point64( + (std::numeric_limits::max)(), + (std::numeric_limits::max)()); + static const PointD InvalidPointD = PointD( + (std::numeric_limits::max)(), + (std::numeric_limits::max)()); + + template + static inline Point MidPoint(const Point& p1, const Point& p2) + { + Point result; + result.x = (p1.x + p2.x) / 2; + result.y = (p1.y + p2.y) / 2; + return result; + } + + // Rect ------------------------------------------------------------------------ + + template + struct Rect; + + using Rect64 = Rect; + using RectD = Rect; + + template + struct Rect { + T left; + T top; + T right; + T bottom; + + Rect(T l, T t, T r, T b) : + left(l), + top(t), + right(r), + bottom(b) {} + + Rect(bool is_valid = true) + { + if (is_valid) + { + left = right = top = bottom = 0; + } + else + { + left = top = (std::numeric_limits::max)(); + right = bottom = std::numeric_limits::lowest(); + } + } + + static Rect InvalidRect() + { + return { + (std::numeric_limits::max)(), + (std::numeric_limits::max)(), + std::numeric_limits::lowest(), + std::numeric_limits::lowest() }; + } + + bool IsValid() const { return left != (std::numeric_limits::max)(); } + + T Width() const { return right - left; } + T Height() const { return bottom - top; } + void Width(T width) { right = left + width; } + void Height(T height) { bottom = top + height; } + + Point MidPoint() const + { + return Point((left + right) / 2, (top + bottom) / 2); + } + + Path AsPath() const + { + Path result; + result.reserve(4); + result.push_back(Point(left, top)); + result.push_back(Point(right, top)); + result.push_back(Point(right, bottom)); + result.push_back(Point(left, bottom)); + return result; + } + + bool Contains(const Point& pt) const + { + return pt.x > left && pt.x < right&& pt.y > top && pt.y < bottom; + } + + bool Contains(const Rect& rec) const + { + return rec.left >= left && rec.right <= right && + rec.top >= top && rec.bottom <= bottom; + } + + void Scale(double scale) { + left *= scale; + top *= scale; + right *= scale; + bottom *= scale; + } + + bool IsEmpty() const { return bottom <= top || right <= left; }; + + bool Intersects(const Rect& rec) const + { + return ((std::max)(left, rec.left) <= (std::min)(right, rec.right)) && + ((std::max)(top, rec.top) <= (std::min)(bottom, rec.bottom)); + }; + + bool operator==(const Rect& other) const { + return left == other.left && right == other.right && + top == other.top && bottom == other.bottom; + } + + Rect& operator+=(const Rect& other) + { + left = (std::min)(left, other.left); + top = (std::min)(top, other.top); + right = (std::max)(right, other.right); + bottom = (std::max)(bottom, other.bottom); + return *this; + } + + Rect operator+(const Rect& other) const + { + Rect result = *this; + result += other; + return result; + } + + friend std::ostream& operator<<(std::ostream& os, const Rect& rect) { + os << "(" << rect.left << "," << rect.top << "," << rect.right << "," << rect.bottom << ") "; + return os; + } + }; + + template + inline Rect ScaleRect(const Rect& rect, double scale) + { + Rect result; + + if constexpr (std::is_integral_v && + is_round_invocable::value && !std::is_integral_v) + { + result.left = static_cast(std::round(rect.left * scale)); + result.top = static_cast(std::round(rect.top * scale)); + result.right = static_cast(std::round(rect.right * scale)); + result.bottom = static_cast(std::round(rect.bottom * scale)); + } + else + { + result.left = static_cast(rect.left * scale); + result.top = static_cast(rect.top * scale); + result.right = static_cast(rect.right * scale); + result.bottom = static_cast(rect.bottom * scale); + } + return result; + } + + static const Rect64 InvalidRect64 = Rect64::InvalidRect(); + static const RectD InvalidRectD = RectD::InvalidRect(); + + template + Rect GetBounds(const Path& path) + { + T xmin = (std::numeric_limits::max)(); + T ymin = (std::numeric_limits::max)(); + T xmax = std::numeric_limits::lowest(); + T ymax = std::numeric_limits::lowest(); + for (const auto& p : path) + { + if (p.x < xmin) xmin = p.x; + if (p.x > xmax) xmax = p.x; + if (p.y < ymin) ymin = p.y; + if (p.y > ymax) ymax = p.y; + } + return Rect(xmin, ymin, xmax, ymax); + } + + template + Rect GetBounds(const Paths& paths) + { + T xmin = (std::numeric_limits::max)(); + T ymin = (std::numeric_limits::max)(); + T xmax = std::numeric_limits::lowest(); + T ymax = std::numeric_limits::lowest(); + for (const Path& path : paths) + for (const Point& p : path) + { + if (p.x < xmin) xmin = p.x; + if (p.x > xmax) xmax = p.x; + if (p.y < ymin) ymin = p.y; + if (p.y > ymax) ymax = p.y; + } + return Rect(xmin, ymin, xmax, ymax); + } + + template + Rect GetBounds(const Path& path) + { + T xmin = (std::numeric_limits::max)(); + T ymin = (std::numeric_limits::max)(); + T xmax = std::numeric_limits::lowest(); + T ymax = std::numeric_limits::lowest(); + for (const auto& p : path) + { + if (p.x < xmin) xmin = static_cast(p.x); + if (p.x > xmax) xmax = static_cast(p.x); + if (p.y < ymin) ymin = static_cast(p.y); + if (p.y > ymax) ymax = static_cast(p.y); + } + return Rect(xmin, ymin, xmax, ymax); + } + + template + Rect GetBounds(const Paths& paths) + { + T xmin = (std::numeric_limits::max)(); + T ymin = (std::numeric_limits::max)(); + T xmax = std::numeric_limits::lowest(); + T ymax = std::numeric_limits::lowest(); + for (const Path& path : paths) + for (const Point& p : path) + { + if (p.x < xmin) xmin = static_cast(p.x); + if (p.x > xmax) xmax = static_cast(p.x); + if (p.y < ymin) ymin = static_cast(p.y); + if (p.y > ymax) ymax = static_cast(p.y); + } + return Rect(xmin, ymin, xmax, ymax); + } + + template + std::ostream& operator << (std::ostream& outstream, const Path& path) + { + if (!path.empty()) + { + auto pt = path.cbegin(), last = path.cend() - 1; + while (pt != last) + outstream << *pt++ << ", "; + outstream << *last << std::endl; + } + return outstream; + } + + template + std::ostream& operator << (std::ostream& outstream, const Paths& paths) + { + for (auto p : paths) + outstream << p; + return outstream; + } + + + template + inline Path ScalePath(const Path& path, + double scale_x, double scale_y, int& error_code) + { + Path result; + if (scale_x == 0 || scale_y == 0) + { + error_code |= scale_error_i; + DoError(scale_error_i); + // if no exception, treat as non-fatal error + if (scale_x == 0) scale_x = 1.0; + if (scale_y == 0) scale_y = 1.0; + } + + result.reserve(path.size()); +#ifdef USINGZ + std::transform(path.begin(), path.end(), back_inserter(result), + [scale_x, scale_y](const auto& pt) + { return Point(pt.x * scale_x, pt.y * scale_y, pt.z); }); +#else + std::transform(path.begin(), path.end(), back_inserter(result), + [scale_x, scale_y](const auto& pt) + { return Point(pt.x * scale_x, pt.y * scale_y); }); +#endif + return result; + } + + template + inline Path ScalePath(const Path& path, + double scale, int& error_code) + { + return ScalePath(path, scale, scale, error_code); + } + + template + inline Paths ScalePaths(const Paths& paths, + double scale_x, double scale_y, int& error_code) + { + Paths result; + + if constexpr (std::is_integral_v) + { + RectD r = GetBounds(paths); + if ((r.left * scale_x) < min_coord || + (r.right * scale_x) > max_coord || + (r.top * scale_y) < min_coord || + (r.bottom * scale_y) > max_coord) + { + error_code |= range_error_i; + DoError(range_error_i); + return result; // empty path + } + } + + result.reserve(paths.size()); + std::transform(paths.begin(), paths.end(), back_inserter(result), + [=, &error_code](const auto& path) + { return ScalePath(path, scale_x, scale_y, error_code); }); + return result; + } + + template + inline Paths ScalePaths(const Paths& paths, + double scale, int& error_code) + { + return ScalePaths(paths, scale, scale, error_code); + } + + template + inline Path TransformPath(const Path& path) + { + Path result; + result.reserve(path.size()); + std::transform(path.cbegin(), path.cend(), std::back_inserter(result), + [](const Point& pt) {return Point(pt); }); + return result; + } + + template + inline Paths TransformPaths(const Paths& paths) + { + Paths result; + std::transform(paths.cbegin(), paths.cend(), std::back_inserter(result), + [](const Path& path) {return TransformPath(path); }); + return result; + } + + template + inline double Sqr(T val) + { + return static_cast(val) * static_cast(val); + } + + template + inline bool NearEqual(const Point& p1, + const Point& p2, double max_dist_sqrd) + { + return Sqr(p1.x - p2.x) + Sqr(p1.y - p2.y) < max_dist_sqrd; + } + + template + inline Path StripNearEqual(const Path& path, + double max_dist_sqrd, bool is_closed_path) + { + if (path.size() == 0) return Path(); + Path result; + result.reserve(path.size()); + typename Path::const_iterator path_iter = path.cbegin(); + Point first_pt = *path_iter++, last_pt = first_pt; + result.push_back(first_pt); + for (; path_iter != path.cend(); ++path_iter) + { + if (!NearEqual(*path_iter, last_pt, max_dist_sqrd)) + { + last_pt = *path_iter; + result.push_back(last_pt); + } + } + if (!is_closed_path) return result; + while (result.size() > 1 && + NearEqual(result.back(), first_pt, max_dist_sqrd)) result.pop_back(); + return result; + } + + template + inline Paths StripNearEqual(const Paths& paths, + double max_dist_sqrd, bool is_closed_path) + { + Paths result; + result.reserve(paths.size()); + for (typename Paths::const_iterator paths_citer = paths.cbegin(); + paths_citer != paths.cend(); ++paths_citer) + { + result.push_back(StripNearEqual(*paths_citer, max_dist_sqrd, is_closed_path)); + } + return result; + } + + template + inline void StripDuplicates( Path& path, bool is_closed_path) + { + //https://stackoverflow.com/questions/1041620/whats-the-most-efficient-way-to-erase-duplicates-and-sort-a-vector#:~:text=Let%27s%20compare%20three%20approaches%3A + path.erase(std::unique(path.begin(), path.end()), path.end()); + if (is_closed_path) + while (path.size() > 1 && path.back() == path.front()) path.pop_back(); + } + + template + inline void StripDuplicates( Paths& paths, bool is_closed_path) + { + for (typename Paths::iterator paths_citer = paths.begin(); + paths_citer != paths.end(); ++paths_citer) + { + StripDuplicates(*paths_citer, is_closed_path); + } + } + + // Miscellaneous ------------------------------------------------------------ + + inline void CheckPrecisionRange(int& precision, int& error_code) + { + if (precision >= -CLIPPER2_MAX_DEC_PRECISION && + precision <= CLIPPER2_MAX_DEC_PRECISION) return; + error_code |= precision_error_i; // non-fatal error + DoError(precision_error_i); // does nothing when exceptions are disabled + precision = precision > 0 ? CLIPPER2_MAX_DEC_PRECISION : -CLIPPER2_MAX_DEC_PRECISION; + } + + inline void CheckPrecisionRange(int& precision) + { + int error_code = 0; + CheckPrecisionRange(precision, error_code); + } + + inline int TriSign(int64_t x) // returns 0, 1 or -1 + { + return (x > 0) - (x < 0); + } + + struct MultiplyUInt64Result + { + const uint64_t result = 0; + const uint64_t carry = 0; + + bool operator==(const MultiplyUInt64Result& other) const + { + return result == other.result && carry == other.carry; + }; + }; + + inline MultiplyUInt64Result Multiply(uint64_t a, uint64_t b) // #834, #835 + { + const auto lo = [](uint64_t x) { return x & 0xFFFFFFFF; }; + const auto hi = [](uint64_t x) { return x >> 32; }; + + const uint64_t x1 = lo(a) * lo(b); + const uint64_t x2 = hi(a) * lo(b) + hi(x1); + const uint64_t x3 = lo(a) * hi(b) + lo(x2); + const uint64_t result = lo(x3) << 32 | lo(x1); + const uint64_t carry = hi(a) * hi(b) + hi(x2) + hi(x3); + + return { result, carry }; + } + + // returns true if (and only if) a * b == c * d + inline bool ProductsAreEqual(int64_t a, int64_t b, int64_t c, int64_t d) + { +#if (defined(__clang__) || defined(__GNUC__)) && UINTPTR_MAX >= UINT64_MAX + const auto ab = static_cast<__int128_t>(a) * static_cast<__int128_t>(b); + const auto cd = static_cast<__int128_t>(c) * static_cast<__int128_t>(d); + return ab == cd; +#else + // nb: unsigned values needed for calculating overflow carry + const auto abs_a = static_cast(std::abs(a)); + const auto abs_b = static_cast(std::abs(b)); + const auto abs_c = static_cast(std::abs(c)); + const auto abs_d = static_cast(std::abs(d)); + + const auto abs_ab = Multiply(abs_a, abs_b); + const auto abs_cd = Multiply(abs_c, abs_d); + + // nb: it's important to differentiate 0 values here from other values + const auto sign_ab = TriSign(a) * TriSign(b); + const auto sign_cd = TriSign(c) * TriSign(d); + + return abs_ab == abs_cd && sign_ab == sign_cd; +#endif + } + + template + inline bool IsCollinear(const Point& pt1, + const Point& sharedPt, const Point& pt2) // #777 + { + const auto a = sharedPt.x - pt1.x; + const auto b = pt2.y - sharedPt.y; + const auto c = sharedPt.y - pt1.y; + const auto d = pt2.x - sharedPt.x; + // When checking for collinearity with very large coordinate values + // then ProductsAreEqual is more accurate than using CrossProduct. + return ProductsAreEqual(a, b, c, d); + } + + + template + inline double CrossProduct(const Point& pt1, const Point& pt2, const Point& pt3) { + return (static_cast(pt2.x - pt1.x) * static_cast(pt3.y - + pt2.y) - static_cast(pt2.y - pt1.y) * static_cast(pt3.x - pt2.x)); + } + + template + inline double CrossProduct(const Point& vec1, const Point& vec2) + { + return static_cast(vec1.y * vec2.x) - static_cast(vec2.y * vec1.x); + } + + template + inline double DotProduct(const Point& pt1, const Point& pt2, const Point& pt3) { + return (static_cast(pt2.x - pt1.x) * static_cast(pt3.x - pt2.x) + + static_cast(pt2.y - pt1.y) * static_cast(pt3.y - pt2.y)); + } + + template + inline double DotProduct(const Point& vec1, const Point& vec2) + { + return static_cast(vec1.x * vec2.x) + static_cast(vec1.y * vec2.y); + } + + template + inline double DistanceSqr(const Point pt1, const Point pt2) + { + return Sqr(pt1.x - pt2.x) + Sqr(pt1.y - pt2.y); + } + + template + inline double PerpendicDistFromLineSqrd(const Point& pt, + const Point& line1, const Point& line2) + { + //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) + //see http://en.wikipedia.org/wiki/Perpendicular_distance + double a = static_cast(pt.x - line1.x); + double b = static_cast(pt.y - line1.y); + double c = static_cast(line2.x - line1.x); + double d = static_cast(line2.y - line1.y); + if (c == 0 && d == 0) return 0; + return Sqr(a * d - c * b) / (c * c + d * d); + } + + template + inline double Area(const Path& path) + { + size_t cnt = path.size(); + if (cnt < 3) return 0.0; + double a = 0.0; + typename Path::const_iterator it1, it2 = path.cend() - 1, stop = it2; + if (!(cnt & 1)) ++stop; + for (it1 = path.cbegin(); it1 != stop;) + { + a += static_cast(it2->y + it1->y) * (it2->x - it1->x); + it2 = it1 + 1; + a += static_cast(it1->y + it2->y) * (it1->x - it2->x); + it1 += 2; + } + if (cnt & 1) + a += static_cast(it2->y + it1->y) * (it2->x - it1->x); + return (a * 0.5); + } + + template + inline double Area(const Paths& paths) + { + double a = 0.0; + for (typename Paths::const_iterator paths_iter = paths.cbegin(); + paths_iter != paths.cend(); ++paths_iter) + { + a += Area(*paths_iter); + } + return a; + } + + template + inline bool IsPositive(const Path& poly) + { + // A curve has positive orientation [and area] if a region 'R' + // is on the left when traveling around the outside of 'R'. + //https://mathworld.wolfram.com/CurveOrientation.html + //nb: This statement is premised on using Cartesian coordinates + return Area(poly) >= 0; + } + +#if CLIPPER2_HI_PRECISION + // caution: this will compromise performance + // https://github.com/AngusJohnson/Clipper2/issues/317#issuecomment-1314023253 + // See also CPP/BenchMark/GetIntersectPtBenchmark.cpp + #define CC_MIN(x,y) ((x)>(y)?(y):(x)) + #define CC_MAX(x,y) ((x)<(y)?(y):(x)) + template + inline bool GetSegmentIntersectPt(const Point& ln1a, const Point& ln1b, + const Point& ln2a, const Point& ln2b, Point& ip) + { + double ln1dy = static_cast(ln1b.y - ln1a.y); + double ln1dx = static_cast(ln1a.x - ln1b.x); + double ln2dy = static_cast(ln2b.y - ln2a.y); + double ln2dx = static_cast(ln2a.x - ln2b.x); + double det = (ln2dy * ln1dx) - (ln1dy * ln2dx); + if (det == 0.0) return false; + T bb0minx = CC_MIN(ln1a.x, ln1b.x); + T bb0miny = CC_MIN(ln1a.y, ln1b.y); + T bb0maxx = CC_MAX(ln1a.x, ln1b.x); + T bb0maxy = CC_MAX(ln1a.y, ln1b.y); + T bb1minx = CC_MIN(ln2a.x, ln2b.x); + T bb1miny = CC_MIN(ln2a.y, ln2b.y); + T bb1maxx = CC_MAX(ln2a.x, ln2b.x); + T bb1maxy = CC_MAX(ln2a.y, ln2b.y); + + if constexpr (std::is_integral_v) + { + int64_t originx = (CC_MIN(bb0maxx, bb1maxx) + CC_MAX(bb0minx, bb1minx)) >> 1; + int64_t originy = (CC_MIN(bb0maxy, bb1maxy) + CC_MAX(bb0miny, bb1miny)) >> 1; + double ln0c = (ln1dy * static_cast(ln1a.x - originx)) + + (ln1dx * static_cast(ln1a.y - originy)); + double ln1c = (ln2dy * static_cast(ln2a.x - originx)) + + (ln2dx * static_cast(ln2a.y - originy)); + double hitx = ((ln1dx * ln1c) - (ln2dx * ln0c)) / det; + double hity = ((ln2dy * ln0c) - (ln1dy * ln1c)) / det; + + ip.x = originx + (T)nearbyint(hitx); + ip.y = originy + (T)nearbyint(hity); + } + else + { + double originx = (CC_MIN(bb0maxx, bb1maxx) + CC_MAX(bb0minx, bb1minx)) / 2.0; + double originy = (CC_MIN(bb0maxy, bb1maxy) + CC_MAX(bb0miny, bb1miny)) / 2.0; + double ln0c = (ln1dy * static_cast(ln1a.x - originx)) + + (ln1dx * static_cast(ln1a.y - originy)); + double ln1c = (ln2dy * static_cast(ln2a.x - originx)) + + (ln2dx * static_cast(ln2a.y - originy)); + double hitx = ((ln1dx * ln1c) - (ln2dx * ln0c)) / det; + double hity = ((ln2dy * ln0c) - (ln1dy * ln1c)) / det; + + ip.x = originx + static_cast(hitx); + ip.y = originy + static_cast(hity); + } + return true; +} +#else + template + inline bool GetSegmentIntersectPt(const Point& ln1a, const Point& ln1b, + const Point& ln2a, const Point& ln2b, Point& ip) + { + // https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection + double dx1 = static_cast(ln1b.x - ln1a.x); + double dy1 = static_cast(ln1b.y - ln1a.y); + double dx2 = static_cast(ln2b.x - ln2a.x); + double dy2 = static_cast(ln2b.y - ln2a.y); + + double det = dy1 * dx2 - dy2 * dx1; + if (det == 0.0) return false; + double t = ((ln1a.x - ln2a.x) * dy2 - (ln1a.y - ln2a.y) * dx2) / det; + if (t <= 0.0) ip = ln1a; + else if (t >= 1.0) ip = ln1b; + else + { + ip.x = static_cast(ln1a.x + t * dx1); + ip.y = static_cast(ln1a.y + t * dy1); + } + return true; + } +#endif + + template + inline Point TranslatePoint(const Point& pt, double dx, double dy) + { +#ifdef USINGZ + return Point(pt.x + dx, pt.y + dy, pt.z); +#else + return Point(pt.x + dx, pt.y + dy); +#endif + } + + + template + inline Point ReflectPoint(const Point& pt, const Point& pivot) + { +#ifdef USINGZ + return Point(pivot.x + (pivot.x - pt.x), pivot.y + (pivot.y - pt.y), pt.z); +#else + return Point(pivot.x + (pivot.x - pt.x), pivot.y + (pivot.y - pt.y)); +#endif + } + + template + inline int GetSign(const T& val) + { + if (!val) return 0; + return (val > 0) ? 1 : -1; + } + + inline bool SegmentsIntersect(const Point64& seg1a, const Point64& seg1b, + const Point64& seg2a, const Point64& seg2b, bool inclusive = false) + { + if (inclusive) + { + double res1 = CrossProduct(seg1a, seg2a, seg2b); + double res2 = CrossProduct(seg1b, seg2a, seg2b); + if (res1 * res2 > 0) return false; + double res3 = CrossProduct(seg2a, seg1a, seg1b); + double res4 = CrossProduct(seg2b, seg1a, seg1b); + if (res3 * res4 > 0) return false; + return (res1 || res2 || res3 || res4); // ensures not collinear + } + else { + return (GetSign(CrossProduct(seg1a, seg2a, seg2b)) * + GetSign(CrossProduct(seg1b, seg2a, seg2b)) < 0) && + (GetSign(CrossProduct(seg2a, seg1a, seg1b)) * + GetSign(CrossProduct(seg2b, seg1a, seg1b)) < 0); + } + } + + template + inline Point GetClosestPointOnSegment(const Point& offPt, + const Point& seg1, const Point& seg2) + { + if (seg1.x == seg2.x && seg1.y == seg2.y) return seg1; + double dx = static_cast(seg2.x - seg1.x); + double dy = static_cast(seg2.y - seg1.y); + double q = + (static_cast(offPt.x - seg1.x) * dx + + static_cast(offPt.y - seg1.y) * dy) / + (Sqr(dx) + Sqr(dy)); + if (q < 0) q = 0; else if (q > 1) q = 1; + if constexpr (std::is_integral_v) + return Point( + seg1.x + static_cast(nearbyint(q * dx)), + seg1.y + static_cast(nearbyint(q * dy))); + else + return Point( + seg1.x + static_cast(q * dx), + seg1.y + static_cast(q * dy)); + } + + enum class PointInPolygonResult { IsOn, IsInside, IsOutside }; + + template + inline PointInPolygonResult PointInPolygon(const Point& pt, const Path& polygon) + { + if (polygon.size() < 3) + return PointInPolygonResult::IsOutside; + + int val = 0; + typename Path::const_iterator cbegin = polygon.cbegin(), first = cbegin, curr, prev; + typename Path::const_iterator cend = polygon.cend(); + + while (first != cend && first->y == pt.y) ++first; + if (first == cend) // not a proper polygon + return PointInPolygonResult::IsOutside; + + bool is_above = first->y < pt.y, starting_above = is_above; + curr = first +1; + while (true) + { + if (curr == cend) + { + if (cend == first || first == cbegin) break; + cend = first; + curr = cbegin; + } + + if (is_above) + { + while (curr != cend && curr->y < pt.y) ++curr; + if (curr == cend) continue; + } + else + { + while (curr != cend && curr->y > pt.y) ++curr; + if (curr == cend) continue; + } + + if (curr == cbegin) + prev = polygon.cend() - 1; //nb: NOT cend (since might equal first) + else + prev = curr - 1; + + if (curr->y == pt.y) + { + if (curr->x == pt.x || + (curr->y == prev->y && + ((pt.x < prev->x) != (pt.x < curr->x)))) + return PointInPolygonResult::IsOn; + ++curr; + if (curr == first) break; + continue; + } + + if (pt.x < curr->x && pt.x < prev->x) + { + // we're only interested in edges crossing on the left + } + else if (pt.x > prev->x && pt.x > curr->x) + val = 1 - val; // toggle val + else + { + double d = CrossProduct(*prev, *curr, pt); + if (d == 0) return PointInPolygonResult::IsOn; + if ((d < 0) == is_above) val = 1 - val; + } + is_above = !is_above; + ++curr; + } + + if (is_above != starting_above) + { + cend = polygon.cend(); + if (curr == cend) curr = cbegin; + if (curr == cbegin) prev = cend - 1; + else prev = curr - 1; + double d = CrossProduct(*prev, *curr, pt); + if (d == 0) return PointInPolygonResult::IsOn; + if ((d < 0) == is_above) val = 1 - val; + } + + return (val == 0) ? + PointInPolygonResult::IsOutside : + PointInPolygonResult::IsInside; + } + +} // namespace + +#endif // CLIPPER_CORE_H diff --git a/clipper2/include/clipper2/clipper.engine.h b/clipper2/include/clipper2/clipper.engine.h new file mode 100644 index 00000000..559f2479 --- /dev/null +++ b/clipper2/include/clipper2/clipper.engine.h @@ -0,0 +1,641 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 17 September 2024 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2024 * +* Purpose : This is the main polygon clipping module * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_ENGINE_H +#define CLIPPER_ENGINE_H + +#include +#include //#541 +#include +#include +#include +#include +#include +#include + +#include "clipper2/clipper.core.h" + +namespace Clipper2Lib { + + struct Scanline; + struct IntersectNode; + struct Active; + struct Vertex; + struct LocalMinima; + struct OutRec; + struct HorzSegment; + + //Note: all clipping operations except for Difference are commutative. + enum class ClipType { NoClip, Intersection, Union, Difference, Xor }; + + enum class PathType { Subject, Clip }; + enum class JoinWith { NoJoin, Left, Right }; + + enum class VertexFlags : uint32_t { + Empty = 0, OpenStart = 1, OpenEnd = 2, LocalMax = 4, LocalMin = 8 + }; + + constexpr enum VertexFlags operator &(enum VertexFlags a, enum VertexFlags b) + { + return (enum VertexFlags)(uint32_t(a) & uint32_t(b)); + } + + constexpr enum VertexFlags operator |(enum VertexFlags a, enum VertexFlags b) + { + return (enum VertexFlags)(uint32_t(a) | uint32_t(b)); + } + + struct Vertex { + Point64 pt; + Vertex* next = nullptr; + Vertex* prev = nullptr; + VertexFlags flags = VertexFlags::Empty; + }; + + struct OutPt { + Point64 pt; + OutPt* next = nullptr; + OutPt* prev = nullptr; + OutRec* outrec; + HorzSegment* horz = nullptr; + + OutPt(const Point64& pt_, OutRec* outrec_): pt(pt_), outrec(outrec_) { + next = this; + prev = this; + } + }; + + class PolyPath; + class PolyPath64; + class PolyPathD; + using PolyTree64 = PolyPath64; + using PolyTreeD = PolyPathD; + + struct OutRec; + typedef std::vector OutRecList; + + //OutRec: contains a path in the clipping solution. Edges in the AEL will + //have OutRec pointers assigned when they form part of the clipping solution. + struct OutRec { + size_t idx = 0; + OutRec* owner = nullptr; + Active* front_edge = nullptr; + Active* back_edge = nullptr; + OutPt* pts = nullptr; + PolyPath* polypath = nullptr; + OutRecList* splits = nullptr; + OutRec* recursive_split = nullptr; + Rect64 bounds = {}; + Path64 path; + bool is_open = false; + + ~OutRec() { + if (splits) delete splits; + // nb: don't delete the split pointers + // as these are owned by ClipperBase's outrec_list_ + }; + }; + + /////////////////////////////////////////////////////////////////// + //Important: UP and DOWN here are premised on Y-axis positive down + //displays, which is the orientation used in Clipper's development. + /////////////////////////////////////////////////////////////////// + + struct Active { + Point64 bot; + Point64 top; + int64_t curr_x = 0; //current (updated at every new scanline) + double dx = 0.0; + int wind_dx = 1; //1 or -1 depending on winding direction + int wind_cnt = 0; + int wind_cnt2 = 0; //winding count of the opposite polytype + OutRec* outrec = nullptr; + //AEL: 'active edge list' (Vatti's AET - active edge table) + // a linked list of all edges (from left to right) that are present + // (or 'active') within the current scanbeam (a horizontal 'beam' that + // sweeps from bottom to top over the paths in the clipping operation). + Active* prev_in_ael = nullptr; + Active* next_in_ael = nullptr; + //SEL: 'sorted edge list' (Vatti's ST - sorted table) + // linked list used when sorting edges into their new positions at the + // top of scanbeams, but also (re)used to process horizontals. + Active* prev_in_sel = nullptr; + Active* next_in_sel = nullptr; + Active* jump = nullptr; + Vertex* vertex_top = nullptr; + LocalMinima* local_min = nullptr; // the bottom of an edge 'bound' (also Vatti) + bool is_left_bound = false; + JoinWith join_with = JoinWith::NoJoin; + }; + + struct LocalMinima { + Vertex* vertex; + PathType polytype; + bool is_open; + LocalMinima(Vertex* v, PathType pt, bool open) : + vertex(v), polytype(pt), is_open(open){} + }; + + struct IntersectNode { + Point64 pt; + Active* edge1; + Active* edge2; + IntersectNode() : pt(Point64(0,0)), edge1(NULL), edge2(NULL) {} + IntersectNode(Active* e1, Active* e2, Point64& pt_) : + pt(pt_), edge1(e1), edge2(e2) {} + }; + + struct HorzSegment { + OutPt* left_op; + OutPt* right_op = nullptr; + bool left_to_right = true; + HorzSegment() : left_op(nullptr) { } + explicit HorzSegment(OutPt* op) : left_op(op) { } + }; + + struct HorzJoin { + OutPt* op1 = nullptr; + OutPt* op2 = nullptr; + HorzJoin() {}; + explicit HorzJoin(OutPt* ltr, OutPt* rtl) : op1(ltr), op2(rtl) { } + }; + +#ifdef USINGZ + typedef std::function ZCallback64; + + typedef std::function ZCallbackD; +#endif + + typedef std::vector HorzSegmentList; + typedef std::unique_ptr LocalMinima_ptr; + typedef std::vector LocalMinimaList; + typedef std::vector IntersectNodeList; + + // ReuseableDataContainer64 ------------------------------------------------ + + class ReuseableDataContainer64 { + private: + friend class ClipperBase; + LocalMinimaList minima_list_; + std::vector vertex_lists_; + void AddLocMin(Vertex& vert, PathType polytype, bool is_open); + public: + virtual ~ReuseableDataContainer64(); + void Clear(); + void AddPaths(const Paths64& paths, PathType polytype, bool is_open); + }; + + // ClipperBase ------------------------------------------------------------- + + class ClipperBase { + private: + ClipType cliptype_ = ClipType::NoClip; + FillRule fillrule_ = FillRule::EvenOdd; + FillRule fillpos = FillRule::Positive; + int64_t bot_y_ = 0; + bool minima_list_sorted_ = false; + bool using_polytree_ = false; + Active* actives_ = nullptr; + Active *sel_ = nullptr; + LocalMinimaList minima_list_; //pointers in case of memory reallocs + LocalMinimaList::iterator current_locmin_iter_; + std::vector vertex_lists_; + std::priority_queue scanline_list_; + IntersectNodeList intersect_nodes_; + HorzSegmentList horz_seg_list_; + std::vector horz_join_list_; + void Reset(); + inline void InsertScanline(int64_t y); + inline bool PopScanline(int64_t &y); + inline bool PopLocalMinima(int64_t y, LocalMinima*& local_minima); + void DisposeAllOutRecs(); + void DisposeVerticesAndLocalMinima(); + void DeleteEdges(Active*& e); + inline void AddLocMin(Vertex &vert, PathType polytype, bool is_open); + bool IsContributingClosed(const Active &e) const; + inline bool IsContributingOpen(const Active &e) const; + void SetWindCountForClosedPathEdge(Active &edge); + void SetWindCountForOpenPathEdge(Active &e); + void InsertLocalMinimaIntoAEL(int64_t bot_y); + void InsertLeftEdge(Active &e); + inline void PushHorz(Active &e); + inline bool PopHorz(Active *&e); + inline OutPt* StartOpenPath(Active &e, const Point64& pt); + inline void UpdateEdgeIntoAEL(Active *e); + void IntersectEdges(Active &e1, Active &e2, const Point64& pt); + inline void DeleteFromAEL(Active &e); + inline void AdjustCurrXAndCopyToSEL(const int64_t top_y); + void DoIntersections(const int64_t top_y); + void AddNewIntersectNode(Active &e1, Active &e2, const int64_t top_y); + bool BuildIntersectList(const int64_t top_y); + void ProcessIntersectList(); + void SwapPositionsInAEL(Active& edge1, Active& edge2); + OutRec* NewOutRec(); + OutPt* AddOutPt(const Active &e, const Point64& pt); + OutPt* AddLocalMinPoly(Active &e1, Active &e2, + const Point64& pt, bool is_new = false); + OutPt* AddLocalMaxPoly(Active &e1, Active &e2, const Point64& pt); + void DoHorizontal(Active &horz); + bool ResetHorzDirection(const Active &horz, const Vertex* max_vertex, + int64_t &horz_left, int64_t &horz_right); + void DoTopOfScanbeam(const int64_t top_y); + Active *DoMaxima(Active &e); + void JoinOutrecPaths(Active &e1, Active &e2); + void FixSelfIntersects(OutRec* outrec); + void DoSplitOp(OutRec* outRec, OutPt* splitOp); + + inline void AddTrialHorzJoin(OutPt* op); + void ConvertHorzSegsToJoins(); + void ProcessHorzJoins(); + + void Split(Active& e, const Point64& pt); + inline void CheckJoinLeft(Active& e, + const Point64& pt, bool check_curr_x = false); + inline void CheckJoinRight(Active& e, + const Point64& pt, bool check_curr_x = false); + protected: + bool preserve_collinear_ = true; + bool reverse_solution_ = false; + int error_code_ = 0; + bool has_open_paths_ = false; + bool succeeded_ = true; + OutRecList outrec_list_; //pointers in case list memory reallocated + bool ExecuteInternal(ClipType ct, FillRule ft, bool use_polytrees); + void CleanCollinear(OutRec* outrec); + bool CheckBounds(OutRec* outrec); + bool CheckSplitOwner(OutRec* outrec, OutRecList* splits); + void RecursiveCheckOwners(OutRec* outrec, PolyPath* polypath); +#ifdef USINGZ + ZCallback64 zCallback_ = nullptr; + void SetZ(const Active& e1, const Active& e2, Point64& pt); +#endif + void CleanUp(); // unlike Clear, CleanUp preserves added paths + void AddPath(const Path64& path, PathType polytype, bool is_open); + void AddPaths(const Paths64& paths, PathType polytype, bool is_open); + public: + virtual ~ClipperBase(); + int ErrorCode() const { return error_code_; }; + void PreserveCollinear(bool val) { preserve_collinear_ = val; }; + bool PreserveCollinear() const { return preserve_collinear_;}; + void ReverseSolution(bool val) { reverse_solution_ = val; }; + bool ReverseSolution() const { return reverse_solution_; }; + void Clear(); + void AddReuseableData(const ReuseableDataContainer64& reuseable_data); +#ifdef USINGZ + int64_t DefaultZ = 0; +#endif + }; + + // PolyPath / PolyTree -------------------------------------------------------- + + //PolyTree: is intended as a READ-ONLY data structure for CLOSED paths returned + //by clipping operations. While this structure is more complex than the + //alternative Paths structure, it does preserve path 'ownership' - ie those + //paths that contain (or own) other paths. This will be useful to some users. + + class PolyPath { + protected: + PolyPath* parent_; + public: + PolyPath(PolyPath* parent = nullptr): parent_(parent){} + virtual ~PolyPath() {}; + //https://en.cppreference.com/w/cpp/language/rule_of_three + PolyPath(const PolyPath&) = delete; + PolyPath& operator=(const PolyPath&) = delete; + + unsigned Level() const + { + unsigned result = 0; + const PolyPath* p = parent_; + while (p) { ++result; p = p->parent_; } + return result; + } + + virtual PolyPath* AddChild(const Path64& path) = 0; + + virtual void Clear() = 0; + virtual size_t Count() const { return 0; } + + const PolyPath* Parent() const { return parent_; } + + bool IsHole() const + { + unsigned lvl = Level(); + //Even levels except level 0 + return lvl && !(lvl & 1); + } + }; + + typedef typename std::vector> PolyPath64List; + typedef typename std::vector> PolyPathDList; + + class PolyPath64 : public PolyPath { + private: + PolyPath64List childs_; + Path64 polygon_; + public: + explicit PolyPath64(PolyPath64* parent = nullptr) : PolyPath(parent) {} + explicit PolyPath64(PolyPath64* parent, const Path64& path) : PolyPath(parent) { polygon_ = path; } + + ~PolyPath64() { + childs_.resize(0); + } + + PolyPath64* operator [] (size_t index) const + { + return childs_[index].get(); //std::unique_ptr + } + + PolyPath64* Child(size_t index) const + { + return childs_[index].get(); + } + + PolyPath64List::const_iterator begin() const { return childs_.cbegin(); } + PolyPath64List::const_iterator end() const { return childs_.cend(); } + + PolyPath64* AddChild(const Path64& path) override + { + return childs_.emplace_back(std::make_unique(this, path)).get(); + } + + void Clear() override + { + childs_.resize(0); + } + + size_t Count() const override + { + return childs_.size(); + } + + const Path64& Polygon() const { return polygon_; }; + + double Area() const + { + return std::accumulate(childs_.cbegin(), childs_.cend(), + Clipper2Lib::Area(polygon_), + [](double a, const auto& child) {return a + child->Area(); }); + } + + }; + + class PolyPathD : public PolyPath { + private: + PolyPathDList childs_; + double scale_; + PathD polygon_; + public: + explicit PolyPathD(PolyPathD* parent = nullptr) : PolyPath(parent) + { + scale_ = parent ? parent->scale_ : 1.0; + } + + explicit PolyPathD(PolyPathD* parent, const Path64& path) : PolyPath(parent) + { + scale_ = parent ? parent->scale_ : 1.0; + int error_code = 0; + polygon_ = ScalePath(path, scale_, error_code); + } + + explicit PolyPathD(PolyPathD* parent, const PathD& path) : PolyPath(parent) + { + scale_ = parent ? parent->scale_ : 1.0; + polygon_ = path; + } + + ~PolyPathD() { + childs_.resize(0); + } + + PolyPathD* operator [] (size_t index) const + { + return childs_[index].get(); + } + + PolyPathD* Child(size_t index) const + { + return childs_[index].get(); + } + + PolyPathDList::const_iterator begin() const { return childs_.cbegin(); } + PolyPathDList::const_iterator end() const { return childs_.cend(); } + + void SetScale(double value) { scale_ = value; } + double Scale() const { return scale_; } + + PolyPathD* AddChild(const Path64& path) override + { + return childs_.emplace_back(std::make_unique(this, path)).get(); + } + + PolyPathD* AddChild(const PathD& path) + { + return childs_.emplace_back(std::make_unique(this, path)).get(); + } + + void Clear() override + { + childs_.resize(0); + } + + size_t Count() const override + { + return childs_.size(); + } + + const PathD& Polygon() const { return polygon_; }; + + double Area() const + { + return std::accumulate(childs_.begin(), childs_.end(), + Clipper2Lib::Area(polygon_), + [](double a, const auto& child) {return a + child->Area(); }); + } + }; + + class Clipper64 : public ClipperBase + { + private: + void BuildPaths64(Paths64& solutionClosed, Paths64* solutionOpen); + void BuildTree64(PolyPath64& polytree, Paths64& open_paths); + public: +#ifdef USINGZ + void SetZCallback(ZCallback64 cb) { zCallback_ = cb; } +#endif + + void AddSubject(const Paths64& subjects) + { + AddPaths(subjects, PathType::Subject, false); + } + void AddOpenSubject(const Paths64& open_subjects) + { + AddPaths(open_subjects, PathType::Subject, true); + } + void AddClip(const Paths64& clips) + { + AddPaths(clips, PathType::Clip, false); + } + + bool Execute(ClipType clip_type, + FillRule fill_rule, Paths64& closed_paths) + { + Paths64 dummy; + return Execute(clip_type, fill_rule, closed_paths, dummy); + } + + bool Execute(ClipType clip_type, FillRule fill_rule, + Paths64& closed_paths, Paths64& open_paths) + { + closed_paths.clear(); + open_paths.clear(); + if (ExecuteInternal(clip_type, fill_rule, false)) + BuildPaths64(closed_paths, &open_paths); + CleanUp(); + return succeeded_; + } + + bool Execute(ClipType clip_type, FillRule fill_rule, PolyTree64& polytree) + { + Paths64 dummy; + return Execute(clip_type, fill_rule, polytree, dummy); + } + + bool Execute(ClipType clip_type, + FillRule fill_rule, PolyTree64& polytree, Paths64& open_paths) + { + if (ExecuteInternal(clip_type, fill_rule, true)) + { + open_paths.clear(); + polytree.Clear(); + BuildTree64(polytree, open_paths); + } + CleanUp(); + return succeeded_; + } + }; + + class ClipperD : public ClipperBase { + private: + double scale_ = 1.0, invScale_ = 1.0; +#ifdef USINGZ + ZCallbackD zCallbackD_ = nullptr; +#endif + void BuildPathsD(PathsD& solutionClosed, PathsD* solutionOpen); + void BuildTreeD(PolyPathD& polytree, PathsD& open_paths); + public: + explicit ClipperD(int precision = 2) : ClipperBase() + { + CheckPrecisionRange(precision, error_code_); + // to optimize scaling / descaling precision + // set the scale to a power of double's radix (2) (#25) + scale_ = std::pow(std::numeric_limits::radix, + std::ilogb(std::pow(10, precision)) + 1); + invScale_ = 1 / scale_; + } + +#ifdef USINGZ + void SetZCallback(ZCallbackD cb) { zCallbackD_ = cb; }; + + void ZCB(const Point64& e1bot, const Point64& e1top, + const Point64& e2bot, const Point64& e2top, Point64& pt) + { + // de-scale (x & y) + // temporarily convert integers to their initial float values + // this will slow clipping marginally but will make it much easier + // to understand the coordinates passed to the callback function + PointD tmp = PointD(pt) * invScale_; + PointD e1b = PointD(e1bot) * invScale_; + PointD e1t = PointD(e1top) * invScale_; + PointD e2b = PointD(e2bot) * invScale_; + PointD e2t = PointD(e2top) * invScale_; + zCallbackD_(e1b,e1t, e2b, e2t, tmp); + pt.z = tmp.z; // only update 'z' + }; + + void CheckCallback() + { + if(zCallbackD_) + // if the user defined float point callback has been assigned + // then assign the proxy callback function + ClipperBase::zCallback_ = + std::bind(&ClipperD::ZCB, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, std::placeholders::_5); + else + ClipperBase::zCallback_ = nullptr; + } + +#endif + + void AddSubject(const PathsD& subjects) + { + AddPaths(ScalePaths(subjects, scale_, error_code_), PathType::Subject, false); + } + + void AddOpenSubject(const PathsD& open_subjects) + { + AddPaths(ScalePaths(open_subjects, scale_, error_code_), PathType::Subject, true); + } + + void AddClip(const PathsD& clips) + { + AddPaths(ScalePaths(clips, scale_, error_code_), PathType::Clip, false); + } + + bool Execute(ClipType clip_type, FillRule fill_rule, PathsD& closed_paths) + { + PathsD dummy; + return Execute(clip_type, fill_rule, closed_paths, dummy); + } + + bool Execute(ClipType clip_type, + FillRule fill_rule, PathsD& closed_paths, PathsD& open_paths) + { +#ifdef USINGZ + CheckCallback(); +#endif + if (ExecuteInternal(clip_type, fill_rule, false)) + { + BuildPathsD(closed_paths, &open_paths); + } + CleanUp(); + return succeeded_; + } + + bool Execute(ClipType clip_type, FillRule fill_rule, PolyTreeD& polytree) + { + PathsD dummy; + return Execute(clip_type, fill_rule, polytree, dummy); + } + + bool Execute(ClipType clip_type, + FillRule fill_rule, PolyTreeD& polytree, PathsD& open_paths) + { +#ifdef USINGZ + CheckCallback(); +#endif + if (ExecuteInternal(clip_type, fill_rule, true)) + { + polytree.Clear(); + polytree.SetScale(invScale_); + open_paths.clear(); + BuildTreeD(polytree, open_paths); + } + CleanUp(); + return succeeded_; + } + + }; + +} // namespace + +#endif // CLIPPER_ENGINE_H diff --git a/clipper2/include/clipper2/clipper.export.h b/clipper2/include/clipper2/clipper.export.h new file mode 100644 index 00000000..5afbba17 --- /dev/null +++ b/clipper2/include/clipper2/clipper.export.h @@ -0,0 +1,827 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 17 September 2024 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2024 * +* Purpose : This module exports the Clipper2 Library (ie DLL/so) * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + + +/* + Boolean clipping: + cliptype: NoClip=0, Intersection=1, Union=2, Difference=3, Xor=4 + fillrule: EvenOdd=0, NonZero=1, Positive=2, Negative=3 + + Polygon offsetting (inflate/deflate): + jointype: Square=0, Bevel=1, Round=2, Miter=3 + endtype: Polygon=0, Joined=1, Butt=2, Square=3, Round=4 + +The path structures used extensively in other parts of this library are all +based on std::vector classes. Since C++ classes can't be accessed by other +languages, these paths are converted here into very simple array data +structures that can be parsed by just about any programming language. + +These 2D paths are defined by series of x and y coordinates together with an +optional user-defined 'z' value (see Z-values below). Hence, a vertex refers +to a single x and y coordinate (+/- a user-defined value). These values will +be either type int64_t or type double. Data structures have names that +indicate the array type by a suffixed '64' or a 'D'. For example, the data +structure CPath64 contains an array of int64_t values, whereas the data +structure CPathD contains an array of double. Where documentation omits +the type suffix (eg CPath), it is simply agnostic to the array's data type. + +For conciseness, the following letters are used in the diagrams below: +N: Number of vertices in a given path +C: Count of structure's paths +A: Array size (as distinct from the size in memory) + + +CPath64 and CPathD: +These are arrays of consecutive vertices preceeded by a pair of values +containing the number of vertices (N) in the path, and a 0 value. +_______________________________________________________________ +| counters | vertex1 | vertex2 | ... | vertexN | +| N, 0 | x1, y1, (z1) | x2, y2, (z2) | ... | xN, yN, (zN) | +--------------------------------------------------------------- + + +CPaths64 and CPathsD: +These are also arrays containing any number of consecutive CPath +structures. Preceeding these consecutive paths, there is a pair of +values that contain the length of the array structure (A) and +the count of following CPath structures (C). + Memory allocation for CPaths64 = A * sizeof(int64_t) + Memory allocation for CPathsD = A * sizeof(double) +__________________________________________ +| counters | path1 | path2 | ... | pathC | +| A, C | | | ... | | +------------------------------------------ + + +CPolytree64 and CPolytreeD: +These structures consist of two values followed by a series of CPolyPath +structures. The first value indicates the total length of the array (A). +The second value indicates the number of following CPolyPath structures +that are the top level CPolyPath in the CPolytree (C). These CPolyPath +may, in turn, contain their own nested CPolyPath children that +collectively make a tree structure. +_________________________________________________________ +| counters | CPolyPath1 | CPolyPath2 | ... | CPolyPathC | +| A, C | | | ... | | +--------------------------------------------------------- + + +CPolyPath64 and CPolyPathD: +These array structures consist of a pair of counter values followed by a +series of polygon vertices and a series of nested CPolyPath children. +The first counter values indicates the number of vertices in the +polygon (N), and the second counter indicates the CPolyPath child count (C). +_____________________________________________________________________________ +|cntrs |vertex1 |vertex2 |...|vertexN |child1|child2|...|childC| +|N, C |x1, y1, (z1)| x2, y2, (z2)|...|xN, yN, (zN)| | |...| | +----------------------------------------------------------------------------- + + +DisposeArray64 & DisposeArrayD: +All array structures are allocated in heap memory which will eventually +need to be released. However, since applications linking to these DLL +functions may use different memory managers, the only safe way to release +this memory is to use the exported DisposeArray functions. + + +(Optional) Z-Values: +Structures will only contain user-defined z-values when the USINGZ +pre-processor identifier is used. The library does not assign z-values +because this field is intended for users to assign custom values to vertices. +Z-values in input paths (subject and clip) will be copied to solution paths. +New vertices at path intersections will generate a callback event that allows +users to assign z-values at these new vertices. The user's callback function +must conform with the DLLZCallback definition and be registered with the +DLL via SetZCallback. To assist the user in assigning z-values, the library +passes in the callback function the new intersection point together with +the four vertices that define the two segments that are intersecting. + +*/ +#ifndef CLIPPER2_EXPORT_H +#define CLIPPER2_EXPORT_H + +#include +#include +#include "clipper2/clipper.core.h" +#include "clipper2/clipper.engine.h" +#include "clipper2/clipper.offset.h" +#include "clipper2/clipper.rectclip.h" + +namespace Clipper2Lib { + +typedef int64_t* CPath64; +typedef int64_t* CPaths64; +typedef double* CPathD; +typedef double* CPathsD; + +typedef int64_t* CPolyPath64; +typedef int64_t* CPolyTree64; +typedef double* CPolyPathD; +typedef double* CPolyTreeD; + +template +struct CRect { + T left; + T top; + T right; + T bottom; +}; + +typedef CRect CRect64; +typedef CRect CRectD; + +template +inline bool CRectIsEmpty(const CRect& rect) +{ + return (rect.right <= rect.left) || (rect.bottom <= rect.top); +} + +template +inline Rect CRectToRect(const CRect& rect) +{ + Rect result; + result.left = rect.left; + result.top = rect.top; + result.right = rect.right; + result.bottom = rect.bottom; + return result; +} + +template +inline T1 Reinterpret(T2 value) { + return *reinterpret_cast(&value); +} + + +#ifdef _WIN32 + #define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport) +#else + #define EXTERN_DLL_EXPORT extern "C" +#endif + + +////////////////////////////////////////////////////// +// EXPORTED FUNCTION DECLARATIONS +////////////////////////////////////////////////////// + +EXTERN_DLL_EXPORT const char* Version(); + +EXTERN_DLL_EXPORT void DisposeArray64(int64_t*& p) +{ + delete[] p; +} + +EXTERN_DLL_EXPORT void DisposeArrayD(double*& p) +{ + delete[] p; +} + +EXTERN_DLL_EXPORT int BooleanOp64(uint8_t cliptype, + uint8_t fillrule, const CPaths64 subjects, + const CPaths64 subjects_open, const CPaths64 clips, + CPaths64& solution, CPaths64& solution_open, + bool preserve_collinear = true, bool reverse_solution = false); + +EXTERN_DLL_EXPORT int BooleanOp_PolyTree64(uint8_t cliptype, + uint8_t fillrule, const CPaths64 subjects, + const CPaths64 subjects_open, const CPaths64 clips, + CPolyTree64& sol_tree, CPaths64& solution_open, + bool preserve_collinear = true, bool reverse_solution = false); + +EXTERN_DLL_EXPORT int BooleanOpD(uint8_t cliptype, + uint8_t fillrule, const CPathsD subjects, + const CPathsD subjects_open, const CPathsD clips, + CPathsD& solution, CPathsD& solution_open, int precision = 2, + bool preserve_collinear = true, bool reverse_solution = false); + +EXTERN_DLL_EXPORT int BooleanOp_PolyTreeD(uint8_t cliptype, + uint8_t fillrule, const CPathsD subjects, + const CPathsD subjects_open, const CPathsD clips, + CPolyTreeD& solution, CPathsD& solution_open, int precision = 2, + bool preserve_collinear = true, bool reverse_solution = false); + +EXTERN_DLL_EXPORT CPaths64 InflatePaths64(const CPaths64 paths, + double delta, uint8_t jointype, uint8_t endtype, + double miter_limit = 2.0, double arc_tolerance = 0.0, + bool reverse_solution = false); + +EXTERN_DLL_EXPORT CPathsD InflatePathsD(const CPathsD paths, + double delta, uint8_t jointype, uint8_t endtype, + int precision = 2, double miter_limit = 2.0, + double arc_tolerance = 0.0, bool reverse_solution = false); + +EXTERN_DLL_EXPORT CPaths64 InflatePath64(const CPath64 path, + double delta, uint8_t jointype, uint8_t endtype, + double miter_limit = 2.0, double arc_tolerance = 0.0, + bool reverse_solution = false); + +EXTERN_DLL_EXPORT CPathsD InflatePathD(const CPathD path, + double delta, uint8_t jointype, uint8_t endtype, + int precision = 2, double miter_limit = 2.0, + double arc_tolerance = 0.0, bool reverse_solution = false); + +// RectClip & RectClipLines: +EXTERN_DLL_EXPORT CPaths64 RectClip64(const CRect64& rect, + const CPaths64 paths); +EXTERN_DLL_EXPORT CPathsD RectClipD(const CRectD& rect, + const CPathsD paths, int precision = 2); +EXTERN_DLL_EXPORT CPaths64 RectClipLines64(const CRect64& rect, + const CPaths64 paths); +EXTERN_DLL_EXPORT CPathsD RectClipLinesD(const CRectD& rect, + const CPathsD paths, int precision = 2); + +////////////////////////////////////////////////////// +// INTERNAL FUNCTIONS +////////////////////////////////////////////////////// + +#ifdef USINGZ +ZCallback64 dllCallback64 = nullptr; +ZCallbackD dllCallbackD = nullptr; + +constexpr int EXPORT_VERTEX_DIMENSIONALITY = 3; +#else +constexpr int EXPORT_VERTEX_DIMENSIONALITY = 2; +#endif + +template +static void GetPathCountAndCPathsArrayLen(const Paths& paths, + size_t& cnt, size_t& array_len) +{ + array_len = 2; + cnt = 0; + for (const Path& path : paths) + if (path.size()) + { + array_len += path.size() * EXPORT_VERTEX_DIMENSIONALITY + 2; + ++cnt; + } +} + +static size_t GetPolyPathArrayLen64(const PolyPath64& pp) +{ + size_t result = 2; // poly_length + child_count + result += pp.Polygon().size() * EXPORT_VERTEX_DIMENSIONALITY; + //plus nested children :) + for (size_t i = 0; i < pp.Count(); ++i) + result += GetPolyPathArrayLen64(*pp[i]); + return result; +} + +static size_t GetPolyPathArrayLenD(const PolyPathD& pp) +{ + size_t result = 2; // poly_length + child_count + result += pp.Polygon().size() * EXPORT_VERTEX_DIMENSIONALITY; + //plus nested children :) + for (size_t i = 0; i < pp.Count(); ++i) + result += GetPolyPathArrayLenD(*pp[i]); + return result; +} + +static void GetPolytreeCountAndCStorageSize64(const PolyTree64& tree, + size_t& cnt, size_t& array_len) +{ + cnt = tree.Count(); // nb: top level count only + array_len = GetPolyPathArrayLen64(tree); +} + +static void GetPolytreeCountAndCStorageSizeD(const PolyTreeD& tree, + size_t& cnt, size_t& array_len) +{ + cnt = tree.Count(); // nb: top level count only + array_len = GetPolyPathArrayLenD(tree); +} + +template +static T* CreateCPathsFromPathsT(const Paths& paths) +{ + size_t cnt = 0, array_len = 0; + GetPathCountAndCPathsArrayLen(paths, cnt, array_len); + T* result = new T[array_len], * v = result; + *v++ = array_len; + *v++ = cnt; + for (const Path& path : paths) + { + if (!path.size()) continue; + *v++ = path.size(); + *v++ = 0; + for (const Point& pt : path) + { + *v++ = pt.x; + *v++ = pt.y; +#ifdef USINGZ + *v++ = Reinterpret(pt.z); +#endif + } + } + return result; +} + +CPathsD CreateCPathsDFromPathsD(const PathsD& paths) +{ + if (!paths.size()) return nullptr; + size_t cnt, array_len; + GetPathCountAndCPathsArrayLen(paths, cnt, array_len); + CPathsD result = new double[array_len], v = result; + *v++ = (double)array_len; + *v++ = (double)cnt; + for (const PathD& path : paths) + { + if (!path.size()) continue; + *v = (double)path.size(); + ++v; *v++ = 0; + for (const PointD& pt : path) + { + *v++ = pt.x; + *v++ = pt.y; +#ifdef USINGZ + * v++ = Reinterpret(pt.z); +#endif + } + } + return result; +} + +CPathsD CreateCPathsDFromPaths64(const Paths64& paths, double scale) +{ + if (!paths.size()) return nullptr; + size_t cnt, array_len; + GetPathCountAndCPathsArrayLen(paths, cnt, array_len); + CPathsD result = new double[array_len], v = result; + *v++ = (double)array_len; + *v++ = (double)cnt; + for (const Path64& path : paths) + { + if (!path.size()) continue; + *v = (double)path.size(); + ++v; *v++ = 0; + for (const Point64& pt : path) + { + *v++ = pt.x * scale; + *v++ = pt.y * scale; +#ifdef USINGZ + *v++ = Reinterpret(pt.z); +#endif + } + } + return result; +} + +template +static Path ConvertCPathToPathT(T* path) +{ + Path result; + if (!path) return result; + T* v = path; + size_t cnt = static_cast(*v); + v += 2; // skip 0 value + result.reserve(cnt); + for (size_t j = 0; j < cnt; ++j) + { + T x = *v++, y = *v++; +#ifdef USINGZ + z_type z = Reinterpret(*v++); + result.push_back(Point(x, y, z)); +#else + result.push_back(Point(x, y)); +#endif + } + return result; +} + +template +static Paths ConvertCPathsToPathsT(T* paths) +{ + Paths result; + if (!paths) return result; + T* v = paths; ++v; + size_t cnt = static_cast(*v++); + result.reserve(cnt); + for (size_t i = 0; i < cnt; ++i) + { + size_t cnt2 = static_cast(*v); + v += 2; + Path path; + path.reserve(cnt2); + for (size_t j = 0; j < cnt2; ++j) + { + T x = *v++, y = *v++; +#ifdef USINGZ + z_type z = Reinterpret(*v++); + path.push_back(Point(x, y, z)); +#else + path.push_back(Point(x, y)); +#endif + } + result.push_back(path); + } + return result; +} + +static Path64 ConvertCPathDToPath64WithScale(const CPathD path, double scale) +{ + Path64 result; + if (!path) return result; + double* v = path; + size_t cnt = static_cast(*v); + v += 2; // skip 0 value + result.reserve(cnt); + for (size_t j = 0; j < cnt; ++j) + { + double x = *v++ * scale; + double y = *v++ * scale; +#ifdef USINGZ + z_type z = Reinterpret(*v++); + result.push_back(Point64(x, y, z)); +#else + result.push_back(Point64(x, y)); +#endif + } + return result; +} + +static Paths64 ConvertCPathsDToPaths64(const CPathsD paths, double scale) +{ + Paths64 result; + if (!paths) return result; + double* v = paths; + ++v; // skip the first value (0) + size_t cnt = static_cast(*v++); + result.reserve(cnt); + for (size_t i = 0; i < cnt; ++i) + { + size_t cnt2 = static_cast(*v); + v += 2; + Path64 path; + path.reserve(cnt2); + for (size_t j = 0; j < cnt2; ++j) + { + double x = *v++ * scale; + double y = *v++ * scale; +#ifdef USINGZ + z_type z = Reinterpret(*v++); + path.push_back(Point64(x, y, z)); +#else + path.push_back(Point64(x, y)); +#endif + } + result.push_back(path); + } + return result; +} + +static void CreateCPolyPath64(const PolyPath64* pp, int64_t*& v) +{ + *v++ = static_cast(pp->Polygon().size()); + *v++ = static_cast(pp->Count()); + for (const Point64& pt : pp->Polygon()) + { + *v++ = pt.x; + *v++ = pt.y; +#ifdef USINGZ + * v++ = Reinterpret(pt.z); // raw memory copy +#endif + } + for (size_t i = 0; i < pp->Count(); ++i) + CreateCPolyPath64(pp->Child(i), v); +} + +static void CreateCPolyPathD(const PolyPathD* pp, double*& v) +{ + *v++ = static_cast(pp->Polygon().size()); + *v++ = static_cast(pp->Count()); + for (const PointD& pt : pp->Polygon()) + { + *v++ = pt.x; + *v++ = pt.y; +#ifdef USINGZ + * v++ = Reinterpret(pt.z); // raw memory copy +#endif + } + for (size_t i = 0; i < pp->Count(); ++i) + CreateCPolyPathD(pp->Child(i), v); +} + +static int64_t* CreateCPolyTree64(const PolyTree64& tree) +{ + size_t cnt, array_len; + GetPolytreeCountAndCStorageSize64(tree, cnt, array_len); + if (!cnt) return nullptr; + // allocate storage + int64_t* result = new int64_t[array_len]; + int64_t* v = result; + *v++ = static_cast(array_len); + *v++ = static_cast(tree.Count()); + for (size_t i = 0; i < tree.Count(); ++i) + CreateCPolyPath64(tree.Child(i), v); + return result; +} + +static double* CreateCPolyTreeD(const PolyTreeD& tree) +{ + double scale = std::log10(tree.Scale()); + size_t cnt, array_len; + GetPolytreeCountAndCStorageSizeD(tree, cnt, array_len); + if (!cnt) return nullptr; + // allocate storage + double* result = new double[array_len]; + double* v = result; + *v++ = static_cast(array_len); + *v++ = static_cast(tree.Count()); + for (size_t i = 0; i < tree.Count(); ++i) + CreateCPolyPathD(tree.Child(i), v); + return result; +} + +////////////////////////////////////////////////////// +// EXPORTED FUNCTION DEFINITIONS +////////////////////////////////////////////////////// + +EXTERN_DLL_EXPORT const char* Version() +{ + return CLIPPER2_VERSION; +} + +EXTERN_DLL_EXPORT int BooleanOp64(uint8_t cliptype, + uint8_t fillrule, const CPaths64 subjects, + const CPaths64 subjects_open, const CPaths64 clips, + CPaths64& solution, CPaths64& solution_open, + bool preserve_collinear, bool reverse_solution) +{ + if (cliptype > static_cast(ClipType::Xor)) return -4; + if (fillrule > static_cast(FillRule::Negative)) return -3; + + Paths64 sub, sub_open, clp, sol, sol_open; + sub = ConvertCPathsToPathsT(subjects); + sub_open = ConvertCPathsToPathsT(subjects_open); + clp = ConvertCPathsToPathsT(clips); + + Clipper64 clipper; + clipper.PreserveCollinear(preserve_collinear); + clipper.ReverseSolution(reverse_solution); +#ifdef USINGZ + if (dllCallback64) + clipper.SetZCallback(dllCallback64); +#endif + if (sub.size() > 0) clipper.AddSubject(sub); + if (sub_open.size() > 0) clipper.AddOpenSubject(sub_open); + if (clp.size() > 0) clipper.AddClip(clp); + if (!clipper.Execute(ClipType(cliptype), FillRule(fillrule), sol, sol_open)) + return -1; // clipping bug - should never happen :) + solution = CreateCPathsFromPathsT(sol); + solution_open = CreateCPathsFromPathsT(sol_open); + return 0; //success !! +} + +EXTERN_DLL_EXPORT int BooleanOp_PolyTree64(uint8_t cliptype, + uint8_t fillrule, const CPaths64 subjects, + const CPaths64 subjects_open, const CPaths64 clips, + CPolyTree64& sol_tree, CPaths64& solution_open, + bool preserve_collinear, bool reverse_solution) +{ + if (cliptype > static_cast(ClipType::Xor)) return -4; + if (fillrule > static_cast(FillRule::Negative)) return -3; + Paths64 sub, sub_open, clp, sol_open; + sub = ConvertCPathsToPathsT(subjects); + sub_open = ConvertCPathsToPathsT(subjects_open); + clp = ConvertCPathsToPathsT(clips); + + PolyTree64 tree; + Clipper64 clipper; + clipper.PreserveCollinear(preserve_collinear); + clipper.ReverseSolution(reverse_solution); +#ifdef USINGZ + if (dllCallback64) + clipper.SetZCallback(dllCallback64); +#endif + if (sub.size() > 0) clipper.AddSubject(sub); + if (sub_open.size() > 0) clipper.AddOpenSubject(sub_open); + if (clp.size() > 0) clipper.AddClip(clp); + if (!clipper.Execute(ClipType(cliptype), FillRule(fillrule), tree, sol_open)) + return -1; // clipping bug - should never happen :) + + sol_tree = CreateCPolyTree64(tree); + solution_open = CreateCPathsFromPathsT(sol_open); + return 0; //success !! +} + +EXTERN_DLL_EXPORT int BooleanOpD(uint8_t cliptype, + uint8_t fillrule, const CPathsD subjects, + const CPathsD subjects_open, const CPathsD clips, + CPathsD& solution, CPathsD& solution_open, int precision, + bool preserve_collinear, bool reverse_solution) +{ + if (precision < -8 || precision > 8) return -5; + if (cliptype > static_cast(ClipType::Xor)) return -4; + if (fillrule > static_cast(FillRule::Negative)) return -3; + //const double scale = std::pow(10, precision); + + PathsD sub, sub_open, clp, sol, sol_open; + sub = ConvertCPathsToPathsT(subjects); + sub_open = ConvertCPathsToPathsT(subjects_open); + clp = ConvertCPathsToPathsT(clips); + + ClipperD clipper(precision); + clipper.PreserveCollinear(preserve_collinear); + clipper.ReverseSolution(reverse_solution); +#ifdef USINGZ + if (dllCallbackD) + clipper.SetZCallback(dllCallbackD); +#endif + if (sub.size() > 0) clipper.AddSubject(sub); + if (sub_open.size() > 0) clipper.AddOpenSubject(sub_open); + if (clp.size() > 0) clipper.AddClip(clp); + if (!clipper.Execute(ClipType(cliptype), + FillRule(fillrule), sol, sol_open)) return -1; + solution = CreateCPathsDFromPathsD(sol); + solution_open = CreateCPathsDFromPathsD(sol_open); + return 0; +} + +EXTERN_DLL_EXPORT int BooleanOp_PolyTreeD(uint8_t cliptype, + uint8_t fillrule, const CPathsD subjects, + const CPathsD subjects_open, const CPathsD clips, + CPolyTreeD& solution, CPathsD& solution_open, int precision, + bool preserve_collinear, bool reverse_solution) +{ + if (precision < -8 || precision > 8) return -5; + if (cliptype > static_cast(ClipType::Xor)) return -4; + if (fillrule > static_cast(FillRule::Negative)) return -3; + //double scale = std::pow(10, precision); + + int err = 0; + PathsD sub, sub_open, clp, sol_open; + sub = ConvertCPathsToPathsT(subjects); + sub_open = ConvertCPathsToPathsT(subjects_open); + clp = ConvertCPathsToPathsT(clips); + + PolyTreeD tree; + ClipperD clipper(precision); + clipper.PreserveCollinear(preserve_collinear); + clipper.ReverseSolution(reverse_solution); +#ifdef USINGZ + if (dllCallbackD) + clipper.SetZCallback(dllCallbackD); +#endif + if (sub.size() > 0) clipper.AddSubject(sub); + if (sub_open.size() > 0) clipper.AddOpenSubject(sub_open); + if (clp.size() > 0) clipper.AddClip(clp); + if (!clipper.Execute(ClipType(cliptype), FillRule(fillrule), tree, sol_open)) + return -1; // clipping bug - should never happen :) + + solution = CreateCPolyTreeD(tree); + solution_open = CreateCPathsDFromPathsD(sol_open); + return 0; //success !! +} + +EXTERN_DLL_EXPORT CPaths64 InflatePaths64(const CPaths64 paths, + double delta, uint8_t jointype, uint8_t endtype, double miter_limit, + double arc_tolerance, bool reverse_solution) +{ + Paths64 pp; + pp = ConvertCPathsToPathsT(paths); + ClipperOffset clip_offset( miter_limit, + arc_tolerance, reverse_solution); + clip_offset.AddPaths(pp, JoinType(jointype), EndType(endtype)); + Paths64 result; + clip_offset.Execute(delta, result); + return CreateCPathsFromPathsT(result); +} + +EXTERN_DLL_EXPORT CPathsD InflatePathsD(const CPathsD paths, + double delta, uint8_t jointype, uint8_t endtype, + int precision, double miter_limit, + double arc_tolerance, bool reverse_solution) +{ + if (precision < -8 || precision > 8 || !paths) return nullptr; + + const double scale = std::pow(10, precision); + ClipperOffset clip_offset(miter_limit, arc_tolerance, reverse_solution); + Paths64 pp = ConvertCPathsDToPaths64(paths, scale); + clip_offset.AddPaths(pp, JoinType(jointype), EndType(endtype)); + Paths64 result; + clip_offset.Execute(delta * scale, result); + return CreateCPathsDFromPaths64(result, 1 / scale); +} + + +EXTERN_DLL_EXPORT CPaths64 InflatePath64(const CPath64 path, + double delta, uint8_t jointype, uint8_t endtype, double miter_limit, + double arc_tolerance, bool reverse_solution) +{ + Path64 pp; + pp = ConvertCPathToPathT(path); + ClipperOffset clip_offset(miter_limit, + arc_tolerance, reverse_solution); + clip_offset.AddPath(pp, JoinType(jointype), EndType(endtype)); + Paths64 result; + clip_offset.Execute(delta, result); + return CreateCPathsFromPathsT(result); +} + +EXTERN_DLL_EXPORT CPathsD InflatePathD(const CPathD path, + double delta, uint8_t jointype, uint8_t endtype, + int precision, double miter_limit, + double arc_tolerance, bool reverse_solution) +{ + if (precision < -8 || precision > 8 || !path) return nullptr; + + const double scale = std::pow(10, precision); + ClipperOffset clip_offset(miter_limit, arc_tolerance, reverse_solution); + Path64 pp = ConvertCPathDToPath64WithScale(path, scale); + clip_offset.AddPath(pp, JoinType(jointype), EndType(endtype)); + Paths64 result; + clip_offset.Execute(delta * scale, result); + + return CreateCPathsDFromPaths64(result, 1 / scale); +} + +EXTERN_DLL_EXPORT CPaths64 RectClip64(const CRect64& rect, const CPaths64 paths) +{ + if (CRectIsEmpty(rect) || !paths) return nullptr; + Rect64 r64 = CRectToRect(rect); + class RectClip64 rc(r64); + Paths64 pp = ConvertCPathsToPathsT(paths); + Paths64 result = rc.Execute(pp); + return CreateCPathsFromPathsT(result); +} + +EXTERN_DLL_EXPORT CPathsD RectClipD(const CRectD& rect, const CPathsD paths, int precision) +{ + if (CRectIsEmpty(rect) || !paths) return nullptr; + if (precision < -8 || precision > 8) return nullptr; + const double scale = std::pow(10, precision); + + RectD r = CRectToRect(rect); + Rect64 rec = ScaleRect(r, scale); + Paths64 pp = ConvertCPathsDToPaths64(paths, scale); + class RectClip64 rc(rec); + Paths64 result = rc.Execute(pp); + + return CreateCPathsDFromPaths64(result, 1 / scale); +} + +EXTERN_DLL_EXPORT CPaths64 RectClipLines64(const CRect64& rect, + const CPaths64 paths) +{ + if (CRectIsEmpty(rect) || !paths) return nullptr; + Rect64 r = CRectToRect(rect); + class RectClipLines64 rcl (r); + Paths64 pp = ConvertCPathsToPathsT(paths); + Paths64 result = rcl.Execute(pp); + return CreateCPathsFromPathsT(result); +} + +EXTERN_DLL_EXPORT CPathsD RectClipLinesD(const CRectD& rect, + const CPathsD paths, int precision) +{ + if (CRectIsEmpty(rect) || !paths) return nullptr; + if (precision < -8 || precision > 8) return nullptr; + + const double scale = std::pow(10, precision); + Rect64 r = ScaleRect(CRectToRect(rect), scale); + class RectClipLines64 rcl(r); + Paths64 pp = ConvertCPathsDToPaths64(paths, scale); + Paths64 result = rcl.Execute(pp); + return CreateCPathsDFromPaths64(result, 1 / scale); +} + +EXTERN_DLL_EXPORT CPaths64 MinkowskiSum64(const CPath64& cpattern, const CPath64& cpath, bool is_closed) +{ + Path64 path = ConvertCPathToPathT(cpath); + Path64 pattern = ConvertCPathToPathT(cpattern); + Paths64 solution = MinkowskiSum(pattern, path, is_closed); + return CreateCPathsFromPathsT(solution); +} + +EXTERN_DLL_EXPORT CPaths64 MinkowskiDiff64(const CPath64& cpattern, const CPath64& cpath, bool is_closed) +{ + Path64 path = ConvertCPathToPathT(cpath); + Path64 pattern = ConvertCPathToPathT(cpattern); + Paths64 solution = MinkowskiDiff(pattern, path, is_closed); + return CreateCPathsFromPathsT(solution); +} + +#ifdef USINGZ +typedef void (*DLLZCallback64)(const Point64& e1bot, const Point64& e1top, const Point64& e2bot, const Point64& e2top, Point64& pt); +typedef void (*DLLZCallbackD)(const PointD& e1bot, const PointD& e1top, const PointD& e2bot, const PointD& e2top, PointD& pt); + +EXTERN_DLL_EXPORT void SetZCallback64(DLLZCallback64 callback) +{ + dllCallback64 = callback; +} + +EXTERN_DLL_EXPORT void SetZCallbackD(DLLZCallbackD callback) +{ + dllCallbackD = callback; +} + +#endif + +} +#endif // CLIPPER2_EXPORT_H diff --git a/clipper2/include/clipper2/clipper.h b/clipper2/include/clipper2/clipper.h new file mode 100644 index 00000000..a2fe5c3c --- /dev/null +++ b/clipper2/include/clipper2/clipper.h @@ -0,0 +1,769 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 27 April 2024 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2024 * +* Purpose : This module provides a simple interface to the Clipper Library * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_H +#define CLIPPER_H + +#include +#include +#include + +#include "clipper2/clipper.core.h" +#include "clipper2/clipper.engine.h" +#include "clipper2/clipper.offset.h" +#include "clipper2/clipper.minkowski.h" +#include "clipper2/clipper.rectclip.h" + +namespace Clipper2Lib { + + inline Paths64 BooleanOp(ClipType cliptype, FillRule fillrule, + const Paths64& subjects, const Paths64& clips) + { + Paths64 result; + Clipper64 clipper; + clipper.AddSubject(subjects); + clipper.AddClip(clips); + clipper.Execute(cliptype, fillrule, result); + return result; + } + + inline void BooleanOp(ClipType cliptype, FillRule fillrule, + const Paths64& subjects, const Paths64& clips, PolyTree64& solution) + { + Paths64 sol_open; + Clipper64 clipper; + clipper.AddSubject(subjects); + clipper.AddClip(clips); + clipper.Execute(cliptype, fillrule, solution, sol_open); + } + + inline PathsD BooleanOp(ClipType cliptype, FillRule fillrule, + const PathsD& subjects, const PathsD& clips, int precision = 2) + { + int error_code = 0; + CheckPrecisionRange(precision, error_code); + PathsD result; + if (error_code) return result; + ClipperD clipper(precision); + clipper.AddSubject(subjects); + clipper.AddClip(clips); + clipper.Execute(cliptype, fillrule, result); + return result; + } + + inline void BooleanOp(ClipType cliptype, FillRule fillrule, + const PathsD& subjects, const PathsD& clips, + PolyTreeD& polytree, int precision = 2) + { + polytree.Clear(); + int error_code = 0; + CheckPrecisionRange(precision, error_code); + if (error_code) return; + ClipperD clipper(precision); + clipper.AddSubject(subjects); + clipper.AddClip(clips); + clipper.Execute(cliptype, fillrule, polytree); + } + + inline Paths64 Intersect(const Paths64& subjects, const Paths64& clips, FillRule fillrule) + { + return BooleanOp(ClipType::Intersection, fillrule, subjects, clips); + } + + inline PathsD Intersect(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) + { + return BooleanOp(ClipType::Intersection, fillrule, subjects, clips, decimal_prec); + } + + inline Paths64 Union(const Paths64& subjects, const Paths64& clips, FillRule fillrule) + { + return BooleanOp(ClipType::Union, fillrule, subjects, clips); + } + + inline PathsD Union(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) + { + return BooleanOp(ClipType::Union, fillrule, subjects, clips, decimal_prec); + } + + inline Paths64 Union(const Paths64& subjects, FillRule fillrule) + { + Paths64 result; + Clipper64 clipper; + clipper.AddSubject(subjects); + clipper.Execute(ClipType::Union, fillrule, result); + return result; + } + + inline PathsD Union(const PathsD& subjects, FillRule fillrule, int precision = 2) + { + PathsD result; + int error_code = 0; + CheckPrecisionRange(precision, error_code); + if (error_code) return result; + ClipperD clipper(precision); + clipper.AddSubject(subjects); + clipper.Execute(ClipType::Union, fillrule, result); + return result; + } + + inline Paths64 Difference(const Paths64& subjects, const Paths64& clips, FillRule fillrule) + { + return BooleanOp(ClipType::Difference, fillrule, subjects, clips); + } + + inline PathsD Difference(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) + { + return BooleanOp(ClipType::Difference, fillrule, subjects, clips, decimal_prec); + } + + inline Paths64 Xor(const Paths64& subjects, const Paths64& clips, FillRule fillrule) + { + return BooleanOp(ClipType::Xor, fillrule, subjects, clips); + } + + inline PathsD Xor(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) + { + return BooleanOp(ClipType::Xor, fillrule, subjects, clips, decimal_prec); + } + + inline Paths64 InflatePaths(const Paths64& paths, double delta, + JoinType jt, EndType et, double miter_limit = 2.0, + double arc_tolerance = 0.0) + { + if (!delta) return paths; + ClipperOffset clip_offset(miter_limit, arc_tolerance); + clip_offset.AddPaths(paths, jt, et); + Paths64 solution; + clip_offset.Execute(delta, solution); + return solution; + } + + inline PathsD InflatePaths(const PathsD& paths, double delta, + JoinType jt, EndType et, double miter_limit = 2.0, + int precision = 2, double arc_tolerance = 0.0) + { + int error_code = 0; + CheckPrecisionRange(precision, error_code); + if (!delta) return paths; + if (error_code) return PathsD(); + const double scale = std::pow(10, precision); + ClipperOffset clip_offset(miter_limit, arc_tolerance); + clip_offset.AddPaths(ScalePaths(paths, scale, error_code), jt, et); + if (error_code) return PathsD(); + Paths64 solution; + clip_offset.Execute(delta * scale, solution); + return ScalePaths(solution, 1 / scale, error_code); + } + + template + inline Path TranslatePath(const Path& path, T dx, T dy) + { + Path result; + result.reserve(path.size()); + std::transform(path.begin(), path.end(), back_inserter(result), + [dx, dy](const auto& pt) { return Point(pt.x + dx, pt.y +dy); }); + return result; + } + + inline Path64 TranslatePath(const Path64& path, int64_t dx, int64_t dy) + { + return TranslatePath(path, dx, dy); + } + + inline PathD TranslatePath(const PathD& path, double dx, double dy) + { + return TranslatePath(path, dx, dy); + } + + template + inline Paths TranslatePaths(const Paths& paths, T dx, T dy) + { + Paths result; + result.reserve(paths.size()); + std::transform(paths.begin(), paths.end(), back_inserter(result), + [dx, dy](const auto& path) { return TranslatePath(path, dx, dy); }); + return result; + } + + inline Paths64 TranslatePaths(const Paths64& paths, int64_t dx, int64_t dy) + { + return TranslatePaths(paths, dx, dy); + } + + inline PathsD TranslatePaths(const PathsD& paths, double dx, double dy) + { + return TranslatePaths(paths, dx, dy); + } + + inline Paths64 RectClip(const Rect64& rect, const Paths64& paths) + { + if (rect.IsEmpty() || paths.empty()) return Paths64(); + RectClip64 rc(rect); + return rc.Execute(paths); + } + + inline Paths64 RectClip(const Rect64& rect, const Path64& path) + { + if (rect.IsEmpty() || path.empty()) return Paths64(); + RectClip64 rc(rect); + return rc.Execute(Paths64{ path }); + } + + inline PathsD RectClip(const RectD& rect, const PathsD& paths, int precision = 2) + { + if (rect.IsEmpty() || paths.empty()) return PathsD(); + int error_code = 0; + CheckPrecisionRange(precision, error_code); + if (error_code) return PathsD(); + const double scale = std::pow(10, precision); + Rect64 r = ScaleRect(rect, scale); + RectClip64 rc(r); + Paths64 pp = ScalePaths(paths, scale, error_code); + if (error_code) return PathsD(); // ie: error_code result is lost + return ScalePaths( + rc.Execute(pp), 1 / scale, error_code); + } + + inline PathsD RectClip(const RectD& rect, const PathD& path, int precision = 2) + { + return RectClip(rect, PathsD{ path }, precision); + } + + inline Paths64 RectClipLines(const Rect64& rect, const Paths64& lines) + { + if (rect.IsEmpty() || lines.empty()) return Paths64(); + RectClipLines64 rcl(rect); + return rcl.Execute(lines); + } + + inline Paths64 RectClipLines(const Rect64& rect, const Path64& line) + { + return RectClipLines(rect, Paths64{ line }); + } + + inline PathsD RectClipLines(const RectD& rect, const PathsD& lines, int precision = 2) + { + if (rect.IsEmpty() || lines.empty()) return PathsD(); + int error_code = 0; + CheckPrecisionRange(precision, error_code); + if (error_code) return PathsD(); + const double scale = std::pow(10, precision); + Rect64 r = ScaleRect(rect, scale); + RectClipLines64 rcl(r); + Paths64 p = ScalePaths(lines, scale, error_code); + if (error_code) return PathsD(); + p = rcl.Execute(p); + return ScalePaths(p, 1 / scale, error_code); + } + + inline PathsD RectClipLines(const RectD& rect, const PathD& line, int precision = 2) + { + return RectClipLines(rect, PathsD{ line }, precision); + } + + namespace details + { + + inline void PolyPathToPaths64(const PolyPath64& polypath, Paths64& paths) + { + paths.push_back(polypath.Polygon()); + for (const auto& child : polypath) + PolyPathToPaths64(*child, paths); + } + + inline void PolyPathToPathsD(const PolyPathD& polypath, PathsD& paths) + { + paths.push_back(polypath.Polygon()); + for (const auto& child : polypath) + PolyPathToPathsD(*child, paths); + } + + inline bool PolyPath64ContainsChildren(const PolyPath64& pp) + { + for (const auto& child : pp) + { + // return false if this child isn't fully contained by its parent + + // checking for a single vertex outside is a bit too crude since + // it doesn't account for rounding errors. It's better to check + // for consecutive vertices found outside the parent's polygon. + + int outsideCnt = 0; + for (const Point64& pt : child->Polygon()) + { + PointInPolygonResult result = PointInPolygon(pt, pp.Polygon()); + if (result == PointInPolygonResult::IsInside) --outsideCnt; + else if (result == PointInPolygonResult::IsOutside) ++outsideCnt; + if (outsideCnt > 1) return false; + else if (outsideCnt < -1) break; + } + + // now check any nested children too + if (child->Count() > 0 && !PolyPath64ContainsChildren(*child)) + return false; + } + return true; + } + + static void OutlinePolyPath(std::ostream& os, + size_t idx, bool isHole, size_t count, const std::string& preamble) + { + std::string plural = (count == 1) ? "." : "s."; + if (isHole) + os << preamble << "+- Hole (" << idx << ") contains " << count << + " nested polygon" << plural << std::endl; + else + os << preamble << "+- Polygon (" << idx << ") contains " << count << + " hole" << plural << std::endl; + } + + static void OutlinePolyPath64(std::ostream& os, const PolyPath64& pp, + size_t idx, std::string preamble) + { + OutlinePolyPath(os, idx, pp.IsHole(), pp.Count(), preamble); + for (size_t i = 0; i < pp.Count(); ++i) + if (pp.Child(i)->Count()) + details::OutlinePolyPath64(os, *pp.Child(i), i, preamble + " "); + } + + static void OutlinePolyPathD(std::ostream& os, const PolyPathD& pp, + size_t idx, std::string preamble) + { + OutlinePolyPath(os, idx, pp.IsHole(), pp.Count(), preamble); + for (size_t i = 0; i < pp.Count(); ++i) + if (pp.Child(i)->Count()) + details::OutlinePolyPathD(os, *pp.Child(i), i, preamble + " "); + } + + template + inline constexpr void MakePathGeneric(const T an_array, + size_t array_size, std::vector& result) + { + result.reserve(array_size / 2); + for (size_t i = 0; i < array_size; i +=2) +#ifdef USINGZ + result.push_back( U{ an_array[i], an_array[i + 1], 0} ); +#else + result.push_back( U{ an_array[i], an_array[i + 1]} ); +#endif + } + + } // end details namespace + + inline std::ostream& operator<< (std::ostream& os, const PolyTree64& pp) + { + std::string plural = (pp.Count() == 1) ? " polygon." : " polygons."; + os << std::endl << "Polytree with " << pp.Count() << plural << std::endl; + for (size_t i = 0; i < pp.Count(); ++i) + if (pp.Child(i)->Count()) + details::OutlinePolyPath64(os, *pp.Child(i), i, " "); + os << std::endl << std::endl; + return os; + } + + inline std::ostream& operator<< (std::ostream& os, const PolyTreeD& pp) + { + std::string plural = (pp.Count() == 1) ? " polygon." : " polygons."; + os << std::endl << "Polytree with " << pp.Count() << plural << std::endl; + for (size_t i = 0; i < pp.Count(); ++i) + if (pp.Child(i)->Count()) + details::OutlinePolyPathD(os, *pp.Child(i), i, " "); + os << std::endl << std::endl; + if (!pp.Level()) os << std::endl; + return os; + } + + inline Paths64 PolyTreeToPaths64(const PolyTree64& polytree) + { + Paths64 result; + for (const auto& child : polytree) + details::PolyPathToPaths64(*child, result); + return result; + } + + inline PathsD PolyTreeToPathsD(const PolyTreeD& polytree) + { + PathsD result; + for (const auto& child : polytree) + details::PolyPathToPathsD(*child, result); + return result; + } + + inline bool CheckPolytreeFullyContainsChildren(const PolyTree64& polytree) + { + for (const auto& child : polytree) + if (child->Count() > 0 && + !details::PolyPath64ContainsChildren(*child)) + return false; + return true; + } + + template::value && + !std::is_same::value, bool + >::type = true> + inline Path64 MakePath(const std::vector& list) + { + const auto size = list.size() - list.size() % 2; + if (list.size() != size) + DoError(non_pair_error_i); // non-fatal without exception handling + Path64 result; + details::MakePathGeneric(list, size, result); + return result; + } + + template::value && + !std::is_same::value, bool + >::type = true> + inline Path64 MakePath(const T(&list)[N]) + { + // Make the compiler error on unpaired value (i.e. no runtime effects). + static_assert(N % 2 == 0, "MakePath requires an even number of arguments"); + Path64 result; + details::MakePathGeneric(list, N, result); + return result; + } + + template::value && + !std::is_same::value, bool + >::type = true> + inline PathD MakePathD(const std::vector& list) + { + const auto size = list.size() - list.size() % 2; + if (list.size() != size) + DoError(non_pair_error_i); // non-fatal without exception handling + PathD result; + details::MakePathGeneric(list, size, result); + return result; + } + + template::value && + !std::is_same::value, bool + >::type = true> + inline PathD MakePathD(const T(&list)[N]) + { + // Make the compiler error on unpaired value (i.e. no runtime effects). + static_assert(N % 2 == 0, "MakePath requires an even number of arguments"); + PathD result; + details::MakePathGeneric(list, N, result); + return result; + } + +#ifdef USINGZ + template + inline Path64 MakePathZ(const T2(&list)[N]) + { + static_assert(N % 3 == 0 && std::numeric_limits::is_integer, + "MakePathZ requires integer values in multiples of 3"); + std::size_t size = N / 3; + Path64 result(size); + for (size_t i = 0; i < size; ++i) + result[i] = Point64(list[i * 3], + list[i * 3 + 1], list[i * 3 + 2]); + return result; + } + + template + inline PathD MakePathZD(const T2(&list)[N]) + { + static_assert(N % 3 == 0, + "MakePathZD requires values in multiples of 3"); + std::size_t size = N / 3; + PathD result(size); + if constexpr (std::numeric_limits::is_integer) + for (size_t i = 0; i < size; ++i) + result[i] = PointD(list[i * 3], + list[i * 3 + 1], list[i * 3 + 2]); + else + for (size_t i = 0; i < size; ++i) + result[i] = PointD(list[i * 3], list[i * 3 + 1], + static_cast(list[i * 3 + 2])); + return result; + } +#endif + + inline Path64 TrimCollinear(const Path64& p, bool is_open_path = false) + { + size_t len = p.size(); + if (len < 3) + { + if (!is_open_path || len < 2 || p[0] == p[1]) return Path64(); + else return p; + } + + Path64 dst; + dst.reserve(len); + Path64::const_iterator srcIt = p.cbegin(), prevIt, stop = p.cend() - 1; + + if (!is_open_path) + { + while (srcIt != stop && IsCollinear(*stop, *srcIt, *(srcIt + 1))) + ++srcIt; + while (srcIt != stop && IsCollinear(*(stop - 1), *stop, *srcIt)) + --stop; + if (srcIt == stop) return Path64(); + } + + prevIt = srcIt++; + dst.push_back(*prevIt); + for (; srcIt != stop; ++srcIt) + { + if (!IsCollinear(*prevIt, *srcIt, *(srcIt + 1))) + { + prevIt = srcIt; + dst.push_back(*prevIt); + } + } + + if (is_open_path) + dst.push_back(*srcIt); + else if (!IsCollinear(*prevIt, *stop, dst[0])) + dst.push_back(*stop); + else + { + while (dst.size() > 2 && + IsCollinear(dst[dst.size() - 1], dst[dst.size() - 2], dst[0])) + dst.pop_back(); + if (dst.size() < 3) return Path64(); + } + return dst; + } + + inline PathD TrimCollinear(const PathD& path, int precision, bool is_open_path = false) + { + int error_code = 0; + CheckPrecisionRange(precision, error_code); + if (error_code) return PathD(); + const double scale = std::pow(10, precision); + Path64 p = ScalePath(path, scale, error_code); + if (error_code) return PathD(); + p = TrimCollinear(p, is_open_path); + return ScalePath(p, 1/scale, error_code); + } + + template + inline double Distance(const Point pt1, const Point pt2) + { + return std::sqrt(DistanceSqr(pt1, pt2)); + } + + template + inline double Length(const Path& path, bool is_closed_path = false) + { + double result = 0.0; + if (path.size() < 2) return result; + auto it = path.cbegin(), stop = path.end() - 1; + for (; it != stop; ++it) + result += Distance(*it, *(it + 1)); + if (is_closed_path) + result += Distance(*stop, *path.cbegin()); + return result; + } + + + template + inline bool NearCollinear(const Point& pt1, const Point& pt2, const Point& pt3, double sin_sqrd_min_angle_rads) + { + double cp = std::abs(CrossProduct(pt1, pt2, pt3)); + return (cp * cp) / (DistanceSqr(pt1, pt2) * DistanceSqr(pt2, pt3)) < sin_sqrd_min_angle_rads; + } + + template + inline Path Ellipse(const Rect& rect, size_t steps = 0) + { + return Ellipse(rect.MidPoint(), + static_cast(rect.Width()) *0.5, + static_cast(rect.Height()) * 0.5, steps); + } + + template + inline Path Ellipse(const Point& center, + double radiusX, double radiusY = 0, size_t steps = 0) + { + if (radiusX <= 0) return Path(); + if (radiusY <= 0) radiusY = radiusX; + if (steps <= 2) + steps = static_cast(PI * sqrt((radiusX + radiusY) / 2)); + + double si = std::sin(2 * PI / steps); + double co = std::cos(2 * PI / steps); + double dx = co, dy = si; + Path result; + result.reserve(steps); + result.push_back(Point(center.x + radiusX, static_cast(center.y))); + for (size_t i = 1; i < steps; ++i) + { + result.push_back(Point(center.x + radiusX * dx, center.y + radiusY * dy)); + double x = dx * co - dy * si; + dy = dy * co + dx * si; + dx = x; + } + return result; + } + + inline size_t GetNext(size_t current, size_t high, + const std::vector& flags) + { + ++current; + while (current <= high && flags[current]) ++current; + if (current <= high) return current; + current = 0; + while (flags[current]) ++current; + return current; + } + + inline size_t GetPrior(size_t current, size_t high, + const std::vector& flags) + { + if (current == 0) current = high; + else --current; + while (current > 0 && flags[current]) --current; + if (!flags[current]) return current; + current = high; + while (flags[current]) --current; + return current; + } + + template + inline Path SimplifyPath(const Path &path, + double epsilon, bool isClosedPath = true) + { + const size_t len = path.size(), high = len -1; + const double epsSqr = Sqr(epsilon); + if (len < 4) return Path(path); + + std::vector flags(len); + std::vector distSqr(len); + size_t prior = high, curr = 0, start, next, prior2; + if (isClosedPath) + { + distSqr[0] = PerpendicDistFromLineSqrd(path[0], path[high], path[1]); + distSqr[high] = PerpendicDistFromLineSqrd(path[high], path[0], path[high - 1]); + } + else + { + distSqr[0] = MAX_DBL; + distSqr[high] = MAX_DBL; + } + for (size_t i = 1; i < high; ++i) + distSqr[i] = PerpendicDistFromLineSqrd(path[i], path[i - 1], path[i + 1]); + + for (;;) + { + if (distSqr[curr] > epsSqr) + { + start = curr; + do + { + curr = GetNext(curr, high, flags); + } while (curr != start && distSqr[curr] > epsSqr); + if (curr == start) break; + } + + prior = GetPrior(curr, high, flags); + next = GetNext(curr, high, flags); + if (next == prior) break; + + // flag for removal the smaller of adjacent 'distances' + if (distSqr[next] < distSqr[curr]) + { + prior2 = prior; + prior = curr; + curr = next; + next = GetNext(next, high, flags); + } + else + prior2 = GetPrior(prior, high, flags); + + flags[curr] = true; + curr = next; + next = GetNext(next, high, flags); + + if (isClosedPath || ((curr != high) && (curr != 0))) + distSqr[curr] = PerpendicDistFromLineSqrd(path[curr], path[prior], path[next]); + if (isClosedPath || ((prior != 0) && (prior != high))) + distSqr[prior] = PerpendicDistFromLineSqrd(path[prior], path[prior2], path[curr]); + } + Path result; + result.reserve(len); + for (typename Path::size_type i = 0; i < len; ++i) + if (!flags[i]) result.push_back(path[i]); + return result; + } + + template + inline Paths SimplifyPaths(const Paths &paths, + double epsilon, bool isClosedPath = true) + { + Paths result; + result.reserve(paths.size()); + for (const auto& path : paths) + result.push_back(SimplifyPath(path, epsilon, isClosedPath)); + return result; + } + + template + inline void RDP(const Path path, std::size_t begin, + std::size_t end, double epsSqrd, std::vector& flags) + { + typename Path::size_type idx = 0; + double max_d = 0; + while (end > begin && path[begin] == path[end]) flags[end--] = false; + for (typename Path::size_type i = begin + 1; i < end; ++i) + { + // PerpendicDistFromLineSqrd - avoids expensive Sqrt() + double d = PerpendicDistFromLineSqrd(path[i], path[begin], path[end]); + if (d <= max_d) continue; + max_d = d; + idx = i; + } + if (max_d <= epsSqrd) return; + flags[idx] = true; + if (idx > begin + 1) RDP(path, begin, idx, epsSqrd, flags); + if (idx < end - 1) RDP(path, idx, end, epsSqrd, flags); + } + + template + inline Path RamerDouglasPeucker(const Path& path, double epsilon) + { + const typename Path::size_type len = path.size(); + if (len < 5) return Path(path); + std::vector flags(len); + flags[0] = true; + flags[len - 1] = true; + RDP(path, 0, len - 1, Sqr(epsilon), flags); + Path result; + result.reserve(len); + for (typename Path::size_type i = 0; i < len; ++i) + if (flags[i]) + result.push_back(path[i]); + return result; + } + + template + inline Paths RamerDouglasPeucker(const Paths& paths, double epsilon) + { + Paths result; + result.reserve(paths.size()); + std::transform(paths.begin(), paths.end(), back_inserter(result), + [epsilon](const auto& path) + { return RamerDouglasPeucker(path, epsilon); }); + return result; + } + +} // end Clipper2Lib namespace + +#endif // CLIPPER_H diff --git a/clipper2/include/clipper2/clipper.minkowski.h b/clipper2/include/clipper2/clipper.minkowski.h new file mode 100644 index 00000000..a3ddcf86 --- /dev/null +++ b/clipper2/include/clipper2/clipper.minkowski.h @@ -0,0 +1,120 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 1 November 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* Purpose : Minkowski Sum and Difference * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_MINKOWSKI_H +#define CLIPPER_MINKOWSKI_H + +#include +#include +#include +#include "clipper2/clipper.core.h" + +namespace Clipper2Lib +{ + + namespace detail + { + inline Paths64 Minkowski(const Path64& pattern, const Path64& path, bool isSum, bool isClosed) + { + size_t delta = isClosed ? 0 : 1; + size_t patLen = pattern.size(), pathLen = path.size(); + if (patLen == 0 || pathLen == 0) return Paths64(); + Paths64 tmp; + tmp.reserve(pathLen); + + if (isSum) + { + for (const Point64& p : path) + { + Path64 path2(pattern.size()); + std::transform(pattern.cbegin(), pattern.cend(), + path2.begin(), [p](const Point64& pt2) {return p + pt2; }); + tmp.push_back(path2); + } + } + else + { + for (const Point64& p : path) + { + Path64 path2(pattern.size()); + std::transform(pattern.cbegin(), pattern.cend(), + path2.begin(), [p](const Point64& pt2) {return p - pt2; }); + tmp.push_back(path2); + } + } + + Paths64 result; + result.reserve((pathLen - delta) * patLen); + size_t g = isClosed ? pathLen - 1 : 0; + for (size_t h = patLen - 1, i = delta; i < pathLen; ++i) + { + for (size_t j = 0; j < patLen; j++) + { + Path64 quad; + quad.reserve(4); + { + quad.push_back(tmp[g][h]); + quad.push_back(tmp[i][h]); + quad.push_back(tmp[i][j]); + quad.push_back(tmp[g][j]); + }; + if (!IsPositive(quad)) + std::reverse(quad.begin(), quad.end()); + result.push_back(quad); + h = j; + } + g = i; + } + return result; + } + + inline Paths64 Union(const Paths64& subjects, FillRule fillrule) + { + Paths64 result; + Clipper64 clipper; + clipper.AddSubject(subjects); + clipper.Execute(ClipType::Union, fillrule, result); + return result; + } + + } // namespace internal + + inline Paths64 MinkowskiSum(const Path64& pattern, const Path64& path, bool isClosed) + { + return detail::Union(detail::Minkowski(pattern, path, true, isClosed), FillRule::NonZero); + } + + inline PathsD MinkowskiSum(const PathD& pattern, const PathD& path, bool isClosed, int decimalPlaces = 2) + { + int error_code = 0; + double scale = pow(10, decimalPlaces); + Path64 pat64 = ScalePath(pattern, scale, error_code); + Path64 path64 = ScalePath(path, scale, error_code); + Paths64 tmp = detail::Union(detail::Minkowski(pat64, path64, true, isClosed), FillRule::NonZero); + return ScalePaths(tmp, 1 / scale, error_code); + } + + inline Paths64 MinkowskiDiff(const Path64& pattern, const Path64& path, bool isClosed) + { + return detail::Union(detail::Minkowski(pattern, path, false, isClosed), FillRule::NonZero); + } + + inline PathsD MinkowskiDiff(const PathD& pattern, const PathD& path, bool isClosed, int decimalPlaces = 2) + { + int error_code = 0; + double scale = pow(10, decimalPlaces); + Path64 pat64 = ScalePath(pattern, scale, error_code); + Path64 path64 = ScalePath(path, scale, error_code); + Paths64 tmp = detail::Union(detail::Minkowski(pat64, path64, false, isClosed), FillRule::NonZero); + return ScalePaths(tmp, 1 / scale, error_code); + } + +} // Clipper2Lib namespace + +#endif // CLIPPER_MINKOWSKI_H diff --git a/clipper2/include/clipper2/clipper.offset.h b/clipper2/include/clipper2/clipper.offset.h new file mode 100644 index 00000000..bb075a6d --- /dev/null +++ b/clipper2/include/clipper2/clipper.offset.h @@ -0,0 +1,124 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 24 March 2024 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2024 * +* Purpose : Path Offset (Inflate/Shrink) * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_OFFSET_H_ +#define CLIPPER_OFFSET_H_ + +#include "clipper.core.h" +#include "clipper.engine.h" + +namespace Clipper2Lib { + +enum class JoinType { Square, Bevel, Round, Miter }; +//Square : Joins are 'squared' at exactly the offset distance (more complex code) +//Bevel : Similar to Square, but the offset distance varies with angle (simple code & faster) + +enum class EndType {Polygon, Joined, Butt, Square, Round}; +//Butt : offsets both sides of a path, with square blunt ends +//Square : offsets both sides of a path, with square extended ends +//Round : offsets both sides of a path, with round extended ends +//Joined : offsets both sides of a path, with joined ends +//Polygon: offsets only one side of a closed path + +typedef std::function DeltaCallback64; + +class ClipperOffset { +private: + + class Group { + public: + Paths64 paths_in; + std::optional lowest_path_idx{}; + bool is_reversed = false; + JoinType join_type; + EndType end_type; + Group(const Paths64& _paths, JoinType _join_type, EndType _end_type); + }; + + int error_code_ = 0; + double delta_ = 0.0; + double group_delta_ = 0.0; + double temp_lim_ = 0.0; + double steps_per_rad_ = 0.0; + double step_sin_ = 0.0; + double step_cos_ = 0.0; + PathD norms; + Path64 path_out; + Paths64* solution = nullptr; + PolyTree64* solution_tree = nullptr; + std::vector groups_; + JoinType join_type_ = JoinType::Bevel; + EndType end_type_ = EndType::Polygon; + + double miter_limit_ = 0.0; + double arc_tolerance_ = 0.0; + bool preserve_collinear_ = false; + bool reverse_solution_ = false; + +#ifdef USINGZ + ZCallback64 zCallback64_ = nullptr; + void ZCB(const Point64& bot1, const Point64& top1, + const Point64& bot2, const Point64& top2, Point64& ip); +#endif + DeltaCallback64 deltaCallback64_ = nullptr; + size_t CalcSolutionCapacity(); + bool CheckReverseOrientation(); + void DoBevel(const Path64& path, size_t j, size_t k); + void DoSquare(const Path64& path, size_t j, size_t k); + void DoMiter(const Path64& path, size_t j, size_t k, double cos_a); + void DoRound(const Path64& path, size_t j, size_t k, double angle); + void BuildNormals(const Path64& path); + void OffsetPolygon(Group& group, const Path64& path); + void OffsetOpenJoined(Group& group, const Path64& path); + void OffsetOpenPath(Group& group, const Path64& path); + void OffsetPoint(Group& group, const Path64& path, size_t j, size_t k); + void DoGroupOffset(Group &group); + void ExecuteInternal(double delta); +public: + explicit ClipperOffset(double miter_limit = 2.0, + double arc_tolerance = 0.0, + bool preserve_collinear = false, + bool reverse_solution = false) : + miter_limit_(miter_limit), arc_tolerance_(arc_tolerance), + preserve_collinear_(preserve_collinear), + reverse_solution_(reverse_solution) { }; + + ~ClipperOffset() { Clear(); }; + + int ErrorCode() const { return error_code_; }; + void AddPath(const Path64& path, JoinType jt_, EndType et_); + void AddPaths(const Paths64& paths, JoinType jt_, EndType et_); + void Clear() { groups_.clear(); norms.clear(); }; + + void Execute(double delta, Paths64& paths); + void Execute(double delta, PolyTree64& polytree); + void Execute(DeltaCallback64 delta_cb, Paths64& paths); + + double MiterLimit() const { return miter_limit_; } + void MiterLimit(double miter_limit) { miter_limit_ = miter_limit; } + + //ArcTolerance: needed for rounded offsets (See offset_triginometry2.svg) + double ArcTolerance() const { return arc_tolerance_; } + void ArcTolerance(double arc_tolerance) { arc_tolerance_ = arc_tolerance; } + + bool PreserveCollinear() const { return preserve_collinear_; } + void PreserveCollinear(bool preserve_collinear){preserve_collinear_ = preserve_collinear;} + + bool ReverseSolution() const { return reverse_solution_; } + void ReverseSolution(bool reverse_solution) {reverse_solution_ = reverse_solution;} + +#ifdef USINGZ + void SetZCallback(ZCallback64 cb) { zCallback64_ = cb; } +#endif + void SetDeltaCallback(DeltaCallback64 cb) { deltaCallback64_ = cb; } + +}; + +} +#endif /* CLIPPER_OFFSET_H_ */ diff --git a/clipper2/include/clipper2/clipper.rectclip.h b/clipper2/include/clipper2/clipper.rectclip.h new file mode 100644 index 00000000..bfcfacf2 --- /dev/null +++ b/clipper2/include/clipper2/clipper.rectclip.h @@ -0,0 +1,82 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 5 July 2024 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2024 * +* Purpose : FAST rectangular clipping * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_RECTCLIP_H +#define CLIPPER_RECTCLIP_H + +#include +#include +#include +#include "clipper2/clipper.core.h" + +namespace Clipper2Lib +{ + + // Location: the order is important here, see StartLocsIsClockwise() + enum class Location { Left, Top, Right, Bottom, Inside }; + + class OutPt2; + typedef std::vector OutPt2List; + + class OutPt2 { + public: + Point64 pt; + size_t owner_idx = 0; + OutPt2List* edge = nullptr; + OutPt2* next = nullptr; + OutPt2* prev = nullptr; + }; + + //------------------------------------------------------------------------------ + // RectClip64 + //------------------------------------------------------------------------------ + + class RectClip64 { + private: + void ExecuteInternal(const Path64& path); + Path64 GetPath(OutPt2*& op); + protected: + const Rect64 rect_; + const Path64 rect_as_path_; + const Point64 rect_mp_; + Rect64 path_bounds_; + std::deque op_container_; + OutPt2List results_; // each path can be broken into multiples + OutPt2List edges_[8]; // clockwise and counter-clockwise + std::vector start_locs_; + void CheckEdges(); + void TidyEdges(size_t idx, OutPt2List& cw, OutPt2List& ccw); + void GetNextLocation(const Path64& path, + Location& loc, size_t& i, size_t highI); + OutPt2* Add(Point64 pt, bool start_new = false); + void AddCorner(Location prev, Location curr); + void AddCorner(Location& loc, bool isClockwise); + public: + explicit RectClip64(const Rect64& rect) : + rect_(rect), + rect_as_path_(rect.AsPath()), + rect_mp_(rect.MidPoint()) {} + Paths64 Execute(const Paths64& paths); + }; + + //------------------------------------------------------------------------------ + // RectClipLines64 + //------------------------------------------------------------------------------ + + class RectClipLines64 : public RectClip64 { + private: + void ExecuteInternal(const Path64& path); + Path64 GetPath(OutPt2*& op); + public: + explicit RectClipLines64(const Rect64& rect) : RectClip64(rect) {}; + Paths64 Execute(const Paths64& paths); + }; + +} // Clipper2Lib namespace +#endif // CLIPPER_RECTCLIP_H diff --git a/clipper2/include/clipper2/clipper.version.h b/clipper2/include/clipper2/clipper.version.h new file mode 100644 index 00000000..61464095 --- /dev/null +++ b/clipper2/include/clipper2/clipper.version.h @@ -0,0 +1,6 @@ +#ifndef CLIPPER_VERSION_H +#define CLIPPER_VERSION_H + +constexpr auto CLIPPER2_VERSION = "1.4.0"; + +#endif // CLIPPER_VERSION_H diff --git a/clipper2/src/clipper.engine.cpp b/clipper2/src/clipper.engine.cpp new file mode 100644 index 00000000..97717322 --- /dev/null +++ b/clipper2/src/clipper.engine.cpp @@ -0,0 +1,3155 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 17 September 2024 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2024 * +* Purpose : This is the main polygon clipping module * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "clipper2/clipper.engine.h" +#include "clipper2/clipper.h" + +// https://github.com/AngusJohnson/Clipper2/discussions/334 +// #discussioncomment-4248602 +#if defined(_MSC_VER) && ( defined(_M_AMD64) || defined(_M_X64) ) +#include +#include +#define fmin(a,b) _mm_cvtsd_f64(_mm_min_sd(_mm_set_sd(a),_mm_set_sd(b))) +#define fmax(a,b) _mm_cvtsd_f64(_mm_max_sd(_mm_set_sd(a),_mm_set_sd(b))) +#define nearbyint(a) _mm_cvtsd_si64(_mm_set_sd(a)) /* Note: expression type is (int64_t) */ +#endif + +namespace Clipper2Lib { + + static const Rect64 invalid_rect = Rect64(false); + + // Every closed path (ie polygon) is made up of a series of vertices forming edge + // 'bounds' that alternate between ascending bounds (containing edges going up + // relative to the Y-axis) and descending bounds. 'Local Minima' refers to + // vertices where ascending and descending bounds join at the bottom, and + // 'Local Maxima' are where ascending and descending bounds join at the top. + + struct Scanline { + int64_t y = 0; + Scanline* next = nullptr; + + explicit Scanline(int64_t y_) : y(y_) {} + }; + + struct HorzSegSorter { + inline bool operator()(const HorzSegment& hs1, const HorzSegment& hs2) + { + if (!hs1.right_op || !hs2.right_op) return (hs1.right_op); + return hs2.left_op->pt.x > hs1.left_op->pt.x; + } + }; + + struct LocMinSorter { + inline bool operator()(const LocalMinima_ptr& locMin1, + const LocalMinima_ptr& locMin2) + { + if (locMin2->vertex->pt.y != locMin1->vertex->pt.y) + return locMin2->vertex->pt.y < locMin1->vertex->pt.y; + else + return locMin2->vertex->pt.x > locMin1->vertex->pt.x; + } + }; + + + inline bool IsOdd(int val) + { + return (val & 1) ? true : false; + } + + + inline bool IsHotEdge(const Active& e) + { + return (e.outrec); + } + + + inline bool IsOpen(const Active& e) + { + return (e.local_min->is_open); + } + + + inline bool IsOpenEnd(const Vertex& v) + { + return (v.flags & (VertexFlags::OpenStart | VertexFlags::OpenEnd)) != + VertexFlags::Empty; + } + + + inline bool IsOpenEnd(const Active& ae) + { + return IsOpenEnd(*ae.vertex_top); + } + + + inline Active* GetPrevHotEdge(const Active& e) + { + Active* prev = e.prev_in_ael; + while (prev && (IsOpen(*prev) || !IsHotEdge(*prev))) + prev = prev->prev_in_ael; + return prev; + } + + inline bool IsFront(const Active& e) + { + return (&e == e.outrec->front_edge); + } + + inline bool IsInvalidPath(OutPt* op) + { + return (!op || op->next == op); + } + + /******************************************************************************* + * Dx: 0(90deg) * + * | * + * +inf (180deg) <--- o ---> -inf (0deg) * + *******************************************************************************/ + + inline double GetDx(const Point64& pt1, const Point64& pt2) + { + double dy = double(pt2.y - pt1.y); + if (dy != 0) + return double(pt2.x - pt1.x) / dy; + else if (pt2.x > pt1.x) + return -std::numeric_limits::max(); + else + return std::numeric_limits::max(); + } + + inline int64_t TopX(const Active& ae, const int64_t currentY) + { + if ((currentY == ae.top.y) || (ae.top.x == ae.bot.x)) return ae.top.x; + else if (currentY == ae.bot.y) return ae.bot.x; + else return ae.bot.x + static_cast(nearbyint(ae.dx * (currentY - ae.bot.y))); + // nb: std::nearbyint (or std::round) substantially *improves* performance here + // as it greatly improves the likelihood of edge adjacency in ProcessIntersectList(). + } + + + inline bool IsHorizontal(const Active& e) + { + return (e.top.y == e.bot.y); + } + + + inline bool IsHeadingRightHorz(const Active& e) + { + return e.dx == -std::numeric_limits::max(); + } + + + inline bool IsHeadingLeftHorz(const Active& e) + { + return e.dx == std::numeric_limits::max(); + } + + + inline void SwapActives(Active*& e1, Active*& e2) + { + Active* e = e1; + e1 = e2; + e2 = e; + } + + inline PathType GetPolyType(const Active& e) + { + return e.local_min->polytype; + } + + inline bool IsSamePolyType(const Active& e1, const Active& e2) + { + return e1.local_min->polytype == e2.local_min->polytype; + } + + inline void SetDx(Active& e) + { + e.dx = GetDx(e.bot, e.top); + } + + inline Vertex* NextVertex(const Active& e) + { + if (e.wind_dx > 0) + return e.vertex_top->next; + else + return e.vertex_top->prev; + } + + //PrevPrevVertex: useful to get the (inverted Y-axis) top of the + //alternate edge (ie left or right bound) during edge insertion. + inline Vertex* PrevPrevVertex(const Active& ae) + { + if (ae.wind_dx > 0) + return ae.vertex_top->prev->prev; + else + return ae.vertex_top->next->next; + } + + + inline Active* ExtractFromSEL(Active* ae) + { + Active* res = ae->next_in_sel; + if (res) + res->prev_in_sel = ae->prev_in_sel; + ae->prev_in_sel->next_in_sel = res; + return res; + } + + + inline void Insert1Before2InSEL(Active* ae1, Active* ae2) + { + ae1->prev_in_sel = ae2->prev_in_sel; + if (ae1->prev_in_sel) + ae1->prev_in_sel->next_in_sel = ae1; + ae1->next_in_sel = ae2; + ae2->prev_in_sel = ae1; + } + + inline bool IsMaxima(const Vertex& v) + { + return ((v.flags & VertexFlags::LocalMax) != VertexFlags::Empty); + } + + + inline bool IsMaxima(const Active& e) + { + return IsMaxima(*e.vertex_top); + } + + inline Vertex* GetCurrYMaximaVertex_Open(const Active& e) + { + Vertex* result = e.vertex_top; + if (e.wind_dx > 0) + while ((result->next->pt.y == result->pt.y) && + ((result->flags & (VertexFlags::OpenEnd | + VertexFlags::LocalMax)) == VertexFlags::Empty)) + result = result->next; + else + while (result->prev->pt.y == result->pt.y && + ((result->flags & (VertexFlags::OpenEnd | + VertexFlags::LocalMax)) == VertexFlags::Empty)) + result = result->prev; + if (!IsMaxima(*result)) result = nullptr; // not a maxima + return result; + } + + inline Vertex* GetCurrYMaximaVertex(const Active& e) + { + Vertex* result = e.vertex_top; + if (e.wind_dx > 0) + while (result->next->pt.y == result->pt.y) result = result->next; + else + while (result->prev->pt.y == result->pt.y) result = result->prev; + if (!IsMaxima(*result)) result = nullptr; // not a maxima + return result; + } + + Active* GetMaximaPair(const Active& e) + { + Active* e2; + e2 = e.next_in_ael; + while (e2) + { + if (e2->vertex_top == e.vertex_top) return e2; // Found! + e2 = e2->next_in_ael; + } + return nullptr; + } + + inline int PointCount(OutPt* op) + { + OutPt* op2 = op; + int cnt = 0; + do + { + op2 = op2->next; + ++cnt; + } while (op2 != op); + return cnt; + } + + inline OutPt* DuplicateOp(OutPt* op, bool insert_after) + { + OutPt* result = new OutPt(op->pt, op->outrec); + if (insert_after) + { + result->next = op->next; + result->next->prev = result; + result->prev = op; + op->next = result; + } + else + { + result->prev = op->prev; + result->prev->next = result; + result->next = op; + op->prev = result; + } + return result; + } + + inline OutPt* DisposeOutPt(OutPt* op) + { + OutPt* result = op->next; + op->prev->next = op->next; + op->next->prev = op->prev; + delete op; + return result; + } + + + inline void DisposeOutPts(OutRec* outrec) + { + OutPt* op = outrec->pts; + op->prev->next = nullptr; + while (op) + { + OutPt* tmp = op; + op = op->next; + delete tmp; + }; + outrec->pts = nullptr; + } + + + bool IntersectListSort(const IntersectNode& a, const IntersectNode& b) + { + //note different inequality tests ... + return (a.pt.y == b.pt.y) ? (a.pt.x < b.pt.x) : (a.pt.y > b.pt.y); + } + + + inline void SetSides(OutRec& outrec, Active& start_edge, Active& end_edge) + { + outrec.front_edge = &start_edge; + outrec.back_edge = &end_edge; + } + + + void SwapOutrecs(Active& e1, Active& e2) + { + OutRec* or1 = e1.outrec; + OutRec* or2 = e2.outrec; + if (or1 == or2) + { + Active* e = or1->front_edge; + or1->front_edge = or1->back_edge; + or1->back_edge = e; + return; + } + if (or1) + { + if (&e1 == or1->front_edge) + or1->front_edge = &e2; + else + or1->back_edge = &e2; + } + if (or2) + { + if (&e2 == or2->front_edge) + or2->front_edge = &e1; + else + or2->back_edge = &e1; + } + e1.outrec = or2; + e2.outrec = or1; + } + + + double Area(OutPt* op) + { + //https://en.wikipedia.org/wiki/Shoelace_formula + double result = 0.0; + OutPt* op2 = op; + do + { + result += static_cast(op2->prev->pt.y + op2->pt.y) * + static_cast(op2->prev->pt.x - op2->pt.x); + op2 = op2->next; + } while (op2 != op); + return result * 0.5; + } + + inline double AreaTriangle(const Point64& pt1, + const Point64& pt2, const Point64& pt3) + { + return (static_cast(pt3.y + pt1.y) * static_cast(pt3.x - pt1.x) + + static_cast(pt1.y + pt2.y) * static_cast(pt1.x - pt2.x) + + static_cast(pt2.y + pt3.y) * static_cast(pt2.x - pt3.x)); + } + + void ReverseOutPts(OutPt* op) + { + if (!op) return; + + OutPt* op1 = op; + OutPt* op2; + + do + { + op2 = op1->next; + op1->next = op1->prev; + op1->prev = op2; + op1 = op2; + } while (op1 != op); + } + + inline void SwapSides(OutRec& outrec) + { + Active* e2 = outrec.front_edge; + outrec.front_edge = outrec.back_edge; + outrec.back_edge = e2; + outrec.pts = outrec.pts->next; + } + + inline OutRec* GetRealOutRec(OutRec* outrec) + { + while (outrec && !outrec->pts) outrec = outrec->owner; + return outrec; + } + + inline bool IsValidOwner(OutRec* outrec, OutRec* testOwner) + { + // prevent outrec owning itself either directly or indirectly + while (testOwner && testOwner != outrec) testOwner = testOwner->owner; + return !testOwner; + } + + inline void UncoupleOutRec(Active ae) + { + OutRec* outrec = ae.outrec; + if (!outrec) return; + outrec->front_edge->outrec = nullptr; + outrec->back_edge->outrec = nullptr; + outrec->front_edge = nullptr; + outrec->back_edge = nullptr; + } + + + inline bool PtsReallyClose(const Point64& pt1, const Point64& pt2) + { + return (std::llabs(pt1.x - pt2.x) < 2) && (std::llabs(pt1.y - pt2.y) < 2); + } + + inline bool IsVerySmallTriangle(const OutPt& op) + { + return op.next->next == op.prev && + (PtsReallyClose(op.prev->pt, op.next->pt) || + PtsReallyClose(op.pt, op.next->pt) || + PtsReallyClose(op.pt, op.prev->pt)); + } + + inline bool IsValidClosedPath(const OutPt* op) + { + return op && (op->next != op) && (op->next != op->prev) && + !IsVerySmallTriangle(*op); + } + + inline bool OutrecIsAscending(const Active* hotEdge) + { + return (hotEdge == hotEdge->outrec->front_edge); + } + + inline void SwapFrontBackSides(OutRec& outrec) + { + Active* tmp = outrec.front_edge; + outrec.front_edge = outrec.back_edge; + outrec.back_edge = tmp; + outrec.pts = outrec.pts->next; + } + + inline bool EdgesAdjacentInAEL(const IntersectNode& inode) + { + return (inode.edge1->next_in_ael == inode.edge2) || (inode.edge1->prev_in_ael == inode.edge2); + } + + inline bool IsJoined(const Active& e) + { + return e.join_with != JoinWith::NoJoin; + } + + inline void SetOwner(OutRec* outrec, OutRec* new_owner) + { + //precondition1: new_owner is never null + while (new_owner->owner && !new_owner->owner->pts) + new_owner->owner = new_owner->owner->owner; + OutRec* tmp = new_owner; + while (tmp && tmp != outrec) tmp = tmp->owner; + if (tmp) new_owner->owner = outrec->owner; + outrec->owner = new_owner; + } + + static PointInPolygonResult PointInOpPolygon(const Point64& pt, OutPt* op) + { + if (op == op->next || op->prev == op->next) + return PointInPolygonResult::IsOutside; + + OutPt* op2 = op; + do + { + if (op->pt.y != pt.y) break; + op = op->next; + } while (op != op2); + if (op->pt.y == pt.y) // not a proper polygon + return PointInPolygonResult::IsOutside; + + bool is_above = op->pt.y < pt.y, starting_above = is_above; + int val = 0; + op2 = op->next; + while (op2 != op) + { + if (is_above) + while (op2 != op && op2->pt.y < pt.y) op2 = op2->next; + else + while (op2 != op && op2->pt.y > pt.y) op2 = op2->next; + if (op2 == op) break; + + // must have touched or crossed the pt.Y horizonal + // and this must happen an even number of times + + if (op2->pt.y == pt.y) // touching the horizontal + { + if (op2->pt.x == pt.x || (op2->pt.y == op2->prev->pt.y && + (pt.x < op2->prev->pt.x) != (pt.x < op2->pt.x))) + return PointInPolygonResult::IsOn; + + op2 = op2->next; + if (op2 == op) break; + continue; + } + + if (pt.x < op2->pt.x && pt.x < op2->prev->pt.x); + // do nothing because + // we're only interested in edges crossing on the left + else if ((pt.x > op2->prev->pt.x && pt.x > op2->pt.x)) + val = 1 - val; // toggle val + else + { + double d = CrossProduct(op2->prev->pt, op2->pt, pt); + if (d == 0) return PointInPolygonResult::IsOn; + if ((d < 0) == is_above) val = 1 - val; + } + is_above = !is_above; + op2 = op2->next; + } + + if (is_above != starting_above) + { + double d = CrossProduct(op2->prev->pt, op2->pt, pt); + if (d == 0) return PointInPolygonResult::IsOn; + if ((d < 0) == is_above) val = 1 - val; + } + + if (val == 0) return PointInPolygonResult::IsOutside; + else return PointInPolygonResult::IsInside; + } + + inline Path64 GetCleanPath(OutPt* op) + { + Path64 result; + OutPt* op2 = op; + while (op2->next != op && + ((op2->pt.x == op2->next->pt.x && op2->pt.x == op2->prev->pt.x) || + (op2->pt.y == op2->next->pt.y && op2->pt.y == op2->prev->pt.y))) op2 = op2->next; + result.push_back(op2->pt); + OutPt* prevOp = op2; + op2 = op2->next; + while (op2 != op) + { + if ((op2->pt.x != op2->next->pt.x || op2->pt.x != prevOp->pt.x) && + (op2->pt.y != op2->next->pt.y || op2->pt.y != prevOp->pt.y)) + { + result.push_back(op2->pt); + prevOp = op2; + } + op2 = op2->next; + } + return result; + } + + inline bool Path1InsidePath2(OutPt* op1, OutPt* op2) + { + // we need to make some accommodation for rounding errors + // so we won't jump if the first vertex is found outside + PointInPolygonResult result; + int outside_cnt = 0; + OutPt* op = op1; + do + { + result = PointInOpPolygon(op->pt, op2); + if (result == PointInPolygonResult::IsOutside) ++outside_cnt; + else if (result == PointInPolygonResult::IsInside) --outside_cnt; + op = op->next; + } while (op != op1 && std::abs(outside_cnt) < 2); + if (std::abs(outside_cnt) > 1) return (outside_cnt < 0); + // since path1's location is still equivocal, check its midpoint + Point64 mp = GetBounds(GetCleanPath(op1)).MidPoint(); + Path64 path2 = GetCleanPath(op2); + return PointInPolygon(mp, path2) != PointInPolygonResult::IsOutside; + } + + //------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ + + void AddLocMin(LocalMinimaList& list, + Vertex& vert, PathType polytype, bool is_open) + { + //make sure the vertex is added only once ... + if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::Empty) return; + + vert.flags = (vert.flags | VertexFlags::LocalMin); + list.push_back(std::make_unique (&vert, polytype, is_open)); + } + + void AddPaths_(const Paths64& paths, PathType polytype, bool is_open, + std::vector& vertexLists, LocalMinimaList& locMinList) + { + const auto total_vertex_count = + std::accumulate(paths.begin(), paths.end(), size_t(0), + [](const auto& a, const Path64& path) + {return a + path.size(); }); + if (total_vertex_count == 0) return; + + Vertex* vertices = new Vertex[total_vertex_count], * v = vertices; + for (const Path64& path : paths) + { + //for each path create a circular double linked list of vertices + Vertex* v0 = v, * curr_v = v, * prev_v = nullptr; + + if (path.empty()) + continue; + + v->prev = nullptr; + int cnt = 0; + for (const Point64& pt : path) + { + if (prev_v) + { + if (prev_v->pt == pt) continue; // ie skips duplicates + prev_v->next = curr_v; + } + curr_v->prev = prev_v; + curr_v->pt = pt; + curr_v->flags = VertexFlags::Empty; + prev_v = curr_v++; + cnt++; + } + if (!prev_v || !prev_v->prev) continue; + if (!is_open && prev_v->pt == v0->pt) + prev_v = prev_v->prev; + prev_v->next = v0; + v0->prev = prev_v; + v = curr_v; // ie get ready for next path + if (cnt < 2 || (cnt == 2 && !is_open)) continue; + + //now find and assign local minima + bool going_up, going_up0; + if (is_open) + { + curr_v = v0->next; + while (curr_v != v0 && curr_v->pt.y == v0->pt.y) + curr_v = curr_v->next; + going_up = curr_v->pt.y <= v0->pt.y; + if (going_up) + { + v0->flags = VertexFlags::OpenStart; + AddLocMin(locMinList , *v0, polytype, true); + } + else + v0->flags = VertexFlags::OpenStart | VertexFlags::LocalMax; + } + else // closed path + { + prev_v = v0->prev; + while (prev_v != v0 && prev_v->pt.y == v0->pt.y) + prev_v = prev_v->prev; + if (prev_v == v0) + continue; // only open paths can be completely flat + going_up = prev_v->pt.y > v0->pt.y; + } + + going_up0 = going_up; + prev_v = v0; + curr_v = v0->next; + while (curr_v != v0) + { + if (curr_v->pt.y > prev_v->pt.y && going_up) + { + prev_v->flags = (prev_v->flags | VertexFlags::LocalMax); + going_up = false; + } + else if (curr_v->pt.y < prev_v->pt.y && !going_up) + { + going_up = true; + AddLocMin(locMinList, *prev_v, polytype, is_open); + } + prev_v = curr_v; + curr_v = curr_v->next; + } + + if (is_open) + { + prev_v->flags = prev_v->flags | VertexFlags::OpenEnd; + if (going_up) + prev_v->flags = prev_v->flags | VertexFlags::LocalMax; + else + AddLocMin(locMinList, *prev_v, polytype, is_open); + } + else if (going_up != going_up0) + { + if (going_up0) AddLocMin(locMinList, *prev_v, polytype, false); + else prev_v->flags = prev_v->flags | VertexFlags::LocalMax; + } + } // end processing current path + + vertexLists.emplace_back(vertices); + } + + //------------------------------------------------------------------------------ + // ReuseableDataContainer64 methods ... + //------------------------------------------------------------------------------ + + void ReuseableDataContainer64::AddLocMin(Vertex& vert, PathType polytype, bool is_open) + { + //make sure the vertex is added only once ... + if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::Empty) return; + + vert.flags = (vert.flags | VertexFlags::LocalMin); + minima_list_.push_back(std::make_unique (&vert, polytype, is_open)); + } + + void ReuseableDataContainer64::AddPaths(const Paths64& paths, + PathType polytype, bool is_open) + { + AddPaths_(paths, polytype, is_open, vertex_lists_, minima_list_); + } + + ReuseableDataContainer64::~ReuseableDataContainer64() + { + Clear(); + } + + void ReuseableDataContainer64::Clear() + { + minima_list_.clear(); + for (auto v : vertex_lists_) delete[] v; + vertex_lists_.clear(); + } + + //------------------------------------------------------------------------------ + // ClipperBase methods ... + //------------------------------------------------------------------------------ + + ClipperBase::~ClipperBase() + { + Clear(); + } + + void ClipperBase::DeleteEdges(Active*& e) + { + while (e) + { + Active* e2 = e; + e = e->next_in_ael; + delete e2; + } + } + + void ClipperBase::CleanUp() + { + DeleteEdges(actives_); + scanline_list_ = std::priority_queue(); + intersect_nodes_.clear(); + DisposeAllOutRecs(); + horz_seg_list_.clear(); + horz_join_list_.clear(); + } + + + void ClipperBase::Clear() + { + CleanUp(); + DisposeVerticesAndLocalMinima(); + current_locmin_iter_ = minima_list_.begin(); + minima_list_sorted_ = false; + has_open_paths_ = false; + } + + + void ClipperBase::Reset() + { + if (!minima_list_sorted_) + { + std::stable_sort(minima_list_.begin(), minima_list_.end(), LocMinSorter()); //#594 + minima_list_sorted_ = true; + } + LocalMinimaList::const_reverse_iterator i; + for (i = minima_list_.rbegin(); i != minima_list_.rend(); ++i) + InsertScanline((*i)->vertex->pt.y); + + current_locmin_iter_ = minima_list_.begin(); + actives_ = nullptr; + sel_ = nullptr; + succeeded_ = true; + } + + +#ifdef USINGZ + void ClipperBase::SetZ(const Active& e1, const Active& e2, Point64& ip) + { + if (!zCallback_) return; + // prioritize subject over clip vertices by passing + // subject vertices before clip vertices in the callback + if (GetPolyType(e1) == PathType::Subject) + { + if (ip == e1.bot) ip.z = e1.bot.z; + else if (ip == e1.top) ip.z = e1.top.z; + else if (ip == e2.bot) ip.z = e2.bot.z; + else if (ip == e2.top) ip.z = e2.top.z; + else ip.z = DefaultZ; + zCallback_(e1.bot, e1.top, e2.bot, e2.top, ip); + } + else + { + if (ip == e2.bot) ip.z = e2.bot.z; + else if (ip == e2.top) ip.z = e2.top.z; + else if (ip == e1.bot) ip.z = e1.bot.z; + else if (ip == e1.top) ip.z = e1.top.z; + else ip.z = DefaultZ; + zCallback_(e2.bot, e2.top, e1.bot, e1.top, ip); + } + } +#endif + + void ClipperBase::AddPath(const Path64& path, PathType polytype, bool is_open) + { + Paths64 tmp; + tmp.push_back(path); + AddPaths(tmp, polytype, is_open); + } + + void ClipperBase::AddPaths(const Paths64& paths, PathType polytype, bool is_open) + { + if (is_open) has_open_paths_ = true; + minima_list_sorted_ = false; + AddPaths_(paths, polytype, is_open, vertex_lists_, minima_list_); + } + + void ClipperBase::AddReuseableData(const ReuseableDataContainer64& reuseable_data) + { + // nb: reuseable_data will continue to own the vertices + // and remains responsible for their clean up. + succeeded_ = false; + minima_list_sorted_ = false; + LocalMinimaList::const_iterator i; + for (i = reuseable_data.minima_list_.cbegin(); i != reuseable_data.minima_list_.cend(); ++i) + { + minima_list_.push_back(std::make_unique ((*i)->vertex, (*i)->polytype, (*i)->is_open)); + if ((*i)->is_open) has_open_paths_ = true; + } + } + + void ClipperBase::InsertScanline(int64_t y) + { + scanline_list_.push(y); + } + + + bool ClipperBase::PopScanline(int64_t& y) + { + if (scanline_list_.empty()) return false; + y = scanline_list_.top(); + scanline_list_.pop(); + while (!scanline_list_.empty() && y == scanline_list_.top()) + scanline_list_.pop(); // Pop duplicates. + return true; + } + + + bool ClipperBase::PopLocalMinima(int64_t y, LocalMinima*& local_minima) + { + if (current_locmin_iter_ == minima_list_.end() || (*current_locmin_iter_)->vertex->pt.y != y) return false; + local_minima = (current_locmin_iter_++)->get(); + return true; + } + + void ClipperBase::DisposeAllOutRecs() + { + for (auto outrec : outrec_list_) + { + if (outrec->pts) DisposeOutPts(outrec); + delete outrec; + } + outrec_list_.resize(0); + } + + void ClipperBase::DisposeVerticesAndLocalMinima() + { + minima_list_.clear(); + for (auto v : vertex_lists_) delete[] v; + vertex_lists_.clear(); + } + + + void ClipperBase::AddLocMin(Vertex& vert, PathType polytype, bool is_open) + { + //make sure the vertex is added only once ... + if ((VertexFlags::LocalMin & vert.flags) != VertexFlags::Empty) return; + + vert.flags = (vert.flags | VertexFlags::LocalMin); + minima_list_.push_back(std::make_unique (&vert, polytype, is_open)); + } + + bool ClipperBase::IsContributingClosed(const Active& e) const + { + switch (fillrule_) + { + case FillRule::EvenOdd: + break; + case FillRule::NonZero: + if (abs(e.wind_cnt) != 1) return false; + break; + case FillRule::Positive: + if (e.wind_cnt != 1) return false; + break; + case FillRule::Negative: + if (e.wind_cnt != -1) return false; + break; + // Should never happen, but adding this to stop a compiler warning + default: + break; + } + + switch (cliptype_) + { + case ClipType::NoClip: + return false; + case ClipType::Intersection: + switch (fillrule_) + { + case FillRule::Positive: + return (e.wind_cnt2 > 0); + case FillRule::Negative: + return (e.wind_cnt2 < 0); + default: + return (e.wind_cnt2 != 0); + } + break; + + case ClipType::Union: + switch (fillrule_) + { + case FillRule::Positive: + return (e.wind_cnt2 <= 0); + case FillRule::Negative: + return (e.wind_cnt2 >= 0); + default: + return (e.wind_cnt2 == 0); + } + break; + + case ClipType::Difference: + bool result; + switch (fillrule_) + { + case FillRule::Positive: + result = (e.wind_cnt2 <= 0); + break; + case FillRule::Negative: + result = (e.wind_cnt2 >= 0); + break; + default: + result = (e.wind_cnt2 == 0); + } + if (GetPolyType(e) == PathType::Subject) + return result; + else + return !result; + break; + + case ClipType::Xor: return true; break; + // Should never happen, but adding this to stop a compiler warning + default: + break; + } + return false; // we should never get here + } + + + inline bool ClipperBase::IsContributingOpen(const Active& e) const + { + bool is_in_clip, is_in_subj; + switch (fillrule_) + { + case FillRule::Positive: + is_in_clip = e.wind_cnt2 > 0; + is_in_subj = e.wind_cnt > 0; + break; + case FillRule::Negative: + is_in_clip = e.wind_cnt2 < 0; + is_in_subj = e.wind_cnt < 0; + break; + default: + is_in_clip = e.wind_cnt2 != 0; + is_in_subj = e.wind_cnt != 0; + } + + switch (cliptype_) + { + case ClipType::Intersection: return is_in_clip; + case ClipType::Union: return (!is_in_subj && !is_in_clip); + default: return !is_in_clip; + } + } + + + void ClipperBase::SetWindCountForClosedPathEdge(Active& e) + { + //Wind counts refer to polygon regions not edges, so here an edge's WindCnt + //indicates the higher of the wind counts for the two regions touching the + //edge. (NB Adjacent regions can only ever have their wind counts differ by + //one. Also, open paths have no meaningful wind directions or counts.) + + Active* e2 = e.prev_in_ael; + //find the nearest closed path edge of the same PolyType in AEL (heading left) + PathType pt = GetPolyType(e); + while (e2 && (GetPolyType(*e2) != pt || IsOpen(*e2))) e2 = e2->prev_in_ael; + + if (!e2) + { + e.wind_cnt = e.wind_dx; + e2 = actives_; + } + else if (fillrule_ == FillRule::EvenOdd) + { + e.wind_cnt = e.wind_dx; + e.wind_cnt2 = e2->wind_cnt2; + e2 = e2->next_in_ael; + } + else + { + //NonZero, positive, or negative filling here ... + //if e's WindCnt is in the SAME direction as its WindDx, then polygon + //filling will be on the right of 'e'. + //NB neither e2.WindCnt nor e2.WindDx should ever be 0. + if (e2->wind_cnt * e2->wind_dx < 0) + { + //opposite directions so 'e' is outside 'e2' ... + if (abs(e2->wind_cnt) > 1) + { + //outside prev poly but still inside another. + if (e2->wind_dx * e.wind_dx < 0) + //reversing direction so use the same WC + e.wind_cnt = e2->wind_cnt; + else + //otherwise keep 'reducing' the WC by 1 (ie towards 0) ... + e.wind_cnt = e2->wind_cnt + e.wind_dx; + } + else + //now outside all polys of same polytype so set own WC ... + e.wind_cnt = (IsOpen(e) ? 1 : e.wind_dx); + } + else + { + //'e' must be inside 'e2' + if (e2->wind_dx * e.wind_dx < 0) + //reversing direction so use the same WC + e.wind_cnt = e2->wind_cnt; + else + //otherwise keep 'increasing' the WC by 1 (ie away from 0) ... + e.wind_cnt = e2->wind_cnt + e.wind_dx; + } + e.wind_cnt2 = e2->wind_cnt2; + e2 = e2->next_in_ael; // ie get ready to calc WindCnt2 + } + + //update wind_cnt2 ... + if (fillrule_ == FillRule::EvenOdd) + while (e2 != &e) + { + if (GetPolyType(*e2) != pt && !IsOpen(*e2)) + e.wind_cnt2 = (e.wind_cnt2 == 0 ? 1 : 0); + e2 = e2->next_in_ael; + } + else + while (e2 != &e) + { + if (GetPolyType(*e2) != pt && !IsOpen(*e2)) + e.wind_cnt2 += e2->wind_dx; + e2 = e2->next_in_ael; + } + } + + + void ClipperBase::SetWindCountForOpenPathEdge(Active& e) + { + Active* e2 = actives_; + if (fillrule_ == FillRule::EvenOdd) + { + int cnt1 = 0, cnt2 = 0; + while (e2 != &e) + { + if (GetPolyType(*e2) == PathType::Clip) + cnt2++; + else if (!IsOpen(*e2)) + cnt1++; + e2 = e2->next_in_ael; + } + e.wind_cnt = (IsOdd(cnt1) ? 1 : 0); + e.wind_cnt2 = (IsOdd(cnt2) ? 1 : 0); + } + else + { + while (e2 != &e) + { + if (GetPolyType(*e2) == PathType::Clip) + e.wind_cnt2 += e2->wind_dx; + else if (!IsOpen(*e2)) + e.wind_cnt += e2->wind_dx; + e2 = e2->next_in_ael; + } + } + } + + bool IsValidAelOrder(const Active& resident, const Active& newcomer) + { + if (newcomer.curr_x != resident.curr_x) + return newcomer.curr_x > resident.curr_x; + + //get the turning direction a1.top, a2.bot, a2.top + double d = CrossProduct(resident.top, newcomer.bot, newcomer.top); + if (d != 0) return d < 0; + + //edges must be collinear to get here + //for starting open paths, place them according to + //the direction they're about to turn + if (!IsMaxima(resident) && (resident.top.y > newcomer.top.y)) + { + return CrossProduct(newcomer.bot, + resident.top, NextVertex(resident)->pt) <= 0; + } + else if (!IsMaxima(newcomer) && (newcomer.top.y > resident.top.y)) + { + return CrossProduct(newcomer.bot, + newcomer.top, NextVertex(newcomer)->pt) >= 0; + } + + int64_t y = newcomer.bot.y; + bool newcomerIsLeft = newcomer.is_left_bound; + + if (resident.bot.y != y || resident.local_min->vertex->pt.y != y) + return newcomer.is_left_bound; + //resident must also have just been inserted + else if (resident.is_left_bound != newcomerIsLeft) + return newcomerIsLeft; + else if (IsCollinear(PrevPrevVertex(resident)->pt, + resident.bot, resident.top)) return true; + else + //compare turning direction of the alternate bound + return (CrossProduct(PrevPrevVertex(resident)->pt, + newcomer.bot, PrevPrevVertex(newcomer)->pt) > 0) == newcomerIsLeft; + } + + + void ClipperBase::InsertLeftEdge(Active& e) + { + Active* e2; + if (!actives_) + { + e.prev_in_ael = nullptr; + e.next_in_ael = nullptr; + actives_ = &e; + } + else if (!IsValidAelOrder(*actives_, e)) + { + e.prev_in_ael = nullptr; + e.next_in_ael = actives_; + actives_->prev_in_ael = &e; + actives_ = &e; + } + else + { + e2 = actives_; + while (e2->next_in_ael && IsValidAelOrder(*e2->next_in_ael, e)) + e2 = e2->next_in_ael; + if (e2->join_with == JoinWith::Right) + e2 = e2->next_in_ael; + if (!e2) return; // should never happen and stops compiler warning :) + e.next_in_ael = e2->next_in_ael; + if (e2->next_in_ael) e2->next_in_ael->prev_in_ael = &e; + e.prev_in_ael = e2; + e2->next_in_ael = &e; + } + } + + + void InsertRightEdge(Active& e, Active& e2) + { + e2.next_in_ael = e.next_in_ael; + if (e.next_in_ael) e.next_in_ael->prev_in_ael = &e2; + e2.prev_in_ael = &e; + e.next_in_ael = &e2; + } + + + void ClipperBase::InsertLocalMinimaIntoAEL(int64_t bot_y) + { + LocalMinima* local_minima; + Active* left_bound, * right_bound; + //Add any local minima (if any) at BotY ... + //nb: horizontal local minima edges should contain locMin.vertex.prev + + while (PopLocalMinima(bot_y, local_minima)) + { + if ((local_minima->vertex->flags & VertexFlags::OpenStart) != VertexFlags::Empty) + { + left_bound = nullptr; + } + else + { + left_bound = new Active(); + left_bound->bot = local_minima->vertex->pt; + left_bound->curr_x = left_bound->bot.x; + left_bound->wind_dx = -1; + left_bound->vertex_top = local_minima->vertex->prev; // ie descending + left_bound->top = left_bound->vertex_top->pt; + left_bound->local_min = local_minima; + SetDx(*left_bound); + } + + if ((local_minima->vertex->flags & VertexFlags::OpenEnd) != VertexFlags::Empty) + { + right_bound = nullptr; + } + else + { + right_bound = new Active(); + right_bound->bot = local_minima->vertex->pt; + right_bound->curr_x = right_bound->bot.x; + right_bound->wind_dx = 1; + right_bound->vertex_top = local_minima->vertex->next; // ie ascending + right_bound->top = right_bound->vertex_top->pt; + right_bound->local_min = local_minima; + SetDx(*right_bound); + } + + //Currently LeftB is just the descending bound and RightB is the ascending. + //Now if the LeftB isn't on the left of RightB then we need swap them. + if (left_bound && right_bound) + { + if (IsHorizontal(*left_bound)) + { + if (IsHeadingRightHorz(*left_bound)) SwapActives(left_bound, right_bound); + } + else if (IsHorizontal(*right_bound)) + { + if (IsHeadingLeftHorz(*right_bound)) SwapActives(left_bound, right_bound); + } + else if (left_bound->dx < right_bound->dx) + SwapActives(left_bound, right_bound); + } + else if (!left_bound) + { + left_bound = right_bound; + right_bound = nullptr; + } + + bool contributing; + left_bound->is_left_bound = true; + InsertLeftEdge(*left_bound); + + if (IsOpen(*left_bound)) + { + SetWindCountForOpenPathEdge(*left_bound); + contributing = IsContributingOpen(*left_bound); + } + else + { + SetWindCountForClosedPathEdge(*left_bound); + contributing = IsContributingClosed(*left_bound); + } + + if (right_bound) + { + right_bound->is_left_bound = false; + right_bound->wind_cnt = left_bound->wind_cnt; + right_bound->wind_cnt2 = left_bound->wind_cnt2; + InsertRightEdge(*left_bound, *right_bound); /////// + if (contributing) + { + AddLocalMinPoly(*left_bound, *right_bound, left_bound->bot, true); + if (!IsHorizontal(*left_bound)) + CheckJoinLeft(*left_bound, left_bound->bot); + } + + while (right_bound->next_in_ael && + IsValidAelOrder(*right_bound->next_in_ael, *right_bound)) + { + IntersectEdges(*right_bound, *right_bound->next_in_ael, right_bound->bot); + SwapPositionsInAEL(*right_bound, *right_bound->next_in_ael); + } + + if (IsHorizontal(*right_bound)) + PushHorz(*right_bound); + else + { + CheckJoinRight(*right_bound, right_bound->bot); + InsertScanline(right_bound->top.y); + } + } + else if (contributing) + { + StartOpenPath(*left_bound, left_bound->bot); + } + + if (IsHorizontal(*left_bound)) + PushHorz(*left_bound); + else + InsertScanline(left_bound->top.y); + } // while (PopLocalMinima()) + } + + + inline void ClipperBase::PushHorz(Active& e) + { + e.next_in_sel = (sel_ ? sel_ : nullptr); + sel_ = &e; + } + + + inline bool ClipperBase::PopHorz(Active*& e) + { + e = sel_; + if (!e) return false; + sel_ = sel_->next_in_sel; + return true; + } + + + OutPt* ClipperBase::AddLocalMinPoly(Active& e1, Active& e2, + const Point64& pt, bool is_new) + { + OutRec* outrec = NewOutRec(); + e1.outrec = outrec; + e2.outrec = outrec; + + if (IsOpen(e1)) + { + outrec->owner = nullptr; + outrec->is_open = true; + if (e1.wind_dx > 0) + SetSides(*outrec, e1, e2); + else + SetSides(*outrec, e2, e1); + } + else + { + Active* prevHotEdge = GetPrevHotEdge(e1); + //e.windDx is the winding direction of the **input** paths + //and unrelated to the winding direction of output polygons. + //Output orientation is determined by e.outrec.frontE which is + //the ascending edge (see AddLocalMinPoly). + if (prevHotEdge) + { + if (using_polytree_) + SetOwner(outrec, prevHotEdge->outrec); + if (OutrecIsAscending(prevHotEdge) == is_new) + SetSides(*outrec, e2, e1); + else + SetSides(*outrec, e1, e2); + } + else + { + outrec->owner = nullptr; + if (is_new) + SetSides(*outrec, e1, e2); + else + SetSides(*outrec, e2, e1); + } + } + + OutPt* op = new OutPt(pt, outrec); + outrec->pts = op; + return op; + } + + + OutPt* ClipperBase::AddLocalMaxPoly(Active& e1, Active& e2, const Point64& pt) + { + if (IsJoined(e1)) Split(e1, pt); + if (IsJoined(e2)) Split(e2, pt); + + if (IsFront(e1) == IsFront(e2)) + { + if (IsOpenEnd(e1)) + SwapFrontBackSides(*e1.outrec); + else if (IsOpenEnd(e2)) + SwapFrontBackSides(*e2.outrec); + else + { + succeeded_ = false; + return nullptr; + } + } + + OutPt* result = AddOutPt(e1, pt); + if (e1.outrec == e2.outrec) + { + OutRec& outrec = *e1.outrec; + outrec.pts = result; + + if (using_polytree_) + { + Active* e = GetPrevHotEdge(e1); + if (!e) + outrec.owner = nullptr; + else + SetOwner(&outrec, e->outrec); + // nb: outRec.owner here is likely NOT the real + // owner but this will be checked in RecursiveCheckOwners() + } + + UncoupleOutRec(e1); + result = outrec.pts; + if (outrec.owner && !outrec.owner->front_edge) + outrec.owner = GetRealOutRec(outrec.owner); + } + //and to preserve the winding orientation of outrec ... + else if (IsOpen(e1)) + { + if (e1.wind_dx < 0) + JoinOutrecPaths(e1, e2); + else + JoinOutrecPaths(e2, e1); + } + else if (e1.outrec->idx < e2.outrec->idx) + JoinOutrecPaths(e1, e2); + else + JoinOutrecPaths(e2, e1); + return result; + } + + void ClipperBase::JoinOutrecPaths(Active& e1, Active& e2) + { + //join e2 outrec path onto e1 outrec path and then delete e2 outrec path + //pointers. (NB Only very rarely do the joining ends share the same coords.) + OutPt* p1_st = e1.outrec->pts; + OutPt* p2_st = e2.outrec->pts; + OutPt* p1_end = p1_st->next; + OutPt* p2_end = p2_st->next; + if (IsFront(e1)) + { + p2_end->prev = p1_st; + p1_st->next = p2_end; + p2_st->next = p1_end; + p1_end->prev = p2_st; + e1.outrec->pts = p2_st; + e1.outrec->front_edge = e2.outrec->front_edge; + if (e1.outrec->front_edge) + e1.outrec->front_edge->outrec = e1.outrec; + } + else + { + p1_end->prev = p2_st; + p2_st->next = p1_end; + p1_st->next = p2_end; + p2_end->prev = p1_st; + e1.outrec->back_edge = e2.outrec->back_edge; + if (e1.outrec->back_edge) + e1.outrec->back_edge->outrec = e1.outrec; + } + + //after joining, the e2.OutRec must contains no vertices ... + e2.outrec->front_edge = nullptr; + e2.outrec->back_edge = nullptr; + e2.outrec->pts = nullptr; + + if (IsOpenEnd(e1)) + { + e2.outrec->pts = e1.outrec->pts; + e1.outrec->pts = nullptr; + } + else + SetOwner(e2.outrec, e1.outrec); + + //and e1 and e2 are maxima and are about to be dropped from the Actives list. + e1.outrec = nullptr; + e2.outrec = nullptr; + } + + OutRec* ClipperBase::NewOutRec() + { + OutRec* result = new OutRec(); + result->idx = outrec_list_.size(); + outrec_list_.push_back(result); + result->pts = nullptr; + result->owner = nullptr; + result->polypath = nullptr; + result->is_open = false; + result->splits = nullptr; + return result; + } + + + OutPt* ClipperBase::AddOutPt(const Active& e, const Point64& pt) + { + OutPt* new_op = nullptr; + + //Outrec.OutPts: a circular doubly-linked-list of POutPt where ... + //op_front[.Prev]* ~~~> op_back & op_back == op_front.Next + OutRec* outrec = e.outrec; + bool to_front = IsFront(e); + OutPt* op_front = outrec->pts; + OutPt* op_back = op_front->next; + + if (to_front) + { + if (pt == op_front->pt) + return op_front; + } + else if (pt == op_back->pt) + return op_back; + + new_op = new OutPt(pt, outrec); + op_back->prev = new_op; + new_op->prev = op_front; + new_op->next = op_back; + op_front->next = new_op; + if (to_front) outrec->pts = new_op; + return new_op; + } + + void ClipperBase::CleanCollinear(OutRec* outrec) + { + outrec = GetRealOutRec(outrec); + if (!outrec || outrec->is_open) return; + if (!IsValidClosedPath(outrec->pts)) + { + DisposeOutPts(outrec); + return; + } + + OutPt* startOp = outrec->pts, * op2 = startOp; + for (; ; ) + { + //NB if preserveCollinear == true, then only remove 180 deg. spikes + if (IsCollinear(op2->prev->pt, op2->pt, op2->next->pt) && + (op2->pt == op2->prev->pt || + op2->pt == op2->next->pt || !preserve_collinear_ || + DotProduct(op2->prev->pt, op2->pt, op2->next->pt) < 0)) + { + + if (op2 == outrec->pts) outrec->pts = op2->prev; + + op2 = DisposeOutPt(op2); + if (!IsValidClosedPath(op2)) + { + DisposeOutPts(outrec); + return; + } + startOp = op2; + continue; + } + op2 = op2->next; + if (op2 == startOp) break; + } + FixSelfIntersects(outrec); + } + + void ClipperBase::DoSplitOp(OutRec* outrec, OutPt* splitOp) + { + // splitOp.prev -> splitOp && + // splitOp.next -> splitOp.next.next are intersecting + OutPt* prevOp = splitOp->prev; + OutPt* nextNextOp = splitOp->next->next; + outrec->pts = prevOp; + + Point64 ip; + GetSegmentIntersectPt(prevOp->pt, splitOp->pt, + splitOp->next->pt, nextNextOp->pt, ip); + +#ifdef USINGZ + if (zCallback_) zCallback_(prevOp->pt, splitOp->pt, + splitOp->next->pt, nextNextOp->pt, ip); +#endif + double area1 = Area(outrec->pts); + double absArea1 = std::fabs(area1); + if (absArea1 < 2) + { + DisposeOutPts(outrec); + return; + } + + double area2 = AreaTriangle(ip, splitOp->pt, splitOp->next->pt); + double absArea2 = std::fabs(area2); + + // de-link splitOp and splitOp.next from the path + // while inserting the intersection point + if (ip == prevOp->pt || ip == nextNextOp->pt) + { + nextNextOp->prev = prevOp; + prevOp->next = nextNextOp; + } + else + { + OutPt* newOp2 = new OutPt(ip, prevOp->outrec); + newOp2->prev = prevOp; + newOp2->next = nextNextOp; + nextNextOp->prev = newOp2; + prevOp->next = newOp2; + } + + // area1 is the path's area *before* splitting, whereas area2 is + // the area of the triangle containing splitOp & splitOp.next. + // So the only way for these areas to have the same sign is if + // the split triangle is larger than the path containing prevOp or + // if there's more than one self-intersection. + if (absArea2 >= 1 && + (absArea2 > absArea1 || (area2 > 0) == (area1 > 0))) + { + OutRec* newOr = NewOutRec(); + newOr->owner = outrec->owner; + + splitOp->outrec = newOr; + splitOp->next->outrec = newOr; + OutPt* newOp = new OutPt(ip, newOr); + newOp->prev = splitOp->next; + newOp->next = splitOp; + newOr->pts = newOp; + splitOp->prev = newOp; + splitOp->next->next = newOp; + + if (using_polytree_) + { + if (Path1InsidePath2(prevOp, newOp)) + { + newOr->splits = new OutRecList(); + newOr->splits->push_back(outrec); + } + else + { + if (!outrec->splits) outrec->splits = new OutRecList(); + outrec->splits->push_back(newOr); + } + } + } + else + { + delete splitOp->next; + delete splitOp; + } + } + + void ClipperBase::FixSelfIntersects(OutRec* outrec) + { + OutPt* op2 = outrec->pts; + for (; ; ) + { + // triangles can't self-intersect + if (op2->prev == op2->next->next) break; + if (SegmentsIntersect(op2->prev->pt, + op2->pt, op2->next->pt, op2->next->next->pt)) + { + if (op2 == outrec->pts || op2->next == outrec->pts) + outrec->pts = outrec->pts->prev; + DoSplitOp(outrec, op2); + if (!outrec->pts) break; + op2 = outrec->pts; + continue; + } + else + op2 = op2->next; + + if (op2 == outrec->pts) break; + } + } + + + inline void UpdateOutrecOwner(OutRec* outrec) + { + OutPt* opCurr = outrec->pts; + for (; ; ) + { + opCurr->outrec = outrec; + opCurr = opCurr->next; + if (opCurr == outrec->pts) return; + } + } + + + OutPt* ClipperBase::StartOpenPath(Active& e, const Point64& pt) + { + OutRec* outrec = NewOutRec(); + outrec->is_open = true; + + if (e.wind_dx > 0) + { + outrec->front_edge = &e; + outrec->back_edge = nullptr; + } + else + { + outrec->front_edge = nullptr; + outrec->back_edge = &e; + } + + e.outrec = outrec; + + OutPt* op = new OutPt(pt, outrec); + outrec->pts = op; + return op; + } + + inline void TrimHorz(Active& horzEdge, bool preserveCollinear) + { + bool wasTrimmed = false; + Point64 pt = NextVertex(horzEdge)->pt; + while (pt.y == horzEdge.top.y) + { + //always trim 180 deg. spikes (in closed paths) + //but otherwise break if preserveCollinear = true + if (preserveCollinear && + ((pt.x < horzEdge.top.x) != (horzEdge.bot.x < horzEdge.top.x))) + break; + + horzEdge.vertex_top = NextVertex(horzEdge); + horzEdge.top = pt; + wasTrimmed = true; + if (IsMaxima(horzEdge)) break; + pt = NextVertex(horzEdge)->pt; + } + + if (wasTrimmed) SetDx(horzEdge); // +/-infinity + } + + + inline void ClipperBase::UpdateEdgeIntoAEL(Active* e) + { + e->bot = e->top; + e->vertex_top = NextVertex(*e); + e->top = e->vertex_top->pt; + e->curr_x = e->bot.x; + SetDx(*e); + + if (IsJoined(*e)) Split(*e, e->bot); + + if (IsHorizontal(*e)) + { + if (!IsOpen(*e)) TrimHorz(*e, preserve_collinear_); + return; + } + + InsertScanline(e->top.y); + CheckJoinLeft(*e, e->bot); + CheckJoinRight(*e, e->bot, true); // (#500) + } + + Active* FindEdgeWithMatchingLocMin(Active* e) + { + Active* result = e->next_in_ael; + while (result) + { + if (result->local_min == e->local_min) return result; + else if (!IsHorizontal(*result) && e->bot != result->bot) result = nullptr; + else result = result->next_in_ael; + } + result = e->prev_in_ael; + while (result) + { + if (result->local_min == e->local_min) return result; + else if (!IsHorizontal(*result) && e->bot != result->bot) return nullptr; + else result = result->prev_in_ael; + } + return result; + } + + + void ClipperBase::IntersectEdges(Active& e1, Active& e2, const Point64& pt) + { + //MANAGE OPEN PATH INTERSECTIONS SEPARATELY ... + if (has_open_paths_ && (IsOpen(e1) || IsOpen(e2))) + { + if (IsOpen(e1) && IsOpen(e2)) return; + Active* edge_o, * edge_c; + if (IsOpen(e1)) + { + edge_o = &e1; + edge_c = &e2; + } + else + { + edge_o = &e2; + edge_c = &e1; + } + if (IsJoined(*edge_c)) Split(*edge_c, pt); // needed for safety + + if (abs(edge_c->wind_cnt) != 1) return; + switch (cliptype_) + { + case ClipType::Union: + if (!IsHotEdge(*edge_c)) return; + break; + default: + if (edge_c->local_min->polytype == PathType::Subject) + return; + } + + switch (fillrule_) + { + case FillRule::Positive: + if (edge_c->wind_cnt != 1) return; + break; + case FillRule::Negative: + if (edge_c->wind_cnt != -1) return; + break; + default: + if (std::abs(edge_c->wind_cnt) != 1) return; + } + +#ifdef USINGZ + OutPt* resultOp; +#endif + //toggle contribution ... + if (IsHotEdge(*edge_o)) + { +#ifdef USINGZ + resultOp = AddOutPt(*edge_o, pt); +#else + AddOutPt(*edge_o, pt); +#endif + if (IsFront(*edge_o)) edge_o->outrec->front_edge = nullptr; + else edge_o->outrec->back_edge = nullptr; + edge_o->outrec = nullptr; + } + + //horizontal edges can pass under open paths at a LocMins + else if (pt == edge_o->local_min->vertex->pt && + !IsOpenEnd(*edge_o->local_min->vertex)) + { + //find the other side of the LocMin and + //if it's 'hot' join up with it ... + Active* e3 = FindEdgeWithMatchingLocMin(edge_o); + if (e3 && IsHotEdge(*e3)) + { + edge_o->outrec = e3->outrec; + if (edge_o->wind_dx > 0) + SetSides(*e3->outrec, *edge_o, *e3); + else + SetSides(*e3->outrec, *e3, *edge_o); + return; + } + else +#ifdef USINGZ + resultOp = StartOpenPath(*edge_o, pt); +#else + StartOpenPath(*edge_o, pt); +#endif + } + else +#ifdef USINGZ + resultOp = StartOpenPath(*edge_o, pt); +#else + StartOpenPath(*edge_o, pt); +#endif + +#ifdef USINGZ + if (zCallback_) SetZ(*edge_o, *edge_c, resultOp->pt); +#endif + return; + } // end of an open path intersection + + //MANAGING CLOSED PATHS FROM HERE ON + + if (IsJoined(e1)) Split(e1, pt); + if (IsJoined(e2)) Split(e2, pt); + + //UPDATE WINDING COUNTS... + + int old_e1_windcnt, old_e2_windcnt; + if (e1.local_min->polytype == e2.local_min->polytype) + { + if (fillrule_ == FillRule::EvenOdd) + { + old_e1_windcnt = e1.wind_cnt; + e1.wind_cnt = e2.wind_cnt; + e2.wind_cnt = old_e1_windcnt; + } + else + { + if (e1.wind_cnt + e2.wind_dx == 0) + e1.wind_cnt = -e1.wind_cnt; + else + e1.wind_cnt += e2.wind_dx; + if (e2.wind_cnt - e1.wind_dx == 0) + e2.wind_cnt = -e2.wind_cnt; + else + e2.wind_cnt -= e1.wind_dx; + } + } + else + { + if (fillrule_ != FillRule::EvenOdd) + { + e1.wind_cnt2 += e2.wind_dx; + e2.wind_cnt2 -= e1.wind_dx; + } + else + { + e1.wind_cnt2 = (e1.wind_cnt2 == 0 ? 1 : 0); + e2.wind_cnt2 = (e2.wind_cnt2 == 0 ? 1 : 0); + } + } + + switch (fillrule_) + { + case FillRule::EvenOdd: + case FillRule::NonZero: + old_e1_windcnt = abs(e1.wind_cnt); + old_e2_windcnt = abs(e2.wind_cnt); + break; + default: + if (fillrule_ == fillpos) + { + old_e1_windcnt = e1.wind_cnt; + old_e2_windcnt = e2.wind_cnt; + } + else + { + old_e1_windcnt = -e1.wind_cnt; + old_e2_windcnt = -e2.wind_cnt; + } + break; + } + + const bool e1_windcnt_in_01 = old_e1_windcnt == 0 || old_e1_windcnt == 1; + const bool e2_windcnt_in_01 = old_e2_windcnt == 0 || old_e2_windcnt == 1; + + if ((!IsHotEdge(e1) && !e1_windcnt_in_01) || + (!IsHotEdge(e2) && !e2_windcnt_in_01)) + return; + + //NOW PROCESS THE INTERSECTION ... +#ifdef USINGZ + OutPt* resultOp = nullptr; +#endif + //if both edges are 'hot' ... + if (IsHotEdge(e1) && IsHotEdge(e2)) + { + if ((old_e1_windcnt != 0 && old_e1_windcnt != 1) || (old_e2_windcnt != 0 && old_e2_windcnt != 1) || + (e1.local_min->polytype != e2.local_min->polytype && cliptype_ != ClipType::Xor)) + { +#ifdef USINGZ + resultOp = AddLocalMaxPoly(e1, e2, pt); + if (zCallback_ && resultOp) SetZ(e1, e2, resultOp->pt); +#else + AddLocalMaxPoly(e1, e2, pt); +#endif + } + else if (IsFront(e1) || (e1.outrec == e2.outrec)) + { + //this 'else if' condition isn't strictly needed but + //it's sensible to split polygons that ony touch at + //a common vertex (not at common edges). + +#ifdef USINGZ + resultOp = AddLocalMaxPoly(e1, e2, pt); + OutPt* op2 = AddLocalMinPoly(e1, e2, pt); + if (zCallback_ && resultOp) SetZ(e1, e2, resultOp->pt); + if (zCallback_) SetZ(e1, e2, op2->pt); +#else + AddLocalMaxPoly(e1, e2, pt); + AddLocalMinPoly(e1, e2, pt); +#endif + } + else + { +#ifdef USINGZ + resultOp = AddOutPt(e1, pt); + OutPt* op2 = AddOutPt(e2, pt); + if (zCallback_) + { + SetZ(e1, e2, resultOp->pt); + SetZ(e1, e2, op2->pt); + } +#else + AddOutPt(e1, pt); + AddOutPt(e2, pt); +#endif + SwapOutrecs(e1, e2); + } + } + else if (IsHotEdge(e1)) + { +#ifdef USINGZ + resultOp = AddOutPt(e1, pt); + if (zCallback_) SetZ(e1, e2, resultOp->pt); +#else + AddOutPt(e1, pt); +#endif + SwapOutrecs(e1, e2); + } + else if (IsHotEdge(e2)) + { +#ifdef USINGZ + resultOp = AddOutPt(e2, pt); + if (zCallback_) SetZ(e1, e2, resultOp->pt); +#else + AddOutPt(e2, pt); +#endif + SwapOutrecs(e1, e2); + } + else + { + int64_t e1Wc2, e2Wc2; + switch (fillrule_) + { + case FillRule::EvenOdd: + case FillRule::NonZero: + e1Wc2 = abs(e1.wind_cnt2); + e2Wc2 = abs(e2.wind_cnt2); + break; + default: + if (fillrule_ == fillpos) + { + e1Wc2 = e1.wind_cnt2; + e2Wc2 = e2.wind_cnt2; + } + else + { + e1Wc2 = -e1.wind_cnt2; + e2Wc2 = -e2.wind_cnt2; + } + break; + } + + if (!IsSamePolyType(e1, e2)) + { +#ifdef USINGZ + resultOp = AddLocalMinPoly(e1, e2, pt, false); + if (zCallback_) SetZ(e1, e2, resultOp->pt); +#else + AddLocalMinPoly(e1, e2, pt, false); +#endif + } + else if (old_e1_windcnt == 1 && old_e2_windcnt == 1) + { +#ifdef USINGZ + resultOp = nullptr; +#endif + switch (cliptype_) + { + case ClipType::Union: + if (e1Wc2 <= 0 && e2Wc2 <= 0) +#ifdef USINGZ + resultOp = AddLocalMinPoly(e1, e2, pt, false); +#else + AddLocalMinPoly(e1, e2, pt, false); +#endif + break; + case ClipType::Difference: + if (((GetPolyType(e1) == PathType::Clip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || + ((GetPolyType(e1) == PathType::Subject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) + { +#ifdef USINGZ + resultOp = AddLocalMinPoly(e1, e2, pt, false); +#else + AddLocalMinPoly(e1, e2, pt, false); +#endif + } + break; + case ClipType::Xor: +#ifdef USINGZ + resultOp = AddLocalMinPoly(e1, e2, pt, false); +#else + AddLocalMinPoly(e1, e2, pt, false); +#endif + break; + default: + if (e1Wc2 > 0 && e2Wc2 > 0) +#ifdef USINGZ + resultOp = AddLocalMinPoly(e1, e2, pt, false); +#else + AddLocalMinPoly(e1, e2, pt, false); +#endif + break; + } +#ifdef USINGZ + if (resultOp && zCallback_) SetZ(e1, e2, resultOp->pt); +#endif + } + } + } + + inline void ClipperBase::DeleteFromAEL(Active& e) + { + Active* prev = e.prev_in_ael; + Active* next = e.next_in_ael; + if (!prev && !next && (&e != actives_)) return; // already deleted + if (prev) + prev->next_in_ael = next; + else + actives_ = next; + if (next) next->prev_in_ael = prev; + delete& e; + } + + + inline void ClipperBase::AdjustCurrXAndCopyToSEL(const int64_t top_y) + { + Active* e = actives_; + sel_ = e; + while (e) + { + e->prev_in_sel = e->prev_in_ael; + e->next_in_sel = e->next_in_ael; + e->jump = e->next_in_sel; + if (e->join_with == JoinWith::Left) + e->curr_x = e->prev_in_ael->curr_x; // also avoids complications + else + e->curr_x = TopX(*e, top_y); + e = e->next_in_ael; + } + } + + bool ClipperBase::ExecuteInternal(ClipType ct, FillRule fillrule, bool use_polytrees) + { + cliptype_ = ct; + fillrule_ = fillrule; + using_polytree_ = use_polytrees; + Reset(); + int64_t y; + if (ct == ClipType::NoClip || !PopScanline(y)) return true; + + while (succeeded_) + { + InsertLocalMinimaIntoAEL(y); + Active* e; + while (PopHorz(e)) DoHorizontal(*e); + if (horz_seg_list_.size() > 0) + { + ConvertHorzSegsToJoins(); + horz_seg_list_.clear(); + } + bot_y_ = y; // bot_y_ == bottom of scanbeam + if (!PopScanline(y)) break; // y new top of scanbeam + DoIntersections(y); + DoTopOfScanbeam(y); + while (PopHorz(e)) DoHorizontal(*e); + } + if (succeeded_) ProcessHorzJoins(); + return succeeded_; + } + + inline void FixOutRecPts(OutRec* outrec) + { + OutPt* op = outrec->pts; + do { + op->outrec = outrec; + op = op->next; + } while (op != outrec->pts); + } + + inline bool SetHorzSegHeadingForward(HorzSegment& hs, OutPt* opP, OutPt* opN) + { + if (opP->pt.x == opN->pt.x) return false; + if (opP->pt.x < opN->pt.x) + { + hs.left_op = opP; + hs.right_op = opN; + hs.left_to_right = true; + } + else + { + hs.left_op = opN; + hs.right_op = opP; + hs.left_to_right = false; + } + return true; + } + + inline bool UpdateHorzSegment(HorzSegment& hs) + { + OutPt* op = hs.left_op; + OutRec* outrec = GetRealOutRec(op->outrec); + bool outrecHasEdges = outrec->front_edge; + int64_t curr_y = op->pt.y; + OutPt* opP = op, * opN = op; + if (outrecHasEdges) + { + OutPt* opA = outrec->pts, * opZ = opA->next; + while (opP != opZ && opP->prev->pt.y == curr_y) + opP = opP->prev; + while (opN != opA && opN->next->pt.y == curr_y) + opN = opN->next; + } + else + { + while (opP->prev != opN && opP->prev->pt.y == curr_y) + opP = opP->prev; + while (opN->next != opP && opN->next->pt.y == curr_y) + opN = opN->next; + } + bool result = + SetHorzSegHeadingForward(hs, opP, opN) && + !hs.left_op->horz; + + if (result) + hs.left_op->horz = &hs; + else + hs.right_op = nullptr; // (for sorting) + return result; + } + + void ClipperBase::ConvertHorzSegsToJoins() + { + auto j = std::count_if(horz_seg_list_.begin(), + horz_seg_list_.end(), + [](HorzSegment& hs) { return UpdateHorzSegment(hs); }); + if (j < 2) return; + + std::stable_sort(horz_seg_list_.begin(), horz_seg_list_.end(), HorzSegSorter()); + + HorzSegmentList::iterator hs1 = horz_seg_list_.begin(), hs2; + HorzSegmentList::iterator hs_end = hs1 +j; + HorzSegmentList::iterator hs_end1 = hs_end - 1; + + for (; hs1 != hs_end1; ++hs1) + { + for (hs2 = hs1 + 1; hs2 != hs_end; ++hs2) + { + if ((hs2->left_op->pt.x >= hs1->right_op->pt.x) || + (hs2->left_to_right == hs1->left_to_right) || + (hs2->right_op->pt.x <= hs1->left_op->pt.x)) continue; + int64_t curr_y = hs1->left_op->pt.y; + if (hs1->left_to_right) + { + while (hs1->left_op->next->pt.y == curr_y && + hs1->left_op->next->pt.x <= hs2->left_op->pt.x) + hs1->left_op = hs1->left_op->next; + while (hs2->left_op->prev->pt.y == curr_y && + hs2->left_op->prev->pt.x <= hs1->left_op->pt.x) + hs2->left_op = hs2->left_op->prev; + HorzJoin join = HorzJoin( + DuplicateOp(hs1->left_op, true), + DuplicateOp(hs2->left_op, false)); + horz_join_list_.push_back(join); + } + else + { + while (hs1->left_op->prev->pt.y == curr_y && + hs1->left_op->prev->pt.x <= hs2->left_op->pt.x) + hs1->left_op = hs1->left_op->prev; + while (hs2->left_op->next->pt.y == curr_y && + hs2->left_op->next->pt.x <= hs1->left_op->pt.x) + hs2->left_op = hs2->left_op->next; + HorzJoin join = HorzJoin( + DuplicateOp(hs2->left_op, true), + DuplicateOp(hs1->left_op, false)); + horz_join_list_.push_back(join); + } + } + } + } + + void MoveSplits(OutRec* fromOr, OutRec* toOr) + { + if (!fromOr->splits) return; + if (!toOr->splits) toOr->splits = new OutRecList(); + OutRecList::iterator orIter = fromOr->splits->begin(); + for (; orIter != fromOr->splits->end(); ++orIter) + toOr->splits->push_back(*orIter); + fromOr->splits->clear(); + } + + + void ClipperBase::ProcessHorzJoins() + { + for (const HorzJoin& j : horz_join_list_) + { + OutRec* or1 = GetRealOutRec(j.op1->outrec); + OutRec* or2 = GetRealOutRec(j.op2->outrec); + + OutPt* op1b = j.op1->next; + OutPt* op2b = j.op2->prev; + j.op1->next = j.op2; + j.op2->prev = j.op1; + op1b->prev = op2b; + op2b->next = op1b; + + if (or1 == or2) // 'join' is really a split + { + or2 = NewOutRec(); + or2->pts = op1b; + FixOutRecPts(or2); + + //if or1->pts has moved to or2 then update or1->pts!! + if (or1->pts->outrec == or2) + { + or1->pts = j.op1; + or1->pts->outrec = or1; + } + + if (using_polytree_) //#498, #520, #584, D#576, #618 + { + if (Path1InsidePath2(or1->pts, or2->pts)) + { + //swap or1's & or2's pts + OutPt* tmp = or1->pts; + or1->pts = or2->pts; + or2->pts = tmp; + FixOutRecPts(or1); + FixOutRecPts(or2); + //or2 is now inside or1 + or2->owner = or1; + } + else if (Path1InsidePath2(or2->pts, or1->pts)) + { + or2->owner = or1; + } + else + or2->owner = or1->owner; + + if (!or1->splits) or1->splits = new OutRecList(); + or1->splits->push_back(or2); + } + else + or2->owner = or1; + } + else + { + or2->pts = nullptr; + if (using_polytree_) + { + SetOwner(or2, or1); + MoveSplits(or2, or1); //#618 + } + else + or2->owner = or1; + } + } + } + + void ClipperBase::DoIntersections(const int64_t top_y) + { + if (BuildIntersectList(top_y)) + { + ProcessIntersectList(); + intersect_nodes_.clear(); + } + } + + void ClipperBase::AddNewIntersectNode(Active& e1, Active& e2, int64_t top_y) + { + Point64 ip; + if (!GetSegmentIntersectPt(e1.bot, e1.top, e2.bot, e2.top, ip)) + ip = Point64(e1.curr_x, top_y); //parallel edges + + //rounding errors can occasionally place the calculated intersection + //point either below or above the scanbeam, so check and correct ... + if (ip.y > bot_y_ || ip.y < top_y) + { + double abs_dx1 = std::fabs(e1.dx); + double abs_dx2 = std::fabs(e2.dx); + if (abs_dx1 > 100 && abs_dx2 > 100) + { + if (abs_dx1 > abs_dx2) + ip = GetClosestPointOnSegment(ip, e1.bot, e1.top); + else + ip = GetClosestPointOnSegment(ip, e2.bot, e2.top); + } + else if (abs_dx1 > 100) + ip = GetClosestPointOnSegment(ip, e1.bot, e1.top); + else if (abs_dx2 > 100) + ip = GetClosestPointOnSegment(ip, e2.bot, e2.top); + else + { + if (ip.y < top_y) ip.y = top_y; + else ip.y = bot_y_; + if (abs_dx1 < abs_dx2) ip.x = TopX(e1, ip.y); + else ip.x = TopX(e2, ip.y); + } + } + intersect_nodes_.push_back(IntersectNode(&e1, &e2, ip)); + } + + bool ClipperBase::BuildIntersectList(const int64_t top_y) + { + if (!actives_ || !actives_->next_in_ael) return false; + + //Calculate edge positions at the top of the current scanbeam, and from this + //we will determine the intersections required to reach these new positions. + AdjustCurrXAndCopyToSEL(top_y); + //Find all edge intersections in the current scanbeam using a stable merge + //sort that ensures only adjacent edges are intersecting. Intersect info is + //stored in FIntersectList ready to be processed in ProcessIntersectList. + //Re merge sorts see https://stackoverflow.com/a/46319131/359538 + + Active* left = sel_, * right, * l_end, * r_end, * curr_base, * tmp; + + while (left && left->jump) + { + Active* prev_base = nullptr; + while (left && left->jump) + { + curr_base = left; + right = left->jump; + l_end = right; + r_end = right->jump; + left->jump = r_end; + while (left != l_end && right != r_end) + { + if (right->curr_x < left->curr_x) + { + tmp = right->prev_in_sel; + for (; ; ) + { + AddNewIntersectNode(*tmp, *right, top_y); + if (tmp == left) break; + tmp = tmp->prev_in_sel; + } + + tmp = right; + right = ExtractFromSEL(tmp); + l_end = right; + Insert1Before2InSEL(tmp, left); + if (left == curr_base) + { + curr_base = tmp; + curr_base->jump = r_end; + if (!prev_base) sel_ = curr_base; + else prev_base->jump = curr_base; + } + } + else left = left->next_in_sel; + } + prev_base = curr_base; + left = r_end; + } + left = sel_; + } + return intersect_nodes_.size() > 0; + } + + void ClipperBase::ProcessIntersectList() + { + //We now have a list of intersections required so that edges will be + //correctly positioned at the top of the scanbeam. However, it's important + //that edge intersections are processed from the bottom up, but it's also + //crucial that intersections only occur between adjacent edges. + + //First we do a quicksort so intersections proceed in a bottom up order ... + std::sort(intersect_nodes_.begin(), intersect_nodes_.end(), IntersectListSort); + //Now as we process these intersections, we must sometimes adjust the order + //to ensure that intersecting edges are always adjacent ... + + IntersectNodeList::iterator node_iter, node_iter2; + for (node_iter = intersect_nodes_.begin(); + node_iter != intersect_nodes_.end(); ++node_iter) + { + if (!EdgesAdjacentInAEL(*node_iter)) + { + node_iter2 = node_iter + 1; + while (!EdgesAdjacentInAEL(*node_iter2)) ++node_iter2; + std::swap(*node_iter, *node_iter2); + } + + IntersectNode& node = *node_iter; + IntersectEdges(*node.edge1, *node.edge2, node.pt); + SwapPositionsInAEL(*node.edge1, *node.edge2); + + node.edge1->curr_x = node.pt.x; + node.edge2->curr_x = node.pt.x; + CheckJoinLeft(*node.edge2, node.pt, true); + CheckJoinRight(*node.edge1, node.pt, true); + } + } + + void ClipperBase::SwapPositionsInAEL(Active& e1, Active& e2) + { + //preconditon: e1 must be immediately to the left of e2 + Active* next = e2.next_in_ael; + if (next) next->prev_in_ael = &e1; + Active* prev = e1.prev_in_ael; + if (prev) prev->next_in_ael = &e2; + e2.prev_in_ael = prev; + e2.next_in_ael = &e1; + e1.prev_in_ael = &e2; + e1.next_in_ael = next; + if (!e2.prev_in_ael) actives_ = &e2; + } + + inline OutPt* GetLastOp(const Active& hot_edge) + { + OutRec* outrec = hot_edge.outrec; + OutPt* result = outrec->pts; + if (&hot_edge != outrec->front_edge) + result = result->next; + return result; + } + + void ClipperBase::AddTrialHorzJoin(OutPt* op) + { + if (op->outrec->is_open) return; + horz_seg_list_.push_back(HorzSegment(op)); + } + + bool ClipperBase::ResetHorzDirection(const Active& horz, + const Vertex* max_vertex, int64_t& horz_left, int64_t& horz_right) + { + if (horz.bot.x == horz.top.x) + { + //the horizontal edge is going nowhere ... + horz_left = horz.curr_x; + horz_right = horz.curr_x; + Active* e = horz.next_in_ael; + while (e && e->vertex_top != max_vertex) e = e->next_in_ael; + return e != nullptr; + } + else if (horz.curr_x < horz.top.x) + { + horz_left = horz.curr_x; + horz_right = horz.top.x; + return true; + } + else + { + horz_left = horz.top.x; + horz_right = horz.curr_x; + return false; // right to left + } + } + + void ClipperBase::DoHorizontal(Active& horz) + /******************************************************************************* + * Notes: Horizontal edges (HEs) at scanline intersections (ie at the top or * + * bottom of a scanbeam) are processed as if layered.The order in which HEs * + * are processed doesn't matter. HEs intersect with the bottom vertices of * + * other HEs[#] and with non-horizontal edges [*]. Once these intersections * + * are completed, intermediate HEs are 'promoted' to the next edge in their * + * bounds, and they in turn may be intersected[%] by other HEs. * + * * + * eg: 3 horizontals at a scanline: / | / / * + * | / | (HE3)o ========%========== o * + * o ======= o(HE2) / | / / * + * o ============#=========*======*========#=========o (HE1) * + * / | / | / * + *******************************************************************************/ + { + Point64 pt; + bool horzIsOpen = IsOpen(horz); + int64_t y = horz.bot.y; + Vertex* vertex_max; + if (horzIsOpen) + vertex_max = GetCurrYMaximaVertex_Open(horz); + else + vertex_max = GetCurrYMaximaVertex(horz); + + //// remove 180 deg.spikes and also simplify + //// consecutive horizontals when PreserveCollinear = true + //if (!horzIsOpen && vertex_max != horz.vertex_top) + // TrimHorz(horz, PreserveCollinear); + + int64_t horz_left, horz_right; + bool is_left_to_right = + ResetHorzDirection(horz, vertex_max, horz_left, horz_right); + + if (IsHotEdge(horz)) + { +#ifdef USINGZ + OutPt* op = AddOutPt(horz, Point64(horz.curr_x, y, horz.bot.z)); +#else + OutPt* op = AddOutPt(horz, Point64(horz.curr_x, y)); +#endif + AddTrialHorzJoin(op); + } + + while (true) // loop through consec. horizontal edges + { + Active* e; + if (is_left_to_right) e = horz.next_in_ael; + else e = horz.prev_in_ael; + + while (e) + { + if (e->vertex_top == vertex_max) + { + if (IsHotEdge(horz) && IsJoined(*e)) + Split(*e, e->top); + + //if (IsHotEdge(horz) != IsHotEdge(*e)) + // DoError(undefined_error_i); + + if (IsHotEdge(horz)) + { + while (horz.vertex_top != vertex_max) + { + AddOutPt(horz, horz.top); + UpdateEdgeIntoAEL(&horz); + } + if (is_left_to_right) + AddLocalMaxPoly(horz, *e, horz.top); + else + AddLocalMaxPoly(*e, horz, horz.top); + } + DeleteFromAEL(*e); + DeleteFromAEL(horz); + return; + } + + //if horzEdge is a maxima, keep going until we reach + //its maxima pair, otherwise check for break conditions + if (vertex_max != horz.vertex_top || IsOpenEnd(horz)) + { + //otherwise stop when 'ae' is beyond the end of the horizontal line + if ((is_left_to_right && e->curr_x > horz_right) || + (!is_left_to_right && e->curr_x < horz_left)) break; + + if (e->curr_x == horz.top.x && !IsHorizontal(*e)) + { + pt = NextVertex(horz)->pt; + if (is_left_to_right) + { + //with open paths we'll only break once past horz's end + if (IsOpen(*e) && !IsSamePolyType(*e, horz) && !IsHotEdge(*e)) + { + if (TopX(*e, pt.y) > pt.x) break; + } + //otherwise we'll only break when horz's outslope is greater than e's + else if (TopX(*e, pt.y) >= pt.x) break; + } + else + { + if (IsOpen(*e) && !IsSamePolyType(*e, horz) && !IsHotEdge(*e)) + { + if (TopX(*e, pt.y) < pt.x) break; + } + else if (TopX(*e, pt.y) <= pt.x) break; + } + } + } + + pt = Point64(e->curr_x, horz.bot.y); + if (is_left_to_right) + { + IntersectEdges(horz, *e, pt); + SwapPositionsInAEL(horz, *e); + CheckJoinLeft(*e, pt); + horz.curr_x = e->curr_x; + e = horz.next_in_ael; + } + else + { + IntersectEdges(*e, horz, pt); + SwapPositionsInAEL(*e, horz); + CheckJoinRight(*e, pt); + horz.curr_x = e->curr_x; + e = horz.prev_in_ael; + } + + if (horz.outrec) + { + //nb: The outrec containining the op returned by IntersectEdges + //above may no longer be associated with horzEdge. + AddTrialHorzJoin(GetLastOp(horz)); + } + } + + //check if we've finished with (consecutive) horizontals ... + if (horzIsOpen && IsOpenEnd(horz)) // ie open at top + { + if (IsHotEdge(horz)) + { + AddOutPt(horz, horz.top); + if (IsFront(horz)) + horz.outrec->front_edge = nullptr; + else + horz.outrec->back_edge = nullptr; + horz.outrec = nullptr; + } + DeleteFromAEL(horz); + return; + } + else if (NextVertex(horz)->pt.y != horz.top.y) + break; + + //still more horizontals in bound to process ... + if (IsHotEdge(horz)) + AddOutPt(horz, horz.top); + UpdateEdgeIntoAEL(&horz); + + is_left_to_right = + ResetHorzDirection(horz, vertex_max, horz_left, horz_right); + } + + if (IsHotEdge(horz)) + { + OutPt* op = AddOutPt(horz, horz.top); + AddTrialHorzJoin(op); + } + + UpdateEdgeIntoAEL(&horz); // end of an intermediate horiz. + } + + void ClipperBase::DoTopOfScanbeam(const int64_t y) + { + sel_ = nullptr; // sel_ is reused to flag horizontals (see PushHorz below) + Active* e = actives_; + while (e) + { + //nb: 'e' will never be horizontal here + if (e->top.y == y) + { + e->curr_x = e->top.x; + if (IsMaxima(*e)) + { + e = DoMaxima(*e); // TOP OF BOUND (MAXIMA) + continue; + } + else + { + //INTERMEDIATE VERTEX ... + if (IsHotEdge(*e)) AddOutPt(*e, e->top); + UpdateEdgeIntoAEL(e); + if (IsHorizontal(*e)) + PushHorz(*e); // horizontals are processed later + } + } + else // i.e. not the top of the edge + e->curr_x = TopX(*e, y); + + e = e->next_in_ael; + } + } + + + Active* ClipperBase::DoMaxima(Active& e) + { + Active* next_e, * prev_e, * max_pair; + prev_e = e.prev_in_ael; + next_e = e.next_in_ael; + if (IsOpenEnd(e)) + { + if (IsHotEdge(e)) AddOutPt(e, e.top); + if (!IsHorizontal(e)) + { + if (IsHotEdge(e)) + { + if (IsFront(e)) + e.outrec->front_edge = nullptr; + else + e.outrec->back_edge = nullptr; + e.outrec = nullptr; + } + DeleteFromAEL(e); + } + return next_e; + } + + max_pair = GetMaximaPair(e); + if (!max_pair) return next_e; // eMaxPair is horizontal + + if (IsJoined(e)) Split(e, e.top); + if (IsJoined(*max_pair)) Split(*max_pair, max_pair->top); + + //only non-horizontal maxima here. + //process any edges between maxima pair ... + while (next_e != max_pair) + { + IntersectEdges(e, *next_e, e.top); + SwapPositionsInAEL(e, *next_e); + next_e = e.next_in_ael; + } + + if (IsOpen(e)) + { + if (IsHotEdge(e)) + AddLocalMaxPoly(e, *max_pair, e.top); + DeleteFromAEL(*max_pair); + DeleteFromAEL(e); + return (prev_e ? prev_e->next_in_ael : actives_); + } + + // e.next_in_ael== max_pair ... + if (IsHotEdge(e)) + AddLocalMaxPoly(e, *max_pair, e.top); + + DeleteFromAEL(e); + DeleteFromAEL(*max_pair); + return (prev_e ? prev_e->next_in_ael : actives_); + } + + void ClipperBase::Split(Active& e, const Point64& pt) + { + if (e.join_with == JoinWith::Right) + { + e.join_with = JoinWith::NoJoin; + e.next_in_ael->join_with = JoinWith::NoJoin; + AddLocalMinPoly(e, *e.next_in_ael, pt, true); + } + else + { + e.join_with = JoinWith::NoJoin; + e.prev_in_ael->join_with = JoinWith::NoJoin; + AddLocalMinPoly(*e.prev_in_ael, e, pt, true); + } + } + + void ClipperBase::CheckJoinLeft(Active& e, + const Point64& pt, bool check_curr_x) + { + Active* prev = e.prev_in_ael; + if (!prev || + !IsHotEdge(e) || !IsHotEdge(*prev) || + IsHorizontal(e) || IsHorizontal(*prev) || + IsOpen(e) || IsOpen(*prev) ) return; + if ((pt.y < e.top.y + 2 || pt.y < prev->top.y + 2) && + ((e.bot.y > pt.y) || (prev->bot.y > pt.y))) return; // avoid trivial joins + + if (check_curr_x) + { + if (PerpendicDistFromLineSqrd(pt, prev->bot, prev->top) > 0.25) return; + } + else if (e.curr_x != prev->curr_x) return; + if (!IsCollinear(e.top, pt, prev->top)) return; + + if (e.outrec->idx == prev->outrec->idx) + AddLocalMaxPoly(*prev, e, pt); + else if (e.outrec->idx < prev->outrec->idx) + JoinOutrecPaths(e, *prev); + else + JoinOutrecPaths(*prev, e); + prev->join_with = JoinWith::Right; + e.join_with = JoinWith::Left; + } + + void ClipperBase::CheckJoinRight(Active& e, + const Point64& pt, bool check_curr_x) + { + Active* next = e.next_in_ael; + if (!next || + !IsHotEdge(e) || !IsHotEdge(*next) || + IsHorizontal(e) || IsHorizontal(*next) || + IsOpen(e) || IsOpen(*next)) return; + if ((pt.y < e.top.y +2 || pt.y < next->top.y +2) && + ((e.bot.y > pt.y) || (next->bot.y > pt.y))) return; // avoid trivial joins + + if (check_curr_x) + { + if (PerpendicDistFromLineSqrd(pt, next->bot, next->top) > 0.35) return; + } + else if (e.curr_x != next->curr_x) return; + if (!IsCollinear(e.top, pt, next->top)) return; + + if (e.outrec->idx == next->outrec->idx) + AddLocalMaxPoly(e, *next, pt); + else if (e.outrec->idx < next->outrec->idx) + JoinOutrecPaths(e, *next); + else + JoinOutrecPaths(*next, e); + + e.join_with = JoinWith::Right; + next->join_with = JoinWith::Left; + } + + inline bool GetHorzExtendedHorzSeg(OutPt*& op, OutPt*& op2) + { + OutRec* outrec = GetRealOutRec(op->outrec); + op2 = op; + if (outrec->front_edge) + { + while (op->prev != outrec->pts && + op->prev->pt.y == op->pt.y) op = op->prev; + while (op2 != outrec->pts && + op2->next->pt.y == op2->pt.y) op2 = op2->next; + return op2 != op; + } + else + { + while (op->prev != op2 && op->prev->pt.y == op->pt.y) + op = op->prev; + while (op2->next != op && op2->next->pt.y == op2->pt.y) + op2 = op2->next; + return op2 != op && op2->next != op; + } + } + + bool BuildPath64(OutPt* op, bool reverse, bool isOpen, Path64& path) + { + if (!op || op->next == op || (!isOpen && op->next == op->prev)) + return false; + + path.resize(0); + Point64 lastPt; + OutPt* op2; + if (reverse) + { + lastPt = op->pt; + op2 = op->prev; + } + else + { + op = op->next; + lastPt = op->pt; + op2 = op->next; + } + path.push_back(lastPt); + + while (op2 != op) + { + if (op2->pt != lastPt) + { + lastPt = op2->pt; + path.push_back(lastPt); + } + if (reverse) + op2 = op2->prev; + else + op2 = op2->next; + } + + if (!isOpen && path.size() == 3 && IsVerySmallTriangle(*op2)) return false; + else return true; + } + + bool ClipperBase::CheckBounds(OutRec* outrec) + { + if (!outrec->pts) return false; + if (!outrec->bounds.IsEmpty()) return true; + CleanCollinear(outrec); + if (!outrec->pts || + !BuildPath64(outrec->pts, reverse_solution_, false, outrec->path)){ + return false;} + outrec->bounds = GetBounds(outrec->path); + return true; + } + + bool ClipperBase::CheckSplitOwner(OutRec* outrec, OutRecList* splits) + { + for (auto split : *splits) + { + split = GetRealOutRec(split); + if(!split || split == outrec || split->recursive_split == outrec) continue; + split->recursive_split = outrec; // prevent infinite loops + + if (split->splits && CheckSplitOwner(outrec, split->splits)) + return true; + else if (CheckBounds(split) && + IsValidOwner(outrec, split) && + split->bounds.Contains(outrec->bounds) && + Path1InsidePath2(outrec->pts, split->pts)) + { + outrec->owner = split; //found in split + return true; + } + } + return false; + } + + void ClipperBase::RecursiveCheckOwners(OutRec* outrec, PolyPath* polypath) + { + // pre-condition: outrec will have valid bounds + // post-condition: if a valid path, outrec will have a polypath + + if (outrec->polypath || outrec->bounds.IsEmpty()) return; + + while (outrec->owner) + { + if (outrec->owner->splits && CheckSplitOwner(outrec, outrec->owner->splits)) break; + if (outrec->owner->pts && CheckBounds(outrec->owner) && + outrec->owner->bounds.Contains(outrec->bounds) && + Path1InsidePath2(outrec->pts, outrec->owner->pts)) break; + outrec->owner = outrec->owner->owner; + } + + if (outrec->owner) + { + if (!outrec->owner->polypath) + RecursiveCheckOwners(outrec->owner, polypath); + outrec->polypath = outrec->owner->polypath->AddChild(outrec->path); + } + else + outrec->polypath = polypath->AddChild(outrec->path); + } + + void Clipper64::BuildPaths64(Paths64& solutionClosed, Paths64* solutionOpen) + { + solutionClosed.resize(0); + solutionClosed.reserve(outrec_list_.size()); + if (solutionOpen) + { + solutionOpen->resize(0); + solutionOpen->reserve(outrec_list_.size()); + } + + // nb: outrec_list_.size() may change in the following + // while loop because polygons may be split during + // calls to CleanCollinear which calls FixSelfIntersects + for (size_t i = 0; i < outrec_list_.size(); ++i) + { + OutRec* outrec = outrec_list_[i]; + if (outrec->pts == nullptr) continue; + + Path64 path; + if (solutionOpen && outrec->is_open) + { + if (BuildPath64(outrec->pts, reverse_solution_, true, path)) + solutionOpen->emplace_back(std::move(path)); + } + else + { + // nb: CleanCollinear can add to outrec_list_ + CleanCollinear(outrec); + //closed paths should always return a Positive orientation + if (BuildPath64(outrec->pts, reverse_solution_, false, path)) + solutionClosed.emplace_back(std::move(path)); + } + } + } + + void Clipper64::BuildTree64(PolyPath64& polytree, Paths64& open_paths) + { + polytree.Clear(); + open_paths.resize(0); + if (has_open_paths_) + open_paths.reserve(outrec_list_.size()); + + // outrec_list_.size() is not static here because + // CheckBounds below can indirectly add additional + // OutRec (via FixOutRecPts & CleanCollinear) + for (size_t i = 0; i < outrec_list_.size(); ++i) + { + OutRec* outrec = outrec_list_[i]; + if (!outrec || !outrec->pts) continue; + if (outrec->is_open) + { + Path64 path; + if (BuildPath64(outrec->pts, reverse_solution_, true, path)) + open_paths.push_back(path); + continue; + } + + if (CheckBounds(outrec)) + RecursiveCheckOwners(outrec, &polytree); + } + } + + bool BuildPathD(OutPt* op, bool reverse, bool isOpen, PathD& path, double inv_scale) + { + if (!op || op->next == op || (!isOpen && op->next == op->prev)) + return false; + + path.resize(0); + Point64 lastPt; + OutPt* op2; + if (reverse) + { + lastPt = op->pt; + op2 = op->prev; + } + else + { + op = op->next; + lastPt = op->pt; + op2 = op->next; + } +#ifdef USINGZ + path.push_back(PointD(lastPt.x * inv_scale, lastPt.y * inv_scale, lastPt.z)); +#else + path.push_back(PointD(lastPt.x * inv_scale, lastPt.y * inv_scale)); +#endif + + while (op2 != op) + { + if (op2->pt != lastPt) + { + lastPt = op2->pt; +#ifdef USINGZ + path.push_back(PointD(lastPt.x * inv_scale, lastPt.y * inv_scale, lastPt.z)); +#else + path.push_back(PointD(lastPt.x * inv_scale, lastPt.y * inv_scale)); +#endif + + } + if (reverse) + op2 = op2->prev; + else + op2 = op2->next; + } + if (path.size() == 3 && IsVerySmallTriangle(*op2)) return false; + return true; + } + + void ClipperD::BuildPathsD(PathsD& solutionClosed, PathsD* solutionOpen) + { + solutionClosed.resize(0); + solutionClosed.reserve(outrec_list_.size()); + if (solutionOpen) + { + solutionOpen->resize(0); + solutionOpen->reserve(outrec_list_.size()); + } + + // outrec_list_.size() is not static here because + // CleanCollinear below can indirectly add additional + // OutRec (via FixOutRecPts) + for (std::size_t i = 0; i < outrec_list_.size(); ++i) + { + OutRec* outrec = outrec_list_[i]; + if (outrec->pts == nullptr) continue; + + PathD path; + if (solutionOpen && outrec->is_open) + { + if (BuildPathD(outrec->pts, reverse_solution_, true, path, invScale_)) + solutionOpen->emplace_back(std::move(path)); + } + else + { + CleanCollinear(outrec); + //closed paths should always return a Positive orientation + if (BuildPathD(outrec->pts, reverse_solution_, false, path, invScale_)) + solutionClosed.emplace_back(std::move(path)); + } + } + } + + void ClipperD::BuildTreeD(PolyPathD& polytree, PathsD& open_paths) + { + polytree.Clear(); + open_paths.resize(0); + if (has_open_paths_) + open_paths.reserve(outrec_list_.size()); + + // outrec_list_.size() is not static here because + // BuildPathD below can indirectly add additional OutRec //#607 + for (size_t i = 0; i < outrec_list_.size(); ++i) + { + OutRec* outrec = outrec_list_[i]; + if (!outrec || !outrec->pts) continue; + if (outrec->is_open) + { + PathD path; + if (BuildPathD(outrec->pts, reverse_solution_, true, path, invScale_)) + open_paths.push_back(path); + continue; + } + + if (CheckBounds(outrec)) + RecursiveCheckOwners(outrec, &polytree); + } + } + +} // namespace clipper2lib From 219f47e51cf868030b1cb8931538c48aeeab7f2e Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 22 Nov 2024 21:14:39 -0800 Subject: [PATCH 13/24] Compiles, but does not actually seem to clip. Hmm. --- Makefile | 6 ++-- clip.cpp | 89 +++++++++++++++++++++----------------------------------- 2 files changed, 36 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index c336b90c..5fd80631 100644 --- a/Makefile +++ b/Makefile @@ -68,16 +68,16 @@ tippecanoe-enumerate: enumerate.o tippecanoe-decode: decode.o projection.o mvt.o write_json.o text.o jsonpull/jsonpull.o dirtiles.o pmtiles_file.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -tile-join: tile-join.o projection.o mbtiles.o mvt.o memfile.o dirtiles.o jsonpull/jsonpull.o text.o evaluator.o csv.o write_json.o pmtiles_file.o clip.o attribute.o thread.o read_json.o +tile-join: tile-join.o projection.o mbtiles.o mvt.o memfile.o dirtiles.o jsonpull/jsonpull.o text.o evaluator.o csv.o write_json.o pmtiles_file.o clip.o attribute.o thread.o read_json.o clipper2/src/clipper.engine.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread tippecanoe-json-tool: jsontool.o jsonpull/jsonpull.o csv.o text.o geojson-loop.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread -unit: unit.o text.o sort.o mvt.o projection.o clip.o attribute.o jsonpull/jsonpull.o evaluator.o read_json.o +unit: unit.o text.o sort.o mvt.o projection.o clip.o attribute.o jsonpull/jsonpull.o evaluator.o read_json.o clipper2/src/clipper.engine.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread -tippecanoe-overzoom: overzoom.o mvt.o clip.o evaluator.o jsonpull/jsonpull.o text.o attribute.o read_json.o projection.o read_json.o +tippecanoe-overzoom: overzoom.o mvt.o clip.o evaluator.o jsonpull/jsonpull.o text.o attribute.o read_json.o projection.o read_json.o clipper2/src/clipper.engine.o $(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread -include $(wildcard *.d) diff --git a/clip.cpp b/clip.cpp index 4b87ee25..7f63441d 100644 --- a/clip.cpp +++ b/clip.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "geometry.hpp" #include "errors.hpp" @@ -1934,73 +1935,49 @@ mvt_tile assign_to_bins(mvt_tile &features, return ret; } -drawvec clip_lines(drawvec const &geom, drawvec const ®ion) { - std::vector events; - - if (region.size() == 0) { - return drawvec(); - } - - // Index region segments - for (size_t i = 1; i < region.size(); i++) { - if (region[i].op == VT_LINETO) { - long long xmin = std::min(region[i - 1].x, region[i].x); - long long ymin = std::min(region[i - 1].y, region[i].y); - long long xmax = std::max(region[i - 1].x, region[i].x); - long long ymax = std::max(region[i - 1].y, region[i].y); - unsigned long long start, end; +static Clipper2Lib::Paths64 geom_to_clipper(drawvec const &geom) { + Clipper2Lib::Paths64 subject; - get_quadkey_bounds(xmin, ymin, xmax, ymax, &start, &end); - events.emplace_back(start, index_event::ENTER, i, 0, xmin, ymin, xmax, ymax); - events.emplace_back(end, index_event::EXIT, i, 0, xmin, ymin, xmax, ymax); + for (size_t i = 0; i < geom.size(); i++) { + if (geom[i].op == VT_MOVETO) { + Clipper2Lib::Path64 path({{geom[i].x, geom[i].y}}); + size_t j; + for (j = i + 1; j < geom.size(); j++) { + if (geom[j].op != VT_LINETO) { + break; + } + path.emplace_back(geom[j].x, geom[j].y); + } + subject.push_back(path); } } - // Index linestring segments - for (size_t i = 1; i < geom.size(); i++) { - if (geom[i].op == VT_LINETO) { - long long xmin = std::min(geom[i - 1].x, geom[i].x); - long long ymin = std::min(geom[i - 1].y, geom[i].y); - long long xmax = std::max(geom[i - 1].x, geom[i].x); - long long ymax = std::max(geom[i - 1].y, geom[i].y); - unsigned long long start, end; + return subject; +} - get_quadkey_bounds(xmin, ymin, xmax, ymax, &start, &end); - events.emplace_back(start, index_event::CHECK, i, 0, xmin, ymin, xmax, ymax); +static void clipper_to_geom(Clipper2Lib::Paths64 const &geom, drawvec &out) { + for (auto const &ring : geom) { + for (size_t i = 0; i < ring.size(); i++) { + out.emplace_back(i == 0 ? VT_MOVETO : VT_LINETO, ring[i].x, ring[i].y); } } +} - std::sort(events.begin(), events.end()); - std::set active; +drawvec clip_lines(drawvec const &geom, drawvec const ®ion) { + Clipper2Lib::Paths64 subject = geom_to_clipper(geom); + Clipper2Lib::Paths64 clip = geom_to_clipper(region); - for (auto &e : events) { - if (e.kind == index_event::ENTER) { - active_bin a(e.layer, e.feature); - a.xmin = e.xmin; - a.ymin = e.ymin; - a.xmax = e.xmax; - a.ymax = e.ymax; + Clipper2Lib::Clipper64 clipper; + clipper.AddOpenSubject(subject); + clipper.AddClip(clip); - active.insert(std::move(a)); - } else if (e.kind == index_event::CHECK) { - for (auto const &a : active) { - if (bbox_intersects(e.xmin, e.ymin, e.xmax, e.ymax, - a.xmin, a.ymin, a.xmax, a.ymax)) { - // compare - } - } - } else /* EXIT */ { - auto const &found = active.find({e.layer, e.feature}); - if (found != active.end()) { - active.erase(found); - } else { - fprintf(stderr, "event mismatch: can't happen\n"); - exit(EXIT_IMPOSSIBLE); - } - } - } + Clipper2Lib::Paths64 solution, open_solution; + clipper.Execute(Clipper2Lib::ClipType::Intersection, Clipper2Lib::FillRule::Positive, solution, open_solution); - return drawvec(); + drawvec out; + clipper_to_geom(solution, out); + clipper_to_geom(open_solution, out); + return out; } std::string overzoom(std::vector const &tiles, int nz, int nx, int ny, From 21f63a756f89db4b5ba09fb15655db2026c28961 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 22 Nov 2024 21:21:22 -0800 Subject: [PATCH 14/24] Oh, it helps if I actually call the function --- clip.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clip.cpp b/clip.cpp index 7f63441d..c162a788 100644 --- a/clip.cpp +++ b/clip.cpp @@ -2065,6 +2065,9 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int } } else if (t == VT_LINE) { geom = clip_lines(geom, c.minx, c.miny, c.maxx, c.maxy); + if (c.dv.size() > 0 && geom.size() > 0) { + geom = clip_lines(geom, c.dv); + } } else if (t == VT_POINT) { geom = clip_point(geom, c.minx, c.miny, c.maxx, c.maxy); if (c.dv.size() > 0 && geom.size() > 0) { From caa91203b7c5001700e74be878ea3c23c42a959b Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Mon, 25 Nov 2024 15:43:51 -0800 Subject: [PATCH 15/24] Add clipping tests --- Makefile | 15 + tests/pbf/countries-1-1-0-clip.json | 35 + tests/pbf/countries-1-1-0.pbf | Bin 0 -> 50553 bytes tests/pbf/places-1-1-0-clip.json | 211 +++ tests/pbf/places-1-1-0.pbf | Bin 0 -> 45352 bytes tests/pbf/roads-1-1-0-clip.json | 1993 +++++++++++++++++++++++++++ tests/pbf/roads-1-1-0.pbf | Bin 0 -> 267536 bytes 7 files changed, 2254 insertions(+) create mode 100644 tests/pbf/countries-1-1-0-clip.json create mode 100644 tests/pbf/countries-1-1-0.pbf create mode 100644 tests/pbf/places-1-1-0-clip.json create mode 100644 tests/pbf/places-1-1-0.pbf create mode 100644 tests/pbf/roads-1-1-0-clip.json create mode 100644 tests/pbf/roads-1-1-0.pbf diff --git a/Makefile b/Makefile index 5fd80631..c1994049 100644 --- a/Makefile +++ b/Makefile @@ -404,6 +404,21 @@ overzoom-test: tippecanoe-overzoom # Verify fix for crash ./tippecanoe-overzoom '-o' tests/10188-crash/out.pbf '-t' '3/2/2' '--assign-to-bins' 'tests/10188-crash/bins.json' '--bin-by-id-list' 'felt:bin_features' '-b5' 'tests/10188-crash/2-0-0.pbf' '2/0/0' rm tests/10188-crash/out.pbf + # Polygon clipping + ./tippecanoe-overzoom -o tests/pbf/countries-1-1-0-clip.pbf --clip-polygon "`cat tests/pbf/region.json`" tests/pbf/countries-1-1-0.pbf 1/1/0 1/1/0 + ./tippecanoe-decode tests/pbf/countries-1-1-0-clip.pbf 1 1 0 > tests/pbf/countries-1-1-0-clip.json.check + cmp tests/pbf/countries-1-1-0-clip.json.check tests/pbf/countries-1-1-0-clip.json + rm tests/pbf/countries-1-1-0-clip.pbf tests/pbf/countries-1-1-0-clip.json.check + # LineString clipping + ./tippecanoe-overzoom -o tests/pbf/roads-1-1-0-clip.pbf --clip-polygon "`cat tests/pbf/region.json`" tests/pbf/roads-1-1-0.pbf 1/1/0 1/1/0 + ./tippecanoe-decode tests/pbf/roads-1-1-0-clip.pbf 1 1 0 > tests/pbf/roads-1-1-0-clip.json.check + cmp tests/pbf/roads-1-1-0-clip.json.check tests/pbf/roads-1-1-0-clip.json + rm tests/pbf/roads-1-1-0-clip.pbf tests/pbf/roads-1-1-0-clip.json.check + # Point clipping + ./tippecanoe-overzoom -o tests/pbf/places-1-1-0-clip.pbf --clip-polygon "`cat tests/pbf/region.json`" tests/pbf/places-1-1-0.pbf 1/1/0 1/1/0 + ./tippecanoe-decode tests/pbf/places-1-1-0-clip.pbf 1 1 0 > tests/pbf/places-1-1-0-clip.json.check + cmp tests/pbf/places-1-1-0-clip.json.check tests/pbf/places-1-1-0-clip.json + rm tests/pbf/places-1-1-0-clip.pbf tests/pbf/places-1-1-0-clip.json.check join-test: tippecanoe tippecanoe-decode tile-join ./tippecanoe -q -f -z12 -o tests/join-population/tabblock_06001420.mbtiles -YALAND10:'Land area' -L'{"file": "tests/join-population/tabblock_06001420.json", "description": "population"}' diff --git a/tests/pbf/countries-1-1-0-clip.json b/tests/pbf/countries-1-1-0-clip.json new file mode 100644 index 00000000..c0b59155 --- /dev/null +++ b/tests/pbf/countries-1-1-0-clip.json @@ -0,0 +1,35 @@ +{ "type": "FeatureCollection", "properties": { "zoom": 1, "x": 1, "y": 0 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "ne_10m_admin_0_countries", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "NAME": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 4.790039, 49.979488 ], [ 4.790039, 49.979488 ], [ 4.877930, 49.922935 ], [ 4.833984, 49.781264 ], [ 4.965820, 49.809632 ], [ 5.141602, 49.696062 ], [ 5.273438, 49.696062 ], [ 5.273438, 49.610710 ], [ 5.361328, 49.639177 ], [ 5.449219, 49.496675 ], [ 5.800781, 49.553726 ], [ 5.800781, 49.496675 ], [ 5.976562, 49.439557 ], [ 6.064453, 49.439557 ], [ 6.108398, 49.496675 ], [ 6.416016, 49.468124 ], [ 6.591797, 49.353756 ], [ 6.547852, 49.325122 ], [ 6.723633, 49.210420 ], [ 6.723633, 49.152970 ], [ 6.855469, 49.152970 ], [ 6.811523, 49.210420 ], [ 6.943359, 49.210420 ], [ 7.031250, 49.181703 ], [ 7.031250, 49.095452 ], [ 7.075195, 49.152970 ], [ 7.294922, 49.095452 ], [ 7.426758, 49.181703 ], [ 7.646484, 49.037868 ], [ 7.910156, 49.037868 ], [ 8.217773, 48.951366 ], [ 7.866211, 48.661943 ], [ 7.822266, 48.516604 ], [ 7.734375, 48.458352 ], [ 7.690430, 48.224673 ], [ 7.558594, 48.107431 ], [ 7.602539, 47.901614 ], [ 7.514648, 47.665387 ], [ 7.602539, 47.576526 ], [ 7.470703, 47.546872 ], [ 7.514648, 47.517201 ], [ 7.426758, 47.487513 ], [ 7.426758, 47.428087 ], [ 6.987305, 47.487513 ], [ 6.987305, 47.428087 ], [ 6.855469, 47.368594 ], [ 7.031250, 47.368594 ], [ 7.031250, 47.309034 ], [ 6.855469, 47.159840 ], [ 6.723633, 47.129951 ], [ 6.767578, 47.100045 ], [ 6.679688, 47.070122 ], [ 6.679688, 47.010226 ], [ 6.416016, 46.920255 ], [ 6.416016, 46.739861 ], [ 6.108398, 46.589069 ], [ 6.152344, 46.558860 ], [ 6.064453, 46.407564 ], [ 6.152344, 46.346928 ], [ 6.108398, 46.255847 ], [ 5.976562, 46.225453 ], [ 5.976562, 46.134170 ], [ 6.108398, 46.134170 ], [ 6.284180, 46.225453 ], [ 6.196289, 46.316584 ], [ 6.284180, 46.407564 ], [ 6.547852, 46.468133 ], [ 6.767578, 46.437857 ], [ 6.767578, 46.134170 ], [ 6.855469, 46.134170 ], [ 6.855469, 46.042736 ], [ 7.031250, 45.951150 ], [ 6.987305, 45.859412 ], [ 6.855469, 45.859412 ], [ 6.767578, 45.767523 ], [ 6.899414, 45.614037 ], [ 4.965820, 45.828799 ], [ 3.383789, 47.338823 ], [ 4.218750, 49.922935 ], [ 4.350586, 49.922935 ], [ 4.482422, 49.922935 ], [ 4.614258, 49.979488 ], [ 4.790039, 49.979488 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Belgium" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 5.932617, 50.148746 ], [ 5.888672, 50.120578 ], [ 5.712891, 49.894634 ], [ 5.712891, 49.809632 ], [ 5.888672, 49.667628 ], [ 5.844727, 49.553726 ], [ 5.625000, 49.553726 ], [ 5.449219, 49.496675 ], [ 5.361328, 49.639177 ], [ 5.273438, 49.610710 ], [ 5.273438, 49.696062 ], [ 5.141602, 49.696062 ], [ 4.965820, 49.809632 ], [ 4.833984, 49.781264 ], [ 4.877930, 49.922935 ], [ 4.790039, 49.979488 ], [ 4.790039, 49.979488 ], [ 5.932617, 50.148746 ] ] ], [ [ [ 4.614258, 49.979488 ], [ 4.482422, 49.922935 ], [ 4.350586, 49.922935 ], [ 4.614258, 49.979488 ] ] ], [ [ [ 6.108398, 50.148746 ], [ 6.108398, 50.120578 ], [ 6.020508, 50.148746 ], [ 6.108398, 50.148746 ] ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Luxembourg" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 6.064453, 50.148746 ], [ 6.108398, 50.148746 ], [ 6.108398, 50.007739 ], [ 6.240234, 49.866317 ], [ 6.503906, 49.809632 ], [ 6.503906, 49.696062 ], [ 6.416016, 49.667628 ], [ 6.328125, 49.468124 ], [ 6.108398, 49.496675 ], [ 6.064453, 49.439557 ], [ 5.976562, 49.439557 ], [ 5.800781, 49.496675 ], [ 5.888672, 49.667628 ], [ 5.800781, 49.724479 ], [ 5.712891, 49.894634 ], [ 5.888672, 50.120578 ], [ 5.932617, 50.148746 ], [ 6.064453, 50.148746 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Liechtenstein" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 9.492188, 47.249407 ], [ 9.624023, 47.129951 ], [ 9.580078, 47.040182 ], [ 9.492188, 47.070122 ], [ 9.492188, 47.249407 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Switzerland" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 8.569336, 47.813155 ], [ 8.613281, 47.754098 ], [ 8.701172, 47.754098 ], [ 8.701172, 47.694974 ], [ 8.789062, 47.724545 ], [ 8.876953, 47.694974 ], [ 8.833008, 47.665387 ], [ 9.228516, 47.665387 ], [ 9.667969, 47.457809 ], [ 9.492188, 47.249407 ], [ 9.492188, 47.070122 ], [ 9.667969, 47.040182 ], [ 8.525391, 46.164614 ], [ 8.437500, 46.225453 ], [ 8.437500, 46.437857 ], [ 8.305664, 46.437857 ], [ 8.305664, 46.377254 ], [ 8.173828, 46.286224 ], [ 8.085938, 46.286224 ], [ 8.129883, 46.134170 ], [ 7.998047, 46.073231 ], [ 7.998047, 45.981695 ], [ 7.866211, 45.981695 ], [ 7.866211, 45.920587 ], [ 7.514648, 45.981695 ], [ 7.250977, 45.890008 ], [ 7.075195, 45.890008 ], [ 6.855469, 46.042736 ], [ 6.855469, 46.134170 ], [ 6.767578, 46.134170 ], [ 6.767578, 46.437857 ], [ 6.591797, 46.468133 ], [ 6.284180, 46.407564 ], [ 6.196289, 46.316584 ], [ 6.284180, 46.225453 ], [ 6.108398, 46.134170 ], [ 5.976562, 46.134170 ], [ 5.976562, 46.225453 ], [ 6.108398, 46.255847 ], [ 6.152344, 46.346928 ], [ 6.064453, 46.407564 ], [ 6.152344, 46.558860 ], [ 6.108398, 46.589069 ], [ 6.416016, 46.739861 ], [ 6.416016, 46.920255 ], [ 6.679688, 47.010226 ], [ 6.679688, 47.070122 ], [ 6.767578, 47.100045 ], [ 6.723633, 47.129951 ], [ 6.855469, 47.159840 ], [ 7.031250, 47.309034 ], [ 7.031250, 47.368594 ], [ 6.855469, 47.368594 ], [ 6.987305, 47.428087 ], [ 6.987305, 47.487513 ], [ 7.426758, 47.428087 ], [ 7.426758, 47.487513 ], [ 7.514648, 47.517201 ], [ 7.470703, 47.546872 ], [ 7.646484, 47.606163 ], [ 7.646484, 47.546872 ], [ 7.778320, 47.546872 ], [ 7.822266, 47.606163 ], [ 7.910156, 47.546872 ], [ 8.041992, 47.546872 ], [ 8.217773, 47.635784 ], [ 8.305664, 47.576526 ], [ 8.437500, 47.576526 ], [ 8.525391, 47.635784 ], [ 8.569336, 47.576526 ], [ 8.613281, 47.665387 ], [ 8.437500, 47.635784 ], [ 8.393555, 47.694974 ], [ 8.569336, 47.813155 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Czechia" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 16.347656, 50.652943 ], [ 16.435547, 50.569283 ], [ 16.347656, 50.485474 ], [ 16.171875, 50.429518 ], [ 16.435547, 50.317408 ], [ 16.567383, 50.120578 ], [ 16.655273, 50.092393 ], [ 16.962891, 50.233152 ], [ 17.006836, 50.205033 ], [ 17.006836, 50.289339 ], [ 16.918945, 50.317408 ], [ 16.875000, 50.429518 ], [ 17.094727, 50.401515 ], [ 17.226562, 50.317408 ], [ 17.358398, 50.317408 ], [ 17.314453, 50.261254 ], [ 17.402344, 50.233152 ], [ 17.666016, 50.261254 ], [ 17.709961, 50.317408 ], [ 17.753906, 50.205033 ], [ 17.578125, 50.176898 ], [ 17.622070, 50.092393 ], [ 17.753906, 50.092393 ], [ 17.709961, 50.064192 ], [ 17.841797, 49.979488 ], [ 18.017578, 50.035974 ], [ 18.281250, 49.951220 ], [ 18.281250, 49.894634 ], [ 18.544922, 49.922935 ], [ 18.544922, 49.809632 ], [ 18.632812, 49.696062 ], [ 18.808594, 49.667628 ], [ 18.852539, 49.496675 ], [ 18.544922, 49.496675 ], [ 18.457031, 49.382373 ], [ 18.369141, 49.382373 ], [ 18.369141, 49.325122 ], [ 18.149414, 49.267805 ], [ 18.105469, 49.066668 ], [ 17.929688, 49.009051 ], [ 17.885742, 48.922499 ], [ 17.797852, 48.922499 ], [ 17.753906, 48.864715 ], [ 17.534180, 48.806863 ], [ 17.358398, 48.806863 ], [ 17.270508, 48.864715 ], [ 17.094727, 48.835797 ], [ 16.962891, 48.603858 ], [ 16.875000, 48.719961 ], [ 16.655273, 48.719961 ], [ 16.655273, 48.777913 ], [ 16.567383, 48.806863 ], [ 16.435547, 48.806863 ], [ 16.391602, 48.719961 ], [ 16.040039, 48.748945 ], [ 15.908203, 48.835797 ], [ 15.556641, 48.893615 ], [ 15.468750, 48.951366 ], [ 15.161133, 48.951366 ], [ 14.985352, 49.009051 ], [ 14.941406, 48.748945 ], [ 14.809570, 48.777913 ], [ 14.677734, 48.574790 ], [ 14.589844, 48.632909 ], [ 14.458008, 48.632909 ], [ 14.326172, 48.545705 ], [ 14.018555, 48.603858 ], [ 14.018555, 48.690960 ], [ 13.623047, 48.893615 ], [ 13.623047, 48.951366 ], [ 13.447266, 48.951366 ], [ 12.963867, 49.325122 ], [ 12.788086, 49.325122 ], [ 12.700195, 49.382373 ], [ 14.194336, 49.325122 ], [ 16.040039, 50.625073 ], [ 16.040039, 50.625073 ], [ 16.083984, 50.652943 ], [ 16.347656, 50.652943 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Germany" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 14.282227, 53.041213 ], [ 14.150391, 52.961875 ], [ 14.106445, 52.855864 ], [ 14.633789, 52.589701 ], [ 14.545898, 52.375599 ], [ 14.589844, 52.268157 ], [ 14.721680, 52.241256 ], [ 14.677734, 52.106505 ], [ 14.765625, 52.079506 ], [ 14.589844, 51.781436 ], [ 14.721680, 51.672555 ], [ 12.480469, 51.618017 ], [ 11.206055, 50.792047 ], [ 11.337891, 49.979488 ], [ 12.436523, 49.382373 ], [ 12.700195, 49.382373 ], [ 12.788086, 49.325122 ], [ 12.963867, 49.325122 ], [ 13.139648, 49.152970 ], [ 13.315430, 49.095452 ], [ 13.447266, 48.951366 ], [ 13.623047, 48.951366 ], [ 13.623047, 48.893615 ], [ 13.798828, 48.777913 ], [ 13.798828, 48.574790 ], [ 13.710938, 48.516604 ], [ 13.623047, 48.574790 ], [ 13.447266, 48.574790 ], [ 13.447266, 48.429201 ], [ 13.315430, 48.312428 ], [ 13.007812, 48.253941 ], [ 12.875977, 48.195387 ], [ 10.722656, 47.813155 ], [ 10.063477, 47.368594 ], [ 10.063477, 47.368594 ], [ 9.931641, 47.546872 ], [ 9.711914, 47.576526 ], [ 9.711914, 47.517201 ], [ 9.624023, 47.517201 ], [ 9.228516, 47.665387 ], [ 8.833008, 47.665387 ], [ 8.876953, 47.694974 ], [ 8.701172, 47.694974 ], [ 8.701172, 47.754098 ], [ 8.613281, 47.754098 ], [ 8.569336, 47.813155 ], [ 8.393555, 47.694974 ], [ 8.437500, 47.635784 ], [ 8.525391, 47.635784 ], [ 8.437500, 47.576526 ], [ 8.305664, 47.576526 ], [ 8.217773, 47.635784 ], [ 8.041992, 47.546872 ], [ 7.910156, 47.546872 ], [ 7.822266, 47.606163 ], [ 7.778320, 47.546872 ], [ 7.646484, 47.546872 ], [ 7.646484, 47.606163 ], [ 7.602539, 47.576526 ], [ 7.514648, 47.665387 ], [ 7.602539, 47.901614 ], [ 7.558594, 48.107431 ], [ 7.690430, 48.224673 ], [ 7.734375, 48.458352 ], [ 7.822266, 48.516604 ], [ 7.866211, 48.661943 ], [ 8.217773, 48.951366 ], [ 7.910156, 49.037868 ], [ 7.646484, 49.037868 ], [ 7.426758, 49.181703 ], [ 7.294922, 49.095452 ], [ 7.075195, 49.152970 ], [ 7.031250, 49.095452 ], [ 7.031250, 49.181703 ], [ 6.943359, 49.210420 ], [ 6.811523, 49.210420 ], [ 6.855469, 49.152970 ], [ 6.723633, 49.152970 ], [ 6.503906, 49.439557 ], [ 6.328125, 49.468124 ], [ 6.416016, 49.667628 ], [ 6.503906, 49.696062 ], [ 6.503906, 49.809632 ], [ 6.240234, 49.866317 ], [ 6.108398, 50.007739 ], [ 6.108398, 50.148746 ], [ 8.217773, 50.429518 ], [ 10.722656, 52.749594 ], [ 13.579102, 53.173119 ], [ 14.282227, 53.041213 ] ] ], [ [ [ 8.613281, 47.665387 ], [ 8.569336, 47.576526 ], [ 8.525391, 47.635784 ], [ 8.613281, 47.665387 ] ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Italy" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 8.437500, 46.437857 ], [ 8.437500, 46.225453 ], [ 8.525391, 46.164614 ], [ 7.690430, 45.552525 ], [ 6.987305, 45.614037 ], [ 6.767578, 45.767523 ], [ 6.855469, 45.859412 ], [ 6.987305, 45.859412 ], [ 6.987305, 45.920587 ], [ 7.250977, 45.890008 ], [ 7.514648, 45.981695 ], [ 7.866211, 45.920587 ], [ 7.866211, 45.981695 ], [ 7.998047, 45.981695 ], [ 7.998047, 46.073231 ], [ 8.129883, 46.134170 ], [ 8.085938, 46.286224 ], [ 8.173828, 46.286224 ], [ 8.305664, 46.377254 ], [ 8.305664, 46.437857 ], [ 8.437500, 46.437857 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Croatia" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 18.940430, 45.736860 ], [ 18.984375, 45.675482 ], [ 18.896484, 45.583290 ], [ 19.116211, 45.521744 ], [ 18.984375, 45.460131 ], [ 18.984375, 45.367584 ], [ 19.423828, 45.213004 ], [ 19.204102, 45.151053 ], [ 19.160156, 45.213004 ], [ 19.160156, 45.151053 ], [ 19.028320, 45.151053 ], [ 19.116211, 45.026950 ], [ 19.116211, 44.933696 ], [ 18.984375, 44.902578 ], [ 19.028320, 44.871443 ], [ 18.764648, 44.902578 ], [ 18.808594, 44.995883 ], [ 18.676758, 45.089036 ], [ 18.544922, 45.058001 ], [ 18.544922, 45.151053 ], [ 18.940430, 45.736860 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Austria" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 9.711914, 47.576526 ], [ 9.931641, 47.546872 ], [ 10.063477, 47.368594 ], [ 10.063477, 47.368594 ], [ 9.667969, 47.070122 ], [ 9.667969, 47.070122 ], [ 9.580078, 47.040182 ], [ 9.624023, 47.129951 ], [ 9.536133, 47.189712 ], [ 9.536133, 47.309034 ], [ 9.667969, 47.398349 ], [ 9.667969, 47.457809 ], [ 9.536133, 47.546872 ], [ 9.711914, 47.517201 ], [ 9.711914, 47.576526 ] ] ], [ [ [ 14.985352, 49.009051 ], [ 15.161133, 48.951366 ], [ 15.468750, 48.951366 ], [ 15.556641, 48.893615 ], [ 15.908203, 48.835797 ], [ 16.040039, 48.748945 ], [ 16.391602, 48.719961 ], [ 16.435547, 48.806863 ], [ 16.567383, 48.806863 ], [ 16.655273, 48.777913 ], [ 16.655273, 48.719961 ], [ 16.875000, 48.719961 ], [ 16.962891, 48.603858 ], [ 16.831055, 48.370848 ], [ 16.918945, 48.341646 ], [ 16.962891, 48.166085 ], [ 17.094727, 48.107431 ], [ 17.050781, 48.048710 ], [ 17.138672, 48.019324 ], [ 17.094727, 47.901614 ], [ 17.006836, 47.872144 ], [ 17.094727, 47.694974 ], [ 16.831055, 47.724545 ], [ 16.787109, 47.665387 ], [ 16.523438, 47.754098 ], [ 16.523438, 47.694974 ], [ 16.391602, 47.665387 ], [ 16.611328, 47.635784 ], [ 16.699219, 47.546872 ], [ 16.611328, 47.428087 ], [ 16.479492, 47.398349 ], [ 13.710938, 48.341646 ], [ 12.875977, 48.195387 ], [ 13.007812, 48.253941 ], [ 13.315430, 48.312428 ], [ 13.447266, 48.429201 ], [ 13.447266, 48.574790 ], [ 13.623047, 48.574790 ], [ 13.710938, 48.516604 ], [ 13.798828, 48.574790 ], [ 13.798828, 48.777913 ], [ 14.018555, 48.690960 ], [ 14.018555, 48.603858 ], [ 14.326172, 48.545705 ], [ 14.458008, 48.632909 ], [ 14.589844, 48.632909 ], [ 14.677734, 48.574790 ], [ 14.809570, 48.777913 ], [ 14.941406, 48.748945 ], [ 14.985352, 49.009051 ] ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Serbia" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 20.302734, 46.042736 ], [ 20.390625, 45.951150 ], [ 20.654297, 45.828799 ], [ 20.698242, 45.736860 ], [ 20.786133, 45.767523 ], [ 20.742188, 45.490946 ], [ 21.093750, 45.274886 ], [ 21.137695, 45.305803 ], [ 21.489258, 45.151053 ], [ 21.445312, 45.026950 ], [ 21.357422, 44.995883 ], [ 21.533203, 44.933696 ], [ 21.533203, 44.871443 ], [ 21.357422, 44.871443 ], [ 21.401367, 44.777936 ], [ 21.577148, 44.777936 ], [ 21.665039, 44.684277 ], [ 22.016602, 44.653024 ], [ 22.104492, 44.496505 ], [ 22.192383, 44.496505 ], [ 22.324219, 44.621754 ], [ 22.324219, 44.119142 ], [ 19.907227, 43.197167 ], [ 19.291992, 43.580391 ], [ 19.335938, 43.612217 ], [ 19.423828, 43.548548 ], [ 19.511719, 43.580391 ], [ 19.467773, 43.771094 ], [ 19.248047, 43.992815 ], [ 19.291992, 44.024422 ], [ 19.379883, 43.961191 ], [ 19.511719, 43.961191 ], [ 19.599609, 43.992815 ], [ 19.599609, 44.056012 ], [ 19.335938, 44.213710 ], [ 19.335938, 44.276671 ], [ 19.160156, 44.276671 ], [ 19.116211, 44.339565 ], [ 19.116211, 44.527843 ], [ 19.335938, 44.715514 ], [ 19.379883, 44.902578 ], [ 18.984375, 44.902578 ], [ 19.116211, 44.933696 ], [ 19.028320, 45.151053 ], [ 19.160156, 45.151053 ], [ 19.160156, 45.213004 ], [ 19.204102, 45.151053 ], [ 19.423828, 45.213004 ], [ 18.984375, 45.367584 ], [ 18.984375, 45.460131 ], [ 19.116211, 45.521744 ], [ 18.896484, 45.583290 ], [ 18.984375, 45.675482 ], [ 18.896484, 45.706179 ], [ 18.984375, 45.798170 ], [ 20.302734, 46.042736 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Slovakia" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 19.379883, 49.582226 ], [ 19.291992, 48.253941 ], [ 18.105469, 47.754098 ], [ 17.753906, 47.754098 ], [ 17.358398, 47.989922 ], [ 17.050781, 48.048710 ], [ 17.094727, 48.107431 ], [ 16.962891, 48.166085 ], [ 16.962891, 48.283193 ], [ 16.831055, 48.370848 ], [ 17.094727, 48.835797 ], [ 17.270508, 48.864715 ], [ 17.358398, 48.806863 ], [ 17.534180, 48.806863 ], [ 17.753906, 48.864715 ], [ 17.797852, 48.922499 ], [ 17.885742, 48.922499 ], [ 17.929688, 49.009051 ], [ 18.105469, 49.066668 ], [ 18.149414, 49.267805 ], [ 18.369141, 49.325122 ], [ 18.369141, 49.382373 ], [ 18.457031, 49.382373 ], [ 18.544922, 49.496675 ], [ 18.940430, 49.496675 ], [ 18.940430, 49.382373 ], [ 19.160156, 49.382373 ], [ 19.204102, 49.496675 ], [ 19.335938, 49.525208 ], [ 19.379883, 49.582226 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Hungary" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 17.138672, 48.019324 ], [ 17.358398, 47.989922 ], [ 17.753906, 47.754098 ], [ 18.105469, 47.754098 ], [ 16.918945, 47.249407 ], [ 16.479492, 47.398349 ], [ 16.611328, 47.428087 ], [ 16.699219, 47.517201 ], [ 16.611328, 47.635784 ], [ 16.391602, 47.665387 ], [ 16.523438, 47.694974 ], [ 16.523438, 47.754098 ], [ 16.787109, 47.665387 ], [ 16.831055, 47.724545 ], [ 17.094727, 47.694974 ], [ 17.006836, 47.872144 ], [ 17.094727, 47.901614 ], [ 17.138672, 48.019324 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Bosnia and Herz." }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 18.676758, 45.089036 ], [ 18.808594, 44.995883 ], [ 18.764648, 44.902578 ], [ 18.852539, 44.871443 ], [ 19.072266, 44.871443 ], [ 19.160156, 44.933696 ], [ 19.379883, 44.902578 ], [ 19.335938, 44.715514 ], [ 19.116211, 44.527843 ], [ 19.116211, 44.339565 ], [ 19.160156, 44.276671 ], [ 19.335938, 44.276671 ], [ 19.335938, 44.213710 ], [ 19.599609, 44.056012 ], [ 19.599609, 43.992815 ], [ 19.511719, 43.961191 ], [ 19.379883, 43.961191 ], [ 19.291992, 44.024422 ], [ 19.248047, 43.992815 ], [ 19.511719, 43.675818 ], [ 19.467773, 43.548548 ], [ 19.335938, 43.612217 ], [ 19.248047, 43.580391 ], [ 18.588867, 43.992815 ], [ 18.544922, 45.058001 ], [ 18.676758, 45.089036 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Poland" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 14.282227, 53.041213 ], [ 16.699219, 52.536273 ], [ 19.511719, 50.986099 ], [ 19.379883, 49.582226 ], [ 19.204102, 49.496675 ], [ 19.160156, 49.382373 ], [ 18.940430, 49.382373 ], [ 18.940430, 49.496675 ], [ 18.852539, 49.496675 ], [ 18.808594, 49.667628 ], [ 18.632812, 49.696062 ], [ 18.544922, 49.809632 ], [ 18.544922, 49.922935 ], [ 18.281250, 49.894634 ], [ 18.281250, 49.951220 ], [ 18.017578, 50.035974 ], [ 17.929688, 49.979488 ], [ 17.753906, 50.007739 ], [ 17.753906, 50.092393 ], [ 17.622070, 50.092393 ], [ 17.578125, 50.148746 ], [ 17.753906, 50.205033 ], [ 17.709961, 50.317408 ], [ 17.666016, 50.261254 ], [ 17.402344, 50.233152 ], [ 17.314453, 50.261254 ], [ 17.358398, 50.317408 ], [ 17.226562, 50.317408 ], [ 17.094727, 50.401515 ], [ 16.875000, 50.429518 ], [ 16.918945, 50.317408 ], [ 17.006836, 50.289339 ], [ 17.006836, 50.205033 ], [ 16.962891, 50.233152 ], [ 16.655273, 50.092393 ], [ 16.567383, 50.120578 ], [ 16.435547, 50.317408 ], [ 16.171875, 50.429518 ], [ 16.347656, 50.485474 ], [ 16.435547, 50.569283 ], [ 16.347656, 50.652943 ], [ 16.083984, 50.652943 ], [ 16.040039, 50.625073 ], [ 14.765625, 51.672555 ], [ 14.721680, 51.672555 ], [ 14.589844, 51.781436 ], [ 14.765625, 52.079506 ], [ 14.677734, 52.106505 ], [ 14.721680, 52.241256 ], [ 14.589844, 52.268157 ], [ 14.545898, 52.375599 ], [ 14.633789, 52.589701 ], [ 14.106445, 52.855864 ], [ 14.150391, 52.961875 ], [ 14.282227, 53.041213 ] ] ] } } +, +{ "type": "Feature", "properties": { "NAME": "Romania" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 21.049805, 46.164614 ], [ 22.324219, 45.274886 ], [ 22.324219, 44.621754 ], [ 22.192383, 44.496505 ], [ 22.104492, 44.496505 ], [ 22.016602, 44.653024 ], [ 21.665039, 44.684277 ], [ 21.577148, 44.777936 ], [ 21.401367, 44.777936 ], [ 21.357422, 44.871443 ], [ 21.533203, 44.871443 ], [ 21.533203, 44.933696 ], [ 21.357422, 44.995883 ], [ 21.445312, 45.026950 ], [ 21.489258, 45.151053 ], [ 21.137695, 45.305803 ], [ 21.093750, 45.274886 ], [ 20.742188, 45.490946 ], [ 20.786133, 45.767523 ], [ 20.698242, 45.736860 ], [ 20.654297, 45.828799 ], [ 20.346680, 45.981695 ], [ 20.302734, 46.042736 ], [ 21.049805, 46.164614 ] ] ] } } +] } +] } diff --git a/tests/pbf/countries-1-1-0.pbf b/tests/pbf/countries-1-1-0.pbf new file mode 100644 index 0000000000000000000000000000000000000000..25f3e118b273e4cfcef9cab592e6930fa7e9df73 GIT binary patch literal 50553 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 literal 0 HcmV?d00001 diff --git a/tests/pbf/places-1-1-0-clip.json b/tests/pbf/places-1-1-0-clip.json new file mode 100644 index 00000000..daad1e62 --- /dev/null +++ b/tests/pbf/places-1-1-0-clip.json @@ -0,0 +1,211 @@ +{ "type": "FeatureCollection", "properties": { "zoom": 1, "x": 1, "y": 0 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "ne_10m_populated_places", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "NAME": "Reims" }, "geometry": { "type": "Point", "coordinates": [ 4.042969, 49.239121 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Diekirch" }, "geometry": { "type": "Point", "coordinates": [ 6.152344, 49.894634 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Arlon" }, "geometry": { "type": "Point", "coordinates": [ 5.800781, 49.696062 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Luxembourg" }, "geometry": { "type": "Point", "coordinates": [ 6.108398, 49.610710 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Metz" }, "geometry": { "type": "Point", "coordinates": [ 6.196289, 49.124219 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Grevenmacher" }, "geometry": { "type": "Point", "coordinates": [ 6.416016, 49.667628 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Saarbrücken" }, "geometry": { "type": "Point", "coordinates": [ 6.987305, 49.239121 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Koblenz" }, "geometry": { "type": "Point", "coordinates": [ 7.602539, 50.345460 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Wiesbaden" }, "geometry": { "type": "Point", "coordinates": [ 8.261719, 50.092393 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Mainz" }, "geometry": { "type": "Point", "coordinates": [ 8.261719, 49.979488 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Karlsruhe" }, "geometry": { "type": "Point", "coordinates": [ 8.393555, 49.009051 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Kassel" }, "geometry": { "type": "Point", "coordinates": [ 9.492188, 51.289406 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Braunschweig" }, "geometry": { "type": "Point", "coordinates": [ 10.502930, 52.241256 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Göttingen" }, "geometry": { "type": "Point", "coordinates": [ 9.931641, 51.508742 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Erfurt" }, "geometry": { "type": "Point", "coordinates": [ 11.030273, 50.958427 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Gießen" }, "geometry": { "type": "Point", "coordinates": [ 8.657227, 50.597186 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Frankfurt" }, "geometry": { "type": "Point", "coordinates": [ 8.657227, 50.092393 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Mannheim" }, "geometry": { "type": "Point", "coordinates": [ 8.481445, 49.496675 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Heidelberg" }, "geometry": { "type": "Point", "coordinates": [ 8.701172, 49.410973 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Coburg" }, "geometry": { "type": "Point", "coordinates": [ 10.986328, 50.261254 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Würzburg" }, "geometry": { "type": "Point", "coordinates": [ 9.931641, 49.809632 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Fürth" }, "geometry": { "type": "Point", "coordinates": [ 10.986328, 49.468124 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Nürnberg" }, "geometry": { "type": "Point", "coordinates": [ 11.074219, 49.439557 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Troyes" }, "geometry": { "type": "Point", "coordinates": [ 4.086914, 48.341646 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Auxerre" }, "geometry": { "type": "Point", "coordinates": [ 3.559570, 47.813155 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Dijon" }, "geometry": { "type": "Point", "coordinates": [ 5.009766, 47.338823 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Nancy" }, "geometry": { "type": "Point", "coordinates": [ 6.196289, 48.690960 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Besançon" }, "geometry": { "type": "Point", "coordinates": [ 6.020508, 47.219568 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Strasbourg" }, "geometry": { "type": "Point", "coordinates": [ 7.734375, 48.574790 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Freiburg" }, "geometry": { "type": "Point", "coordinates": [ 7.866211, 47.989922 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Mulhouse" }, "geometry": { "type": "Point", "coordinates": [ 7.338867, 47.754098 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Basel" }, "geometry": { "type": "Point", "coordinates": [ 7.602539, 47.576526 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Delémont" }, "geometry": { "type": "Point", "coordinates": [ 7.338867, 47.368594 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Biel" }, "geometry": { "type": "Point", "coordinates": [ 7.250977, 47.159840 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Solothurn" }, "geometry": { "type": "Point", "coordinates": [ 7.558594, 47.219568 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Liestal" }, "geometry": { "type": "Point", "coordinates": [ 7.734375, 47.487513 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Aarau" }, "geometry": { "type": "Point", "coordinates": [ 8.041992, 47.398349 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Luzern" }, "geometry": { "type": "Point", "coordinates": [ 8.261719, 47.040182 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Geneva" }, "geometry": { "type": "Point", "coordinates": [ 6.152344, 46.195042 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Neuchâtel" }, "geometry": { "type": "Point", "coordinates": [ 6.943359, 47.010226 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Lausanne" }, "geometry": { "type": "Point", "coordinates": [ 6.635742, 46.528635 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Annecy" }, "geometry": { "type": "Point", "coordinates": [ 6.108398, 45.890008 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Fribourg" }, "geometry": { "type": "Point", "coordinates": [ 7.163086, 46.800059 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Bern" }, "geometry": { "type": "Point", "coordinates": [ 7.470703, 46.920255 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Sion" }, "geometry": { "type": "Point", "coordinates": [ 7.338867, 46.225453 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Sarnen" }, "geometry": { "type": "Point", "coordinates": [ 8.261719, 46.890232 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Stans" }, "geometry": { "type": "Point", "coordinates": [ 8.393555, 46.950262 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Aosta" }, "geometry": { "type": "Point", "coordinates": [ 7.294922, 45.736860 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Stuttgart" }, "geometry": { "type": "Point", "coordinates": [ 9.184570, 48.777913 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Schaffhausen" }, "geometry": { "type": "Point", "coordinates": [ 8.613281, 47.694974 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Frauenfeld" }, "geometry": { "type": "Point", "coordinates": [ 8.920898, 47.546872 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Zürich" }, "geometry": { "type": "Point", "coordinates": [ 8.569336, 47.368594 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Zug" }, "geometry": { "type": "Point", "coordinates": [ 8.481445, 47.189712 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Glarus" }, "geometry": { "type": "Point", "coordinates": [ 9.052734, 47.040182 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Herisau" }, "geometry": { "type": "Point", "coordinates": [ 9.272461, 47.368594 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Saint Gallen" }, "geometry": { "type": "Point", "coordinates": [ 9.360352, 47.428087 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Appenzell" }, "geometry": { "type": "Point", "coordinates": [ 9.404297, 47.338823 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Bregenz" }, "geometry": { "type": "Point", "coordinates": [ 9.755859, 47.517201 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Vaduz" }, "geometry": { "type": "Point", "coordinates": [ 9.536133, 47.129951 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Ulm" }, "geometry": { "type": "Point", "coordinates": [ 10.019531, 48.400032 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Augsburg" }, "geometry": { "type": "Point", "coordinates": [ 10.898438, 48.341646 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Schwyz" }, "geometry": { "type": "Point", "coordinates": [ 8.657227, 47.010226 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Altdorf" }, "geometry": { "type": "Point", "coordinates": [ 8.657227, 46.890232 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Berlin" }, "geometry": { "type": "Point", "coordinates": [ 13.403320, 52.536273 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Magdeburg" }, "geometry": { "type": "Point", "coordinates": [ 11.601562, 52.133488 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Potsdam" }, "geometry": { "type": "Point", "coordinates": [ 13.051758, 52.402419 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Regensburg" }, "geometry": { "type": "Point", "coordinates": [ 12.128906, 49.009051 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Cottbus" }, "geometry": { "type": "Point", "coordinates": [ 14.326172, 51.781436 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Zielona Góra" }, "geometry": { "type": "Point", "coordinates": [ 15.512695, 51.944265 ] } } +, +{ "type": "Feature", "properties": { "NAME": "České Budějovice" }, "geometry": { "type": "Point", "coordinates": [ 14.458008, 48.980217 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Hradec Králové" }, "geometry": { "type": "Point", "coordinates": [ 15.820312, 50.205033 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Pardubice" }, "geometry": { "type": "Point", "coordinates": [ 15.776367, 50.035974 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Jihlava" }, "geometry": { "type": "Point", "coordinates": [ 15.600586, 49.410973 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Brno" }, "geometry": { "type": "Point", "coordinates": [ 16.611328, 49.210420 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Poznań" }, "geometry": { "type": "Point", "coordinates": [ 16.918945, 52.402419 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Wrocław" }, "geometry": { "type": "Point", "coordinates": [ 17.050781, 51.124213 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Opole" }, "geometry": { "type": "Point", "coordinates": [ 17.929688, 50.680797 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Olomouc" }, "geometry": { "type": "Point", "coordinates": [ 17.270508, 49.582226 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Ostrava" }, "geometry": { "type": "Point", "coordinates": [ 18.237305, 49.837982 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Zlín" }, "geometry": { "type": "Point", "coordinates": [ 17.666016, 49.239121 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Gliwice" }, "geometry": { "type": "Point", "coordinates": [ 18.676758, 50.317408 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Bytom" }, "geometry": { "type": "Point", "coordinates": [ 18.896484, 50.345460 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Katowice" }, "geometry": { "type": "Point", "coordinates": [ 19.028320, 50.261254 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Žilina" }, "geometry": { "type": "Point", "coordinates": [ 18.764648, 49.210420 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Ingolstadt" }, "geometry": { "type": "Point", "coordinates": [ 11.469727, 48.777913 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Munich" }, "geometry": { "type": "Point", "coordinates": [ 11.557617, 48.136767 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Passau" }, "geometry": { "type": "Point", "coordinates": [ 13.447266, 48.574790 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Linz" }, "geometry": { "type": "Point", "coordinates": [ 14.282227, 48.312428 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Vienna" }, "geometry": { "type": "Point", "coordinates": [ 16.347656, 48.195387 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Wiener Neustadt" }, "geometry": { "type": "Point", "coordinates": [ 16.259766, 47.813155 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Eisenstadt" }, "geometry": { "type": "Point", "coordinates": [ 16.523438, 47.842658 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Bratislava" }, "geometry": { "type": "Point", "coordinates": [ 17.138672, 48.136767 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Trnava" }, "geometry": { "type": "Point", "coordinates": [ 17.578125, 48.370848 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Győr" }, "geometry": { "type": "Point", "coordinates": [ 17.622070, 47.694974 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Banská Bystrica" }, "geometry": { "type": "Point", "coordinates": [ 19.160156, 48.719961 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Zvolen" }, "geometry": { "type": "Point", "coordinates": [ 19.116211, 48.574790 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Novi Sad" }, "geometry": { "type": "Point", "coordinates": [ 19.863281, 45.243953 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Zrenjanin" }, "geometry": { "type": "Point", "coordinates": [ 20.390625, 45.367584 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Timișoara" }, "geometry": { "type": "Point", "coordinates": [ 21.225586, 45.767523 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Reșița" }, "geometry": { "type": "Point", "coordinates": [ 21.884766, 45.305803 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Tuzla" }, "geometry": { "type": "Point", "coordinates": [ 18.676758, 44.559163 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Belgrade" }, "geometry": { "type": "Point", "coordinates": [ 20.478516, 44.809122 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Čačak" }, "geometry": { "type": "Point", "coordinates": [ 20.346680, 43.897892 ] } } +, +{ "type": "Feature", "properties": { "NAME": "Kragujevac" }, "geometry": { "type": "Point", "coordinates": [ 20.917969, 44.024422 ] } } +] } +] } diff --git a/tests/pbf/places-1-1-0.pbf b/tests/pbf/places-1-1-0.pbf new file mode 100644 index 0000000000000000000000000000000000000000..e36effdb0f7559e656b92d0f9f20ecb8b510a659 GIT binary patch literal 45352 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 Me{9C@T*Z$805-k+MF0Q* literal 0 HcmV?d00001 diff --git a/tests/pbf/roads-1-1-0-clip.json b/tests/pbf/roads-1-1-0-clip.json new file mode 100644 index 00000000..bc07f230 --- /dev/null +++ b/tests/pbf/roads-1-1-0-clip.json @@ -0,0 +1,1993 @@ +{ "type": "FeatureCollection", "properties": { "zoom": 1, "x": 1, "y": 0 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "ne_10m_roads", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "name": "17" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.042969, 49.296472 ], [ 3.999023, 49.325122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.086914, 49.239121 ], [ 4.042969, 49.296472 ], [ 3.999023, 49.296472 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 3.999023, 49.239121 ], [ 4.042969, 49.210420 ], [ 4.086914, 49.239121 ] ] } } +, +{ "type": "Feature", "properties": { "name": "17" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.086914, 49.267805 ], [ 4.086914, 49.210420 ], [ 4.218750, 49.181703 ], [ 4.306641, 49.037868 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 3.955078, 49.037868 ], [ 4.042969, 49.239121 ] ] } } +, +{ "type": "Feature", "properties": { "name": "420" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.526367, 49.866317 ], [ 4.526367, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { "name": "411" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.229492, 50.035974 ], [ 5.229492, 50.035974 ], [ 5.273438, 49.922935 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.361328, 49.894634 ], [ 5.405273, 50.064192 ], [ 5.405273, 50.064192 ] ] } } +, +{ "type": "Feature", "properties": { "name": "46" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.009766, 49.696062 ], [ 5.097656, 49.866317 ], [ 5.229492, 49.866317 ], [ 5.273438, 49.922935 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.273438, 49.894634 ], [ 5.361328, 49.894634 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.273438, 49.894634 ], [ 5.361328, 49.922935 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.493164, 49.866317 ], [ 5.361328, 49.894634 ] ] } } +, +{ "type": "Feature", "properties": { "name": "46" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.350586, 49.525208 ], [ 4.174805, 49.296472 ], [ 4.086914, 49.267805 ] ] } } +, +{ "type": "Feature", "properties": { "name": "44" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.174805, 49.866317 ], [ 4.438477, 49.894634 ], [ 4.702148, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { "name": "46" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.790039, 49.752880 ], [ 4.350586, 49.525208 ] ] } } +, +{ "type": "Feature", "properties": { "name": "17" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.218750, 48.719961 ], [ 4.306641, 49.066668 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.570312, 48.719961 ], [ 4.570312, 48.806863 ], [ 4.350586, 48.951366 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.185547, 49.496675 ], [ 5.009766, 49.410973 ], [ 4.833984, 49.439557 ], [ 4.746094, 49.382373 ], [ 4.526367, 49.382373 ], [ 4.394531, 49.296472 ], [ 4.042969, 49.239121 ] ] } } +, +{ "type": "Feature", "properties": { "name": "44" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.790039, 49.752880 ], [ 5.009766, 49.696062 ] ] } } +, +{ "type": "Feature", "properties": { "name": "44" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.625000, 49.439557 ], [ 5.405273, 49.468124 ], [ 5.361328, 49.582226 ], [ 5.009766, 49.696062 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.185547, 49.496675 ], [ 5.185547, 49.553726 ], [ 5.053711, 49.610710 ], [ 5.053711, 49.696062 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.361328, 49.525208 ], [ 5.185547, 49.496675 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.405273, 49.181703 ], [ 5.229492, 49.353756 ], [ 5.185547, 49.496675 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.449219, 49.124219 ], [ 5.405273, 49.181703 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.273438, 49.095452 ], [ 5.273438, 48.835797 ], [ 5.185547, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.493164, 49.095452 ], [ 5.317383, 49.124219 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.625000, 48.690960 ], [ 5.493164, 48.806863 ], [ 5.537109, 48.980217 ], [ 5.449219, 49.037868 ], [ 5.449219, 49.124219 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.502930, 52.562995 ], [ 10.502930, 52.321911 ] ] } } +, +{ "type": "Feature", "properties": { "name": "35" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.998047, 50.401515 ], [ 8.085938, 50.373496 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.756836, 50.120578 ], [ 5.756836, 50.064192 ], [ 5.493164, 49.866317 ] ] } } +, +{ "type": "Feature", "properties": { "name": "421" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 50.148746 ], [ 6.108398, 49.866317 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.328125, 50.176898 ], [ 6.372070, 50.176898 ] ] } } +, +{ "type": "Feature", "properties": { "name": "29" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.372070, 50.176898 ], [ 6.416016, 50.205033 ] ] } } +, +{ "type": "Feature", "properties": { "name": "29" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.372070, 50.176898 ], [ 6.591797, 50.035974 ] ] } } +, +{ "type": "Feature", "properties": { "name": "42" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.591797, 50.035974 ], [ 6.899414, 49.979488 ] ] } } +, +{ "type": "Feature", "properties": { "name": "29" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.943359, 50.205033 ], [ 6.943359, 50.261254 ] ] } } +, +{ "type": "Feature", "properties": { "name": "44" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.943359, 50.205033 ], [ 6.855469, 50.148746 ], [ 6.943359, 49.979488 ], [ 6.723633, 49.781264 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.493164, 49.866317 ], [ 5.537109, 49.752880 ], [ 5.800781, 49.667628 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.493164, 50.092393 ], [ 5.581055, 50.007739 ], [ 5.712891, 49.979488 ], [ 5.800781, 49.667628 ] ] } } +, +{ "type": "Feature", "properties": { "name": "44" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.625000, 49.439557 ], [ 5.625000, 49.525208 ], [ 5.800781, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.625000, 49.210420 ], [ 5.625000, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.756836, 49.496675 ], [ 5.800781, 49.667628 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.756836, 49.496675 ], [ 5.844727, 49.496675 ], [ 5.932617, 49.410973 ] ] } } +, +{ "type": "Feature", "properties": { "name": "421" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 49.866317 ], [ 6.152344, 49.610710 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.800781, 49.553726 ], [ 6.108398, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 49.610710 ], [ 6.108398, 49.582226 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.800781, 49.667628 ], [ 5.976562, 49.639177 ], [ 6.108398, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 49.582226 ], [ 6.108398, 49.353756 ], [ 6.196289, 49.325122 ], [ 6.152344, 49.210420 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 49.610710 ], [ 6.152344, 49.610710 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 49.610710 ], [ 6.152344, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.317383, 49.124219 ], [ 5.537109, 49.210420 ], [ 5.800781, 49.181703 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.932617, 49.410973 ], [ 6.020508, 49.325122 ], [ 6.152344, 49.296472 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.625000, 49.439557 ], [ 5.712891, 49.439557 ], [ 5.756836, 49.353756 ], [ 6.020508, 49.181703 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.196289, 49.181703 ], [ 5.888672, 49.210420 ], [ 5.625000, 49.124219 ], [ 4.877930, 49.095452 ], [ 4.526367, 49.009051 ], [ 4.306641, 49.066668 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.196289, 49.152970 ], [ 6.196289, 49.124219 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.240234, 49.124219 ], [ 6.196289, 49.181703 ] ] } } +, +{ "type": "Feature", "properties": { "name": "29" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.635742, 50.035974 ], [ 6.503906, 49.951220 ], [ 6.416016, 49.781264 ], [ 6.196289, 49.667628 ] ] } } +, +{ "type": "Feature", "properties": { "name": "44" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 49.582226 ], [ 6.240234, 49.667628 ], [ 6.416016, 49.667628 ], [ 6.591797, 49.781264 ], [ 6.723633, 49.781264 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 49.610710 ], [ 6.240234, 49.610710 ], [ 6.372070, 49.525208 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.372070, 49.525208 ], [ 6.459961, 49.525208 ], [ 6.416016, 49.496675 ] ] } } +, +{ "type": "Feature", "properties": { "name": "29" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 49.525208 ], [ 6.459961, 49.496675 ], [ 6.547852, 49.439557 ], [ 6.635742, 49.468124 ], [ 6.767578, 49.325122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.767578, 49.809632 ], [ 6.635742, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.767578, 49.809632 ], [ 6.899414, 49.667628 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.635742, 49.752880 ], [ 6.635742, 49.553726 ], [ 6.855469, 49.496675 ], [ 6.943359, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.723633, 49.781264 ], [ 6.811523, 49.752880 ], [ 6.899414, 49.582226 ], [ 6.987305, 49.582226 ] ] } } +, +{ "type": "Feature", "properties": { "name": "422" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.943359, 49.181703 ], [ 6.987305, 49.582226 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.943359, 49.353756 ], [ 6.943359, 49.296472 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.767578, 49.325122 ], [ 6.943359, 49.267805 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.943359, 49.296472 ], [ 6.943359, 49.239121 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.943359, 49.239121 ], [ 6.987305, 49.239121 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.987305, 49.239121 ], [ 7.031250, 49.210420 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.196289, 49.124219 ], [ 6.855469, 49.152970 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.855469, 49.124219 ], [ 7.119141, 48.980217 ], [ 7.119141, 48.835797 ], [ 7.250977, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { "name": "31" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.426758, 50.345460 ], [ 7.514648, 50.205033 ], [ 7.646484, 50.205033 ], [ 7.602539, 50.092393 ], [ 7.690430, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.041992, 50.401515 ], [ 8.041992, 50.401515 ] ] } } +, +{ "type": "Feature", "properties": { "name": "44" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.294922, 50.317408 ], [ 7.207031, 50.233152 ], [ 6.943359, 50.205033 ] ] } } +, +{ "type": "Feature", "properties": { "name": "42" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.690430, 50.007739 ], [ 7.294922, 49.951220 ], [ 7.207031, 49.866317 ], [ 6.899414, 49.979488 ] ] } } +, +{ "type": "Feature", "properties": { "name": "31" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.690430, 50.007739 ], [ 7.866211, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.437500, 50.625073 ], [ 8.437500, 50.625073 ] ] } } +, +{ "type": "Feature", "properties": { "name": "44" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 8.085938, 50.401515 ], [ 8.085938, 50.401515 ] ], [ [ 8.437500, 50.625073 ], [ 8.437500, 50.625073 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.041992, 50.401515 ], [ 8.085938, 50.401515 ] ] } } +, +{ "type": "Feature", "properties": { "name": "31" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.129883, 49.781264 ], [ 7.866211, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.866211, 49.866317 ], [ 7.866211, 49.922935 ] ] } } +, +{ "type": "Feature", "properties": { "name": "35" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.085938, 50.401515 ], [ 8.261719, 50.317408 ], [ 8.261719, 50.176898 ], [ 8.393555, 50.064192 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.173828, 50.007739 ], [ 8.173828, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { "name": "42" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.910156, 49.922935 ], [ 8.173828, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { "name": "42" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.393555, 50.064192 ], [ 8.261719, 50.064192 ], [ 8.173828, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { "name": "35" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.393555, 50.064192 ], [ 8.481445, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.349609, 50.064192 ], [ 8.349609, 49.951220 ], [ 8.173828, 49.951220 ], [ 8.129883, 49.781264 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.899414, 49.667628 ], [ 7.031250, 49.724479 ], [ 7.031250, 49.781264 ], [ 7.119141, 49.781264 ], [ 7.163086, 49.667628 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.163086, 49.667628 ], [ 7.250977, 49.724479 ], [ 7.382812, 49.696062 ], [ 7.514648, 49.809632 ], [ 7.866211, 49.866317 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.987305, 49.582226 ], [ 7.163086, 49.610710 ], [ 7.250977, 49.525208 ], [ 7.382812, 49.525208 ], [ 7.426758, 49.439557 ], [ 7.514648, 49.439557 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.514648, 49.439557 ], [ 7.602539, 49.410973 ], [ 7.602539, 49.239121 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.602539, 49.239121 ], [ 7.514648, 49.210420 ], [ 6.987305, 49.353756 ], [ 6.767578, 49.325122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.866211, 49.866317 ], [ 7.910156, 49.781264 ], [ 7.778320, 49.696062 ], [ 7.866211, 49.496675 ], [ 7.778320, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.778320, 49.468124 ], [ 7.734375, 49.439557 ], [ 8.217773, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.129883, 49.781264 ], [ 8.041992, 49.639177 ], [ 7.910156, 49.610710 ], [ 7.778320, 49.496675 ] ] } } +, +{ "type": "Feature", "properties": { "name": "31" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.305664, 49.553726 ], [ 8.305664, 49.667628 ], [ 8.173828, 49.696062 ], [ 8.129883, 49.781264 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.217773, 49.468124 ], [ 8.305664, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.305664, 49.468124 ], [ 8.437500, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.481445, 49.353756 ], [ 8.349609, 49.410973 ], [ 8.305664, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.690430, 48.748945 ], [ 7.778320, 48.864715 ], [ 7.954102, 48.951366 ], [ 7.954102, 49.095452 ], [ 8.129883, 49.152970 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.261719, 49.066668 ], [ 8.349609, 49.296472 ], [ 8.481445, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.349609, 49.439557 ], [ 8.217773, 49.382373 ], [ 8.129883, 49.210420 ], [ 8.173828, 49.095452 ], [ 8.261719, 49.066668 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.173828, 48.980217 ], [ 8.261719, 49.066668 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.261719, 49.066668 ], [ 8.393555, 49.009051 ] ] } } +, +{ "type": "Feature", "properties": { "name": "331" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.745117, 50.903033 ], [ 8.789062, 50.847573 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.228516, 51.069017 ], [ 8.789062, 50.847573 ] ] } } +, +{ "type": "Feature", "properties": { "name": "331" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.492188, 51.261915 ], [ 9.228516, 51.371780 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.404297, 51.261915 ], [ 9.228516, 51.069017 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.580078, 51.316881 ], [ 9.492188, 51.316881 ], [ 9.448242, 51.399206 ], [ 9.272461, 51.454007 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.843750, 51.454007 ], [ 9.799805, 51.399206 ], [ 9.667969, 51.399206 ], [ 9.492188, 51.261915 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.492188, 51.261915 ], [ 9.448242, 51.096623 ], [ 9.580078, 50.847573 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.833008, 50.597186 ], [ 9.140625, 50.764259 ], [ 9.580078, 50.819818 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.239258, 52.321911 ], [ 10.283203, 52.321911 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.371094, 52.268157 ], [ 10.107422, 52.187405 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.327148, 52.402419 ], [ 10.415039, 52.321911 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.283203, 52.321911 ], [ 10.371094, 52.268157 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.019531, 52.133488 ], [ 10.107422, 52.133488 ], [ 10.195312, 52.052490 ], [ 10.151367, 51.835778 ], [ 9.887695, 51.672555 ], [ 9.843750, 51.454007 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.195312, 52.079506 ], [ 10.546875, 52.241256 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.502930, 52.321911 ], [ 10.502930, 52.241256 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.502930, 52.268157 ], [ 10.371094, 52.268157 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.546875, 52.241256 ], [ 10.502930, 52.052490 ], [ 10.590820, 51.944265 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.689453, 51.808615 ], [ 11.513672, 51.781436 ], [ 10.766602, 51.862924 ], [ 10.678711, 51.944265 ], [ 10.371094, 51.917168 ], [ 10.283203, 51.971346 ], [ 10.151367, 51.971346 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.546875, 52.241256 ], [ 10.722656, 52.295042 ], [ 10.722656, 52.456009 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.502930, 52.268157 ], [ 10.766602, 52.268157 ], [ 10.942383, 52.214339 ], [ 11.030273, 52.241256 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.337891, 51.944265 ], [ 11.118164, 51.944265 ], [ 10.986328, 51.890054 ], [ 10.942383, 51.754240 ], [ 10.854492, 51.699800 ], [ 10.810547, 51.481383 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.151367, 51.862924 ], [ 10.195312, 51.754240 ], [ 10.722656, 51.481383 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.580078, 51.316881 ], [ 9.799805, 51.179343 ], [ 10.107422, 51.124213 ], [ 10.195312, 51.041394 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.975586, 51.124213 ], [ 10.019531, 51.013755 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.580078, 50.819818 ], [ 9.755859, 50.847573 ], [ 10.151367, 51.041394 ], [ 10.371094, 51.013755 ], [ 10.546875, 50.903033 ], [ 10.722656, 50.875311 ], [ 11.206055, 50.958427 ], [ 11.381836, 50.958427 ], [ 11.425781, 50.930738 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.810547, 51.481383 ], [ 10.854492, 51.344339 ], [ 10.986328, 51.234407 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.986328, 51.234407 ], [ 10.942383, 51.124213 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.942383, 51.124213 ], [ 10.942383, 51.013755 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.030273, 50.903033 ], [ 10.942383, 51.013755 ], [ 11.074219, 51.041394 ], [ 11.162109, 51.179343 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.162109, 51.179343 ], [ 11.206055, 51.289406 ], [ 11.030273, 51.481383 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.030273, 50.903033 ], [ 11.030273, 50.986099 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 50.429518 ], [ 10.766602, 50.513427 ], [ 10.854492, 50.541363 ], [ 10.810547, 50.625073 ], [ 11.030273, 50.903033 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.437500, 50.625073 ], [ 8.525391, 50.597186 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.525391, 50.625073 ], [ 8.569336, 50.541363 ], [ 8.701172, 50.485474 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.789062, 50.847573 ], [ 8.701172, 50.652943 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.701172, 50.652943 ], [ 8.613281, 50.513427 ] ] } } +, +{ "type": "Feature", "properties": { "name": "451" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.833008, 50.625073 ], [ 8.569336, 50.120578 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.701172, 50.652943 ], [ 8.833008, 50.625073 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.701172, 50.485474 ], [ 8.964844, 50.401515 ], [ 9.052734, 50.176898 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 50.120578 ], [ 8.393555, 50.064192 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 50.120578 ], [ 8.613281, 50.148746 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.393555, 50.064192 ], [ 8.481445, 50.035974 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.481445, 50.007739 ], [ 8.481445, 49.894634 ], [ 8.613281, 49.837982 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.481445, 50.035974 ], [ 8.613281, 50.064192 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 50.064192 ], [ 8.613281, 50.120578 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 50.064192 ], [ 8.613281, 49.866317 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.052734, 50.176898 ], [ 9.096680, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.052734, 50.176898 ], [ 8.569336, 50.120578 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.711914, 50.485474 ], [ 9.404297, 50.261254 ], [ 9.052734, 50.176898 ] ] } } +, +{ "type": "Feature", "properties": { "name": "451" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 49.837982 ], [ 8.876953, 49.894634 ], [ 8.876953, 49.979488 ], [ 8.964844, 50.035974 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.052734, 49.979488 ], [ 9.008789, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 49.866317 ], [ 8.525391, 49.752880 ], [ 8.569336, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { "name": "451" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 50.120578 ], [ 8.569336, 49.325122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 49.553726 ], [ 8.569336, 49.525208 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 49.525208 ], [ 8.525391, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.855469, 49.152970 ], [ 7.734375, 49.496675 ], [ 8.657227, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.525391, 49.468124 ], [ 8.657227, 49.410973 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.525391, 49.468124 ], [ 8.569336, 49.325122 ] ] } } +, +{ "type": "Feature", "properties": { "name": "35" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 49.837982 ], [ 8.613281, 49.210420 ], [ 8.393555, 49.009051 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 49.124219 ], [ 8.657227, 49.037868 ], [ 9.140625, 48.835797 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.272461, 49.152970 ], [ 9.052734, 49.239121 ], [ 8.657227, 49.267805 ], [ 8.481445, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.096680, 50.007739 ], [ 9.096680, 49.781264 ], [ 9.228516, 49.667628 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.063477, 49.752880 ], [ 9.580078, 49.781264 ], [ 9.536133, 49.866317 ], [ 9.272461, 50.007739 ], [ 8.964844, 50.007739 ], [ 8.920898, 50.064192 ], [ 8.657227, 50.064192 ], [ 8.481445, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.843750, 49.752880 ], [ 9.360352, 49.296472 ], [ 9.228516, 48.980217 ], [ 9.008789, 48.806863 ], [ 9.008789, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.360352, 48.806863 ], [ 9.404297, 48.980217 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.580078, 50.847573 ], [ 9.755859, 50.345460 ], [ 10.063477, 50.092393 ], [ 10.063477, 50.035974 ] ] } } +, +{ "type": "Feature", "properties": { "name": "48" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.063477, 50.007739 ], [ 10.283203, 50.064192 ], [ 10.898438, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.151367, 50.035974 ], [ 10.151367, 50.148746 ], [ 10.327148, 50.429518 ], [ 10.458984, 50.429518 ], [ 10.458984, 50.569283 ], [ 10.678711, 50.680797 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.678711, 50.680797 ], [ 10.766602, 50.736455 ], [ 11.030273, 50.736455 ], [ 11.030273, 50.903033 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.678711, 50.680797 ], [ 10.810547, 50.485474 ], [ 10.942383, 50.401515 ], [ 10.942383, 50.317408 ], [ 11.030273, 50.317408 ], [ 11.074219, 50.233152 ], [ 10.942383, 49.979488 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 49.979488 ], [ 10.854492, 50.035974 ], [ 10.986328, 50.176898 ], [ 10.986328, 50.289339 ], [ 10.898438, 50.429518 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 49.922935 ], [ 10.898438, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 49.951220 ], [ 10.898438, 49.979488 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 49.894634 ], [ 10.898438, 49.922935 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 49.894634 ], [ 10.942383, 49.894634 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 49.951220 ], [ 11.074219, 49.781264 ], [ 10.986328, 49.525208 ], [ 11.118164, 49.382373 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.942383, 49.894634 ], [ 10.986328, 49.866317 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.975586, 49.752880 ], [ 9.931641, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.931641, 49.752880 ], [ 9.843750, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.019531, 49.752880 ], [ 9.975586, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.063477, 49.781264 ], [ 10.107422, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.063477, 49.781264 ], [ 10.063477, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { "name": "43" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.063477, 50.035974 ], [ 9.975586, 49.894634 ], [ 10.107422, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { "name": "43" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.107422, 49.781264 ], [ 10.283203, 49.210420 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.239258, 50.035974 ], [ 10.371094, 49.894634 ], [ 10.371094, 49.781264 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.239258, 49.210420 ], [ 9.448242, 49.210420 ], [ 9.272461, 49.152970 ] ] } } +, +{ "type": "Feature", "properties": { "name": "43" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.283203, 49.210420 ], [ 10.195312, 49.095452 ], [ 10.195312, 48.603858 ], [ 10.107422, 48.574790 ], [ 10.151367, 48.019324 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.986328, 49.553726 ], [ 10.898438, 49.582226 ], [ 10.898438, 49.667628 ], [ 10.766602, 49.752880 ], [ 10.678711, 49.724479 ], [ 10.195312, 49.809632 ], [ 10.063477, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.986328, 49.553726 ], [ 10.986328, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.986328, 49.468124 ], [ 11.074219, 49.439557 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.074219, 49.439557 ], [ 11.118164, 49.439557 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.074219, 49.382373 ], [ 10.986328, 49.325122 ], [ 10.766602, 49.325122 ], [ 10.678711, 49.267805 ], [ 10.239258, 49.210420 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.118164, 49.382373 ], [ 11.250000, 49.410973 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.206055, 49.353756 ], [ 11.206055, 49.382373 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.239258, 48.429201 ], [ 10.371094, 48.574790 ], [ 10.590820, 48.632909 ], [ 10.942383, 48.922499 ], [ 10.986328, 49.095452 ], [ 11.118164, 49.239121 ], [ 11.074219, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { "name": "54" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.042969, 48.253941 ], [ 3.691406, 48.253941 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 3.911133, 49.009051 ], [ 3.955078, 49.037868 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 3.823242, 48.719961 ], [ 3.955078, 48.719961 ] ], [ [ 3.955078, 48.719961 ], [ 4.042969, 48.777913 ], [ 4.262695, 48.719961 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 3.867188, 48.893615 ], [ 3.999023, 48.864715 ], [ 4.350586, 48.951366 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.042969, 48.312428 ], [ 3.735352, 48.516604 ] ] } } +, +{ "type": "Feature", "properties": { "name": "17" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.218750, 48.195387 ], [ 4.218750, 48.719961 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.042969, 48.253941 ], [ 4.042969, 48.312428 ] ] } } +, +{ "type": "Feature", "properties": { "name": "54" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.174805, 48.224673 ], [ 4.042969, 48.253941 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 3.559570, 47.783635 ], [ 3.515625, 47.783635 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 3.603516, 47.842658 ], [ 3.691406, 47.872144 ], [ 3.735352, 48.019324 ], [ 4.042969, 48.166085 ], [ 4.042969, 48.253941 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 3.647461, 47.783635 ], [ 3.559570, 47.783635 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 3.427734, 47.338823 ], [ 3.559570, 47.487513 ] ], [ [ 3.559570, 47.487513 ], [ 3.515625, 47.665387 ], [ 3.603516, 47.813155 ] ] ] } } +, +{ "type": "Feature", "properties": { "name": "15" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 4.570312, 47.249407 ], [ 4.262695, 47.457809 ], [ 4.042969, 47.487513 ], [ 3.955078, 47.546872 ], [ 3.955078, 47.635784 ], [ 3.735352, 47.724545 ], [ 3.735352, 47.783635 ] ], [ [ 3.735352, 47.783635 ], [ 3.559570, 47.842658 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.570312, 47.872144 ], [ 3.647461, 47.783635 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.042969, 47.487513 ], [ 4.833984, 46.860191 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.262695, 48.719961 ], [ 4.658203, 48.719961 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.306641, 49.037868 ], [ 4.614258, 48.748945 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.086914, 48.312428 ], [ 4.350586, 48.370848 ], [ 4.394531, 48.429201 ], [ 4.746094, 48.429201 ], [ 4.877930, 48.603858 ], [ 4.965820, 48.632909 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.141602, 48.136767 ], [ 4.877930, 48.253941 ], [ 4.790039, 48.224673 ], [ 4.614258, 48.283193 ], [ 4.306641, 48.224673 ], [ 4.174805, 48.312428 ], [ 4.042969, 48.312428 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.185547, 48.777913 ], [ 4.965820, 48.632909 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.658203, 48.719961 ], [ 5.009766, 48.632909 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.009766, 48.632909 ], [ 5.493164, 48.719961 ], [ 5.888672, 48.661943 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.009766, 48.603858 ], [ 5.141602, 48.400032 ], [ 5.097656, 48.166085 ], [ 5.229492, 47.931066 ] ] } } +, +{ "type": "Feature", "properties": { "name": "17" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.229492, 47.901614 ], [ 4.965820, 48.078079 ], [ 4.174805, 48.224673 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.141602, 48.107431 ], [ 5.097656, 48.107431 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.097656, 48.107431 ], [ 4.965820, 48.078079 ], [ 4.833984, 47.931066 ], [ 4.658203, 47.931066 ], [ 4.570312, 47.872144 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.174805, 48.224673 ], [ 4.218750, 48.166085 ], [ 4.306641, 48.166085 ], [ 4.394531, 48.019324 ], [ 4.526367, 47.989922 ], [ 4.570312, 47.724545 ], [ 4.746094, 47.457809 ], [ 5.009766, 47.338823 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.570312, 47.249407 ], [ 4.658203, 47.309034 ], [ 5.141602, 47.309034 ] ] } } +, +{ "type": "Feature", "properties": { "name": "15" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.921875, 47.070122 ], [ 4.746094, 47.100045 ], [ 4.702148, 47.189712 ], [ 4.570312, 47.249407 ] ] } } +, +{ "type": "Feature", "properties": { "name": "17" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.141602, 47.309034 ], [ 5.229492, 47.546872 ], [ 5.185547, 47.724545 ], [ 5.273438, 47.842658 ], [ 5.229492, 47.931066 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.361328, 47.842658 ], [ 5.273438, 47.606163 ], [ 5.185547, 47.546872 ] ] } } +, +{ "type": "Feature", "properties": { "name": "21" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.844727, 48.224673 ], [ 5.712891, 48.195387 ], [ 5.537109, 47.989922 ], [ 5.229492, 47.931066 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.317383, 47.872144 ], [ 5.493164, 47.989922 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.493164, 47.989922 ], [ 5.449219, 48.048710 ], [ 5.537109, 48.195387 ], [ 5.712891, 48.341646 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.053711, 47.309034 ], [ 4.965820, 47.338823 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.053711, 47.309034 ], [ 5.097656, 47.338823 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.053711, 47.309034 ], [ 5.097656, 47.279229 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.185547, 47.546872 ], [ 5.053711, 47.398349 ], [ 5.053711, 47.309034 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.097656, 47.338823 ], [ 5.097656, 47.279229 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.921875, 47.070122 ], [ 4.877930, 47.040182 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.361328, 47.129951 ], [ 5.317383, 47.249407 ], [ 5.141602, 47.309034 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.449219, 47.129951 ], [ 5.449219, 47.070122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 3.999023, 46.769968 ], [ 4.218750, 46.950262 ], [ 4.306641, 46.950262 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.306641, 46.950262 ], [ 4.350586, 47.070122 ], [ 4.482422, 47.100045 ], [ 4.570312, 47.219568 ] ] } } +, +{ "type": "Feature", "properties": { "name": "607" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.174805, 46.589069 ], [ 4.306641, 46.619261 ], [ 4.394531, 46.709736 ], [ 4.833984, 46.739861 ] ] } } +, +{ "type": "Feature", "properties": { "name": "21" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.790039, 46.286224 ], [ 4.921875, 46.528635 ], [ 4.833984, 46.649436 ], [ 4.833984, 46.950262 ], [ 5.009766, 47.159840 ], [ 5.009766, 47.249407 ], [ 5.141602, 47.309034 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.833984, 46.800059 ], [ 4.877930, 46.769968 ] ] } } +, +{ "type": "Feature", "properties": { "name": "62" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.790039, 46.286224 ], [ 4.658203, 46.407564 ], [ 4.482422, 46.377254 ], [ 4.394531, 46.437857 ], [ 4.350586, 46.437857 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.273438, 46.255847 ], [ 4.921875, 46.286224 ], [ 4.877930, 46.346928 ], [ 4.790039, 46.346928 ] ] } } +, +{ "type": "Feature", "properties": { "name": "15" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.746094, 46.042736 ], [ 4.790039, 46.286224 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.790039, 46.316584 ], [ 4.833984, 46.316584 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.361328, 47.129951 ], [ 5.185547, 47.040182 ], [ 4.921875, 47.070122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.449219, 47.070122 ], [ 4.877930, 46.769968 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 4.921875, 45.859412 ], [ 4.921875, 45.920587 ], [ 5.229492, 46.195042 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.361328, 47.129951 ], [ 5.625000, 46.890232 ], [ 5.317383, 46.558860 ], [ 5.229492, 46.255847 ] ] } } +, +{ "type": "Feature", "properties": { "name": "62" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.229492, 46.255847 ], [ 5.317383, 46.255847 ], [ 5.317383, 46.073231 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.229492, 46.195042 ], [ 5.361328, 46.012224 ] ] } } +, +{ "type": "Feature", "properties": { "name": "611" }, "geometry": { "type": "LineString", "coordinates": [ [ 4.921875, 45.859412 ], [ 5.141602, 45.859412 ], [ 5.317383, 45.951150 ], [ 5.317383, 46.073231 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.361328, 46.012224 ], [ 5.361328, 45.981695 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.712891, 48.370848 ], [ 5.625000, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { "name": "21" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.888672, 48.661943 ], [ 5.932617, 48.516604 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.932617, 48.545705 ], [ 5.888672, 48.545705 ] ] } } +, +{ "type": "Feature", "properties": { "name": "21" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.932617, 48.516604 ], [ 5.844727, 48.224673 ] ] } } +, +{ "type": "Feature", "properties": { "name": "21" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 49.210420 ], [ 6.196289, 49.152970 ], [ 6.064453, 48.922499 ], [ 6.152344, 48.806863 ], [ 6.108398, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 48.719961 ], [ 6.196289, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { "name": "23" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.888672, 48.661943 ], [ 6.108398, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 48.690960 ], [ 6.152344, 48.719961 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.932617, 48.545705 ], [ 6.152344, 48.661943 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.196289, 48.690960 ], [ 6.152344, 48.661943 ] ] } } +, +{ "type": "Feature", "properties": { "name": "23" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 48.690960 ], [ 6.196289, 48.632909 ] ] } } +, +{ "type": "Feature", "properties": { "name": "23" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.635742, 48.048710 ], [ 6.635742, 48.107431 ], [ 6.196289, 48.400032 ], [ 6.196289, 48.632909 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.196289, 48.632909 ], [ 6.416016, 48.603858 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.712891, 48.341646 ], [ 5.712891, 48.370848 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.888672, 48.312428 ], [ 5.756836, 48.312428 ], [ 5.712891, 48.370848 ], [ 5.537109, 48.283193 ], [ 5.361328, 48.283193 ], [ 5.229492, 48.166085 ], [ 4.965820, 48.078079 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.888672, 48.545705 ], [ 5.888672, 48.487486 ], [ 5.712891, 48.370848 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.844727, 48.224673 ], [ 6.503906, 48.195387 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.416016, 48.603858 ], [ 6.723633, 48.574790 ], [ 6.855469, 48.603858 ], [ 6.987305, 48.719961 ], [ 7.250977, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.416016, 48.603858 ], [ 6.899414, 48.400032 ], [ 6.943359, 48.195387 ], [ 7.031250, 48.166085 ] ] } } +, +{ "type": "Feature", "properties": { "name": "17" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 47.635784 ], [ 5.976562, 47.724545 ], [ 5.800781, 47.724545 ], [ 5.405273, 47.872144 ], [ 5.273438, 47.872144 ] ] } } +, +{ "type": "Feature", "properties": { "name": "23" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.976562, 47.309034 ], [ 6.108398, 47.428087 ], [ 6.152344, 47.635784 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.976562, 47.279229 ], [ 6.020508, 47.219568 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.064453, 47.309034 ], [ 5.712891, 46.830134 ] ] } } +, +{ "type": "Feature", "properties": { "name": "23" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 47.635784 ], [ 6.416016, 47.813155 ], [ 6.416016, 47.931066 ], [ 6.635742, 48.048710 ] ] } } +, +{ "type": "Feature", "properties": { "name": "17" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.855469, 47.576526 ], [ 6.503906, 47.694974 ], [ 6.152344, 47.635784 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.338867, 47.754098 ], [ 6.943359, 47.665387 ], [ 6.855469, 47.576526 ] ] } } +, +{ "type": "Feature", "properties": { "name": "27" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.855469, 47.576526 ], [ 6.943359, 47.576526 ], [ 6.987305, 47.487513 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.855469, 47.576526 ], [ 6.811523, 47.457809 ], [ 6.020508, 47.309034 ], [ 5.844727, 47.189712 ], [ 5.361328, 47.129951 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.250977, 48.777913 ], [ 7.207031, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.954102, 48.458352 ], [ 7.646484, 48.545705 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.382812, 48.107431 ], [ 7.250977, 48.166085 ], [ 7.031250, 48.166085 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.734375, 48.690960 ], [ 7.690430, 48.574790 ], [ 7.514648, 48.516604 ], [ 7.470703, 48.341646 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.470703, 48.341646 ], [ 7.382812, 48.283193 ], [ 7.338867, 48.078079 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.470703, 48.341646 ], [ 7.646484, 48.429201 ], [ 7.778320, 48.661943 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.514648, 47.635784 ], [ 7.426758, 47.754098 ], [ 7.382812, 48.107431 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.382812, 48.107431 ], [ 7.646484, 48.048710 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.250977, 48.777913 ], [ 7.646484, 48.777913 ], [ 7.778320, 48.661943 ] ] } } +, +{ "type": "Feature", "properties": { "name": "52" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.690430, 48.603858 ], [ 7.822266, 48.603858 ], [ 7.954102, 48.516604 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.778320, 48.574790 ], [ 7.822266, 48.690960 ], [ 8.041992, 48.806863 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.778320, 48.661943 ], [ 7.910156, 48.719961 ], [ 8.173828, 48.980217 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.734375, 48.574790 ], [ 7.778320, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.690430, 48.516604 ], [ 7.734375, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.778320, 48.574790 ], [ 7.910156, 48.545705 ] ] } } +, +{ "type": "Feature", "properties": { "name": "35" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.393555, 48.980217 ], [ 7.954102, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { "name": "35" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.954102, 48.574790 ], [ 7.734375, 48.224673 ], [ 7.822266, 48.107431 ], [ 7.778320, 48.019324 ] ] } } +, +{ "type": "Feature", "properties": { "name": "531" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 47.989922 ], [ 8.393555, 48.136767 ], [ 8.217773, 48.166085 ], [ 8.217773, 48.283193 ], [ 7.998047, 48.312428 ], [ 7.954102, 48.458352 ] ] } } +, +{ "type": "Feature", "properties": { "name": "512" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.294922, 47.754098 ], [ 7.075195, 47.872144 ], [ 6.767578, 47.842658 ], [ 6.635742, 47.960502 ], [ 6.635742, 48.048710 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.338867, 48.078079 ], [ 7.338867, 47.783635 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.338867, 47.783635 ], [ 7.514648, 47.635784 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.338867, 47.754098 ], [ 7.382812, 47.783635 ] ] } } +, +{ "type": "Feature", "properties": { "name": "35" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.778320, 48.019324 ], [ 7.602539, 47.931066 ], [ 7.602539, 47.635784 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.558594, 47.783635 ], [ 7.338867, 47.754098 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.514648, 47.635784 ], [ 7.602539, 47.635784 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.602539, 47.635784 ], [ 7.646484, 47.546872 ], [ 7.822266, 47.546872 ] ] } } +, +{ "type": "Feature", "properties": { "name": "27" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.987305, 47.487513 ], [ 7.075195, 47.457809 ] ] } } +, +{ "type": "Feature", "properties": { "name": "27" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.075195, 47.457809 ], [ 7.207031, 47.368594 ], [ 7.382812, 47.338823 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.207031, 47.219568 ], [ 7.382812, 47.159840 ] ] } } +, +{ "type": "Feature", "properties": { "name": "27" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.382812, 47.338823 ], [ 7.382812, 47.279229 ], [ 7.207031, 47.219568 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.382812, 47.159840 ], [ 7.207031, 47.129951 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.207031, 47.129951 ], [ 7.031250, 47.040182 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.250977, 47.129951 ], [ 7.382812, 47.040182 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.646484, 47.546872 ], [ 7.646484, 47.457809 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.910156, 47.309034 ], [ 7.734375, 47.309034 ], [ 7.514648, 47.219568 ], [ 7.514648, 47.159840 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.514648, 47.189712 ], [ 7.382812, 47.159840 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.646484, 47.635784 ], [ 7.778320, 47.842658 ], [ 8.085938, 47.931066 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.217773, 47.457809 ], [ 8.129883, 47.457809 ], [ 8.041992, 47.546872 ], [ 7.602539, 47.635784 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.734375, 47.546872 ], [ 7.910156, 47.309034 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.822266, 47.309034 ], [ 7.910156, 47.309034 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.041992, 47.517201 ], [ 8.173828, 47.606163 ], [ 8.261719, 47.606163 ], [ 8.305664, 47.546872 ], [ 8.525391, 47.546872 ], [ 8.613281, 47.428087 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.217773, 47.457809 ], [ 7.910156, 47.309034 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.393555, 47.428087 ], [ 8.525391, 47.398349 ] ] } } +, +{ "type": "Feature", "properties": { "name": "35" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.910156, 47.309034 ], [ 7.998047, 47.189712 ], [ 8.173828, 47.189712 ], [ 8.305664, 47.070122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.437500, 47.159840 ], [ 8.305664, 47.070122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.305664, 47.070122 ], [ 8.305664, 47.010226 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.305664, 47.070122 ], [ 8.129883, 47.070122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.305664, 47.040182 ], [ 8.305664, 47.070122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.581055, 46.980252 ], [ 5.712891, 46.830134 ] ] } } +, +{ "type": "Feature", "properties": { "name": "21" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 46.134170 ], [ 5.844727, 46.073231 ], [ 5.844727, 46.164614 ], [ 5.712891, 46.164614 ], [ 5.317383, 46.073231 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 5.581055, 46.830134 ], [ 5.888672, 46.800059 ], [ 5.976562, 46.558860 ], [ 6.064453, 46.558860 ], [ 6.020508, 46.498392 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.020508, 46.498392 ], [ 6.108398, 46.498392 ], [ 6.064453, 46.316584 ], [ 6.152344, 46.286224 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 46.255847 ], [ 6.108398, 46.225453 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 46.195042 ], [ 6.240234, 46.286224 ], [ 6.503906, 46.377254 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.108398, 46.225453 ], [ 6.152344, 46.195042 ] ] } } +, +{ "type": "Feature", "properties": { "name": "23" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.416016, 46.709736 ], [ 6.328125, 47.159840 ], [ 5.976562, 47.279229 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.031250, 47.040182 ], [ 6.899414, 47.010226 ], [ 6.635742, 46.830134 ], [ 6.635742, 46.769968 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.416016, 46.739861 ], [ 6.591797, 46.739861 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.591797, 46.739861 ], [ 6.591797, 46.558860 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.943359, 46.980252 ], [ 6.855469, 47.100045 ], [ 6.679688, 47.040182 ], [ 6.591797, 47.070122 ], [ 6.591797, 47.129951 ], [ 6.328125, 47.129951 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.328125, 46.103709 ], [ 6.284180, 46.195042 ], [ 6.152344, 46.195042 ], [ 6.108398, 46.134170 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.152344, 46.164614 ], [ 6.108398, 46.255847 ], [ 6.284180, 46.468133 ], [ 6.503906, 46.558860 ], [ 6.679688, 46.558860 ], [ 6.811523, 46.498392 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.503906, 46.377254 ], [ 6.811523, 46.407564 ], [ 6.987305, 46.225453 ] ] } } +, +{ "type": "Feature", "properties": { "name": "27" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.811523, 46.498392 ], [ 6.899414, 46.468133 ], [ 6.943359, 46.316584 ], [ 7.119141, 46.134170 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.987305, 46.195042 ], [ 6.987305, 46.225453 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.987305, 46.225453 ], [ 6.987305, 46.195042 ] ] } } +, +{ "type": "Feature", "properties": { "name": "712" }, "geometry": { "type": "LineString", "coordinates": [ [ 5.976562, 45.736860 ], [ 6.108398, 45.981695 ], [ 6.240234, 46.012224 ], [ 6.328125, 46.103709 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 6.855469, 45.920587 ], [ 6.635742, 45.951150 ], [ 6.591797, 46.073231 ], [ 6.284180, 46.103709 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.943359, 45.798170 ], [ 6.855469, 45.920587 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 6.767578, 45.644768 ], [ 6.943359, 45.736860 ], [ 7.031250, 45.736860 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.382812, 46.950262 ], [ 7.207031, 46.980252 ], [ 6.811523, 46.830134 ], [ 6.767578, 46.769968 ], [ 6.591797, 46.739861 ] ] } } +, +{ "type": "Feature", "properties": { "name": "27" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.426758, 46.950262 ], [ 7.163086, 46.860191 ], [ 7.075195, 46.649436 ], [ 6.899414, 46.589069 ], [ 6.899414, 46.468133 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.382812, 47.040182 ], [ 7.470703, 47.010226 ], [ 7.426758, 46.950262 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.514648, 47.159840 ], [ 7.426758, 46.950262 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.470703, 46.980252 ], [ 7.426758, 46.950262 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.822266, 46.679594 ], [ 7.646484, 46.679594 ], [ 7.602539, 46.860191 ], [ 7.426758, 46.950262 ] ] } } +, +{ "type": "Feature", "properties": { "name": "62" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.119141, 46.134170 ], [ 7.558594, 46.286224 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 46.950262 ], [ 8.305664, 47.010226 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.305664, 47.010226 ], [ 8.173828, 46.769968 ], [ 7.866211, 46.679594 ] ] } } +, +{ "type": "Feature", "properties": { "name": "62" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.558594, 46.286224 ], [ 7.954102, 46.316584 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.954102, 46.316584 ], [ 8.261719, 46.528635 ], [ 8.569336, 46.619261 ] ] } } +, +{ "type": "Feature", "properties": { "name": "62" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.954102, 46.316584 ], [ 8.041992, 46.195042 ], [ 8.305664, 46.164614 ], [ 8.261719, 46.073231 ], [ 8.305664, 46.012224 ] ] } } +, +{ "type": "Feature", "properties": { "name": "27" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.119141, 46.134170 ], [ 7.250977, 45.981695 ], [ 7.207031, 45.890008 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.163086, 45.859412 ], [ 7.294922, 45.798170 ], [ 7.294922, 45.736860 ] ] } } +, +{ "type": "Feature", "properties": { "name": "27" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.207031, 45.890008 ], [ 7.163086, 45.828799 ], [ 7.338867, 45.736860 ] ] } } +, +{ "type": "Feature", "properties": { "name": "25" }, "geometry": { "type": "LineString", "coordinates": [ [ 7.778320, 45.614037 ], [ 7.646484, 45.767523 ], [ 7.163086, 45.706179 ], [ 6.943359, 45.798170 ] ] } } +, +{ "type": "Feature", "properties": { "name": "52" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.393555, 49.009051 ], [ 8.569336, 48.922499 ], [ 8.789062, 48.922499 ], [ 8.833008, 48.835797 ], [ 8.964844, 48.835797 ], [ 9.140625, 48.719961 ], [ 9.272461, 48.719961 ], [ 9.448242, 48.632909 ], [ 9.624023, 48.632909 ], [ 9.667969, 48.545705 ], [ 10.107422, 48.458352 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.096680, 48.864715 ], [ 9.228516, 48.835797 ], [ 9.316406, 48.748945 ], [ 9.711914, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.052734, 48.719961 ], [ 9.184570, 48.806863 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.833008, 47.842658 ], [ 8.613281, 47.931066 ], [ 8.569336, 48.195387 ], [ 8.657227, 48.224673 ], [ 8.657227, 48.370848 ], [ 8.789062, 48.429201 ], [ 9.008789, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.184570, 48.922499 ], [ 9.184570, 48.690960 ], [ 9.272461, 48.632909 ], [ 9.052734, 48.400032 ], [ 8.745117, 48.195387 ], [ 8.569336, 48.195387 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.184570, 48.806863 ], [ 9.228516, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.448242, 48.719961 ], [ 9.360352, 48.661943 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.228516, 48.777913 ], [ 9.316406, 48.835797 ], [ 9.887695, 48.806863 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.701172, 47.901614 ], [ 8.833008, 47.989922 ], [ 9.096680, 47.989922 ], [ 9.448242, 48.078079 ], [ 9.580078, 48.224673 ], [ 10.019531, 48.400032 ], [ 10.019531, 48.458352 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.481445, 47.931066 ], [ 8.525391, 47.989922 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 7.646484, 48.048710 ], [ 7.822266, 48.019324 ], [ 7.866211, 47.960502 ], [ 7.954102, 47.989922 ], [ 8.129883, 47.901614 ], [ 8.525391, 47.931066 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.525391, 47.989922 ], [ 8.613281, 47.989922 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.525391, 47.931066 ], [ 8.613281, 47.960502 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.481445, 47.901614 ], [ 8.613281, 47.813155 ], [ 8.657227, 47.694974 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.217773, 47.635784 ], [ 8.349609, 47.606163 ], [ 8.481445, 47.694974 ], [ 8.613281, 47.694974 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.701172, 47.546872 ], [ 8.613281, 47.665387 ], [ 8.657227, 47.694974 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.745117, 47.754098 ], [ 8.657227, 47.694974 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.876953, 47.813155 ], [ 8.745117, 47.754098 ] ] } } +, +{ "type": "Feature", "properties": { "name": "54" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.096680, 47.842658 ], [ 8.833008, 47.842658 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.789062, 47.546872 ], [ 9.096680, 47.606163 ], [ 9.140625, 47.665387 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.481445, 47.398349 ], [ 8.481445, 47.219568 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.964844, 47.249407 ], [ 8.745117, 47.249407 ], [ 8.525391, 47.368594 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.580078, 47.457809 ], [ 9.492188, 47.487513 ], [ 9.404297, 47.428087 ], [ 9.228516, 47.428087 ], [ 9.140625, 47.487513 ], [ 8.964844, 47.457809 ], [ 8.833008, 47.546872 ], [ 8.701172, 47.546872 ], [ 8.657227, 47.398349 ], [ 8.217773, 47.457809 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 47.249407 ], [ 8.437500, 47.189712 ], [ 8.437500, 47.100045 ], [ 8.613281, 47.010226 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.305664, 47.040182 ], [ 8.481445, 47.070122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.525391, 47.368594 ], [ 8.525391, 47.309034 ], [ 8.701172, 47.189712 ], [ 8.920898, 47.219568 ], [ 9.052734, 47.129951 ], [ 9.404297, 47.070122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 47.428087 ], [ 8.833008, 47.309034 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.833008, 47.309034 ], [ 8.789062, 47.189712 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.096680, 47.309034 ], [ 8.964844, 47.249407 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 46.890232 ], [ 8.876953, 46.860191 ], [ 8.920898, 46.920255 ], [ 9.008789, 46.920255 ], [ 9.096680, 47.010226 ], [ 9.052734, 47.129951 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.140625, 47.665387 ], [ 9.052734, 47.754098 ], [ 8.789062, 47.842658 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.789062, 47.872144 ], [ 9.140625, 47.813155 ], [ 9.272461, 47.694974 ], [ 9.492188, 47.665387 ] ] } } +, +{ "type": "Feature", "properties": { "name": "532" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.448242, 47.487513 ], [ 9.140625, 47.665387 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.019531, 48.370848 ], [ 9.887695, 48.253941 ], [ 9.755859, 47.901614 ], [ 9.667969, 47.872144 ], [ 9.624023, 47.606163 ] ] } } +, +{ "type": "Feature", "properties": { "name": "54" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.755859, 47.606163 ], [ 9.580078, 47.606163 ], [ 9.492188, 47.665387 ], [ 9.272461, 47.694974 ], [ 9.096680, 47.842658 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.492188, 47.665387 ], [ 9.536133, 47.606163 ], [ 9.755859, 47.546872 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.096680, 47.309034 ], [ 9.228516, 47.189712 ], [ 9.492188, 47.219568 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.492188, 47.219568 ], [ 9.448242, 47.159840 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.404297, 47.070122 ], [ 9.492188, 47.010226 ] ] } } +, +{ "type": "Feature", "properties": { "name": "43" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.580078, 47.457809 ], [ 9.711914, 47.457809 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.755859, 47.606163 ], [ 9.711914, 47.457809 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.755859, 47.487513 ], [ 9.624023, 47.249407 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.536133, 47.159840 ], [ 9.580078, 47.249407 ] ] } } +, +{ "type": "Feature", "properties": { "name": "43" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.448242, 47.040182 ], [ 9.492188, 47.279229 ], [ 9.667969, 47.457809 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.492188, 47.159840 ], [ 9.624023, 47.249407 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.448242, 47.159840 ], [ 9.536133, 47.159840 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.624023, 47.279229 ], [ 9.711914, 47.189712 ], [ 9.799805, 47.159840 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.107422, 48.864715 ], [ 10.458984, 48.864715 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.975586, 48.429201 ], [ 9.975586, 48.458352 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.019531, 48.400032 ], [ 10.107422, 48.341646 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.766602, 48.748945 ], [ 10.458984, 48.864715 ], [ 10.458984, 48.980217 ], [ 10.283203, 49.095452 ], [ 10.283203, 49.239121 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.766602, 48.719961 ], [ 10.810547, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.766602, 48.748945 ], [ 10.854492, 48.719961 ], [ 10.898438, 48.429201 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 48.429201 ], [ 10.898438, 48.224673 ], [ 10.810547, 48.078079 ] ] } } +, +{ "type": "Feature", "properties": { "name": "52" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.107422, 48.458352 ], [ 11.030273, 48.429201 ], [ 11.425781, 48.195387 ] ] } } +, +{ "type": "Feature", "properties": { "name": "43" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.151367, 48.019324 ], [ 10.019531, 47.813155 ], [ 9.799805, 47.724545 ], [ 9.755859, 47.606163 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.722656, 48.048710 ], [ 10.634766, 47.931066 ], [ 10.634766, 47.783635 ], [ 10.458984, 47.783635 ], [ 10.239258, 47.665387 ], [ 9.843750, 47.665387 ], [ 9.755859, 47.606163 ] ] } } +, +{ "type": "Feature", "properties": { "name": "562" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.151367, 48.019324 ], [ 10.371094, 47.783635 ], [ 10.371094, 47.694974 ], [ 10.502930, 47.665387 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.854492, 47.842658 ], [ 10.810547, 48.078079 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.789062, 47.189712 ], [ 8.569336, 47.040182 ] ] } } +, +{ "type": "Feature", "properties": { "name": "41" }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 47.010226 ], [ 8.613281, 46.920255 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 46.679594 ], [ 8.613281, 46.558860 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 46.950262 ], [ 8.657227, 46.739861 ], [ 8.613281, 46.679594 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 46.619261 ], [ 8.613281, 46.619261 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.613281, 46.558860 ], [ 8.745117, 46.528635 ], [ 8.833008, 46.437857 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 8.569336, 46.619261 ], [ 8.833008, 46.679594 ], [ 8.876953, 46.739861 ], [ 9.272461, 46.800059 ], [ 9.360352, 46.860191 ], [ 9.404297, 46.860191 ] ] } } +, +{ "type": "Feature", "properties": { "name": "43" }, "geometry": { "type": "LineString", "coordinates": [ [ 9.492188, 47.010226 ], [ 9.536133, 46.950262 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.601562, 52.187405 ], [ 11.645508, 52.456009 ], [ 11.909180, 52.616390 ], [ 11.733398, 52.802761 ], [ 11.733398, 52.908902 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.865234, 52.589701 ], [ 11.821289, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.348633, 52.988337 ], [ 12.436523, 52.935397 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.128906, 52.961875 ], [ 12.041016, 52.776186 ], [ 12.084961, 52.643063 ], [ 11.997070, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.480469, 52.855864 ], [ 12.348633, 52.749594 ], [ 12.348633, 52.616390 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.744141, 52.908902 ], [ 12.480469, 52.855864 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.304688, 52.988337 ], [ 12.436523, 52.961875 ], [ 12.612305, 52.696361 ], [ 12.963867, 52.562995 ], [ 13.271484, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.348633, 52.616390 ], [ 12.348633, 52.536273 ], [ 12.524414, 52.429222 ] ] } } +, +{ "type": "Feature", "properties": { "name": "251" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.183594, 52.722986 ], [ 13.227539, 52.855864 ], [ 13.139648, 52.935397 ], [ 13.183594, 53.120405 ] ] } } +, +{ "type": "Feature", "properties": { "name": "26" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.051758, 52.722986 ], [ 12.788086, 52.802761 ], [ 12.744141, 52.935397 ], [ 12.568359, 53.014783 ], [ 12.568359, 53.014783 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.963867, 52.482780 ], [ 12.963867, 52.536273 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.183594, 52.882391 ], [ 13.007812, 52.882391 ], [ 12.832031, 52.961875 ], [ 12.744141, 52.908902 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.007812, 52.722986 ], [ 13.271484, 52.749594 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.875977, 52.589701 ], [ 13.007812, 52.722986 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.271484, 52.749594 ], [ 13.227539, 52.776186 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.271484, 52.749594 ], [ 13.271484, 52.696361 ] ] } } +, +{ "type": "Feature", "properties": { "name": "26" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.227539, 52.722986 ], [ 13.183594, 52.669720 ], [ 13.315430, 52.616390 ], [ 13.271484, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.359375, 52.562995 ], [ 13.271484, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.535156, 52.855864 ], [ 13.315430, 52.908902 ], [ 13.183594, 52.882391 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.447266, 52.749594 ], [ 13.227539, 52.776186 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.666992, 52.855864 ], [ 13.535156, 52.855864 ] ] } } +, +{ "type": "Feature", "properties": { "name": "28" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.579102, 52.643063 ], [ 13.579102, 52.776186 ], [ 13.798828, 52.935397 ], [ 13.886719, 53.120405 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.754883, 52.375599 ], [ 13.798828, 52.482780 ], [ 13.666992, 52.616390 ], [ 13.491211, 52.643063 ], [ 13.359375, 52.722986 ], [ 13.051758, 52.722986 ], [ 12.963867, 52.482780 ], [ 12.832031, 52.402419 ], [ 12.832031, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.403320, 52.562995 ], [ 13.403320, 52.616390 ], [ 13.271484, 52.696361 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.359375, 52.562995 ], [ 13.403320, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.359375, 52.509535 ], [ 13.359375, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.271484, 52.509535 ], [ 13.359375, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.359375, 52.482780 ], [ 13.359375, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.403320, 52.509535 ], [ 13.754883, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.491211, 52.643063 ], [ 13.447266, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.271484, 52.509535 ], [ 13.447266, 52.509535 ], [ 13.447266, 52.589701 ], [ 13.315430, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.403320, 52.562995 ], [ 13.447266, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.491211, 52.562995 ], [ 13.535156, 52.616390 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.447266, 52.562995 ], [ 13.491211, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.447266, 52.749594 ], [ 13.579102, 52.696361 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.579102, 52.696361 ], [ 13.623047, 52.669720 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.447266, 52.643063 ], [ 13.535156, 52.616390 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.623047, 52.669720 ], [ 13.579102, 52.643063 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.579102, 52.643063 ], [ 13.579102, 52.696361 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.579102, 52.616390 ], [ 13.579102, 52.643063 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.535156, 52.616390 ], [ 13.579102, 52.616390 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.579102, 52.616390 ], [ 13.623047, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.623047, 52.589701 ], [ 13.754883, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.798828, 52.829321 ], [ 13.666992, 52.855864 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.623047, 52.669720 ], [ 13.623047, 52.749594 ], [ 13.798828, 52.829321 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.798828, 52.829321 ], [ 14.018555, 52.776186 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.754883, 52.509535 ], [ 14.370117, 52.536273 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.798828, 52.829321 ], [ 14.018555, 53.014783 ], [ 14.194336, 53.041213 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.018555, 52.776186 ], [ 14.106445, 52.776186 ], [ 14.150391, 52.696361 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.150391, 52.696361 ], [ 14.414062, 52.536273 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.370117, 52.536273 ], [ 14.589844, 52.589701 ], [ 14.897461, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.633789, 52.589701 ], [ 14.633789, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.029297, 52.882391 ], [ 15.029297, 52.829321 ], [ 15.249023, 52.696361 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.897461, 52.562995 ], [ 15.205078, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.205078, 52.722986 ], [ 14.721680, 52.643063 ], [ 14.633789, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.249023, 52.696361 ], [ 15.424805, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.249023, 52.696361 ], [ 15.205078, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.205078, 52.589701 ], [ 15.424805, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.424805, 52.589701 ], [ 15.512695, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.249023, 52.696361 ], [ 15.292969, 52.776186 ], [ 15.380859, 52.802761 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.424805, 52.589701 ], [ 15.512695, 52.589701 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.512695, 52.589701 ], [ 16.171875, 52.562995 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.513672, 52.187405 ], [ 11.557617, 52.079506 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.645508, 52.079506 ], [ 11.557617, 52.079506 ] ] } } +, +{ "type": "Feature", "properties": { "name": "49" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.216797, 51.426614 ], [ 12.128906, 51.454007 ], [ 11.997070, 51.563412 ], [ 11.865234, 51.590723 ], [ 11.821289, 51.672555 ], [ 11.645508, 51.727028 ], [ 11.689453, 51.971346 ], [ 11.601562, 52.160455 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.645508, 52.160455 ], [ 11.645508, 52.106505 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.645508, 52.187405 ], [ 11.645508, 52.160455 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.260742, 51.890054 ], [ 11.733398, 52.133488 ], [ 11.645508, 52.106505 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.821289, 52.214339 ], [ 11.733398, 52.133488 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.865234, 52.268157 ], [ 11.821289, 52.214339 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.997070, 52.562995 ], [ 12.128906, 52.375599 ], [ 11.865234, 52.268157 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.557617, 52.079506 ], [ 11.469727, 51.971346 ], [ 11.337891, 51.944265 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.172852, 52.402419 ], [ 12.524414, 52.429222 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.524414, 52.429222 ], [ 12.612305, 52.402419 ] ] } } +, +{ "type": "Feature", "properties": { "name": "30" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.283203, 52.348763 ], [ 10.810547, 52.321911 ], [ 11.030273, 52.241256 ], [ 11.601562, 52.160455 ], [ 11.777344, 52.241256 ], [ 12.260742, 52.241256 ], [ 12.436523, 52.268157 ], [ 12.524414, 52.348763 ], [ 12.832031, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.612305, 52.402419 ], [ 12.612305, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.612305, 52.348763 ], [ 12.612305, 52.133488 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.392578, 51.890054 ], [ 12.260742, 51.890054 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 9.843750, 51.454007 ], [ 9.931641, 51.399206 ], [ 10.590820, 51.426614 ], [ 10.678711, 51.481383 ], [ 11.557617, 51.454007 ], [ 11.733398, 51.399206 ], [ 11.865234, 51.426614 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.909180, 51.590723 ], [ 11.865234, 51.426614 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.953125, 51.289406 ], [ 11.953125, 51.289406 ], [ 11.865234, 51.426614 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.041016, 51.508742 ], [ 12.128906, 51.426614 ], [ 12.172852, 51.426614 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.656250, 51.808615 ], [ 12.436523, 51.699800 ], [ 12.436523, 51.618017 ], [ 12.348633, 51.645294 ], [ 12.172852, 51.536086 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.612305, 51.618017 ], [ 12.656250, 51.808615 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.832031, 52.402419 ], [ 12.612305, 52.402419 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.963867, 52.482780 ], [ 12.963867, 52.536273 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.963867, 52.456009 ], [ 12.963867, 52.482780 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.051758, 52.402419 ], [ 12.963867, 52.456009 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.832031, 52.321911 ], [ 12.832031, 52.402419 ] ] } } +, +{ "type": "Feature", "properties": { "name": "30" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.832031, 52.348763 ], [ 12.919922, 52.295042 ], [ 13.579102, 52.321911 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.832031, 52.402419 ], [ 13.051758, 52.402419 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.612305, 52.133488 ], [ 12.700195, 52.106505 ] ] } } +, +{ "type": "Feature", "properties": { "name": "51" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.260742, 51.481383 ], [ 12.260742, 51.808615 ], [ 12.919922, 52.214339 ], [ 12.919922, 52.295042 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.700195, 52.106505 ], [ 12.875977, 52.079506 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.875977, 52.079506 ], [ 13.007812, 52.241256 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.875977, 52.079506 ], [ 12.656250, 51.862924 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.051758, 52.295042 ], [ 13.051758, 52.402419 ] ] } } +, +{ "type": "Feature", "properties": { "name": "51" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.271484, 52.509535 ], [ 13.095703, 52.321911 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.183594, 52.429222 ], [ 13.359375, 52.482780 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.271484, 52.509535 ], [ 13.359375, 52.482780 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.315430, 52.295042 ], [ 13.227539, 52.214339 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.007812, 52.241256 ], [ 13.051758, 52.295042 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.656250, 51.862924 ], [ 12.392578, 51.890054 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.656250, 51.808615 ], [ 12.656250, 51.862924 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.875977, 52.079506 ], [ 13.007812, 51.998410 ], [ 13.095703, 51.998410 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.227539, 52.214339 ], [ 13.227539, 52.106505 ], [ 13.095703, 51.998410 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.183594, 51.781436 ], [ 12.963867, 51.781436 ], [ 12.656250, 51.862924 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.095703, 51.998410 ], [ 13.183594, 51.781436 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.183594, 51.781436 ], [ 13.271484, 51.699800 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.447266, 52.348763 ], [ 13.535156, 52.375599 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.447266, 52.295042 ], [ 13.447266, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.447266, 52.214339 ], [ 13.447266, 52.295042 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.535156, 52.375599 ], [ 13.579102, 52.402419 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.535156, 52.375599 ], [ 13.579102, 52.402419 ] ] } } +, +{ "type": "Feature", "properties": { "name": "36" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.579102, 52.321911 ], [ 13.579102, 52.402419 ], [ 13.491211, 52.456009 ], [ 13.271484, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { "name": "30" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.579102, 52.321911 ], [ 13.754883, 52.375599 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.491211, 52.052490 ], [ 13.447266, 52.214339 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.095703, 51.971346 ], [ 13.271484, 51.890054 ], [ 13.666992, 51.835778 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.623047, 51.971346 ], [ 13.491211, 52.052490 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.183594, 51.618017 ], [ 13.271484, 51.727028 ], [ 13.403320, 51.699800 ], [ 13.842773, 51.917168 ] ] } } +, +{ "type": "Feature", "properties": { "name": "36" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.930664, 51.835778 ], [ 13.798828, 51.917168 ], [ 13.798828, 51.998410 ], [ 13.666992, 52.052490 ], [ 13.579102, 52.321911 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.754883, 51.944265 ], [ 13.623047, 51.971346 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.886719, 51.944265 ], [ 13.754883, 51.944265 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.886719, 51.944265 ], [ 13.798828, 51.890054 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.842773, 51.917168 ], [ 14.194336, 52.079506 ], [ 14.194336, 52.187405 ], [ 14.370117, 52.214339 ], [ 14.501953, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.930664, 51.835778 ], [ 13.930664, 51.645294 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.271484, 51.699800 ], [ 13.315430, 51.618017 ] ] } } +, +{ "type": "Feature", "properties": { "name": "48" }, "geometry": { "type": "LineString", "coordinates": [ [ 10.898438, 49.951220 ], [ 11.337891, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.172852, 49.525208 ], [ 12.172852, 49.496675 ] ] } } +, +{ "type": "Feature", "properties": { "name": "51" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.557617, 49.866317 ], [ 11.557617, 49.781264 ], [ 11.074219, 49.382373 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.250000, 49.468124 ], [ 11.293945, 49.496675 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.250000, 49.410973 ], [ 11.162109, 49.525208 ], [ 10.986328, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { "name": "56" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.601562, 49.296472 ], [ 11.250000, 49.410973 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.250000, 49.468124 ], [ 11.293945, 49.410973 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.250000, 49.410973 ], [ 11.997070, 49.410973 ], [ 12.172852, 49.496675 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.162109, 49.382373 ], [ 11.250000, 49.095452 ], [ 11.469727, 48.951366 ], [ 11.469727, 48.690960 ], [ 11.645508, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { "name": "56" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.601562, 49.296472 ], [ 11.733398, 49.152970 ], [ 11.865234, 49.152970 ], [ 11.909180, 49.066668 ], [ 12.084961, 49.009051 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.997070, 49.382373 ], [ 12.041016, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.041016, 49.353756 ], [ 12.172852, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.700195, 48.719961 ], [ 12.612305, 48.864715 ], [ 12.656250, 49.210420 ], [ 12.304688, 49.210420 ], [ 12.260742, 49.095452 ], [ 12.084961, 49.037868 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.084961, 49.009051 ], [ 12.128906, 48.980217 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.084961, 49.009051 ], [ 12.084961, 48.980217 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.084961, 48.951366 ], [ 12.084961, 48.980217 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.172852, 49.496675 ], [ 12.216797, 49.525208 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.139648, 48.951366 ], [ 13.095703, 48.951366 ] ] } } +, +{ "type": "Feature", "properties": { "name": "53" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.963867, 48.835797 ], [ 13.095703, 48.893615 ], [ 13.139648, 48.980217 ], [ 13.227539, 48.980217 ], [ 13.227539, 49.152970 ], [ 13.315430, 49.210420 ], [ 13.271484, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { "name": "30" }, "geometry": { "type": "LineString", "coordinates": [ [ 13.754883, 52.348763 ], [ 14.501953, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.370117, 52.536273 ], [ 14.589844, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.545898, 52.348763 ], [ 14.238281, 52.429222 ], [ 14.150391, 52.509535 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.545898, 52.348763 ], [ 14.545898, 52.321911 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.545898, 52.321911 ], [ 14.633789, 52.214339 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.633789, 52.214339 ], [ 14.633789, 52.133488 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.633789, 52.133488 ], [ 14.677734, 51.971346 ] ] } } +, +{ "type": "Feature", "properties": { "name": "36" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.721680, 51.672555 ], [ 14.458008, 51.727028 ], [ 14.150391, 51.727028 ], [ 14.062500, 51.808615 ], [ 13.930664, 51.835778 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.414062, 51.862924 ], [ 14.326172, 51.754240 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.326172, 51.727028 ], [ 14.326172, 51.754240 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.326172, 51.754240 ], [ 14.458008, 51.727028 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.677734, 51.971346 ], [ 14.589844, 51.944265 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.589844, 51.944265 ], [ 14.414062, 51.862924 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.545898, 52.348763 ], [ 14.677734, 52.321911 ], [ 14.765625, 52.214339 ], [ 15.161133, 52.025459 ] ] } } +, +{ "type": "Feature", "properties": { "name": "36" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.600586, 51.371780 ], [ 15.292969, 51.454007 ], [ 14.809570, 51.672555 ] ] } } +, +{ "type": "Feature", "properties": { "name": "36" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.809570, 51.672555 ], [ 14.721680, 51.672555 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.161133, 51.645294 ], [ 14.897461, 51.645294 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.117188, 52.052490 ], [ 15.117188, 52.025459 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.677734, 51.971346 ], [ 14.765625, 51.944265 ], [ 15.117188, 52.025459 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.161133, 52.025459 ], [ 15.556641, 51.944265 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.292969, 51.618017 ], [ 15.161133, 51.645294 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.326172, 51.645294 ], [ 14.326172, 51.727028 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.458008, 51.727028 ], [ 14.545898, 51.672555 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.512695, 51.563412 ], [ 15.292969, 51.618017 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.292969, 51.234407 ], [ 15.644531, 51.344339 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.512695, 52.589701 ], [ 15.556641, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.556641, 52.348763 ], [ 15.556641, 52.268157 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.512695, 52.241256 ], [ 15.556641, 52.241256 ] ] } } +, +{ "type": "Feature", "properties": { "name": "30" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.501953, 52.348763 ], [ 15.117188, 52.321911 ], [ 15.556641, 52.241256 ], [ 15.732422, 52.348763 ], [ 16.127930, 52.375599 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.556641, 52.268157 ], [ 15.600586, 52.079506 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.600586, 52.079506 ], [ 15.644531, 52.025459 ], [ 15.556641, 51.998410 ], [ 15.556641, 51.944265 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.556641, 51.944265 ], [ 15.688477, 51.862924 ], [ 15.732422, 51.699800 ], [ 16.127930, 51.481383 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.732422, 51.808615 ], [ 15.600586, 51.754240 ], [ 15.556641, 51.563412 ] ] } } +, +{ "type": "Feature", "properties": { "name": "30" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.127930, 52.375599 ], [ 16.918945, 52.375599 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.556641, 51.563412 ], [ 15.600586, 51.536086 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.952148, 51.590723 ], [ 15.952148, 51.536086 ], [ 15.864258, 51.508742 ], [ 15.600586, 51.536086 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.600586, 51.536086 ], [ 15.600586, 51.371780 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.600586, 51.371780 ], [ 15.556641, 51.261915 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.820312, 51.261915 ], [ 15.556641, 51.261915 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.556641, 51.261915 ], [ 15.600586, 51.096623 ] ] } } +, +{ "type": "Feature", "properties": { "name": "36" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.776367, 51.289406 ], [ 15.600586, 51.371780 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.171875, 51.151786 ], [ 15.776367, 51.289406 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.600586, 51.096623 ], [ 15.732422, 50.903033 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.688477, 50.903033 ], [ 15.776367, 50.930738 ], [ 15.908203, 50.903033 ], [ 16.083984, 50.958427 ], [ 16.083984, 50.903033 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.171875, 51.041394 ], [ 16.083984, 50.903033 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.083984, 50.875311 ], [ 16.083984, 50.930738 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.996094, 50.708634 ], [ 16.083984, 50.875311 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.215820, 51.426614 ], [ 16.127930, 51.261915 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.127930, 51.454007 ], [ 16.215820, 51.426614 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.215820, 51.399206 ], [ 16.040039, 51.371780 ], [ 15.952148, 51.261915 ], [ 15.820312, 51.261915 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.215820, 51.426614 ], [ 16.347656, 51.261915 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.127930, 51.261915 ], [ 16.171875, 51.041394 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.699219, 51.013755 ], [ 16.303711, 51.151786 ], [ 16.171875, 51.151786 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.347656, 51.261915 ], [ 16.655273, 51.151786 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.083984, 50.930738 ], [ 16.347656, 50.847573 ], [ 16.567383, 50.847573 ], [ 16.962891, 51.041394 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.644531, 50.345460 ], [ 15.688477, 50.317408 ], [ 15.820312, 50.205033 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.249023, 50.035974 ], [ 15.205078, 50.035974 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.468750, 49.837982 ], [ 15.249023, 50.035974 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.633789, 49.639177 ], [ 14.633789, 49.639177 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.633789, 49.639177 ], [ 14.633789, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.633789, 49.553726 ], [ 14.721680, 49.382373 ] ] } } +, +{ "type": "Feature", "properties": { "name": "49" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.106445, 49.325122 ], [ 14.150391, 49.325122 ], [ 14.194336, 49.124219 ], [ 14.545898, 49.009051 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.721680, 49.382373 ], [ 14.721680, 49.239121 ], [ 14.458008, 49.009051 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.501953, 49.009051 ], [ 14.458008, 48.922499 ] ] } } +, +{ "type": "Feature", "properties": { "name": "49" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.677734, 49.210420 ], [ 14.721680, 49.037868 ], [ 14.853516, 48.951366 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.853516, 49.809632 ], [ 14.941406, 49.752880 ], [ 15.073242, 49.724479 ], [ 15.117188, 49.610710 ], [ 15.600586, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { "name": "49" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.545898, 49.009051 ], [ 14.765625, 49.009051 ] ] } } +, +{ "type": "Feature", "properties": { "name": "551" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.336914, 49.525208 ], [ 15.073242, 49.325122 ], [ 15.029297, 49.124219 ], [ 14.765625, 49.009051 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.996094, 50.680797 ], [ 15.996094, 50.708634 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 15.908203, 50.373496 ], [ 15.864258, 50.485474 ], [ 15.864258, 50.513427 ] ], [ [ 15.996094, 50.680797 ], [ 15.996094, 50.680797 ] ] ] } } +, +{ "type": "Feature", "properties": { "name": "67" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.776367, 50.233152 ], [ 15.908203, 50.373496 ], [ 16.083984, 50.401515 ] ] } } +, +{ "type": "Feature", "properties": { "name": "67" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.083984, 50.401515 ], [ 16.215820, 50.457504 ], [ 16.303711, 50.401515 ], [ 16.435547, 50.401515 ], [ 16.787109, 50.513427 ], [ 16.875000, 50.903033 ] ] } } +, +{ "type": "Feature", "properties": { "name": "67" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.336914, 50.148746 ], [ 15.688477, 50.148746 ], [ 15.820312, 50.233152 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.820312, 50.205033 ], [ 15.820312, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.523438, 49.781264 ], [ 16.215820, 49.894634 ], [ 15.820312, 50.205033 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.820312, 49.951220 ], [ 15.820312, 49.724479 ], [ 15.644531, 49.610710 ], [ 15.336914, 49.525208 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.600586, 49.468124 ], [ 15.468750, 49.837982 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.600586, 49.468124 ], [ 15.600586, 49.439557 ] ] } } +, +{ "type": "Feature", "properties": { "name": "59" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.556641, 49.325122 ], [ 15.600586, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { "name": "59" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.688477, 49.124219 ], [ 15.556641, 49.325122 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.600586, 49.468124 ], [ 15.688477, 49.410973 ], [ 15.908203, 49.410973 ], [ 16.611328, 49.152970 ] ] } } +, +{ "type": "Feature", "properties": { "name": "461" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.479492, 49.781264 ], [ 16.611328, 49.525208 ], [ 16.523438, 49.152970 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.567383, 49.210420 ], [ 16.655273, 49.181703 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.831055, 49.181703 ], [ 16.655273, 49.152970 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.611328, 49.152970 ], [ 16.523438, 48.980217 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.611328, 49.152970 ], [ 16.743164, 48.922499 ], [ 16.918945, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { "name": "261" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.962891, 52.375599 ], [ 16.962891, 52.348763 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.171875, 52.562995 ], [ 16.918945, 52.402419 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 17.006836, 52.375599 ], [ 17.006836, 52.348763 ] ], [ [ 16.875000, 52.375599 ], [ 16.918945, 52.429222 ] ] ] } } +, +{ "type": "Feature", "properties": { "name": "261" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.918945, 52.375599 ], [ 16.699219, 52.268157 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.006836, 52.375599 ], [ 17.050781, 52.295042 ], [ 17.270508, 52.214339 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 17.402344, 52.160455 ], [ 17.490234, 51.971346 ] ], [ [ 17.270508, 52.214339 ], [ 17.358398, 52.187405 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.490234, 51.971346 ], [ 17.797852, 51.890054 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.446289, 51.699800 ], [ 17.094727, 51.699800 ], [ 16.875000, 51.618017 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.490234, 51.971346 ], [ 17.402344, 51.699800 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.797852, 51.645294 ], [ 17.446289, 51.699800 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.490234, 51.971346 ], [ 17.797852, 51.890054 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.797852, 51.890054 ], [ 17.797852, 51.672555 ], [ 17.929688, 51.344339 ], [ 18.149414, 51.206883 ], [ 18.281250, 50.958427 ], [ 18.544922, 50.847573 ], [ 18.676758, 50.680797 ], [ 18.676758, 50.569283 ], [ 18.940430, 50.373496 ], [ 18.984375, 50.261254 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.841797, 51.645294 ], [ 17.797852, 51.645294 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.105469, 51.754240 ], [ 17.841797, 51.645294 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.061523, 51.781436 ], [ 18.061523, 51.754240 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 17.929688, 51.862924 ], [ 18.105469, 51.754240 ] ], [ [ 17.797852, 51.890054 ], [ 17.885742, 51.890054 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.797852, 51.645294 ], [ 18.105469, 51.754240 ] ] } } +, +{ "type": "Feature", "properties": { "name": "261" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.699219, 52.268157 ], [ 16.699219, 52.133488 ], [ 16.523438, 51.971346 ], [ 16.655273, 51.754240 ], [ 16.875000, 51.618017 ], [ 16.918945, 51.399206 ], [ 17.050781, 51.316881 ], [ 17.006836, 51.206883 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.402344, 51.699800 ], [ 17.270508, 51.590723 ], [ 17.270508, 51.454007 ], [ 17.006836, 51.316881 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.611328, 51.179343 ], [ 16.918945, 51.151786 ], [ 17.006836, 51.096623 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.962891, 51.041394 ], [ 16.875000, 51.069017 ], [ 16.699219, 51.013755 ] ] } } +, +{ "type": "Feature", "properties": { "name": "67" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.875000, 50.903033 ], [ 16.962891, 51.041394 ] ] } } +, +{ "type": "Feature", "properties": { "name": "261" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.006836, 51.206883 ], [ 16.962891, 51.041394 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.050781, 51.124213 ], [ 17.050781, 51.096623 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.050781, 51.096623 ], [ 16.962891, 51.041394 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.050781, 51.096623 ], [ 17.314453, 50.958427 ], [ 17.314453, 50.903033 ], [ 17.490234, 50.847573 ] ] } } +, +{ "type": "Feature", "properties": { "name": "67" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.962891, 51.069017 ], [ 17.182617, 51.179343 ], [ 17.314453, 51.179343 ], [ 17.666016, 51.289406 ], [ 18.369141, 51.316881 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.490234, 50.847573 ], [ 17.622070, 50.764259 ], [ 17.929688, 50.680797 ] ] } } +, +{ "type": "Feature", "properties": { "name": "30" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.006836, 52.375599 ], [ 16.918945, 52.375599 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.105469, 51.754240 ], [ 18.149414, 51.754240 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.369141, 51.316881 ], [ 18.500977, 51.426614 ], [ 18.632812, 51.454007 ], [ 18.632812, 51.481383 ] ] } } +, +{ "type": "Feature", "properties": { "name": "67" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.369141, 51.316881 ], [ 18.500977, 51.234407 ], [ 18.632812, 51.234407 ], [ 18.896484, 51.316881 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.116211, 50.819818 ], [ 18.588867, 51.041394 ], [ 18.588867, 51.206883 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.632812, 50.708634 ], [ 19.160156, 50.819818 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.379883, 51.041394 ], [ 19.379883, 51.041394 ], [ 19.204102, 50.930738 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.204102, 50.930738 ], [ 19.072266, 50.792047 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.655273, 50.429518 ], [ 17.006836, 50.457504 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.006836, 50.457504 ], [ 17.358398, 50.457504 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.655273, 50.457504 ], [ 17.182617, 50.457504 ], [ 17.709961, 50.680797 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.358398, 50.457504 ], [ 17.490234, 50.429518 ], [ 17.578125, 50.317408 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.962891, 51.041394 ], [ 17.226562, 50.847573 ], [ 17.666016, 50.708634 ], [ 18.017578, 50.485474 ], [ 18.281250, 50.485474 ], [ 18.544922, 50.345460 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.666016, 50.680797 ], [ 17.929688, 50.708634 ], [ 18.061523, 50.652943 ], [ 18.457031, 50.764259 ], [ 18.632812, 50.708634 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.578125, 50.317408 ], [ 17.885742, 50.345460 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.929688, 50.680797 ], [ 17.929688, 50.541363 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.237305, 50.680797 ], [ 17.929688, 50.680797 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.929688, 50.680797 ], [ 18.325195, 50.513427 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.929688, 50.541363 ], [ 17.973633, 50.457504 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.973633, 50.457504 ], [ 18.105469, 50.345460 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.885742, 50.345460 ], [ 18.105469, 50.345460 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.105469, 50.345460 ], [ 18.413086, 50.261254 ], [ 18.676758, 50.289339 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.105469, 50.345460 ], [ 18.237305, 50.092393 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.281250, 49.837982 ], [ 18.061523, 49.951220 ], [ 17.841797, 49.979488 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.182617, 49.582226 ], [ 17.138672, 49.667628 ], [ 16.875000, 49.781264 ], [ 16.479492, 49.781264 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.402344, 49.610710 ], [ 17.270508, 49.553726 ], [ 17.182617, 49.582226 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.578125, 49.553726 ], [ 17.402344, 49.610710 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.446289, 49.468124 ], [ 17.534180, 49.525208 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.446289, 49.066668 ], [ 17.534180, 49.124219 ], [ 17.534180, 49.267805 ], [ 17.446289, 49.325122 ], [ 17.446289, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.050781, 49.325122 ], [ 16.831055, 49.181703 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.831055, 49.181703 ], [ 16.962891, 49.181703 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.962891, 49.181703 ], [ 17.138672, 49.181703 ] ] } } +, +{ "type": "Feature", "properties": { "name": "462" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.226562, 49.582226 ], [ 17.050781, 49.325122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.006836, 49.267805 ], [ 17.226562, 49.325122 ], [ 17.358398, 49.296472 ], [ 17.446289, 49.353756 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.138672, 49.181703 ], [ 17.402344, 49.066668 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.709961, 49.553726 ], [ 17.578125, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { "name": "462" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.797852, 49.582226 ], [ 17.709961, 49.553726 ] ] } } +, +{ "type": "Feature", "properties": { "name": "462" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.325195, 49.639177 ], [ 18.193359, 49.639177 ], [ 17.973633, 49.553726 ], [ 17.797852, 49.582226 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.709961, 49.553726 ], [ 17.929688, 49.496675 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.369141, 49.951220 ], [ 18.105469, 49.752880 ], [ 17.753906, 49.582226 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.929688, 49.496675 ], [ 18.017578, 49.468124 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.534180, 49.210420 ], [ 17.578125, 49.181703 ], [ 17.666016, 49.239121 ], [ 17.885742, 49.239121 ], [ 17.973633, 49.325122 ], [ 18.017578, 49.610710 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.402344, 49.066668 ], [ 17.622070, 49.037868 ], [ 17.709961, 48.980217 ], [ 17.885742, 48.980217 ], [ 17.973633, 48.893615 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.457031, 50.625073 ], [ 18.237305, 50.680797 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.325195, 50.513427 ], [ 18.413086, 50.485474 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.413086, 50.485474 ], [ 18.632812, 50.401515 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.720703, 50.373496 ], [ 18.544922, 50.345460 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.632812, 50.513427 ], [ 18.457031, 50.625073 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.852539, 50.429518 ], [ 18.764648, 50.513427 ], [ 18.632812, 50.513427 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.676758, 50.289339 ], [ 18.676758, 50.317408 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.632812, 50.401515 ], [ 18.808594, 50.373496 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.116211, 50.317408 ], [ 18.720703, 50.373496 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.808594, 50.373496 ], [ 18.852539, 50.345460 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.896484, 50.345460 ], [ 18.852539, 50.429518 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.852539, 50.345460 ], [ 18.896484, 50.345460 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.896484, 50.345460 ], [ 18.940430, 50.345460 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.940430, 50.345460 ], [ 19.028320, 50.261254 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.544922, 50.345460 ], [ 18.588867, 50.261254 ], [ 19.028320, 50.261254 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.676758, 50.289339 ], [ 18.544922, 50.120578 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.237305, 50.092393 ], [ 18.544922, 50.092393 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.544922, 50.092393 ], [ 18.720703, 50.035974 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.237305, 50.092393 ], [ 18.193359, 50.035974 ], [ 18.325195, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.325195, 49.951220 ], [ 18.369141, 49.894634 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.544922, 50.120578 ], [ 18.500977, 50.007739 ], [ 18.369141, 49.951220 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.676758, 50.289339 ], [ 18.808594, 50.401515 ], [ 18.984375, 50.457504 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.720703, 50.035974 ], [ 18.940430, 49.979488 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.072266, 50.792047 ], [ 19.204102, 50.485474 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.984375, 50.457504 ], [ 19.204102, 50.457504 ] ] } } +, +{ "type": "Feature", "properties": { "name": "462" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.467773, 50.289339 ], [ 19.116211, 50.317408 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.204102, 50.485474 ], [ 19.248047, 50.373496 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.204102, 50.429518 ], [ 19.072266, 50.261254 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.204102, 50.457504 ], [ 19.467773, 50.485474 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.984375, 50.261254 ], [ 18.720703, 50.092393 ], [ 18.808594, 49.781264 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.072266, 50.261254 ], [ 19.116211, 50.233152 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.028320, 50.261254 ], [ 19.072266, 50.176898 ], [ 18.984375, 50.148746 ], [ 19.028320, 50.092393 ], [ 18.940430, 50.064192 ], [ 18.940430, 50.007739 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.160156, 50.233152 ], [ 19.160156, 50.148746 ], [ 19.028320, 50.120578 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.248047, 50.373496 ], [ 19.160156, 50.233152 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.028320, 50.261254 ], [ 19.160156, 50.233152 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.116211, 50.233152 ], [ 19.160156, 50.233152 ] ] } } +, +{ "type": "Feature", "properties": { "name": "40" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.160156, 50.233152 ], [ 19.248047, 50.148746 ], [ 19.467773, 50.176898 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.160156, 50.233152 ], [ 19.423828, 50.148746 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.940430, 50.007739 ], [ 19.028320, 49.866317 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.423828, 50.148746 ], [ 19.467773, 50.148746 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.423828, 49.866317 ], [ 19.028320, 49.837982 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.676758, 49.752880 ], [ 18.281250, 49.837982 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.237305, 49.866317 ], [ 18.369141, 49.667628 ] ] } } +, +{ "type": "Feature", "properties": { "name": "462" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.676758, 49.752880 ], [ 18.632812, 49.696062 ], [ 18.325195, 49.639177 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.369141, 49.667628 ], [ 18.457031, 49.468124 ], [ 18.413086, 49.410973 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.632812, 49.752880 ], [ 18.808594, 49.809632 ] ] } } +, +{ "type": "Feature", "properties": { "name": "462" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.028320, 49.866317 ], [ 18.808594, 49.752880 ], [ 18.676758, 49.752880 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.017578, 49.468124 ], [ 18.237305, 49.468124 ], [ 18.500977, 49.382373 ] ] } } +, +{ "type": "Feature", "properties": { "name": "442" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.500977, 49.382373 ], [ 18.588867, 49.210420 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.973633, 48.893615 ], [ 17.973633, 48.951366 ], [ 18.369141, 49.037868 ], [ 18.588867, 49.210420 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.588867, 49.210420 ], [ 18.720703, 49.210420 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.632812, 49.696062 ], [ 18.720703, 49.639177 ], [ 18.764648, 49.468124 ], [ 18.852539, 49.439557 ], [ 18.764648, 49.210420 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.764648, 49.210420 ], [ 18.984375, 49.095452 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.808594, 49.809632 ], [ 19.028320, 49.809632 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.028320, 49.809632 ], [ 19.204102, 49.696062 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.984375, 49.095452 ], [ 19.116211, 49.152970 ], [ 19.291992, 49.066668 ] ] } } +, +{ "type": "Feature", "properties": { "name": "77" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.116211, 48.835797 ], [ 19.248047, 48.864715 ], [ 19.291992, 49.095452 ] ] } } +, +{ "type": "Feature", "properties": { "name": "77" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.291992, 49.066668 ], [ 19.291992, 49.210420 ], [ 19.379883, 49.239121 ] ] } } +, +{ "type": "Feature", "properties": { "name": "50" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.291992, 49.066668 ], [ 19.335938, 49.095452 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 10.810547, 48.690960 ], [ 11.030273, 48.690960 ], [ 11.337891, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.337891, 48.777913 ], [ 11.469727, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.469727, 48.690960 ], [ 11.821289, 48.777913 ], [ 11.909180, 48.893615 ], [ 12.084961, 48.951366 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.337891, 48.224673 ], [ 11.162109, 48.078079 ] ] } } +, +{ "type": "Feature", "properties": { "name": "54" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.425781, 48.166085 ], [ 10.898438, 48.048710 ], [ 10.327148, 48.048710 ], [ 10.151367, 47.989922 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.425781, 48.224673 ], [ 11.425781, 48.166085 ], [ 11.513672, 48.136767 ] ] } } +, +{ "type": "Feature", "properties": { "name": "52" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.513672, 48.253941 ], [ 11.425781, 48.224673 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.513672, 48.136767 ], [ 11.601562, 48.253941 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.557617, 48.136767 ], [ 11.601562, 48.166085 ] ] } } +, +{ "type": "Feature", "properties": { "name": "533" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.513672, 48.166085 ], [ 11.425781, 47.960502 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.513672, 48.136767 ], [ 11.513672, 48.107431 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.513672, 48.107431 ], [ 11.557617, 48.136767 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.601562, 48.253941 ], [ 11.601562, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { "name": "53" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.469727, 48.253941 ], [ 11.513672, 48.312428 ], [ 11.953125, 48.429201 ], [ 12.084961, 48.574790 ], [ 12.744141, 48.719961 ], [ 12.919922, 48.835797 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.601562, 48.166085 ], [ 11.645508, 48.224673 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.601562, 48.166085 ], [ 11.689453, 48.048710 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.645508, 48.136767 ], [ 11.557617, 48.136767 ] ] } } +, +{ "type": "Feature", "properties": { "name": "52" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.689453, 48.078079 ], [ 11.777344, 48.195387 ], [ 11.689453, 48.253941 ], [ 11.513672, 48.253941 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.777344, 48.136767 ], [ 11.645508, 48.136767 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.557617, 48.107431 ], [ 11.601562, 48.107431 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 11.513672, 48.136767 ], [ 11.645508, 48.048710 ], [ 11.689453, 48.078079 ] ] } } +, +{ "type": "Feature", "properties": { "name": "552" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.777344, 48.136767 ], [ 11.909180, 48.166085 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.172852, 49.496675 ], [ 12.084961, 48.893615 ], [ 11.909180, 48.748945 ], [ 11.733398, 48.690960 ], [ 11.645508, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { "name": "552" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.909180, 48.166085 ], [ 12.216797, 48.166085 ], [ 12.392578, 48.253941 ] ] } } +, +{ "type": "Feature", "properties": { "name": "552" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.392578, 48.253941 ], [ 12.832031, 48.253941 ] ] } } +, +{ "type": "Feature", "properties": { "name": "45" }, "geometry": { "type": "LineString", "coordinates": [ [ 11.689453, 48.078079 ], [ 11.689453, 47.989922 ] ] } } +, +{ "type": "Feature", "properties": { "name": "56" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.084961, 49.009051 ], [ 12.480469, 48.980217 ], [ 12.963867, 48.835797 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.403320, 48.429201 ], [ 13.271484, 48.341646 ], [ 13.007812, 48.283193 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.062500, 49.325122 ], [ 13.754883, 49.037868 ], [ 13.710938, 48.864715 ], [ 13.491211, 48.806863 ], [ 13.491211, 48.690960 ], [ 13.227539, 48.661943 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.359375, 48.574790 ], [ 13.403320, 48.545705 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.403320, 48.545705 ], [ 13.403320, 48.487486 ] ] } } +, +{ "type": "Feature", "properties": { "name": "56" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.963867, 48.835797 ], [ 13.403320, 48.574790 ], [ 13.403320, 48.341646 ], [ 13.491211, 48.283193 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.447266, 48.574790 ], [ 13.403320, 48.545705 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.403320, 48.487486 ], [ 13.403320, 48.429201 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 13.403320, 48.487486 ], [ 13.447266, 48.400032 ], [ 13.623047, 48.400032 ], [ 14.106445, 48.283193 ], [ 14.326172, 48.312428 ] ] } } +, +{ "type": "Feature", "properties": { "name": "552" }, "geometry": { "type": "LineString", "coordinates": [ [ 12.832031, 48.253941 ], [ 13.227539, 48.283193 ], [ 13.271484, 48.253941 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 12.832031, 48.224673 ], [ 12.788086, 48.166085 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.458008, 48.922499 ], [ 14.458008, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.458008, 48.777913 ], [ 14.458008, 48.370848 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.458008, 48.370848 ], [ 14.282227, 48.283193 ], [ 14.282227, 48.224673 ] ] } } +, +{ "type": "Feature", "properties": { "name": "55" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.194336, 48.166085 ], [ 14.282227, 48.224673 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 14.106445, 48.195387 ], [ 14.326172, 48.224673 ] ] } } +, +{ "type": "Feature", "properties": { "name": "49" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.853516, 48.951366 ], [ 14.897461, 48.864715 ] ] } } +, +{ "type": "Feature", "properties": { "name": "49" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.897461, 48.864715 ], [ 14.941406, 48.806863 ], [ 14.985352, 48.835797 ], [ 15.117188, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 14.282227, 48.224673 ], [ 14.501953, 48.224673 ], [ 14.633789, 48.107431 ], [ 14.853516, 48.166085 ], [ 15.205078, 48.166085 ], [ 15.292969, 48.224673 ], [ 15.512695, 48.166085 ], [ 15.820312, 48.195387 ], [ 16.435547, 48.136767 ] ] } } +, +{ "type": "Feature", "properties": { "name": "59" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.083984, 48.777913 ], [ 16.040039, 48.893615 ], [ 15.688477, 49.124219 ] ] } } +, +{ "type": "Feature", "properties": { "name": "59" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.083984, 48.632909 ], [ 16.083984, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { "name": "59" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.171875, 48.400032 ], [ 16.083984, 48.632909 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.732422, 48.224673 ], [ 15.776367, 48.341646 ], [ 15.644531, 48.429201 ] ] } } +, +{ "type": "Feature", "properties": { "name": "49" }, "geometry": { "type": "LineString", "coordinates": [ [ 15.117188, 48.777913 ], [ 15.688477, 48.661943 ], [ 16.127930, 48.429201 ], [ 16.127930, 48.370848 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.996094, 48.136767 ], [ 15.996094, 48.078079 ], [ 16.171875, 48.048710 ], [ 16.347656, 48.166085 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.083984, 48.835797 ], [ 16.523438, 48.980217 ] ] } } +, +{ "type": "Feature", "properties": { "name": "461" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.523438, 48.980217 ], [ 16.655273, 48.748945 ] ] } } +, +{ "type": "Feature", "properties": { "name": "461" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.655273, 48.748945 ], [ 16.611328, 48.516604 ] ] } } +, +{ "type": "Feature", "properties": { "name": "461" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.611328, 48.516604 ], [ 16.479492, 48.370848 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.655273, 48.603858 ], [ 16.787109, 48.690960 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.787109, 48.690960 ], [ 16.918945, 48.777913 ] ] } } +, +{ "type": "Feature", "properties": { "name": "461" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.479492, 48.370848 ], [ 16.347656, 48.312428 ] ] } } +, +{ "type": "Feature", "properties": { "name": "59" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.347656, 48.136767 ], [ 16.391602, 48.283193 ], [ 16.303711, 48.370848 ], [ 16.171875, 48.400032 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.743164, 48.048710 ], [ 16.435547, 48.136767 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 15.644531, 48.429201 ], [ 15.864258, 48.429201 ], [ 16.040039, 48.370848 ], [ 16.435547, 48.400032 ], [ 16.523438, 48.283193 ], [ 16.347656, 48.166085 ] ] } } +, +{ "type": "Feature", "properties": { "name": "49" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.127930, 47.724545 ], [ 15.776367, 47.635784 ] ] } } +, +{ "type": "Feature", "properties": { "name": "59" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.127930, 47.517201 ], [ 16.127930, 47.754098 ], [ 16.215820, 47.783635 ], [ 16.215820, 47.960502 ], [ 16.347656, 48.048710 ], [ 16.303711, 48.136767 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.699219, 47.606163 ], [ 16.391602, 47.931066 ], [ 16.391602, 48.166085 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.479492, 47.813155 ], [ 16.347656, 47.754098 ], [ 16.215820, 47.842658 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.226562, 47.872144 ], [ 17.138672, 47.783635 ], [ 17.226562, 47.724545 ], [ 17.270508, 47.517201 ], [ 16.787109, 47.279229 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.918945, 48.777913 ], [ 17.094727, 48.893615 ], [ 17.314453, 48.893615 ], [ 17.446289, 49.066668 ] ] } } +, +{ "type": "Feature", "properties": { "name": "58" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.743164, 48.048710 ], [ 16.875000, 48.107431 ], [ 17.138672, 48.107431 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 16.918945, 48.777913 ], [ 17.050781, 48.574790 ], [ 17.006836, 48.224673 ], [ 17.094727, 48.107431 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.138672, 48.136767 ], [ 17.226562, 48.195387 ] ] } } +, +{ "type": "Feature", "properties": { "name": "65" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.094727, 48.107431 ], [ 17.182617, 48.048710 ], [ 17.182617, 47.872144 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.094727, 48.107431 ], [ 17.270508, 48.224673 ], [ 17.446289, 48.224673 ], [ 17.534180, 48.312428 ], [ 17.709961, 48.370848 ], [ 17.797852, 48.632909 ], [ 17.929688, 48.690960 ], [ 17.973633, 48.893615 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.973633, 48.893615 ], [ 18.193359, 48.806863 ], [ 18.237305, 48.719961 ] ] } } +, +{ "type": "Feature", "properties": { "name": "58" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.622070, 48.312428 ], [ 17.753906, 48.253941 ], [ 18.017578, 48.341646 ], [ 18.149414, 48.312428 ] ] } } +, +{ "type": "Feature", "properties": { "name": "575" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.105469, 48.312428 ], [ 18.193359, 47.960502 ], [ 18.193359, 47.813155 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.226562, 47.872144 ], [ 16.875000, 47.960502 ], [ 16.875000, 48.019324 ], [ 16.743164, 48.019324 ], [ 16.743164, 48.078079 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.699219, 47.606163 ], [ 17.050781, 47.576526 ], [ 17.578125, 47.694974 ] ] } } +, +{ "type": "Feature", "properties": { "name": "60" }, "geometry": { "type": "LineString", "coordinates": [ [ 17.885742, 47.665387 ], [ 17.578125, 47.665387 ], [ 17.226562, 47.872144 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.237305, 48.719961 ], [ 18.457031, 48.719961 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.457031, 48.719961 ], [ 18.764648, 48.777913 ], [ 18.764648, 48.632909 ], [ 18.896484, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.896484, 48.574790 ], [ 18.940430, 48.748945 ], [ 18.852539, 48.893615 ], [ 18.940430, 49.095452 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.940430, 48.603858 ], [ 19.116211, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { "name": "571" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.149414, 48.312428 ], [ 18.237305, 48.370848 ], [ 18.632812, 48.370848 ], [ 18.764648, 48.516604 ], [ 18.940430, 48.603858 ] ] } } +, +{ "type": "Feature", "properties": { "name": "77" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.116211, 48.661943 ], [ 19.116211, 48.835797 ] ] } } +, +{ "type": "Feature", "properties": { "name": "77" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.116211, 48.574790 ], [ 19.116211, 48.661943 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.116211, 48.574790 ], [ 19.160156, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { "name": "77" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.896484, 48.107431 ], [ 18.852539, 48.136767 ], [ 18.852539, 48.195387 ], [ 19.072266, 48.341646 ], [ 19.116211, 48.574790 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.072266, 48.574790 ], [ 19.291992, 48.545705 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 16.347656, 48.048710 ], [ 16.918945, 47.279229 ], [ 16.918945, 47.279229 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 17.666016, 47.665387 ], [ 17.709961, 47.576526 ] ] } } +, +{ "type": "Feature", "properties": { "name": "70" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.544922, 45.120053 ], [ 18.588867, 45.120053 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.764648, 45.490946 ], [ 18.808594, 45.490946 ] ] } } +, +{ "type": "Feature", "properties": { "name": "73" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.940430, 45.398450 ], [ 18.808594, 45.490946 ] ] } } +, +{ "type": "Feature", "properties": { "name": "70" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.588867, 45.120053 ], [ 18.808594, 45.058001 ], [ 19.335938, 45.058001 ] ] } } +, +{ "type": "Feature", "properties": { "name": "73" }, "geometry": { "type": "LineString", "coordinates": [ [ 18.720703, 45.089036 ], [ 18.808594, 45.274886 ], [ 18.720703, 45.305803 ], [ 18.720703, 45.398450 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.808594, 45.274886 ], [ 18.984375, 45.367584 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.808594, 45.552525 ], [ 19.072266, 45.521744 ], [ 19.116211, 45.614037 ], [ 18.984375, 45.644768 ], [ 18.984375, 45.706179 ], [ 19.116211, 45.767523 ] ] } } +, +{ "type": "Feature", "properties": { "name": "662" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.423828, 45.243953 ], [ 19.335938, 45.367584 ], [ 19.248047, 45.367584 ], [ 19.291992, 45.521744 ], [ 19.204102, 45.552525 ], [ 19.160156, 45.828799 ], [ 19.204102, 45.859412 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.072266, 45.305803 ], [ 18.940430, 45.398450 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.863281, 45.305803 ], [ 19.819336, 45.243953 ], [ 19.511719, 45.274886 ], [ 19.291992, 45.213004 ], [ 19.072266, 45.305803 ] ] } } +, +{ "type": "Feature", "properties": { "name": "662" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.423828, 45.026950 ], [ 19.423828, 45.243953 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.995117, 45.981695 ], [ 19.995117, 45.920587 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.907227, 45.274886 ], [ 19.731445, 45.367584 ], [ 19.687500, 45.798170 ], [ 19.731445, 45.920587 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.643555, 45.798170 ], [ 20.039062, 45.614037 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.995117, 45.920587 ], [ 20.083008, 45.920587 ], [ 20.126953, 45.798170 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.126953, 45.798170 ], [ 20.039062, 45.614037 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.039062, 45.521744 ], [ 19.907227, 45.460131 ], [ 19.819336, 45.336702 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.863281, 45.243953 ], [ 19.819336, 45.243953 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.819336, 45.243953 ], [ 19.819336, 45.213004 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.819336, 45.336702 ], [ 19.863281, 45.243953 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.907227, 45.274886 ], [ 19.819336, 45.213004 ], [ 19.863281, 45.089036 ], [ 19.731445, 44.715514 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.434570, 44.809122 ], [ 19.995117, 45.089036 ], [ 19.863281, 45.243953 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.039062, 45.614037 ], [ 20.039062, 45.521744 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.170898, 45.583290 ], [ 20.039062, 45.614037 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.302734, 45.490946 ], [ 20.170898, 45.583290 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.610352, 46.073231 ], [ 20.610352, 46.073231 ], [ 20.522461, 45.951150 ], [ 20.698242, 45.859412 ], [ 20.698242, 45.736860 ], [ 20.566406, 45.644768 ], [ 20.434570, 45.367584 ], [ 20.126953, 45.398450 ], [ 19.863281, 45.305803 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.390625, 45.367584 ], [ 20.302734, 45.490946 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.390625, 45.367584 ], [ 20.390625, 45.213004 ] ] } } +, +{ "type": "Feature", "properties": { "name": "671" }, "geometry": { "type": "LineString", "coordinates": [ [ 21.225586, 45.767523 ], [ 21.181641, 46.012224 ], [ 21.225586, 46.042736 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 21.225586, 45.767523 ], [ 21.049805, 45.736860 ], [ 21.005859, 45.798170 ], [ 20.698242, 45.798170 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 21.269531, 45.243953 ], [ 21.445312, 45.274886 ], [ 21.708984, 45.026950 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 21.884766, 45.583290 ], [ 21.840820, 45.490946 ], [ 21.840820, 45.429299 ], [ 21.928711, 45.398450 ], [ 21.840820, 45.026950 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.544922, 44.809122 ], [ 18.676758, 44.933696 ], [ 18.720703, 45.089036 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.544922, 44.527843 ], [ 18.588867, 44.527843 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.632812, 44.465151 ], [ 18.588867, 44.527843 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.588867, 44.527843 ], [ 18.720703, 44.276671 ], [ 18.632812, 44.119142 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.588867, 44.527843 ], [ 18.764648, 44.527843 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.808594, 44.465151 ], [ 18.632812, 44.465151 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.764648, 44.527843 ], [ 18.808594, 44.465151 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.984375, 44.402392 ], [ 18.808594, 44.465151 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.940430, 44.182204 ], [ 18.896484, 44.245199 ], [ 18.720703, 44.245199 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.072266, 45.058001 ], [ 18.984375, 45.367584 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.731445, 44.715514 ], [ 19.555664, 44.777936 ], [ 19.291992, 44.653024 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.379883, 45.026950 ], [ 19.423828, 45.026950 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 18.588867, 44.527843 ], [ 18.588867, 44.621754 ], [ 18.544922, 44.653024 ] ], [ [ 18.544922, 44.809122 ], [ 18.808594, 44.871443 ], [ 19.028320, 44.840291 ], [ 19.204102, 44.746733 ], [ 19.335938, 44.840291 ], [ 19.291992, 44.933696 ], [ 19.423828, 45.058001 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.116211, 44.402392 ], [ 18.984375, 44.402392 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.291992, 44.653024 ], [ 19.160156, 44.527843 ], [ 19.160156, 44.276671 ], [ 19.028320, 44.150681 ], [ 18.940430, 44.182204 ], [ 18.940430, 44.056012 ], [ 18.852539, 43.992815 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.291992, 44.496505 ], [ 19.204102, 44.527843 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.632812, 44.119142 ], [ 18.588867, 44.087585 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 18.852539, 43.992815 ], [ 18.808594, 43.929550 ], [ 18.720703, 43.897892 ] ] } } +, +{ "type": "Feature", "properties": { "name": "762" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.072266, 43.707594 ], [ 19.028320, 43.739352 ] ] } } +, +{ "type": "Feature", "properties": { "name": "762" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.072266, 43.707594 ], [ 19.072266, 43.707594 ] ] } } +, +{ "type": "Feature", "properties": { "name": "761" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.731445, 43.802819 ], [ 19.511719, 43.834527 ], [ 19.511719, 43.771094 ], [ 19.072266, 43.707594 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.643555, 43.389082 ], [ 19.643555, 43.357138 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.731445, 44.715514 ], [ 19.731445, 44.746733 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.907227, 45.274886 ], [ 20.083008, 45.213004 ], [ 20.083008, 45.120053 ], [ 20.478516, 44.809122 ] ] } } +, +{ "type": "Feature", "properties": { "name": "70" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.335938, 45.058001 ], [ 20.258789, 44.809122 ], [ 20.478516, 44.809122 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.346680, 44.746733 ], [ 20.302734, 44.621754 ], [ 20.039062, 44.653024 ], [ 19.995117, 44.590467 ], [ 19.907227, 44.590467 ], [ 19.731445, 44.715514 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.258789, 44.809122 ], [ 20.346680, 44.715514 ], [ 20.434570, 44.715514 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.731445, 44.715514 ], [ 19.731445, 44.527843 ], [ 19.907227, 44.402392 ], [ 19.863281, 44.276671 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.248047, 44.527843 ], [ 19.423828, 44.496505 ], [ 19.863281, 44.276671 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.863281, 44.276671 ], [ 20.039062, 44.276671 ], [ 20.214844, 44.370987 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.390625, 45.213004 ], [ 20.390625, 45.026950 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.390625, 45.026950 ], [ 20.522461, 44.809122 ] ] } } +, +{ "type": "Feature", "properties": { "name": "70" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.478516, 44.809122 ], [ 20.654297, 44.871443 ], [ 20.742188, 44.995883 ], [ 20.874023, 45.058001 ], [ 21.269531, 45.089036 ], [ 21.313477, 45.182037 ], [ 21.225586, 45.274886 ], [ 21.181641, 45.644768 ], [ 21.225586, 45.767523 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.478516, 44.777936 ], [ 20.478516, 44.684277 ], [ 20.698242, 44.465151 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.654297, 44.559163 ], [ 20.698242, 44.308127 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.214844, 44.370987 ], [ 20.566406, 44.339565 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.566406, 44.339565 ], [ 20.698242, 44.308127 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.698242, 44.308127 ], [ 20.698242, 44.245199 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 21.181641, 44.621754 ], [ 20.961914, 44.590467 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.961914, 44.590467 ], [ 20.961914, 44.559163 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.961914, 44.590467 ], [ 21.093750, 44.621754 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.698242, 44.245199 ], [ 20.917969, 44.024422 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.775391, 43.897892 ], [ 19.599609, 43.834527 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.863281, 43.866218 ], [ 19.819336, 43.866218 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 19.819336, 43.866218 ], [ 19.775391, 43.897892 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.039062, 43.834527 ], [ 19.907227, 44.024422 ], [ 19.863281, 44.276671 ] ] } } +, +{ "type": "Feature", "properties": { "name": "761" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.039062, 43.834527 ], [ 19.951172, 43.802819 ], [ 19.819336, 43.866218 ], [ 19.731445, 43.802819 ] ] } } +, +{ "type": "Feature", "properties": { "name": "761" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.390625, 43.897892 ], [ 20.302734, 43.866218 ], [ 20.126953, 43.929550 ], [ 20.039062, 43.834527 ] ] } } +, +{ "type": "Feature", "properties": { "name": "763" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.434570, 44.809122 ], [ 20.434570, 44.684277 ], [ 20.302734, 44.590467 ], [ 20.214844, 44.370987 ], [ 20.302734, 44.276671 ], [ 20.258789, 44.182204 ], [ 20.478516, 44.150681 ], [ 20.390625, 43.897892 ] ] } } +, +{ "type": "Feature", "properties": { "name": "761" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.566406, 43.897892 ], [ 20.390625, 43.897892 ] ] } } +, +{ "type": "Feature", "properties": { "name": "761" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.786133, 43.961191 ], [ 20.566406, 43.897892 ] ] } } +, +{ "type": "Feature", "properties": { "name": "761" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.566406, 43.897892 ], [ 20.698242, 43.707594 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.698242, 43.707594 ], [ 20.698242, 43.739352 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 21.093750, 44.182204 ], [ 21.005859, 44.150681 ], [ 21.005859, 44.056012 ], [ 20.786133, 43.929550 ], [ 20.742188, 43.707594 ] ] } } +, +{ "type": "Feature", "properties": { "name": "761" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.698242, 43.707594 ], [ 21.005859, 43.612217 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.874023, 43.644026 ], [ 20.961914, 43.612217 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.698242, 43.707594 ], [ 20.566406, 43.644026 ], [ 20.610352, 43.452919 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 21.708984, 44.653024 ], [ 21.577148, 44.809122 ], [ 21.577148, 44.995883 ], [ 21.708984, 45.058001 ], [ 21.928711, 45.026950 ], [ 22.016602, 44.933696 ], [ 22.148438, 44.933696 ], [ 22.192383, 44.995883 ], [ 22.280273, 44.995883 ] ], [ [ 22.280273, 44.995883 ], [ 22.324219, 44.933696 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 21.181641, 44.621754 ], [ 21.269531, 44.590467 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 20.698242, 44.245199 ], [ 21.093750, 44.245199 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 20.478516, 44.809122 ], [ 20.610352, 44.684277 ], [ 20.610352, 44.590467 ], [ 20.917969, 44.590467 ], [ 21.049805, 44.496505 ], [ 21.093750, 44.150681 ], [ 21.269531, 44.024422 ] ] } } +, +{ "type": "Feature", "properties": { "name": "70" }, "geometry": { "type": "LineString", "coordinates": [ [ 21.577148, 45.798170 ], [ 21.225586, 45.767523 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 21.093750, 44.621754 ], [ 21.489258, 44.590467 ], [ 21.665039, 44.465151 ], [ 21.840820, 44.496505 ], [ 21.884766, 44.370987 ], [ 21.972656, 44.433780 ], [ 21.972656, 44.370987 ], [ 22.192383, 44.339565 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 22.016602, 44.056012 ], [ 22.060547, 44.056012 ] ], [ [ 21.269531, 44.590467 ], [ 21.313477, 44.465151 ], [ 21.533203, 44.245199 ], [ 21.928711, 44.213710 ], [ 22.016602, 44.056012 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 21.137695, 44.621754 ], [ 21.533203, 44.746733 ], [ 21.533203, 44.684277 ], [ 21.621094, 44.653024 ], [ 21.928711, 44.653024 ], [ 22.060547, 44.465151 ], [ 22.192383, 44.465151 ] ], [ [ 22.192383, 44.465151 ], [ 22.324219, 44.684277 ] ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 22.192383, 44.339565 ], [ 22.192383, 44.465151 ] ] } } +, +{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 22.324219, 44.308127 ], [ 22.192383, 44.339565 ] ] } } +, +{ "type": "Feature", "properties": { "name": "75" }, "geometry": { "type": "LineString", "coordinates": [ [ 21.269531, 44.024422 ], [ 21.269531, 43.961191 ], [ 21.401367, 43.961191 ], [ 21.445312, 43.802819 ] ] } } +, +{ "type": "Feature", "properties": { "name": "761" }, "geometry": { "type": "LineString", "coordinates": [ [ 21.401367, 43.866218 ], [ 21.621094, 43.866218 ] ] } } +, +{ "type": "Feature", "properties": { "name": "763" }, "geometry": { "type": "LineString", "coordinates": [ [ 19.731445, 43.802819 ], [ 19.687500, 43.675818 ], [ 19.819336, 43.484812 ], [ 19.643555, 43.452919 ], [ 19.687500, 43.325178 ] ] } } +] } +] } diff --git a/tests/pbf/roads-1-1-0.pbf b/tests/pbf/roads-1-1-0.pbf new file mode 100644 index 0000000000000000000000000000000000000000..22a26fbf44a2174d5cd11c88c23d039aa80610d8 GIT binary patch literal 267536 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

-7u098gmHhg45RyJX=$1-VE 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 literal 0 HcmV?d00001 From c7649e39e5b917c329646ef20d7247e237e6ab9f Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Mon, 25 Nov 2024 15:54:41 -0800 Subject: [PATCH 16/24] Add missing fixture, and don't crash if it is missing --- clip.cpp | 5 ++ tests/pbf/region.json | 135 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 tests/pbf/region.json diff --git a/clip.cpp b/clip.cpp index c162a788..dda4032f 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1174,8 +1174,13 @@ bool pnpoly_mp(drawvec const &geom, long long x, long long y) { clipbbox parse_clip_poly(std::string arg) { json_pull *jp = json_begin_string(arg.c_str()); json_object *j = json_read_tree(jp); + if (j == NULL) { + fprintf(stderr, "Expected JSON object, not %s\n", arg.c_str()); + exit(EXIT_ARGS); + } if (j->type != JSON_HASH) { fprintf(stderr, "Expected JSON geometry object, not %s\n", arg.c_str()); + exit(EXIT_ARGS); } std::pair parsed_geometry = parse_geometry(j, jp, j, 0, 0, 0, 1LL << 32, false); diff --git a/tests/pbf/region.json b/tests/pbf/region.json new file mode 100644 index 00000000..19b21c96 --- /dev/null +++ b/tests/pbf/region.json @@ -0,0 +1,135 @@ + { + "coordinates": [ + [ + [ + [ + 13.577060272719763, + 53.17369971291083 + ], + [ + 10.704205888641951, + 52.74867374387799 + ], + [ + 8.234559137417222, + 50.4321686022941 + ], + [ + 4.20248280888643, + 49.91569934015271 + ], + [ + 3.3960675431802656, + 47.351710786357756 + ], + [ + 4.958497120486356, + 45.82785468647634 + ], + [ + 7.680148642243836, + 45.54618382040567 + ], + [ + 10.704205888641951, + 47.82759699398349 + ], + [ + 13.728263135039242, + 48.332677316517476 + ], + [ + 16.903523243756865, + 47.24917200504791 + ], + [ + 19.272368086768267, + 48.26561972235635 + ], + [ + 19.52437285730184, + 50.97481113632679 + ], + [ + 16.701919427330296, + 52.53459175523133 + ], + [ + 13.577060272719763, + 53.17369971291083 + ] + ], + [ + [ + 14.78668317127898, + 51.66775442536286 + ], + [ + 12.46823928237373, + 51.6051918576735 + ], + [ + 11.208215429708275, + 50.78400718973347 + ], + [ + 11.359418292027812, + 49.980563422399655 + ], + [ + 12.417838328266726, + 49.39363856874314 + ], + [ + 14.181871721999357, + 49.32798696801095 + ], + [ + 16.046707023944435, + 50.62440671313237 + ], + [ + 14.78668317127898, + 51.66775442536286 + ] + ] + ], + [ + [ + [ + 21.055284848897287, + 46.16048194834923 + ], + [ + 18.988845730525668, + 45.81027671022295 + ], + [ + 18.53523714356635, + 45.13878150945956 + ], + [ + 18.585638097672586, + 43.989754759795915 + ], + [ + 19.896062904445103, + 43.18663878167516 + ], + [ + 22.31530870156351, + 44.134624205316555 + ], + [ + 22.31530870156351, + 45.280813880909534 + ], + [ + 21.055284848897287, + 46.16048194834923 + ] + ] + ] + ], + "type": "MultiPolygon" + } From f41970b72ae931c4a69be312925d48a8a5bc2104 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Tue, 26 Nov 2024 13:17:29 -0800 Subject: [PATCH 17/24] Remember to do polygon clipping after binning too --- clip.cpp | 117 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 54 deletions(-) diff --git a/clip.cpp b/clip.cpp index dda4032f..0f366fba 100644 --- a/clip.cpp +++ b/clip.cpp @@ -460,6 +460,51 @@ drawvec clip_point_poly(drawvec &geom, drawvec const &bounds) { return out; } +static Clipper2Lib::Paths64 geom_to_clipper(drawvec const &geom) { + Clipper2Lib::Paths64 subject; + + for (size_t i = 0; i < geom.size(); i++) { + if (geom[i].op == VT_MOVETO) { + Clipper2Lib::Path64 path({{geom[i].x, geom[i].y}}); + size_t j; + for (j = i + 1; j < geom.size(); j++) { + if (geom[j].op != VT_LINETO) { + break; + } + path.emplace_back(geom[j].x, geom[j].y); + } + subject.push_back(path); + } + } + + return subject; +} + +static void clipper_to_geom(Clipper2Lib::Paths64 const &geom, drawvec &out) { + for (auto const &ring : geom) { + for (size_t i = 0; i < ring.size(); i++) { + out.emplace_back(i == 0 ? VT_MOVETO : VT_LINETO, ring[i].x, ring[i].y); + } + } +} + +drawvec clip_lines(drawvec const &geom, drawvec const ®ion) { + Clipper2Lib::Paths64 subject = geom_to_clipper(geom); + Clipper2Lib::Paths64 clip = geom_to_clipper(region); + + Clipper2Lib::Clipper64 clipper; + clipper.AddOpenSubject(subject); + clipper.AddClip(clip); + + Clipper2Lib::Paths64 solution, open_solution; + clipper.Execute(Clipper2Lib::ClipType::Intersection, Clipper2Lib::FillRule::Positive, solution, open_solution); + + drawvec out; + clipper_to_geom(solution, out); + clipper_to_geom(open_solution, out); + return out; +} + void to_tile_scale(drawvec &geom, int z, int detail) { if (32 - detail - z < 0) { for (size_t i = 0; i < geom.size(); i++) { @@ -1492,19 +1537,28 @@ static bool feature_out(std::vector const &features, mvt_layer &ou long long dy = (long long) ny << (32 - nz); double scale = (double) outlayer.extent / (1LL << (32 - nz)); - for (auto const &c : clipbboxes) { - clipbbox local; - local.minx = std::llround((c.minx - dx) * scale); - local.miny = std::llround((c.miny - dy) * scale); - local.maxx = std::llround((c.maxx - dx) * scale); - local.maxy = std::llround((c.maxy - dy) * scale); + for (auto const &c_world : clipbboxes) { + clipbbox c = c_world; + c.minx = std::llround((c_world.minx - dx) * scale); + c.miny = std::llround((c_world.miny - dy) * scale); + c.maxx = std::llround((c_world.maxx - dx) * scale); + c.maxy = std::llround((c_world.maxy - dy) * scale); if (t == VT_POLYGON) { - geom = simple_clip_poly(geom, local.minx, local.miny, local.maxx, local.maxy, false); + geom = simple_clip_poly(geom, c.minx, c.miny, c.maxx, c.maxy, false); + if (c.dv.size() > 0 && geom.size() > 0) { + geom = clip_poly(geom, c.dv); + } } else if (t == VT_LINE) { - geom = clip_lines(geom, local.minx, local.miny, local.maxx, local.maxy); + geom = clip_lines(geom, c.minx, c.miny, c.maxx, c.maxy); + if (c.dv.size() > 0 && geom.size() > 0) { + geom = clip_lines(geom, c.dv); + } } else if (t == VT_POINT) { - geom = clip_point(geom, local.minx, local.miny, local.maxx, local.maxy); + geom = clip_point(geom, c.minx, c.miny, c.maxx, c.maxy); + if (c.dv.size() > 0 && geom.size() > 0) { + geom = clip_point_poly(geom, c.dv); + } } } @@ -1940,51 +1994,6 @@ mvt_tile assign_to_bins(mvt_tile &features, return ret; } -static Clipper2Lib::Paths64 geom_to_clipper(drawvec const &geom) { - Clipper2Lib::Paths64 subject; - - for (size_t i = 0; i < geom.size(); i++) { - if (geom[i].op == VT_MOVETO) { - Clipper2Lib::Path64 path({{geom[i].x, geom[i].y}}); - size_t j; - for (j = i + 1; j < geom.size(); j++) { - if (geom[j].op != VT_LINETO) { - break; - } - path.emplace_back(geom[j].x, geom[j].y); - } - subject.push_back(path); - } - } - - return subject; -} - -static void clipper_to_geom(Clipper2Lib::Paths64 const &geom, drawvec &out) { - for (auto const &ring : geom) { - for (size_t i = 0; i < ring.size(); i++) { - out.emplace_back(i == 0 ? VT_MOVETO : VT_LINETO, ring[i].x, ring[i].y); - } - } -} - -drawvec clip_lines(drawvec const &geom, drawvec const ®ion) { - Clipper2Lib::Paths64 subject = geom_to_clipper(geom); - Clipper2Lib::Paths64 clip = geom_to_clipper(region); - - Clipper2Lib::Clipper64 clipper; - clipper.AddOpenSubject(subject); - clipper.AddClip(clip); - - Clipper2Lib::Paths64 solution, open_solution; - clipper.Execute(Clipper2Lib::ClipType::Intersection, Clipper2Lib::FillRule::Positive, solution, open_solution); - - drawvec out; - clipper_to_geom(solution, out); - clipper_to_geom(open_solution, out); - return out; -} - std::string overzoom(std::vector const &tiles, int nz, int nx, int ny, int detail_or_unspecified, int buffer, std::set const &keep, From 02efa9f1e13bae1ba11c5e2a5a9300f7be6d1bf9 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Tue, 26 Nov 2024 14:15:58 -0800 Subject: [PATCH 18/24] Fix scaling before post-binning clipping. Add test. --- Makefile | 5 +++++ clip.cpp | 8 +++++++- read_json.cpp | 11 +++++++---- read_json.hpp | 2 +- tests/pbf/bin-11-327-791-ids-clip.pbf.out.json | 7 +++++++ 5 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 tests/pbf/bin-11-327-791-ids-clip.pbf.out.json diff --git a/Makefile b/Makefile index c1994049..85130114 100644 --- a/Makefile +++ b/Makefile @@ -377,6 +377,11 @@ overzoom-test: tippecanoe-overzoom ./tippecanoe-decode tests/pbf/bin-11-327-791-ids.pbf.out 11 327 791 > tests/pbf/bin-11-327-791-ids.pbf.out.json.check cmp tests/pbf/bin-11-327-791-ids.pbf.out.json.check tests/pbf/bin-11-327-791-ids.pbf.out.json rm tests/pbf/bin-11-327-791-ids.pbf.out.json.check tests/pbf/bin-11-327-791-ids.pbf.out + # Binning by id, clipping by polygon + ./tippecanoe-overzoom -o tests/pbf/bin-11-327-791-ids-clip.pbf.out --clip-polygon='{"coordinates":[[[-122.4527379,37.8128815],[-122.4598853,37.7834743],[-122.4280914,37.7959397],[-122.4527379,37.8128815]]],"type":"Polygon"}' --assign-to-bins tests/pbf/sf-zips.json --bin-by-id-list bin-ids tests/pbf/yearbuilt.pbf 11/327/791 11/327/791 + ./tippecanoe-decode tests/pbf/bin-11-327-791-ids-clip.pbf.out 11 327 791 > tests/pbf/bin-11-327-791-ids-clip.pbf.out.json.check + cmp tests/pbf/bin-11-327-791-ids-clip.pbf.out.json.check tests/pbf/bin-11-327-791-ids-clip.pbf.out.json + rm tests/pbf/bin-11-327-791-ids-clip.pbf.out.json.check tests/pbf/bin-11-327-791-ids-clip.pbf.out # Binning by id, attribute stripping # Note that it still works even if we exclude the ID that we are binning by ./tippecanoe-overzoom -yZCTA5CE10 -ytippecanoe:count -o tests/pbf/bin-11-327-791-ids-zip.pbf.out --assign-to-bins tests/pbf/sf-zips.json --bin-by-id-list bin-ids tests/pbf/yearbuilt.pbf 11/327/791 11/327/791 diff --git a/clip.cpp b/clip.cpp index 0f366fba..2d1740a5 100644 --- a/clip.cpp +++ b/clip.cpp @@ -1228,7 +1228,7 @@ clipbbox parse_clip_poly(std::string arg) { exit(EXIT_ARGS); } - std::pair parsed_geometry = parse_geometry(j, jp, j, 0, 0, 0, 1LL << 32, false); + std::pair parsed_geometry = parse_geometry(j, jp, j, 0, 0, 0, 1LL << 32, false, false); json_end(jp); clipbbox out; @@ -1539,11 +1539,17 @@ static bool feature_out(std::vector const &features, mvt_layer &ou for (auto const &c_world : clipbboxes) { clipbbox c = c_world; + c.minx = std::llround((c_world.minx - dx) * scale); c.miny = std::llround((c_world.miny - dy) * scale); c.maxx = std::llround((c_world.maxx - dx) * scale); c.maxy = std::llround((c_world.maxy - dy) * scale); + for (auto &p : c.dv) { + p.x = std::llround((p.x - dx) * scale); + p.y = std::llround((p.y - dy) * scale); + } + if (t == VT_POLYGON) { geom = simple_clip_poly(geom, c.minx, c.miny, c.maxx, c.maxy, false); if (c.dv.size() > 0 && geom.size() > 0) { diff --git a/read_json.cpp b/read_json.cpp index 2a95e4d3..63329acb 100644 --- a/read_json.cpp +++ b/read_json.cpp @@ -179,7 +179,7 @@ static std::vector to_feature(drawvec &geom) { } std::pair parse_geometry(json_object *geometry, json_pull *jp, json_object *j, - int z, int x, int y, long long extent, bool fix_longitudes) { + int z, int x, int y, long long extent, bool fix_longitudes, bool mvt_style) { json_object *geometry_type = json_hash_get(geometry, "type"); if (geometry_type == NULL) { fprintf(stderr, "Filter output:%d: null geometry (additional not reported): ", jp->line); @@ -291,8 +291,11 @@ std::pair parse_geometry(json_object *geometry, json_pull *jp, jso } } dv = remove_noop(dv, mb_geometry[t], 0); - if (mb_geometry[t] == VT_POLYGON) { - dv = close_poly(dv); + + if (mvt_style) { + if (mb_geometry[t] == VT_POLYGON) { + dv = close_poly(dv); + } } return std::pair(t, dv); @@ -364,7 +367,7 @@ std::vector parse_layers(FILE *fp, int z, unsigned x, unsigned y, int exit(EXIT_JSON); } - std::pair parsed_geometry = parse_geometry(geometry, jp, j, z, x, y, extent, fix_longitudes); + std::pair parsed_geometry = parse_geometry(geometry, jp, j, z, x, y, extent, fix_longitudes, true); int t = parsed_geometry.first; drawvec &dv = parsed_geometry.second; diff --git a/read_json.hpp b/read_json.hpp index 6323c497..a5d5d7b2 100644 --- a/read_json.hpp +++ b/read_json.hpp @@ -13,7 +13,7 @@ extern int mb_geometry[GEOM_TYPES]; void json_context(json_object *j); void parse_coordinates(int t, json_object *j, drawvec &out, int op, const char *fname, int line, json_object *feature); std::pair parse_geometry(json_object *geometry, json_pull *jp, json_object *j, - int z, int x, int y, long long extent, bool fix_longitudes); + int z, int x, int y, long long extent, bool fix_longitudes, bool mvt_style); std::vector parse_layers(FILE *fp, int z, unsigned x, unsigned y, int extent, bool fix_longitudes); serial_val stringify_value(json_object *value, const char *reading, int line, json_object *feature); diff --git a/tests/pbf/bin-11-327-791-ids-clip.pbf.out.json b/tests/pbf/bin-11-327-791-ids-clip.pbf.out.json new file mode 100644 index 00000000..1fb063bd --- /dev/null +++ b/tests/pbf/bin-11-327-791-ids-clip.pbf.out.json @@ -0,0 +1,7 @@ +{ "type": "FeatureCollection", "properties": { "zoom": 11, "x": 327, "y": 791 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "parsed", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "bin-ids": "236,237,510,514", "ZCTA5CE10": "94129", "GEOID10": "94129", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 5968455, "AWATER10": 14697, "INTPTLAT10": "+37.7973402", "INTPTLON10": "-122.4644664", "tippecanoe:count": 4 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.448120, 37.806936 ], [ -122.448120, 37.806393 ], [ -122.448463, 37.806122 ], [ -122.448292, 37.804766 ], [ -122.451553, 37.803409 ], [ -122.450180, 37.802867 ], [ -122.450008, 37.802460 ], [ -122.447605, 37.800697 ], [ -122.447262, 37.798527 ], [ -122.448120, 37.798255 ], [ -122.448292, 37.797848 ], [ -122.447948, 37.797441 ], [ -122.448635, 37.797441 ], [ -122.448635, 37.797034 ], [ -122.447948, 37.796899 ], [ -122.447948, 37.796492 ], [ -122.448978, 37.796356 ], [ -122.447433, 37.795814 ], [ -122.447433, 37.795542 ], [ -122.447777, 37.795407 ], [ -122.448635, 37.795542 ], [ -122.448978, 37.795000 ], [ -122.448635, 37.794728 ], [ -122.447948, 37.793101 ], [ -122.448463, 37.792829 ], [ -122.448635, 37.791880 ], [ -122.458334, 37.789879 ], [ -122.454300, 37.806495 ], [ -122.452412, 37.806258 ], [ -122.448120, 37.806936 ] ], [ [ -122.452583, 37.803274 ], [ -122.452412, 37.803138 ], [ -122.450008, 37.802460 ], [ -122.451210, 37.803138 ], [ -122.452583, 37.803274 ] ] ] } } +, +{ "type": "Feature", "properties": { "bin-ids": "529,531", "ZCTA5CE10": "94123", "GEOID10": "94123", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 2646572, "AWATER10": 218721, "INTPTLAT10": "+37.8009336", "INTPTLON10": "-122.4383664", "tippecanoe:count": 2 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -122.447004, 37.808936 ], [ -122.428250, 37.796051 ], [ -122.433529, 37.795407 ], [ -122.433357, 37.794457 ], [ -122.434902, 37.794322 ], [ -122.435074, 37.795271 ], [ -122.436790, 37.795000 ], [ -122.436619, 37.794050 ], [ -122.440739, 37.793508 ], [ -122.440910, 37.794457 ], [ -122.441769, 37.794322 ], [ -122.441597, 37.793372 ], [ -122.446404, 37.792829 ], [ -122.446232, 37.791880 ], [ -122.447605, 37.791744 ], [ -122.448635, 37.794728 ], [ -122.448978, 37.795000 ], [ -122.448635, 37.795542 ], [ -122.447777, 37.795407 ], [ -122.447433, 37.795542 ], [ -122.447433, 37.795814 ], [ -122.448978, 37.796356 ], [ -122.447948, 37.796492 ], [ -122.447948, 37.796899 ], [ -122.448635, 37.797034 ], [ -122.448635, 37.797441 ], [ -122.447948, 37.797441 ], [ -122.448292, 37.797848 ], [ -122.448120, 37.798255 ], [ -122.447262, 37.798527 ], [ -122.447605, 37.800697 ], [ -122.450008, 37.802460 ], [ -122.450180, 37.802867 ], [ -122.451553, 37.803409 ], [ -122.448292, 37.804766 ], [ -122.448463, 37.806122 ], [ -122.448120, 37.806393 ], [ -122.448120, 37.806936 ], [ -122.448635, 37.808563 ], [ -122.447004, 37.808936 ] ] ], [ [ [ -122.452583, 37.803274 ], [ -122.451210, 37.803138 ], [ -122.450008, 37.802460 ], [ -122.452583, 37.803274 ] ] ] ] } } +] } +] } From ae0c14be83514d99a872e268bd30c91519bcd067 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Tue, 26 Nov 2024 15:28:17 -0800 Subject: [PATCH 19/24] Remove unused parts of clipper --- clipper2/include/clipper2/clipper.h | 98 -------------- clipper2/include/clipper2/clipper.minkowski.h | 120 ----------------- clipper2/include/clipper2/clipper.offset.h | 124 ------------------ clipper2/include/clipper2/clipper.rectclip.h | 82 ------------ 4 files changed, 424 deletions(-) delete mode 100644 clipper2/include/clipper2/clipper.minkowski.h delete mode 100644 clipper2/include/clipper2/clipper.offset.h delete mode 100644 clipper2/include/clipper2/clipper.rectclip.h diff --git a/clipper2/include/clipper2/clipper.h b/clipper2/include/clipper2/clipper.h index a2fe5c3c..fee38391 100644 --- a/clipper2/include/clipper2/clipper.h +++ b/clipper2/include/clipper2/clipper.h @@ -16,9 +16,6 @@ #include "clipper2/clipper.core.h" #include "clipper2/clipper.engine.h" -#include "clipper2/clipper.offset.h" -#include "clipper2/clipper.minkowski.h" -#include "clipper2/clipper.rectclip.h" namespace Clipper2Lib { @@ -132,35 +129,6 @@ namespace Clipper2Lib { return BooleanOp(ClipType::Xor, fillrule, subjects, clips, decimal_prec); } - inline Paths64 InflatePaths(const Paths64& paths, double delta, - JoinType jt, EndType et, double miter_limit = 2.0, - double arc_tolerance = 0.0) - { - if (!delta) return paths; - ClipperOffset clip_offset(miter_limit, arc_tolerance); - clip_offset.AddPaths(paths, jt, et); - Paths64 solution; - clip_offset.Execute(delta, solution); - return solution; - } - - inline PathsD InflatePaths(const PathsD& paths, double delta, - JoinType jt, EndType et, double miter_limit = 2.0, - int precision = 2, double arc_tolerance = 0.0) - { - int error_code = 0; - CheckPrecisionRange(precision, error_code); - if (!delta) return paths; - if (error_code) return PathsD(); - const double scale = std::pow(10, precision); - ClipperOffset clip_offset(miter_limit, arc_tolerance); - clip_offset.AddPaths(ScalePaths(paths, scale, error_code), jt, et); - if (error_code) return PathsD(); - Paths64 solution; - clip_offset.Execute(delta * scale, solution); - return ScalePaths(solution, 1 / scale, error_code); - } - template inline Path TranslatePath(const Path& path, T dx, T dy) { @@ -201,72 +169,6 @@ namespace Clipper2Lib { return TranslatePaths(paths, dx, dy); } - inline Paths64 RectClip(const Rect64& rect, const Paths64& paths) - { - if (rect.IsEmpty() || paths.empty()) return Paths64(); - RectClip64 rc(rect); - return rc.Execute(paths); - } - - inline Paths64 RectClip(const Rect64& rect, const Path64& path) - { - if (rect.IsEmpty() || path.empty()) return Paths64(); - RectClip64 rc(rect); - return rc.Execute(Paths64{ path }); - } - - inline PathsD RectClip(const RectD& rect, const PathsD& paths, int precision = 2) - { - if (rect.IsEmpty() || paths.empty()) return PathsD(); - int error_code = 0; - CheckPrecisionRange(precision, error_code); - if (error_code) return PathsD(); - const double scale = std::pow(10, precision); - Rect64 r = ScaleRect(rect, scale); - RectClip64 rc(r); - Paths64 pp = ScalePaths(paths, scale, error_code); - if (error_code) return PathsD(); // ie: error_code result is lost - return ScalePaths( - rc.Execute(pp), 1 / scale, error_code); - } - - inline PathsD RectClip(const RectD& rect, const PathD& path, int precision = 2) - { - return RectClip(rect, PathsD{ path }, precision); - } - - inline Paths64 RectClipLines(const Rect64& rect, const Paths64& lines) - { - if (rect.IsEmpty() || lines.empty()) return Paths64(); - RectClipLines64 rcl(rect); - return rcl.Execute(lines); - } - - inline Paths64 RectClipLines(const Rect64& rect, const Path64& line) - { - return RectClipLines(rect, Paths64{ line }); - } - - inline PathsD RectClipLines(const RectD& rect, const PathsD& lines, int precision = 2) - { - if (rect.IsEmpty() || lines.empty()) return PathsD(); - int error_code = 0; - CheckPrecisionRange(precision, error_code); - if (error_code) return PathsD(); - const double scale = std::pow(10, precision); - Rect64 r = ScaleRect(rect, scale); - RectClipLines64 rcl(r); - Paths64 p = ScalePaths(lines, scale, error_code); - if (error_code) return PathsD(); - p = rcl.Execute(p); - return ScalePaths(p, 1 / scale, error_code); - } - - inline PathsD RectClipLines(const RectD& rect, const PathD& line, int precision = 2) - { - return RectClipLines(rect, PathsD{ line }, precision); - } - namespace details { diff --git a/clipper2/include/clipper2/clipper.minkowski.h b/clipper2/include/clipper2/clipper.minkowski.h deleted file mode 100644 index a3ddcf86..00000000 --- a/clipper2/include/clipper2/clipper.minkowski.h +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* -* Author : Angus Johnson * -* Date : 1 November 2023 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2023 * -* Purpose : Minkowski Sum and Difference * -* License : http://www.boost.org/LICENSE_1_0.txt * -*******************************************************************************/ - -#ifndef CLIPPER_MINKOWSKI_H -#define CLIPPER_MINKOWSKI_H - -#include -#include -#include -#include "clipper2/clipper.core.h" - -namespace Clipper2Lib -{ - - namespace detail - { - inline Paths64 Minkowski(const Path64& pattern, const Path64& path, bool isSum, bool isClosed) - { - size_t delta = isClosed ? 0 : 1; - size_t patLen = pattern.size(), pathLen = path.size(); - if (patLen == 0 || pathLen == 0) return Paths64(); - Paths64 tmp; - tmp.reserve(pathLen); - - if (isSum) - { - for (const Point64& p : path) - { - Path64 path2(pattern.size()); - std::transform(pattern.cbegin(), pattern.cend(), - path2.begin(), [p](const Point64& pt2) {return p + pt2; }); - tmp.push_back(path2); - } - } - else - { - for (const Point64& p : path) - { - Path64 path2(pattern.size()); - std::transform(pattern.cbegin(), pattern.cend(), - path2.begin(), [p](const Point64& pt2) {return p - pt2; }); - tmp.push_back(path2); - } - } - - Paths64 result; - result.reserve((pathLen - delta) * patLen); - size_t g = isClosed ? pathLen - 1 : 0; - for (size_t h = patLen - 1, i = delta; i < pathLen; ++i) - { - for (size_t j = 0; j < patLen; j++) - { - Path64 quad; - quad.reserve(4); - { - quad.push_back(tmp[g][h]); - quad.push_back(tmp[i][h]); - quad.push_back(tmp[i][j]); - quad.push_back(tmp[g][j]); - }; - if (!IsPositive(quad)) - std::reverse(quad.begin(), quad.end()); - result.push_back(quad); - h = j; - } - g = i; - } - return result; - } - - inline Paths64 Union(const Paths64& subjects, FillRule fillrule) - { - Paths64 result; - Clipper64 clipper; - clipper.AddSubject(subjects); - clipper.Execute(ClipType::Union, fillrule, result); - return result; - } - - } // namespace internal - - inline Paths64 MinkowskiSum(const Path64& pattern, const Path64& path, bool isClosed) - { - return detail::Union(detail::Minkowski(pattern, path, true, isClosed), FillRule::NonZero); - } - - inline PathsD MinkowskiSum(const PathD& pattern, const PathD& path, bool isClosed, int decimalPlaces = 2) - { - int error_code = 0; - double scale = pow(10, decimalPlaces); - Path64 pat64 = ScalePath(pattern, scale, error_code); - Path64 path64 = ScalePath(path, scale, error_code); - Paths64 tmp = detail::Union(detail::Minkowski(pat64, path64, true, isClosed), FillRule::NonZero); - return ScalePaths(tmp, 1 / scale, error_code); - } - - inline Paths64 MinkowskiDiff(const Path64& pattern, const Path64& path, bool isClosed) - { - return detail::Union(detail::Minkowski(pattern, path, false, isClosed), FillRule::NonZero); - } - - inline PathsD MinkowskiDiff(const PathD& pattern, const PathD& path, bool isClosed, int decimalPlaces = 2) - { - int error_code = 0; - double scale = pow(10, decimalPlaces); - Path64 pat64 = ScalePath(pattern, scale, error_code); - Path64 path64 = ScalePath(path, scale, error_code); - Paths64 tmp = detail::Union(detail::Minkowski(pat64, path64, false, isClosed), FillRule::NonZero); - return ScalePaths(tmp, 1 / scale, error_code); - } - -} // Clipper2Lib namespace - -#endif // CLIPPER_MINKOWSKI_H diff --git a/clipper2/include/clipper2/clipper.offset.h b/clipper2/include/clipper2/clipper.offset.h deleted file mode 100644 index bb075a6d..00000000 --- a/clipper2/include/clipper2/clipper.offset.h +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************* -* Author : Angus Johnson * -* Date : 24 March 2024 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2024 * -* Purpose : Path Offset (Inflate/Shrink) * -* License : http://www.boost.org/LICENSE_1_0.txt * -*******************************************************************************/ - -#ifndef CLIPPER_OFFSET_H_ -#define CLIPPER_OFFSET_H_ - -#include "clipper.core.h" -#include "clipper.engine.h" - -namespace Clipper2Lib { - -enum class JoinType { Square, Bevel, Round, Miter }; -//Square : Joins are 'squared' at exactly the offset distance (more complex code) -//Bevel : Similar to Square, but the offset distance varies with angle (simple code & faster) - -enum class EndType {Polygon, Joined, Butt, Square, Round}; -//Butt : offsets both sides of a path, with square blunt ends -//Square : offsets both sides of a path, with square extended ends -//Round : offsets both sides of a path, with round extended ends -//Joined : offsets both sides of a path, with joined ends -//Polygon: offsets only one side of a closed path - -typedef std::function DeltaCallback64; - -class ClipperOffset { -private: - - class Group { - public: - Paths64 paths_in; - std::optional lowest_path_idx{}; - bool is_reversed = false; - JoinType join_type; - EndType end_type; - Group(const Paths64& _paths, JoinType _join_type, EndType _end_type); - }; - - int error_code_ = 0; - double delta_ = 0.0; - double group_delta_ = 0.0; - double temp_lim_ = 0.0; - double steps_per_rad_ = 0.0; - double step_sin_ = 0.0; - double step_cos_ = 0.0; - PathD norms; - Path64 path_out; - Paths64* solution = nullptr; - PolyTree64* solution_tree = nullptr; - std::vector groups_; - JoinType join_type_ = JoinType::Bevel; - EndType end_type_ = EndType::Polygon; - - double miter_limit_ = 0.0; - double arc_tolerance_ = 0.0; - bool preserve_collinear_ = false; - bool reverse_solution_ = false; - -#ifdef USINGZ - ZCallback64 zCallback64_ = nullptr; - void ZCB(const Point64& bot1, const Point64& top1, - const Point64& bot2, const Point64& top2, Point64& ip); -#endif - DeltaCallback64 deltaCallback64_ = nullptr; - size_t CalcSolutionCapacity(); - bool CheckReverseOrientation(); - void DoBevel(const Path64& path, size_t j, size_t k); - void DoSquare(const Path64& path, size_t j, size_t k); - void DoMiter(const Path64& path, size_t j, size_t k, double cos_a); - void DoRound(const Path64& path, size_t j, size_t k, double angle); - void BuildNormals(const Path64& path); - void OffsetPolygon(Group& group, const Path64& path); - void OffsetOpenJoined(Group& group, const Path64& path); - void OffsetOpenPath(Group& group, const Path64& path); - void OffsetPoint(Group& group, const Path64& path, size_t j, size_t k); - void DoGroupOffset(Group &group); - void ExecuteInternal(double delta); -public: - explicit ClipperOffset(double miter_limit = 2.0, - double arc_tolerance = 0.0, - bool preserve_collinear = false, - bool reverse_solution = false) : - miter_limit_(miter_limit), arc_tolerance_(arc_tolerance), - preserve_collinear_(preserve_collinear), - reverse_solution_(reverse_solution) { }; - - ~ClipperOffset() { Clear(); }; - - int ErrorCode() const { return error_code_; }; - void AddPath(const Path64& path, JoinType jt_, EndType et_); - void AddPaths(const Paths64& paths, JoinType jt_, EndType et_); - void Clear() { groups_.clear(); norms.clear(); }; - - void Execute(double delta, Paths64& paths); - void Execute(double delta, PolyTree64& polytree); - void Execute(DeltaCallback64 delta_cb, Paths64& paths); - - double MiterLimit() const { return miter_limit_; } - void MiterLimit(double miter_limit) { miter_limit_ = miter_limit; } - - //ArcTolerance: needed for rounded offsets (See offset_triginometry2.svg) - double ArcTolerance() const { return arc_tolerance_; } - void ArcTolerance(double arc_tolerance) { arc_tolerance_ = arc_tolerance; } - - bool PreserveCollinear() const { return preserve_collinear_; } - void PreserveCollinear(bool preserve_collinear){preserve_collinear_ = preserve_collinear;} - - bool ReverseSolution() const { return reverse_solution_; } - void ReverseSolution(bool reverse_solution) {reverse_solution_ = reverse_solution;} - -#ifdef USINGZ - void SetZCallback(ZCallback64 cb) { zCallback64_ = cb; } -#endif - void SetDeltaCallback(DeltaCallback64 cb) { deltaCallback64_ = cb; } - -}; - -} -#endif /* CLIPPER_OFFSET_H_ */ diff --git a/clipper2/include/clipper2/clipper.rectclip.h b/clipper2/include/clipper2/clipper.rectclip.h deleted file mode 100644 index bfcfacf2..00000000 --- a/clipper2/include/clipper2/clipper.rectclip.h +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* -* Author : Angus Johnson * -* Date : 5 July 2024 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2024 * -* Purpose : FAST rectangular clipping * -* License : http://www.boost.org/LICENSE_1_0.txt * -*******************************************************************************/ - -#ifndef CLIPPER_RECTCLIP_H -#define CLIPPER_RECTCLIP_H - -#include -#include -#include -#include "clipper2/clipper.core.h" - -namespace Clipper2Lib -{ - - // Location: the order is important here, see StartLocsIsClockwise() - enum class Location { Left, Top, Right, Bottom, Inside }; - - class OutPt2; - typedef std::vector OutPt2List; - - class OutPt2 { - public: - Point64 pt; - size_t owner_idx = 0; - OutPt2List* edge = nullptr; - OutPt2* next = nullptr; - OutPt2* prev = nullptr; - }; - - //------------------------------------------------------------------------------ - // RectClip64 - //------------------------------------------------------------------------------ - - class RectClip64 { - private: - void ExecuteInternal(const Path64& path); - Path64 GetPath(OutPt2*& op); - protected: - const Rect64 rect_; - const Path64 rect_as_path_; - const Point64 rect_mp_; - Rect64 path_bounds_; - std::deque op_container_; - OutPt2List results_; // each path can be broken into multiples - OutPt2List edges_[8]; // clockwise and counter-clockwise - std::vector start_locs_; - void CheckEdges(); - void TidyEdges(size_t idx, OutPt2List& cw, OutPt2List& ccw); - void GetNextLocation(const Path64& path, - Location& loc, size_t& i, size_t highI); - OutPt2* Add(Point64 pt, bool start_new = false); - void AddCorner(Location prev, Location curr); - void AddCorner(Location& loc, bool isClockwise); - public: - explicit RectClip64(const Rect64& rect) : - rect_(rect), - rect_as_path_(rect.AsPath()), - rect_mp_(rect.MidPoint()) {} - Paths64 Execute(const Paths64& paths); - }; - - //------------------------------------------------------------------------------ - // RectClipLines64 - //------------------------------------------------------------------------------ - - class RectClipLines64 : public RectClip64 { - private: - void ExecuteInternal(const Path64& path); - Path64 GetPath(OutPt2*& op); - public: - explicit RectClipLines64(const Rect64& rect) : RectClip64(rect) {}; - Paths64 Execute(const Paths64& paths); - }; - -} // Clipper2Lib namespace -#endif // CLIPPER_RECTCLIP_H From e5e277a76d4678aad8fdcccb8df21a6428a518c1 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Tue, 26 Nov 2024 15:33:52 -0800 Subject: [PATCH 20/24] Rename for consistency --- clip.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clip.cpp b/clip.cpp index 2d1740a5..f83aeb9c 100644 --- a/clip.cpp +++ b/clip.cpp @@ -387,7 +387,7 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try return ret; } -drawvec clip_poly(drawvec &geom, drawvec const &bounds) { +drawvec clip_poly_poly(drawvec &geom, drawvec const &bounds) { geom = remove_noop(geom, VT_POLYGON, 0); mapbox::geometry::multi_polygon result; @@ -488,7 +488,7 @@ static void clipper_to_geom(Clipper2Lib::Paths64 const &geom, drawvec &out) { } } -drawvec clip_lines(drawvec const &geom, drawvec const ®ion) { +drawvec clip_lines_poly(drawvec const &geom, drawvec const ®ion) { Clipper2Lib::Paths64 subject = geom_to_clipper(geom); Clipper2Lib::Paths64 clip = geom_to_clipper(region); @@ -1553,12 +1553,12 @@ static bool feature_out(std::vector const &features, mvt_layer &ou if (t == VT_POLYGON) { geom = simple_clip_poly(geom, c.minx, c.miny, c.maxx, c.maxy, false); if (c.dv.size() > 0 && geom.size() > 0) { - geom = clip_poly(geom, c.dv); + geom = clip_poly_poly(geom, c.dv); } } else if (t == VT_LINE) { geom = clip_lines(geom, c.minx, c.miny, c.maxx, c.maxy); if (c.dv.size() > 0 && geom.size() > 0) { - geom = clip_lines(geom, c.dv); + geom = clip_lines_poly(geom, c.dv); } } else if (t == VT_POINT) { geom = clip_point(geom, c.minx, c.miny, c.maxx, c.maxy); @@ -2081,12 +2081,12 @@ std::string overzoom(std::vector const &tiles, int nz, int nx, int if (t == VT_POLYGON) { geom = simple_clip_poly(geom, c.minx, c.miny, c.maxx, c.maxy, false); if (c.dv.size() > 0 && geom.size() > 0) { - geom = clip_poly(geom, c.dv); + geom = clip_poly_poly(geom, c.dv); } } else if (t == VT_LINE) { geom = clip_lines(geom, c.minx, c.miny, c.maxx, c.maxy); if (c.dv.size() > 0 && geom.size() > 0) { - geom = clip_lines(geom, c.dv); + geom = clip_lines_poly(geom, c.dv); } } else if (t == VT_POINT) { geom = clip_point(geom, c.minx, c.miny, c.maxx, c.maxy); From 641f97f7db115f0e495df7588b190ebcd313c935 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Wed, 27 Nov 2024 11:45:44 -0800 Subject: [PATCH 21/24] Revert accidentally added line --- overzoom.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/overzoom.cpp b/overzoom.cpp index 63822d0f..da098042 100644 --- a/overzoom.cpp +++ b/overzoom.cpp @@ -69,7 +69,6 @@ int main(int argc, char **argv) { {"assign-to-bins", required_argument, 0, 'b' & 0x1F}, {"bin-by-id-list", required_argument, 0, 'c' & 0x1F}, {"accumulate-numeric-attributes", required_argument, 0, 'a' & 0x1F}, - {"numeric-attributes", required_argument, 0, 'a' & 0x1F}, {"no-tile-compression", no_argument, 0, 'd' & 0x1F}, {"clip-bounding-box", required_argument, 0, 'k' & 0x1F}, {"clip-polygon", required_argument, 0, 'l' & 0x1F}, From 75511a74cd2138aa251aaa1c0809742b9026be29 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Wed, 27 Nov 2024 12:22:36 -0800 Subject: [PATCH 22/24] Clip the clip regions to the tile bounds to reduce their complexity --- clip.cpp | 5 ++--- geometry.hpp | 4 ++++ overzoom.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/clip.cpp b/clip.cpp index f83aeb9c..76d23089 100644 --- a/clip.cpp +++ b/clip.cpp @@ -387,8 +387,7 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try return ret; } -drawvec clip_poly_poly(drawvec &geom, drawvec const &bounds) { - geom = remove_noop(geom, VT_POLYGON, 0); +drawvec clip_poly_poly(drawvec const &geom, drawvec const &bounds) { mapbox::geometry::multi_polygon result; { @@ -450,7 +449,7 @@ drawvec clip_poly_poly(drawvec &geom, drawvec const &bounds) { return ret; } -drawvec clip_point_poly(drawvec &geom, drawvec const &bounds) { +drawvec clip_point_poly(drawvec const &geom, drawvec const &bounds) { drawvec out; for (auto const &p : geom) { if (pnpoly_mp(bounds, p.x, p.y)) { diff --git a/geometry.hpp b/geometry.hpp index bc616058..db96a2cd 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -102,6 +102,10 @@ int pnpoly(const drawvec &vert, size_t start, size_t nvert, long long testx, lon bool pnpoly_mp(drawvec const &geom, long long x, long long y); double distance_from_line(long long point_x, long long point_y, long long segA_x, long long segA_y, long long segB_x, long long segB_y); +drawvec clip_poly_poly(drawvec const &geom, drawvec const &bounds); +drawvec clip_lines_poly(drawvec const &geom, drawvec const &bounds); +drawvec clip_point_poly(drawvec const &geom, drawvec const &bounds); + struct input_tile { std::string tile; int z; diff --git a/overzoom.cpp b/overzoom.cpp index da098042..b6fa1b56 100644 --- a/overzoom.cpp +++ b/overzoom.cpp @@ -259,6 +259,34 @@ int main(int argc, char **argv) { fclose(f); } + // clip the clip polygons, if any, to the tile bounds, + // to reduce their complexity + + if (clipbboxes.size() > 0) { + long long wx1 = (nx - buffer / 256.0) * (1LL << (32 - nz)); + long long wy1 = (ny - buffer / 256.0) * (1LL << (32 - nz)); + long long wx2 = (nx + 1 + buffer / 256.0) * (1LL << (32 - nz)); + long long wy2 = (ny + 1 + buffer / 256.0) * (1LL << (32 - nz)); + + drawvec tile_bounds; + tile_bounds.emplace_back(VT_MOVETO, wx1, wy1); + tile_bounds.emplace_back(VT_LINETO, wx2, wy1); + tile_bounds.emplace_back(VT_LINETO, wx2, wy2); + tile_bounds.emplace_back(VT_LINETO, wx1, wy2); + tile_bounds.emplace_back(VT_LINETO, wx1, wy1); + + for (auto &c : clipbboxes) { + c.minx = std::max(c.minx, wx1); + c.miny = std::max(c.miny, wy1); + c.maxx = std::min(c.maxx, wx2); + c.maxy = std::min(c.maxy, wy2); + + if (c.dv.size() > 0) { + c.dv = clip_poly_poly(c.dv, tile_bounds); + } + } + } + json_object *json_filter = NULL; if (filter.size() > 0) { json_filter = parse_filter(filter.c_str()); From 1be64f628493a7509b619173251ce81cd6c78529 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Wed, 27 Nov 2024 13:35:37 -0800 Subject: [PATCH 23/24] Add a test of clipping the clip region down to the tile boundary --- Makefile | 5 +++++ tests/pbf/countries-8-135-86-bigclip.json | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 tests/pbf/countries-8-135-86-bigclip.json diff --git a/Makefile b/Makefile index 85130114..7f521ea3 100644 --- a/Makefile +++ b/Makefile @@ -424,6 +424,11 @@ overzoom-test: tippecanoe-overzoom ./tippecanoe-decode tests/pbf/places-1-1-0-clip.pbf 1 1 0 > tests/pbf/places-1-1-0-clip.json.check cmp tests/pbf/places-1-1-0-clip.json.check tests/pbf/places-1-1-0-clip.json rm tests/pbf/places-1-1-0-clip.pbf tests/pbf/places-1-1-0-clip.json.check + # Polygon clipping, with excessively large clip region + ./tippecanoe-overzoom -b10 -o tests/pbf/countries-8-135-86-bigclip.pbf --clip-polygon "`cat tests/pbf/region.json`" tests/pbf/countries-1-1-0.pbf 1/1/0 8/135/86 + ./tippecanoe-decode tests/pbf/countries-8-135-86-bigclip.pbf 8 135 86 > tests/pbf/countries-8-135-86-bigclip.json.check + cmp tests/pbf/countries-8-135-86-bigclip.json.check tests/pbf/countries-8-135-86-bigclip.json + rm tests/pbf/countries-8-135-86-bigclip.pbf tests/pbf/countries-8-135-86-bigclip.json.check join-test: tippecanoe tippecanoe-decode tile-join ./tippecanoe -q -f -z12 -o tests/join-population/tabblock_06001420.mbtiles -YALAND10:'Land area' -L'{"file": "tests/join-population/tabblock_06001420.json", "description": "population"}' diff --git a/tests/pbf/countries-8-135-86-bigclip.json b/tests/pbf/countries-8-135-86-bigclip.json new file mode 100644 index 00000000..23135cf0 --- /dev/null +++ b/tests/pbf/countries-8-135-86-bigclip.json @@ -0,0 +1,5 @@ +{ "type": "FeatureCollection", "properties": { "zoom": 8, "x": 135, "y": 86 }, "features": [ +{ "type": "FeatureCollection", "properties": { "layer": "ne_10m_admin_0_countries", "version": 2, "extent": 4096 }, "features": [ +{ "type": "Feature", "properties": { "NAME": "Germany" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 11.210518, 50.771208 ], [ 11.304932, 50.271568 ], [ 11.304932, 49.802541 ], [ 9.788818, 49.802541 ], [ 9.788818, 50.771208 ], [ 11.210518, 50.771208 ] ] ] } } +] } +] } From d425846b50ab89b226bf3b7363cc8a55ecd70f25 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Wed, 27 Nov 2024 13:38:26 -0800 Subject: [PATCH 24/24] Update version and changelog --- CHANGELOG.md | 4 ++++ version.hpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae134e42..20edf8fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.71.0 + +* Add --clip-bounding-box and --clip-polygon options to tippecanoe-overzoom + # 2.70.1 * Raise tippecanoe-decode limit on the size of individual tiles diff --git a/version.hpp b/version.hpp index 320fd50a..a67e7576 100644 --- a/version.hpp +++ b/version.hpp @@ -1,6 +1,6 @@ #ifndef VERSION_HPP #define VERSION_HPP -#define VERSION "v2.70.1" +#define VERSION "v2.71.0" #endif