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/Makefile b/Makefile index be1b08ce..7f521ea3 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 @@ -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 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 +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 +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) @@ -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 @@ -372,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 @@ -391,9 +401,34 @@ 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 + # 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 + # 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/clip.cpp b/clip.cpp index 06d29c12..76d23089 100644 --- a/clip.cpp +++ b/clip.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "geometry.hpp" #include "errors.hpp" @@ -13,6 +14,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, @@ -385,6 +387,123 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try return ret; } +drawvec clip_poly_poly(drawvec const &geom, drawvec const &bounds) { + 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_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); + } + } + + drawvec ret; + decode_clipped(result, ret, 1); + return ret; +} + +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)) { + out.push_back(p); + } + } + 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_poly(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++) { @@ -1075,6 +1194,68 @@ 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); + 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, 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, @@ -1087,7 +1268,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 +1295,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 @@ -1317,28 +1499,80 @@ 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) { + // 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_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) { + 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_poly(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) { + geom = clip_point_poly(geom, c.dv); + } + } } + + 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; @@ -1577,7 +1811,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; @@ -1740,7 +1974,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; @@ -1776,7 +2011,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; @@ -1836,8 +2072,32 @@ 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) { + 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_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_poly(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) { + geom = clip_point_poly(geom, c.dv); + } + } + } + } + // 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) { @@ -1903,7 +2163,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; } @@ -1963,7 +2223,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; @@ -2003,7 +2263,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); } @@ -2015,7 +2275,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--) { 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..fee38391 --- /dev/null +++ b/clipper2/include/clipper2/clipper.h @@ -0,0 +1,671 @@ +/******************************************************************************* +* 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" + +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); + } + + 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); + } + + 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.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 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/geometry.hpp b/geometry.hpp index 7d8d81f0..db96a2cd 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -99,8 +99,13 @@ 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); +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; @@ -115,6 +120,20 @@ 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; + + drawvec dv; // empty, or arbitrary clipping polygon +}; + std::string overzoom(std::vector const &tiles, int nz, int nx, int ny, int detail, int buffer, std::set const &keep, @@ -127,7 +146,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,11 +161,14 @@ 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); 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/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/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..b6fa1b56 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]); @@ -68,6 +70,8 @@ int main(int argc, char **argv) { {"bin-by-id-list", required_argument, 0, 'c' & 0x1F}, {"accumulate-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}, }; @@ -158,6 +162,25 @@ 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; + } + + case 'l' & 0x1F: { + clipbbox clip = parse_clip_poly(optarg); + clipbboxes.push_back(clip); + break; + } + default: fprintf(stderr, "Unrecognized flag -%c\n", i); usage(argv); @@ -236,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()); @@ -262,7 +313,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/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..63329acb 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,129 @@ 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, 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); + 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 (mvt_style) { + 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 +331,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 +339,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 +359,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; - - // 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); - } + std::pair parsed_geometry = parse_geometry(geometry, jp, j, z, x, y, extent, fix_longitudes, true); - 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..a5d5d7b2 100644 --- a/read_json.hpp +++ b/read_json.hpp @@ -11,7 +11,9 @@ 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::pair parse_geometry(json_object *geometry, json_pull *jp, json_object *j, + 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/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 ] ] ] } } +] } +] } 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 ] ] ] ] } } +] } +] } 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 ] ] ] ] } } +] } +] } 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 00000000..25f3e118 Binary files /dev/null and b/tests/pbf/countries-1-1-0.pbf differ 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 ] ] ] } } +] } +] } 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 00000000..e36effdb Binary files /dev/null and b/tests/pbf/places-1-1-0.pbf differ 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" + } 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 00000000..22a26fbf Binary files /dev/null and b/tests/pbf/roads-1-1-0.pbf differ 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; } 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