Merge remote-tracking branch 'origin/main' into tile-join-sqlite

This commit is contained in:
Erica Fischer
2024-12-02 11:35:28 -08:00
62 changed files with 11604 additions and 589 deletions
+35
View File
@@ -1,3 +1,38 @@
# 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
# 2.70.0
* Performance improvements to tippecanoe-overzoom with attribute exclusion
# 2.69.0
* Fix crash when the first bin gets clipped away
# 2.68.0
* Adds `--no-tile-compression` option to `tippecanoe-overzoom`
* Make `tippecanoe-overzoom` clip the output tile to the tile buffer after assigning points to bins
* Adds `--include`/`-y` option to `tippecanoe-decode` to decode only specified attributes
* Cleans up some inconsistent handling of variable tile extents in overzooming code
* Speeds up overzooming slightly in `tile-join` by doing less preflighting to discover which child tiles contain features
# 2.67.0
* Reduce memory consumption of duplicate attribute names in `serial_feature`
* The maxzoom guess calculation now takes into account the number of duplicate feature locations
# 2.66.0
* Only bin by ID, not by geometry, if --bin-by-id-list is specified
* Do attribute accumulation in overzoom in mvt_value instead of converting to serial_val
* Fix bool values read from flatgeobuf sources (#289)
# 2.65.0
* Improve spatial distribution of --retain-points-multiplier features
+77 -8
View File
@@ -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)
@@ -291,8 +291,8 @@ overzoom-test: tippecanoe-overzoom
./tippecanoe-decode tests/pbf/13-1310-3166.pbf 13 1310 3166 > tests/pbf/13-1310-3166.pbf.json.check
cmp tests/pbf/13-1310-3166.pbf.json.check tests/pbf/13-1310-3166.pbf.json
rm tests/pbf/13-1310-3166.pbf tests/pbf/13-1310-3166.pbf.json.check
# Multiple inputs
./tippecanoe-overzoom -o tests/pbf/13-1310-3166-ne.pbf -t 13/1310/3166 tests/pbf/11-327-791.pbf 11/327/791 tests/pbf/0-0-0.pbf 0/0/0
# Multiple inputs, no compression
./tippecanoe-overzoom --no-tile-compression -o tests/pbf/13-1310-3166-ne.pbf -t 13/1310/3166 tests/pbf/11-327-791.pbf 11/327/791 tests/pbf/0-0-0.pbf 0/0/0
./tippecanoe-decode tests/pbf/13-1310-3166-ne.pbf 13 1310 3166 > tests/pbf/13-1310-3166-ne.pbf.json.check
cmp tests/pbf/13-1310-3166-ne.pbf.json.check tests/pbf/13-1310-3166-ne.pbf.json
rm tests/pbf/13-1310-3166-ne.pbf tests/pbf/13-1310-3166-ne.pbf.json.check
@@ -362,16 +362,32 @@ 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
cmp tests/pbf/bin-11-327-791.pbf.out.json.check tests/pbf/bin-11-327-791.pbf.out.json
rm tests/pbf/bin-11-327-791.pbf.out.json.check tests/pbf/bin-11-327-791.pbf.out
# Binning by id
./tippecanoe-overzoom -o tests/pbf/bin-11-327-791-ids.pbf.out --assign-to-bins tests/pbf/sf-zips.json --bin-by-id bin-ids tests/pbf/yearbuilt.pbf 11/327/791 11/327/791
./tippecanoe-overzoom -o tests/pbf/bin-11-327-791-ids.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
./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
./tippecanoe-decode tests/pbf/bin-11-327-791-ids-zip.pbf.out 11 327 791 > tests/pbf/bin-11-327-791-ids-zip.pbf.out.json.check
cmp tests/pbf/bin-11-327-791-ids-zip.pbf.out.json.check tests/pbf/bin-11-327-791-ids-zip.pbf.out.json
rm tests/pbf/bin-11-327-791-ids-zip.pbf.out.json.check tests/pbf/bin-11-327-791-ids-zip.pbf.out
# Binning with longitude wraparound problems
./tippecanoe-overzoom -o tests/pbf/0-0-0-pop-2-0-1.pbf.out --accumulate-numeric-attributes=tippecanoe --assign-to-bins tests/pbf/h3-2-0-1.geojson tests/pbf/0-0-0.pbf 2/0/1 2/0/1
./tippecanoe-decode tests/pbf/0-0-0-pop-2-0-1.pbf.out 2 0 1 > tests/pbf/0-0-0-pop-2-0-1.pbf.out.json.check
@@ -385,6 +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"}'
@@ -615,11 +659,36 @@ accumulate-test:
# the cluster sizes still add up to the 243 original features
test `./tippecanoe-decode -c tests/pbf/bins-0-0-0.pbf 0 0 0 | sed 's/.*clustered:cluster_size": //' | awk '{sum += $$1} END {print sum}'` == 243
#
# Binning with attribute stripping
./tippecanoe-overzoom -y clustered:count:POP1950 -y clustered:sum:POP1950 -y POP1950 -y clustered:cluster_size --assign-to-bins tests/pbf/h3-0-0-0.geojson --accumulate-numeric-attributes=clustered --accumulate-attribute '{"clustered:cluster_size":"sum"}' -o tests/pbf/bins-0-0-0.pbf tests/pbf/accum.dir/0/0/0.pbf 0/0/0 0/0/0
# Now there are 30 bins with POP1950 clusters
test `./tippecanoe-decode -c tests/pbf/bins-0-0-0.pbf 0 0 0 | grep 'clustered:count:POP1950' | wc -l` == 41
# There are none with bare POP1950 (which is expected; we should only have summary statistics)
test `./tippecanoe-decode -c tests/pbf/bins-0-0-0.pbf 0 0 0 | grep -v 'clustered:count:POP1950' | grep 'POP1950' | wc -l` == 0
# And 4 with no POP1950 at all
test `./tippecanoe-decode -c tests/pbf/bins-0-0-0.pbf 0 0 0 | grep -v 'POP1950' | wc -l` == 3
#
# the clustered and megatile-filtered and binned POP1950s add up to 161590
test `./tippecanoe-decode -c tests/pbf/bins-0-0-0.pbf 0 0 0 | grep 'clustered:sum:POP1950' | sed 's/.*"clustered:sum:POP1950": //' | awk '{sum += $$1} END {print sum}'` == 161590
# which is the right global total
# Make sure we do *not* accumulate a numeric attribute that already has the magic prefix:
test `./tippecanoe-decode -c tests/pbf/bins-0-0-0.pbf 0 0 0 | grep sum:clustered:unrelated | wc -l` == 0
# And those attributes do *not* make it onto the bins
test `./tippecanoe-decode -c tests/pbf/bins-0-0-0.pbf 0 0 0 | grep clustered:unrelated | wc -l` == 0
# the cluster sizes still add up to the 243 original features
test `./tippecanoe-decode -c tests/pbf/bins-0-0-0.pbf 0 0 0 | sed 's/.*clustered:cluster_size": //' | awk '{sum += $$1} END {print sum}'` == 243
#
#
# A tile where the counts and means were previously wrong:
./tippecanoe-overzoom --accumulate-numeric-attributes=felt -m -o tests/pbf/yearbuilt-accum.pbf tests/pbf/yearbuilt.pbf 0/0/0 0/0/0
./tippecanoe-decode tests/pbf/yearbuilt-accum.pbf 0 0 0 > tests/pbf/yearbuilt-accum.pbf.json.check
cmp tests/pbf/yearbuilt-accum.pbf.json.check tests/pbf/yearbuilt-accum.pbf.json
rm tests/pbf/yearbuilt-accum.pbf tests/pbf/yearbuilt-accum.pbf.json.check
# Same tile, with attribute stripping
./tippecanoe-overzoom --accumulate-numeric-attributes=felt -y bldgsqft -y felt:sum:bldgsqft -m -o tests/pbf/yearbuilt-accum-bldgsqft.pbf tests/pbf/yearbuilt.pbf 0/0/0 0/0/0
./tippecanoe-decode tests/pbf/yearbuilt-accum-bldgsqft.pbf 0 0 0 > tests/pbf/yearbuilt-accum-bldgsqft.pbf.json.check
cmp tests/pbf/yearbuilt-accum-bldgsqft.pbf.json.check tests/pbf/yearbuilt-accum-bldgsqft.pbf.json
rm tests/pbf/yearbuilt-accum-bldgsqft.pbf tests/pbf/yearbuilt-accum-bldgsqft.pbf.json.check
join-filter-test: tippecanoe tippecanoe-decode tile-join
# Comes out different from the direct tippecanoe run because null attributes are lost
+32 -35
View File
@@ -88,36 +88,33 @@ void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribut
set_attribute_accum(attribute_accum, name, type);
}
void preserve_attribute(attribute_op const &op, std::string const &key, serial_val const &val, std::vector<std::string> &full_keys, std::vector<serial_val> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state) {
template <class T>
static void preserve_attribute1(attribute_op const &op, std::string const &key, T const &val, std::vector<std::shared_ptr<std::string>> &full_keys, std::vector<T> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state, key_pool &key_pool) {
for (size_t i = 0; i < full_keys.size(); i++) {
if (key == full_keys[i]) {
if (key == *full_keys[i]) {
switch (op) {
case op_sum:
full_values[i].s = milo::dtoa_milo(atof(full_values[i].s.c_str()) + atof(val.s.c_str()));
full_values[i].type = mvt_double;
full_values[i] = (full_values[i].to_double() + val.to_double());
return;
case op_product:
full_values[i].s = milo::dtoa_milo(atof(full_values[i].s.c_str()) * atof(val.s.c_str()));
full_values[i].type = mvt_double;
full_values[i] = (full_values[i].to_double() * val.to_double());
return;
case op_max: {
double existing = atof(full_values[i].s.c_str());
double maybe = atof(val.s.c_str());
double existing = full_values[i].to_double();
double maybe = val.to_double();
if (maybe > existing) {
full_values[i].s = val.s.c_str();
full_values[i].type = mvt_double;
full_values[i] = val;
}
return;
}
case op_min: {
double existing = atof(full_values[i].s.c_str());
double maybe = atof(val.s.c_str());
double existing = full_values[i].to_double();
double maybe = val.to_double();
if (maybe < existing) {
full_values[i].s = val.s.c_str();
full_values[i].type = mvt_double;
full_values[i] = val;
}
return;
}
@@ -126,30 +123,26 @@ void preserve_attribute(attribute_op const &op, std::string const &key, serial_v
auto state = attribute_accum_state.find(key);
if (state == attribute_accum_state.end()) {
accum_state s;
s.sum = atof(full_values[i].s.c_str()) + atof(val.s.c_str());
s.sum = full_values[i].to_double() + val.to_double();
s.count = 2;
attribute_accum_state.insert(std::pair<std::string, accum_state>(key, s));
full_values[i].s = milo::dtoa_milo(s.sum / s.count);
full_values[i].type = mvt_double;
full_values[i] = (s.sum / s.count);
} else {
state->second.sum += atof(val.s.c_str());
state->second.sum += val.to_double();
state->second.count += 1;
full_values[i].s = milo::dtoa_milo(state->second.sum / state->second.count);
full_values[i].type = mvt_double;
full_values[i] = (state->second.sum / state->second.count);
}
return;
}
case op_concat:
full_values[i].s += val.s;
full_values[i].type = mvt_string;
full_values[i].set_string_value(full_values[i].get_string_value() + val.get_string_value());
return;
case op_comma:
full_values[i].s += std::string(",") + val.s;
full_values[i].type = mvt_string;
full_values[i].set_string_value(full_values[i].get_string_value() + "," + val.get_string_value());
return;
case op_count: {
@@ -159,12 +152,10 @@ void preserve_attribute(attribute_op const &op, std::string const &key, serial_v
s.count = 2;
attribute_accum_state.insert(std::pair<std::string, accum_state>(key, s));
full_values[i].type = mvt_double;
full_values[i].s = std::to_string(s.count);
full_values[i] = (s.count);
} else { // already present, incrementing
state->second.count += 1;
full_values[i].type = mvt_double;
full_values[i].s = std::to_string(state->second.count);
full_values[i] = (state->second.count);
}
return;
}
@@ -174,13 +165,12 @@ void preserve_attribute(attribute_op const &op, std::string const &key, serial_v
// not found, so we are making a new value
serial_val sv;
T v;
switch (op) {
case op_sum:
case op_max:
case op_min:
sv.s = val.s;
sv.type = mvt_double;
v = val;
break;
case op_count: {
@@ -190,12 +180,11 @@ void preserve_attribute(attribute_op const &op, std::string const &key, serial_v
s.count = 1;
attribute_accum_state.insert(std::pair<std::string, accum_state>(key, s));
sv.s = std::to_string(s.count);
v = (s.count);
} else { // already present, incrementing
fprintf(stderr, "preserve_attribute: can't happen (count)\n");
exit(EXIT_IMPOSSIBLE);
}
sv.type = mvt_double;
break;
}
@@ -204,6 +193,14 @@ void preserve_attribute(attribute_op const &op, std::string const &key, serial_v
exit(EXIT_IMPOSSIBLE);
}
full_keys.push_back(key);
full_values.push_back(sv);
full_keys.push_back(key_pool.pool(key));
full_values.push_back(v);
}
void preserve_attribute(attribute_op const &op, std::string const &key, mvt_value const &val, std::vector<std::shared_ptr<std::string>> &full_keys, std::vector<mvt_value> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state, key_pool &key_pool) {
preserve_attribute1(op, key, val, full_keys, full_values, attribute_accum_state, key_pool);
}
void preserve_attribute(attribute_op const &op, std::string const &key, serial_val const &val, std::vector<std::shared_ptr<std::string>> &full_keys, std::vector<serial_val> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state, key_pool &key_pool) {
preserve_attribute1(op, key, val, full_keys, full_values, attribute_accum_state, key_pool);
}
+7 -1
View File
@@ -4,6 +4,9 @@
#include <vector>
#include <unordered_map>
#include <map>
#include <memory>
#include "mvt.hpp"
#include "milo/dtoa_milo.h"
enum attribute_op {
op_sum,
@@ -22,10 +25,13 @@ struct accum_state {
};
struct serial_val;
struct key_pool;
void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribute_accum, std::string name, std::string type);
void set_attribute_accum(std::unordered_map<std::string, attribute_op> &attribute_accum, const char *arg, char **argv);
void preserve_attribute(attribute_op const &op, const std::string &key, serial_val const &val, std::vector<std::string> &full_keys, std::vector<serial_val> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state);
void preserve_attribute(attribute_op const &op, std::string const &key, serial_val const &val, std::vector<std::shared_ptr<std::string>> &full_keys, std::vector<serial_val> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state, key_pool &key_pool);
void preserve_attribute(attribute_op const &op, std::string const &key, mvt_value const &val, std::vector<std::shared_ptr<std::string>> &full_keys, std::vector<mvt_value> &full_values, std::unordered_map<std::string, accum_state> &attribute_accum_state, key_pool &key_pool);
extern std::map<std::string, attribute_op> numeric_operations;
+452 -118
View File
@@ -4,6 +4,7 @@
#include <mapbox/geometry/point.hpp>
#include <mapbox/geometry/multi_polygon.hpp>
#include <mapbox/geometry/wagyu/wagyu.hpp>
#include <clipper2/clipper.h>
#include <limits.h>
#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<std::pair<double, double>> clip_poly1(std::vector<std::pair<double, double>> &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<long long> result;
{
mapbox::geometry::wagyu::wagyu<long long> wagyu;
for (size_t i = 0; i < geom.size(); i++) {
if (geom[i].op == VT_MOVETO) {
mapbox::geometry::linear_ring<long long> lr;
lr.push_back(mapbox::geometry::point<long long>(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<long long>(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<long long> lr;
lr.push_back(mapbox::geometry::point<long long>(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<long long>(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 &region) {
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,8 +1194,70 @@ bool pnpoly_mp(std::vector<mvt_geometry> 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<int, drawvec> 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<input_tile> const &tiles, int nz, int nx, int ny,
int detail, int buffer,
int detail_or_unspecified, int buffer,
std::set<std::string> const &keep,
std::set<std::string> const &exclude,
std::vector<std::string> const &exclude_prefix,
@@ -1087,7 +1268,8 @@ std::string overzoom(std::vector<input_tile> const &tiles, int nz, int nx, int n
std::vector<std::string> const &unidecode_data, double simplification,
double tiny_polygon_size,
std::vector<mvt_layer> const &bins, std::string const &bin_by_id_list,
std::string const &accumulate_numeric) {
std::string const &accumulate_numeric, size_t feature_limit,
std::vector<clipbbox> const &clipbboxes) {
std::vector<source_tile> decoded;
for (auto const &t : tiles) {
@@ -1113,7 +1295,7 @@ std::string overzoom(std::vector<input_tile> const &tiles, int nz, int nx, int n
decoded.push_back(out);
}
return overzoom(decoded, nz, nx, ny, detail, 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);
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
@@ -1127,7 +1309,30 @@ struct tile_feature {
size_t seq = 0;
};
static void add_mean(mvt_feature &feature, mvt_layer &layer, std::string const &accumulate_numeric) {
static bool should_keep(std::string const &key,
std::set<std::string> const &keep,
std::set<std::string> const &exclude,
std::vector<std::string> const &exclude_prefix) {
if (keep.size() == 0 || keep.find(key) != keep.end()) {
if (exclude.find(key) != exclude.end()) {
return false;
}
for (auto const &prefix : exclude_prefix) {
if (starts_with(key, prefix)) {
return false;
}
}
return true;
}
return false;
}
static void add_mean(mvt_feature &feature, mvt_layer &layer, std::string const &accumulate_numeric,
std::set<std::string> const &keep, std::set<std::string> const &exclude,
std::vector<std::string> const &exclude_prefix) {
std::string accumulate_numeric_colon = accumulate_numeric + ":";
std::unordered_map<std::string, size_t> attributes;
@@ -1156,21 +1361,26 @@ static void add_mean(mvt_feature &feature, mvt_layer &layer, std::string const &
mvt_value mean;
mean.type = mvt_double;
mean.numeric_value.double_value = mvt_value_to_double(sum) / count_val;
layer.tag(feature, accumulate_numeric + ":mean:" + trunc, mean);
if (should_keep(key, keep, exclude, exclude_prefix)) {
layer.tag(feature, accumulate_numeric + ":mean:" + trunc, mean);
}
}
}
}
};
// accumulate :sum:, :min:, :max:, and :count: versions of the specified attribute
static void preserve_numeric(const std::string &key, const mvt_value &val, // numeric attribute being accumulated
std::vector<std::string> &full_keys, // keys of feature being accumulated onto
std::vector<serial_val> &full_values, // values of features being accumulated onto
const std::string &accumulate_numeric, // prefix of accumulations
std::set<std::string> &keys, // key presence in the source feature
std::map<std::string, size_t> &numeric_out_field, // key index in the output feature
std::unordered_map<std::string, accum_state> &attribute_accum_state // accumulation state for preserve_attribute()
) {
static void preserve_numeric(const std::string &key, const mvt_value &val, // numeric attribute being accumulated
std::vector<std::shared_ptr<std::string>> &full_keys, // keys of feature being accumulated onto
std::vector<mvt_value> &full_values, // values of features being accumulated onto
const std::string &accumulate_numeric, // prefix of accumulations
std::set<std::string> &keys, // key presence in the source feature
std::map<std::string, size_t> &numeric_out_field, // key index in the output feature
std::unordered_map<std::string, accum_state> &attribute_accum_state, // accumulation state for preserve_attribute()
key_pool &key_pool,
std::set<std::string> const &keep, std::set<std::string> const &exclude,
std::vector<std::string> const &exclude_prefix) {
// If this is a numeric attribute, but there is also a prefix:sum (etc.) for the
// same attribute, we want to use that one instead of this one.
@@ -1203,6 +1413,10 @@ static void preserve_numeric(const std::string &key, const mvt_value &val, /
// and then put it back on for the output field
std::string prefixed = accumulate_numeric + ":" + op.first + ":" + outkey;
if (!should_keep(prefixed, keep, exclude, exclude_prefix)) {
continue;
}
// Does it exist in the output feature already?
auto prefixed_attr = numeric_out_field.find(prefixed);
@@ -1213,41 +1427,37 @@ static void preserve_numeric(const std::string &key, const mvt_value &val, /
if (out_attr == numeric_out_field.end()) {
// not present at all, so copy our value to the prefixed output
numeric_out_field.emplace(prefixed, full_keys.size());
full_keys.push_back(prefixed);
full_keys.push_back(key_pool.pool(prefixed));
if (op.second == op_count) {
if (starting_from_accumulation) {
// copy our count
full_values.push_back(mvt_value_to_serial_val(val));
full_values.push_back(val);
} else {
// new count of 1
serial_val sv;
sv.type = mvt_double;
sv.s = "1";
full_values.push_back(sv);
full_values.push_back(mvt_value(1));
}
} else {
full_values.push_back(mvt_value_to_serial_val(val));
full_values.push_back(val);
}
} else {
// exists unprefixed, so copy it, and then accumulate on our value
numeric_out_field.emplace(prefixed, full_keys.size());
full_keys.push_back(prefixed);
full_keys.push_back(key_pool.pool(prefixed));
if (op.second == op_count) {
serial_val sv;
sv.type = mvt_double;
mvt_value v;
if (starting_from_accumulation) {
// sum our count onto the existing 1
sv.s = std::to_string(1 + mvt_value_to_long_long(val));
v = mvt_value(1 + mvt_value_to_long_long(val));
} else {
// sum our 1 onto the existing 1
sv.s = "2";
v = mvt_value(2);
}
full_values.push_back(sv);
full_values.push_back(v);
} else {
full_values.push_back(full_values[out_attr->second]);
preserve_attribute(op.second, prefixed, mvt_value_to_serial_val(val), full_keys, full_values, attribute_accum_state);
preserve_attribute(op.second, prefixed, val, full_keys, full_values, attribute_accum_state, key_pool);
}
}
} else {
@@ -1255,51 +1465,119 @@ static void preserve_numeric(const std::string &key, const mvt_value &val, /
if (op.second == op_count) {
if (starting_from_accumulation) {
// sum our count onto the existing count
full_values[prefixed_attr->second].s = std::to_string(atoll(full_values[prefixed_attr->second].s.c_str()) + mvt_value_to_long_long(val));
full_values[prefixed_attr->second] = mvt_value(mvt_value_to_long_long(full_values[prefixed_attr->second]) + mvt_value_to_long_long(val));
} else {
full_values[prefixed_attr->second].s = std::to_string(atoll(full_values[prefixed_attr->second].s.c_str()) + 1);
full_values[prefixed_attr->second] = mvt_value(mvt_value_to_long_long(full_values[prefixed_attr->second]) + 1);
}
} else {
preserve_attribute(op.second, prefixed, mvt_value_to_serial_val(val), full_keys, full_values, attribute_accum_state);
preserve_attribute(op.second, prefixed, val, full_keys, full_values, attribute_accum_state, key_pool);
}
}
}
}
}
static bool should_keep(std::string const &key,
std::set<std::string> const &keep,
std::set<std::string> const &exclude,
std::vector<std::string> const &exclude_prefix) {
if (keep.size() == 0 || keep.find(key) != keep.end()) {
if (exclude.find(key) != exclude.end()) {
return false;
}
static void handle_closepath_from_mvt(drawvec &geom) {
// mvt geometries close polygons with a mvt_closepath operation
// tippecanoe-internal geometries close polygons with a lineto to the initial point
for (auto const &prefix : exclude_prefix) {
if (starts_with(key, prefix)) {
return false;
}
}
size_t last_open = 0;
return true;
for (size_t i = 0; i < geom.size(); i++) {
if (geom[i].op == mvt_closepath) {
geom[i] = draw(mvt_lineto, geom[last_open].x, geom[last_open].y);
} else if (geom[i].op == mvt_moveto) {
last_open = i;
}
}
return false;
}
static void feature_out(std::vector<tile_feature> const &features, mvt_layer &outlayer,
// returns true if a feature was output; false if it was clipped away
static bool feature_out(std::vector<tile_feature> const &features, mvt_layer &outlayer,
std::set<std::string> const &keep,
std::set<std::string> const &exclude,
std::vector<std::string> const &exclude_prefix,
std::unordered_map<std::string, attribute_op> const &attribute_accum,
std::shared_ptr<std::string> const &tile_stringpool,
std::string const &accumulate_numeric) {
std::string const &accumulate_numeric,
key_pool &key_pool, int buffer, bool include_nonaggregate,
std::vector<clipbbox> const &clipbboxes, int nz, int nx, int ny) {
// Add geometry to output feature
drawvec geom = features[0].geom;
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;
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 (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;
outfeature.type = features[0].t;
for (auto const &g : features[0].geom) {
for (auto const &g : geom) {
outfeature.geometry.emplace_back(g.op, g.x, g.y);
}
@@ -1315,31 +1593,31 @@ static void feature_out(std::vector<tile_feature> const &features, mvt_layer &ou
if (attribute_accum.size() > 0 || accumulate_numeric.size() > 0) {
// convert the attributes of the output feature
// from mvt_value to serial_val so they can have
// from layer references to a vector so they can have
// attributes from the other features of the
// multiplier cluster accumulated onto them
std::unordered_map<std::string, accum_state> attribute_accum_state;
std::vector<std::string> full_keys;
std::vector<serial_val> full_values;
std::vector<std::shared_ptr<std::string>> full_keys;
std::vector<mvt_value> full_values;
std::map<std::string, size_t> numeric_out_field;
for (size_t i = 0; i + 1 < features[0].tags.size(); i += 2) {
const std::string &key = features[0].layer->keys[features[0].tags[i]];
auto f = attribute_accum.find(key);
if (f != attribute_accum.end()) {
// this attribute has an accumulator, so convert it
full_keys.push_back(features[0].layer->keys[features[0].tags[i]]);
full_values.push_back(mvt_value_to_serial_val(features[0].layer->values[features[0].tags[i + 1]]));
} else if (accumulate_numeric.size() > 0 && features[0].layer->values[features[0].tags[i + 1]].is_numeric()) {
// convert numeric for accumulation
numeric_out_field.emplace(key, full_keys.size());
full_keys.push_back(key);
full_values.push_back(mvt_value_to_serial_val(features[0].layer->values[features[0].tags[i + 1]]));
} else {
// otherwise just tag it directly onto the output feature
if (should_keep(features[0].layer->keys[features[0].tags[i]], keep, exclude, exclude_prefix)) {
outlayer.tag(outfeature, features[0].layer->keys[features[0].tags[i]], features[0].layer->values[features[0].tags[i + 1]]);
auto const &f = features[0];
for (size_t i = 0; i + 1 < f.tags.size(); i += 2) {
const std::string &key = f.layer->keys[f.tags[i]];
if (should_keep(key, keep, exclude, exclude_prefix)) {
if (attribute_accum.find(key) != attribute_accum.end()) {
// this attribute has an accumulator, so convert it
full_keys.push_back(key_pool.pool(f.layer->keys[f.tags[i]]));
full_values.push_back(f.layer->values[f.tags[i + 1]]);
} else if (accumulate_numeric.size() > 0 && f.layer->values[f.tags[i + 1]].is_numeric()) {
// convert numeric for accumulation
numeric_out_field.emplace(key, full_keys.size());
full_keys.push_back(key_pool.pool(key));
full_values.push_back(f.layer->values[f.tags[i + 1]]);
} else if (include_nonaggregate) {
// otherwise just tag it directly onto the output feature
outlayer.tag(outfeature, f.layer->keys[f.tags[i]], f.layer->values[f.tags[i + 1]]);
}
}
}
@@ -1353,22 +1631,26 @@ static void feature_out(std::vector<tile_feature> const &features, mvt_layer &ou
for (size_t j = 0; j + 1 < features[i].tags.size(); j += 2) {
const std::string &key = features[i].layer->keys[features[i].tags[j]];
keys.insert(key);
if (should_keep(key, keep, exclude, exclude_prefix)) {
keys.insert(key);
}
}
for (size_t j = 0; j + 1 < features[i].tags.size(); j += 2) {
const std::string &key = features[i].layer->keys[features[i].tags[j]];
auto f = attribute_accum.find(key);
if (f != attribute_accum.end()) {
serial_val val = mvt_value_to_serial_val(features[i].layer->values[features[i].tags[j + 1]]);
preserve_attribute(f->second, key, val, full_keys, full_values, attribute_accum_state);
} else if (accumulate_numeric.size() > 0) {
const mvt_value &val = features[i].layer->values[features[i].tags[j + 1]];
if (val.is_numeric()) {
preserve_numeric(key, val, full_keys, full_values,
accumulate_numeric,
keys, numeric_out_field, attribute_accum_state);
if (should_keep(key, keep, exclude, exclude_prefix)) {
auto found = attribute_accum.find(key);
if (found != attribute_accum.end()) {
mvt_value val = features[i].layer->values[features[i].tags[j + 1]];
preserve_attribute(found->second, key, val, full_keys, full_values, attribute_accum_state, key_pool);
} else if (accumulate_numeric.size() > 0) {
const mvt_value &val = features[i].layer->values[features[i].tags[j + 1]];
if (val.is_numeric()) {
preserve_numeric(key, val, full_keys, full_values,
accumulate_numeric,
keys, numeric_out_field, attribute_accum_state, key_pool,
keep, exclude, exclude_prefix);
}
}
}
}
@@ -1378,15 +1660,15 @@ static void feature_out(std::vector<tile_feature> const &features, mvt_layer &ou
// and tag them onto the output feature
for (size_t i = 0; i < full_keys.size(); i++) {
if (should_keep(full_keys[i], keep, exclude, exclude_prefix)) {
outlayer.tag(outfeature, full_keys[i], stringified_to_mvt_value(full_values[i].type, full_values[i].s.c_str(), tile_stringpool));
if (should_keep(*full_keys[i], keep, exclude, exclude_prefix)) {
outlayer.tag(outfeature, *full_keys[i], full_values[i]);
}
}
if (accumulate_numeric.size() > 0) {
add_mean(outfeature, outlayer, accumulate_numeric);
add_mean(outfeature, outlayer, accumulate_numeric, keep, exclude, exclude_prefix);
}
} else {
} else if (include_nonaggregate) {
for (size_t i = 0; i + 1 < features[0].tags.size(); i += 2) {
if (should_keep(features[0].layer->keys[features[0].tags[i]], keep, exclude, exclude_prefix)) {
outlayer.tag(outfeature, features[0].layer->keys[features[0].tags[i]], features[0].layer->values[features[0].tags[i + 1]]);
@@ -1395,7 +1677,10 @@ static void feature_out(std::vector<tile_feature> const &features, mvt_layer &ou
}
outlayer.features.push_back(std::move(outfeature));
return true;
}
return false;
}
static struct preservecmp {
@@ -1520,13 +1805,19 @@ static std::vector<size_t> parse_ids_string(mvt_value const &v) {
mvt_tile assign_to_bins(mvt_tile &features,
std::vector<mvt_layer> const &bins, std::string const &bin_by_id_list,
int z, int x, int y, int detail,
int z, int x, int y,
std::unordered_map<std::string, attribute_op> const &attribute_accum,
std::string const &accumulate_numeric,
std::set<std::string> keep,
std::set<std::string> exclude,
std::vector<std::string> exclude_prefix) {
std::vector<std::string> exclude_prefix,
int buffer, std::vector<clipbbox> const &clipbboxes) {
std::vector<index_event> events;
key_pool key_pool;
if (bins.size() == 0) {
return mvt_tile();
}
// Index bins
for (size_t i = 0; i < bins.size(); i++) {
@@ -1534,7 +1825,7 @@ mvt_tile assign_to_bins(mvt_tile &features,
long long xmin, ymin, xmax, ymax;
unsigned long long start, end;
get_bbox(bins[i].features[j].geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, detail);
get_bbox(bins[i].features[j].geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, bins[i].detail());
get_quadkey_bounds(xmin, ymin, xmax, ymax, &start, &end);
events.emplace_back(start, index_event::ENTER, i, j, xmin, ymin, xmax, ymax);
events.emplace_back(end, index_event::EXIT, i, j, xmin, ymin, xmax, ymax);
@@ -1554,7 +1845,7 @@ mvt_tile assign_to_bins(mvt_tile &features,
fid_to_feature.emplace(features.layers[i].features[j].id, std::make_pair(i, j));
}
get_bbox(features.layers[i].features[j].geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, detail);
get_bbox(features.layers[i].features[j].geometry, &xmin, &ymin, &xmax, &ymax, z, x, y, features.layers[i].detail());
get_quadkey_bounds(xmin, ymin, xmax, ymax, &start, &end);
events.emplace_back(start, index_event::CHECK, i, j, xmin, ymin, xmax, ymax);
}
@@ -1565,12 +1856,11 @@ mvt_tile assign_to_bins(mvt_tile &features,
std::set<active_bin> active;
mvt_layer outlayer;
outlayer.extent = 1 << detail;
outlayer.extent = bins[0].extent;
outlayer.version = 2;
outlayer.name = features.layers[0].name;
std::vector<std::vector<tile_feature>> outfeatures;
std::shared_ptr<std::string> tile_stringpool = std::make_shared<std::string>();
for (auto &e : events) {
if (e.kind == index_event::ENTER) {
@@ -1629,6 +1919,10 @@ mvt_tile assign_to_bins(mvt_tile &features,
active.insert(std::move(a));
} else if (e.kind == index_event::CHECK) {
if (bin_by_id_list.size() > 0) {
continue; // only bin by id, not geometrically
}
auto const &feature = features.layers[e.layer].features[e.feature];
if (feature.geometry.size() == 0) {
@@ -1678,21 +1972,25 @@ mvt_tile assign_to_bins(mvt_tile &features,
for (size_t i = 0; i < outfeatures.size(); i++) {
if (outfeatures[i].size() > 1) {
feature_out(outfeatures[i], outlayer,
keep, exclude, exclude_prefix, attribute_accum,
tile_stringpool, accumulate_numeric);
mvt_feature &nfeature = outlayer.features.back();
mvt_value val;
val.type = mvt_uint;
val.numeric_value.uint_value = outfeatures[i].size() - 1;
if (feature_out(outfeatures[i], outlayer,
keep, exclude, exclude_prefix, attribute_accum,
accumulate_numeric, key_pool, buffer, true,
clipbboxes, z, x, y)) {
mvt_feature &nfeature = outlayer.features.back();
mvt_value val;
val.type = mvt_uint;
val.numeric_value.uint_value = outfeatures[i].size() - 1;
std::string attrname;
if (accumulate_numeric.size() == 0) {
attrname = "tippecanoe:count";
} else {
attrname = accumulate_numeric + ":count";
std::string attrname;
if (accumulate_numeric.size() == 0) {
attrname = "tippecanoe:count";
} else {
attrname = accumulate_numeric + ":count";
}
if (should_keep(attrname, keep, exclude, exclude_prefix)) {
outlayer.tag(nfeature, attrname, val);
}
}
outlayer.tag(nfeature, attrname, val);
}
}
@@ -1702,7 +2000,7 @@ mvt_tile assign_to_bins(mvt_tile &features,
}
std::string overzoom(std::vector<source_tile> const &tiles, int nz, int nx, int ny,
int detail, int buffer,
int detail_or_unspecified, int buffer,
std::set<std::string> const &keep,
std::set<std::string> const &exclude,
std::vector<std::string> const &exclude_prefix,
@@ -1713,15 +2011,16 @@ std::string overzoom(std::vector<source_tile> const &tiles, int nz, int nx, int
std::vector<std::string> const &unidecode_data, double simplification,
double tiny_polygon_size,
std::vector<mvt_layer> const &bins, std::string const &bin_by_id_list,
std::string const &accumulate_numeric) {
std::string const &accumulate_numeric, size_t feature_limit,
std::vector<clipbbox> const &clipbboxes) {
mvt_tile outtile;
std::shared_ptr<std::string> tile_stringpool = std::make_shared<std::string>();
key_pool key_pool;
for (auto const &tile : tiles) {
for (auto const &layer : tile.tile.layers) {
mvt_layer *outlayer = NULL;
int det = detail;
int det = detail_or_unspecified;
if (det <= 0) {
det = std::round(log(layer.extent) / log(2));
}
@@ -1773,8 +2072,32 @@ std::string overzoom(std::vector<source_tile> 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) {
@@ -1840,7 +2163,10 @@ std::string overzoom(std::vector<source_tile> 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, tile_stringpool, accumulate_numeric);
feature_out(pending_tile_features, *outlayer, keep, exclude, exclude_prefix, attribute_accum, accumulate_numeric, key_pool, -1, bins.size() == 0, std::vector<clipbbox>(), nz, nx, ny);
if (outlayer->features.size() >= feature_limit) {
break;
}
pending_tile_features.clear();
}
}
@@ -1854,16 +2180,16 @@ std::string overzoom(std::vector<source_tile> const &tiles, int nz, int nx, int
if (t == VT_POLYGON && tiny_polygon_size > 0) {
bool simplified_away_by_reduction = false;
geom = reduce_tiny_poly(geom, nz, detail, &still_need_simplification_after_reduction, &simplified_away_by_reduction, &accum_area, tiny_polygon_size);
geom = reduce_tiny_poly(geom, nz, det, &still_need_simplification_after_reduction, &simplified_away_by_reduction, &accum_area, tiny_polygon_size);
} else {
still_need_simplification_after_reduction = true;
}
if (simplification > 0 && still_need_simplification_after_reduction) {
if (t == VT_POLYGON) {
geom = simplify_lines_basic(geom, nz, detail, simplification, 4);
geom = simplify_lines_basic(geom, nz, det, simplification, 4);
} else if (t == VT_LINE) {
geom = simplify_lines_basic(geom, nz, detail, simplification, 0);
geom = simplify_lines_basic(geom, nz, det, simplification, 0);
}
}
@@ -1897,8 +2223,11 @@ std::string overzoom(std::vector<source_tile> 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, tile_stringpool, accumulate_numeric);
feature_out(pending_tile_features, *outlayer, keep, exclude, exclude_prefix, attribute_accum, accumulate_numeric, key_pool, -1, bins.size() == 0, std::vector<clipbbox>(), nz, nx, ny);
pending_tile_features.clear();
if (outlayer->features.size() >= feature_limit) {
break;
}
}
if (preserve_input_order) {
@@ -1927,10 +2256,14 @@ std::string overzoom(std::vector<source_tile> const &tiles, int nz, int nx, int
std::vector<source_tile> sts;
sts.push_back(st);
// feature_limit arg is 1, because we just care whether there are any overzoomed features
// left after clipping to the child tile, not about their actual content
std::string child = overzoom(sts,
nz + 1, nx * 2 + x, ny * 2 + y,
detail, 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);
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, clipbboxes);
if (child.size() > 0) {
next_overzoomed_tiles->emplace_back(nx * 2 + x, ny * 2 + y);
}
@@ -1940,8 +2273,9 @@ std::string overzoom(std::vector<source_tile> const &tiles, int nz, int nx, int
}
if (bins.size() > 0) {
outtile = assign_to_bins(outtile, bins, bin_by_id_list, nz, nx, ny, detail, attribute_accum, accumulate_numeric,
keep, exclude, exclude_prefix);
outtile = assign_to_bins(outtile, bins, bin_by_id_list, nz, nx, ny,
attribute_accum, accumulate_numeric,
keep, exclude, exclude_prefix, buffer, clipbboxes);
}
for (ssize_t i = outtile.layers.size() - 1; i >= 0; i--) {
+23
View File
@@ -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.
File diff suppressed because it is too large Load Diff
+641
View File
@@ -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 <cstdlib>
#include <stdint.h> //#541
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
#include <numeric>
#include <memory>
#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<OutRec*> 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<void(const Point64& e1bot, const Point64& e1top,
const Point64& e2bot, const Point64& e2top, Point64& pt)> ZCallback64;
typedef std::function<void(const PointD& e1bot, const PointD& e1top,
const PointD& e2bot, const PointD& e2top, PointD& pt)> ZCallbackD;
#endif
typedef std::vector<HorzSegment> HorzSegmentList;
typedef std::unique_ptr<LocalMinima> LocalMinima_ptr;
typedef std::vector<LocalMinima_ptr> LocalMinimaList;
typedef std::vector<IntersectNode> IntersectNodeList;
// ReuseableDataContainer64 ------------------------------------------------
class ReuseableDataContainer64 {
private:
friend class ClipperBase;
LocalMinimaList minima_list_;
std::vector<Vertex*> 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*> vertex_lists_;
std::priority_queue<int64_t> scanline_list_;
IntersectNodeList intersect_nodes_;
HorzSegmentList horz_seg_list_;
std::vector<HorzJoin> 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<std::unique_ptr<PolyPath64>> PolyPath64List;
typedef typename std::vector<std::unique_ptr<PolyPathD>> 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<PolyPath64>(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<int64_t>(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<double, int64_t>(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<PolyPathD>(this, path)).get();
}
PolyPathD* AddChild(const PathD& path)
{
return childs_.emplace_back(std::make_unique<PolyPathD>(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<double>(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<double>::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<int64_t, double>(subjects, scale_, error_code_), PathType::Subject, false);
}
void AddOpenSubject(const PathsD& open_subjects)
{
AddPaths(ScalePaths<int64_t, double>(open_subjects, scale_, error_code_), PathType::Subject, true);
}
void AddClip(const PathsD& clips)
{
AddPaths(ScalePaths<int64_t, double>(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
+827
View File
@@ -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 <cstdlib>
#include <vector>
#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 <typename T>
struct CRect {
T left;
T top;
T right;
T bottom;
};
typedef CRect<int64_t> CRect64;
typedef CRect<double> CRectD;
template <typename T>
inline bool CRectIsEmpty(const CRect<T>& rect)
{
return (rect.right <= rect.left) || (rect.bottom <= rect.top);
}
template <typename T>
inline Rect<T> CRectToRect(const CRect<T>& rect)
{
Rect<T> result;
result.left = rect.left;
result.top = rect.top;
result.right = rect.right;
result.bottom = rect.bottom;
return result;
}
template <typename T1, typename T2>
inline T1 Reinterpret(T2 value) {
return *reinterpret_cast<T1*>(&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 <typename T>
static void GetPathCountAndCPathsArrayLen(const Paths<T>& paths,
size_t& cnt, size_t& array_len)
{
array_len = 2;
cnt = 0;
for (const Path<T>& 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 <typename T>
static T* CreateCPathsFromPathsT(const Paths<T>& 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<T>& path : paths)
{
if (!path.size()) continue;
*v++ = path.size();
*v++ = 0;
for (const Point<T>& pt : path)
{
*v++ = pt.x;
*v++ = pt.y;
#ifdef USINGZ
*v++ = Reinterpret<T>(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<double>(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<double>(pt.z);
#endif
}
}
return result;
}
template <typename T>
static Path<T> ConvertCPathToPathT(T* path)
{
Path<T> result;
if (!path) return result;
T* v = path;
size_t cnt = static_cast<size_t>(*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<z_type>(*v++);
result.push_back(Point<T>(x, y, z));
#else
result.push_back(Point<T>(x, y));
#endif
}
return result;
}
template <typename T>
static Paths<T> ConvertCPathsToPathsT(T* paths)
{
Paths<T> result;
if (!paths) return result;
T* v = paths; ++v;
size_t cnt = static_cast<size_t>(*v++);
result.reserve(cnt);
for (size_t i = 0; i < cnt; ++i)
{
size_t cnt2 = static_cast<size_t>(*v);
v += 2;
Path<T> path;
path.reserve(cnt2);
for (size_t j = 0; j < cnt2; ++j)
{
T x = *v++, y = *v++;
#ifdef USINGZ
z_type z = Reinterpret<z_type>(*v++);
path.push_back(Point<T>(x, y, z));
#else
path.push_back(Point<T>(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<size_t>(*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<z_type>(*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<size_t>(*v++);
result.reserve(cnt);
for (size_t i = 0; i < cnt; ++i)
{
size_t cnt2 = static_cast<size_t>(*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<z_type>(*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<int64_t>(pp->Polygon().size());
*v++ = static_cast<int64_t>(pp->Count());
for (const Point64& pt : pp->Polygon())
{
*v++ = pt.x;
*v++ = pt.y;
#ifdef USINGZ
* v++ = Reinterpret<int64_t>(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<double>(pp->Polygon().size());
*v++ = static_cast<double>(pp->Count());
for (const PointD& pt : pp->Polygon())
{
*v++ = pt.x;
*v++ = pt.y;
#ifdef USINGZ
* v++ = Reinterpret<double>(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<int64_t>(array_len);
*v++ = static_cast<int64_t>(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<double>(array_len);
*v++ = static_cast<double>(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<uint8_t>(ClipType::Xor)) return -4;
if (fillrule > static_cast<uint8_t>(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<uint8_t>(ClipType::Xor)) return -4;
if (fillrule > static_cast<uint8_t>(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<uint8_t>(ClipType::Xor)) return -4;
if (fillrule > static_cast<uint8_t>(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<uint8_t>(ClipType::Xor)) return -4;
if (fillrule > static_cast<uint8_t>(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<int64_t, double>(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<int64_t, double>(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
+671
View File
@@ -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 <cstdlib>
#include <type_traits>
#include <vector>
#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 <typename T>
inline Path<T> TranslatePath(const Path<T>& path, T dx, T dy)
{
Path<T> result;
result.reserve(path.size());
std::transform(path.begin(), path.end(), back_inserter(result),
[dx, dy](const auto& pt) { return Point<T>(pt.x + dx, pt.y +dy); });
return result;
}
inline Path64 TranslatePath(const Path64& path, int64_t dx, int64_t dy)
{
return TranslatePath<int64_t>(path, dx, dy);
}
inline PathD TranslatePath(const PathD& path, double dx, double dy)
{
return TranslatePath<double>(path, dx, dy);
}
template <typename T>
inline Paths<T> TranslatePaths(const Paths<T>& paths, T dx, T dy)
{
Paths<T> 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<int64_t>(paths, dx, dy);
}
inline PathsD TranslatePaths(const PathsD& paths, double dx, double dy)
{
return TranslatePaths<double>(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<typename T, typename U>
inline constexpr void MakePathGeneric(const T an_array,
size_t array_size, std::vector<U>& 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<typename T,
typename std::enable_if<
std::is_integral<T>::value &&
!std::is_same<char, T>::value, bool
>::type = true>
inline Path64 MakePath(const std::vector<T>& 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<typename T, std::size_t N,
typename std::enable_if<
std::is_integral<T>::value &&
!std::is_same<char, T>::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<typename T,
typename std::enable_if<
std::is_arithmetic<T>::value &&
!std::is_same<char, T>::value, bool
>::type = true>
inline PathD MakePathD(const std::vector<T>& 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<typename T, std::size_t N,
typename std::enable_if<
std::is_arithmetic<T>::value &&
!std::is_same<char, T>::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<typename T2, std::size_t N>
inline Path64 MakePathZ(const T2(&list)[N])
{
static_assert(N % 3 == 0 && std::numeric_limits<T2>::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<typename T2, std::size_t N>
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<T2>::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<int64_t>(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<int64_t, double>(path, scale, error_code);
if (error_code) return PathD();
p = TrimCollinear(p, is_open_path);
return ScalePath<double, int64_t>(p, 1/scale, error_code);
}
template <typename T>
inline double Distance(const Point<T> pt1, const Point<T> pt2)
{
return std::sqrt(DistanceSqr(pt1, pt2));
}
template <typename T>
inline double Length(const Path<T>& 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 <typename T>
inline bool NearCollinear(const Point<T>& pt1, const Point<T>& pt2, const Point<T>& 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 <typename T>
inline Path<T> Ellipse(const Rect<T>& rect, size_t steps = 0)
{
return Ellipse(rect.MidPoint(),
static_cast<double>(rect.Width()) *0.5,
static_cast<double>(rect.Height()) * 0.5, steps);
}
template <typename T>
inline Path<T> Ellipse(const Point<T>& center,
double radiusX, double radiusY = 0, size_t steps = 0)
{
if (radiusX <= 0) return Path<T>();
if (radiusY <= 0) radiusY = radiusX;
if (steps <= 2)
steps = static_cast<size_t>(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<T> result;
result.reserve(steps);
result.push_back(Point<T>(center.x + radiusX, static_cast<double>(center.y)));
for (size_t i = 1; i < steps; ++i)
{
result.push_back(Point<T>(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<bool>& 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<bool>& 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 <typename T>
inline Path<T> SimplifyPath(const Path<T> &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<T>(path);
std::vector<bool> flags(len);
std::vector<double> 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<T> result;
result.reserve(len);
for (typename Path<T>::size_type i = 0; i < len; ++i)
if (!flags[i]) result.push_back(path[i]);
return result;
}
template <typename T>
inline Paths<T> SimplifyPaths(const Paths<T> &paths,
double epsilon, bool isClosedPath = true)
{
Paths<T> result;
result.reserve(paths.size());
for (const auto& path : paths)
result.push_back(SimplifyPath(path, epsilon, isClosedPath));
return result;
}
template <typename T>
inline void RDP(const Path<T> path, std::size_t begin,
std::size_t end, double epsSqrd, std::vector<bool>& flags)
{
typename Path<T>::size_type idx = 0;
double max_d = 0;
while (end > begin && path[begin] == path[end]) flags[end--] = false;
for (typename Path<T>::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 <typename T>
inline Path<T> RamerDouglasPeucker(const Path<T>& path, double epsilon)
{
const typename Path<T>::size_type len = path.size();
if (len < 5) return Path<T>(path);
std::vector<bool> flags(len);
flags[0] = true;
flags[len - 1] = true;
RDP(path, 0, len - 1, Sqr(epsilon), flags);
Path<T> result;
result.reserve(len);
for (typename Path<T>::size_type i = 0; i < len; ++i)
if (flags[i])
result.push_back(path[i]);
return result;
}
template <typename T>
inline Paths<T> RamerDouglasPeucker(const Paths<T>& paths, double epsilon)
{
Paths<T> result;
result.reserve(paths.size());
std::transform(paths.begin(), paths.end(), back_inserter(result),
[epsilon](const auto& path)
{ return RamerDouglasPeucker<T>(path, epsilon); });
return result;
}
} // end Clipper2Lib namespace
#endif // CLIPPER_H
@@ -0,0 +1,6 @@
#ifndef CLIPPER_VERSION_H
#define CLIPPER_VERSION_H
constexpr auto CLIPPER2_VERSION = "1.4.0";
#endif // CLIPPER_VERSION_H
File diff suppressed because it is too large Load Diff
+19 -10
View File
@@ -28,6 +28,7 @@
int minzoom = 0;
int maxzoom = 32;
bool force = false;
std::set<std::string> include_attr;
bool progress_time() {
return false;
@@ -217,7 +218,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::set<std::st
} else if (coordinate_mode == 2) { // integer
scale = 1;
}
layer_to_geojson(layer, z, x, y, !pipeline, pipeline, pipeline, false, 0, 0, 0, !force, state, scale);
layer_to_geojson(layer, z, x, y, !pipeline, pipeline, pipeline, false, 0, 0, 0, !force, state, scale, include_attr);
if (!pipeline) {
if (true) {
@@ -246,23 +247,26 @@ void decode(char *fname, int z, unsigned x, unsigned y, std::set<std::string> co
if (fd >= 0) {
struct stat st;
if (fstat(fd, &st) == 0) {
if (st.st_size < 50 * 1024 * 1024) {
char *map = (char *) mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map != NULL && map != MAP_FAILED) {
if (strcmp(map, "SQLite format 3") != 0 && strncmp(map, "PMTiles", 7) != 0) {
if (z >= 0) {
char *map = (char *) mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map != NULL && map != MAP_FAILED) {
if (strcmp(map, "SQLite format 3") != 0 && strncmp(map, "PMTiles", 7) != 0) {
if (z >= 0) {
if (st.st_size > 250 * 1024 * 1024) {
fprintf(stderr, "%s: unrealistically large single-tile size %zu\n", fname, (size_t) st.st_size);
exit(EXIT_MEMORY);
} else {
std::string s = std::string(map, st.st_size);
handle(s, z, x, y, to_decode, pipeline, stats, state, coordinate_mode);
munmap(map, st.st_size);
return;
} else {
fprintf(stderr, "Must specify zoom/x/y to decode a single pbf file\n");
exit(EXIT_ARGS);
}
} else {
fprintf(stderr, "Must specify zoom/x/y to decode a single pbf file\n");
exit(EXIT_ARGS);
}
}
munmap(map, st.st_size);
}
munmap(map, st.st_size);
} else {
perror("fstat");
}
@@ -571,6 +575,7 @@ int main(int argc, char **argv) {
{"stats", no_argument, 0, 'S'},
{"force", no_argument, 0, 'f'},
{"exclude-metadata-row", required_argument, 0, 'x'},
{"include", required_argument, 0, 'y'},
{0, 0, 0, 0},
};
@@ -630,6 +635,10 @@ int main(int argc, char **argv) {
exclude_meta.insert(optarg);
break;
case 'y':
include_attr.insert(optarg);
break;
default:
usage(argv);
}
+3 -2
View File
@@ -146,8 +146,9 @@ void readFeature(const FlatGeobuf::Feature *feature, long long feature_sequence_
sf.geometry = dv;
sf.t = drawvec_type;
std::vector<std::string> full_keys;
std::vector<std::shared_ptr<std::string>> full_keys;
std::vector<serial_val> full_values;
key_pool key_pool;
// assume tabular schema with columns in header
size_t p_pos = 0;
@@ -243,7 +244,7 @@ void readFeature(const FlatGeobuf::Feature *feature, long long feature_sequence_
fprintf(stderr, "flatgeobuf has unsupported column type %u\n", (unsigned int)col_type);
exit(EXIT_IMPOSSIBLE);
}
full_keys.push_back(h_column_names[col_idx]);
full_keys.push_back(key_pool.pool(h_column_names[col_idx]));
full_values.push_back(sv);
}
+5 -4
View File
@@ -270,14 +270,14 @@ std::vector<drawvec_type> readGeometry(protozero::pbf_reader &pbf, size_t dim, d
return ret;
}
void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<std::string> &keys, struct serialization_state *sst, int layer, std::string layername) {
void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<std::string> &keys, struct serialization_state *sst, int layer, std::string layername, key_pool &key_pool) {
std::vector<drawvec_type> dv;
long long id = 0;
bool has_id = false;
std::vector<serial_val> values;
std::map<std::string, serial_val> other;
std::vector<std::string> full_keys;
std::vector<std::shared_ptr<std::string>> full_keys;
std::vector<serial_val> full_values;
while (pbf.next()) {
@@ -338,7 +338,7 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
exit(EXIT_IMPOSSIBLE);
}
full_keys.push_back(keys[properties[i]]);
full_keys.push_back(key_pool.pool(keys[properties[i]]));
full_values.push_back(values[properties[i + 1]]);
}
@@ -434,10 +434,11 @@ struct queue_run_arg {
void *run_parse_feature(void *v) {
struct queue_run_arg *qra = (struct queue_run_arg *) v;
key_pool key_pool;
for (size_t i = qra->start; i < qra->end; i++) {
struct queued_feature &qf = feature_queue[i];
readFeature(qf.pbf, qf.dim, qf.e, *qf.keys, &(*qf.sst)[qra->segment], qf.layer, qf.layername);
readFeature(qf.pbf, qf.dim, qf.e, *qf.keys, &(*qf.sst)[qra->segment], qf.layer, qf.layername, key_pool);
}
return NULL;
+3 -2
View File
@@ -58,6 +58,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
}
size_t seq = 0;
key_pool key_pool;
while ((s = csv_getline(f)).size() > 0) {
std::string err = check_utf8(s);
if (err != "") {
@@ -89,7 +90,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
drawvec dv;
dv.push_back(draw(VT_MOVETO, x, y));
std::vector<std::string> full_keys;
std::vector<std::shared_ptr<std::string>> full_keys;
std::vector<serial_val> full_values;
for (size_t i = 0; i < line.size(); i++) {
@@ -107,7 +108,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
}
sv.s = line[i];
full_keys.push_back(header[i]);
full_keys.push_back(key_pool.pool(header[i]));
full_values.push_back(sv);
}
}
+6 -5
View File
@@ -182,23 +182,24 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
nprop = properties->value.object.length;
}
std::vector<std::string> keys;
std::vector<std::shared_ptr<std::string>> full_keys;
std::vector<serial_val> values;
keys.reserve(nprop);
full_keys.reserve(nprop);
values.reserve(nprop);
key_pool key_pool;
for (size_t i = 0; i < nprop; i++) {
if (properties->value.object.keys[i]->type == JSON_STRING) {
serial_val sv = stringify_value(properties->value.object.values[i], sst->fname, sst->line, feature);
keys.emplace_back(properties->value.object.keys[i]->value.string.string);
full_keys.emplace_back(key_pool.pool(properties->value.object.keys[i]->value.string.string));
values.push_back(std::move(sv));
}
}
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;
@@ -211,7 +212,7 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
sf.geometry = dv;
sf.feature_minzoom = 0; // Will be filled in during index merging
sf.seq = *(sst->layer_seq);
sf.full_keys = std::move(keys);
sf.full_keys = std::move(full_keys);
sf.full_values = std::move(values);
return serialize_feature(sst, sf, tippecanoe_layername);
+25 -2
View File
@@ -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<source_tile> const &tiles, int nz, int nx, int ny,
int detail, int buffer,
std::set<std::string> const &keep,
@@ -127,7 +146,8 @@ std::string overzoom(std::vector<source_tile> const &tiles, int nz, int nx, int
std::vector<std::string> const &unidecode_data, double simplification,
double tiny_polygon_size,
std::vector<mvt_layer> const &bins, std::string const &bin_by_id_list,
std::string const &accumulate_numeric);
std::string const &accumulate_numeric, size_t feature_limit,
std::vector<clipbbox> const &clipbboxes);
std::string overzoom(std::vector<input_tile> const &tiles, int nz, int nx, int ny,
int detail, int buffer,
@@ -141,11 +161,14 @@ std::string overzoom(std::vector<input_tile> const &tiles, int nz, int nx, int n
std::vector<std::string> const &unidecode_data, double simplification,
double tiny_polygon_size,
std::vector<mvt_layer> const &bins, std::string const &bin_by_id_list,
std::string const &accumulate_numeric);
std::string const &accumulate_numeric, size_t feature_limit,
std::vector<clipbbox> 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
+27 -20
View File
@@ -1241,6 +1241,10 @@ int vertexcmp(const void *void1, const void *void2) {
return 0;
}
double round_droprate(double r) {
return std::round(r * 100000.0) / 100000.0;
}
std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, const char *outdir, std::set<std::string> *exclude, std::set<std::string> *include, int exclude_all, json_object *filter, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma, long long *file_bbox, long long *file_bbox1, long long *file_bbox2, const char *prefilter, const char *postfilter, const char *description, bool guess_maxzoom, bool guess_cluster_maxzoom, std::unordered_map<std::string, int> const *attribute_types, const char *pgm, std::unordered_map<std::string, attribute_op> const *attribute_accum, std::map<std::string, std::string> const &attribute_descriptions, std::string const &commandline, int minimum_maxzoom) {
int ret = EXIT_SUCCESS;
@@ -2295,6 +2299,7 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
double mean = 0;
size_t count = 0;
double m2 = 0;
size_t dupes = 0;
long long progress = -1;
long long ip;
@@ -2330,6 +2335,8 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
mean += delta / count;
double delta2 = newValue - mean;
m2 += delta * delta2;
} else {
dupes++;
}
long long nprogress = 100 * ip / indices;
@@ -2376,13 +2383,6 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
if (maxzoom < 0) {
maxzoom = 0;
}
if (maxzoom > 32 - full_detail) {
maxzoom = 32 - full_detail;
}
if (maxzoom > 33 - low_detail) { // that is, maxzoom - 1 > 32 - low_detail
maxzoom = 33 - low_detail;
}
if (!quiet) {
fprintf(stderr,
"Choosing a maxzoom of -z%d for features typically %d feet (%d meters) apart, ",
@@ -2413,7 +2413,7 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
// features is small, the drop rate should be large because the features are evenly
// spaced, and if the standard deviation is large, the drop rate can be small because
// the features are in clumps.
droprate = exp(-0.7681 * log(stddev) + 1.582);
droprate = round_droprate(exp(-0.7681 * log(stddev) + 1.582));
if (droprate < 0) {
droprate = 0;
@@ -2422,6 +2422,13 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
if (!quiet) {
fprintf(stderr, "Choosing a drop rate of %f\n", droprate);
}
if (dupes != 0 && droprate != 0) {
maxzoom += std::round(log((dupes + count) / count) / log(droprate));
if (!quiet) {
fprintf(stderr, "Increasing maxzoom to %d to account for %zu duplicate feature locations\n", maxzoom, dupes);
}
}
}
}
@@ -2430,16 +2437,6 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
double want2 = exp(dist_sum / dist_count) / 8;
int mz = ceil(log(360 / (.00000274 * want2)) / log(2) - full_detail);
if (mz < 0) {
mz = 0;
}
if (mz > 32 - full_detail) {
mz = 32 - full_detail;
}
if (mz > 33 - low_detail) { // that is, mz - 1 > 32 - low_detail
mz = 33 - low_detail;
}
if (mz > maxzoom || count <= 0) {
if (!quiet) {
fprintf(stderr, "Choosing a maxzoom of -z%d for resolution of about %d feet (%d meters) within features\n", mz, (int) exp(dist_sum / dist_count), (int) (exp(dist_sum / dist_count) / 3.28084));
@@ -2448,6 +2445,16 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
}
}
if (maxzoom < 0) {
maxzoom = 0;
}
if (maxzoom > 32 - full_detail) {
maxzoom = 32 - full_detail;
}
if (maxzoom > 33 - low_detail) { // that is, maxzoom - 1 > 32 - low_detail
maxzoom = 33 - low_detail;
}
double total_tile_count = 0;
for (int i = 1; i <= maxzoom; i++) {
double tile_count = ceil(area_sum / ((1LL << (32 - i)) * (1LL << (32 - i))));
@@ -2608,7 +2615,7 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
if (maxzoom == 0) {
droprate = 2.5;
} else {
droprate = exp(log((double) max[0].count / max[maxzoom].count) / (maxzoom));
droprate = round_droprate(exp(log((double) max[0].count / max[maxzoom].count) / (maxzoom)));
if (!quiet) {
fprintf(stderr, "Choosing a drop rate of -r%f to get from %lld to %lld in %d zooms\n", droprate, max[maxzoom].count, max[0].count, maxzoom);
}
@@ -2634,7 +2641,7 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i
if (max[z].count / interval >= max_features) {
interval = (double) max[z].count / max_features;
droprate = exp(log(interval) / (basezoom - z));
droprate = round_droprate(exp(log(interval) / (basezoom - z)));
interval = exp(log(droprate) * (basezoom - z));
if (!quiet) {
-12
View File
@@ -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<clipbbox> clipbboxes;
void checkdisk(std::vector<struct reader> *r);
+1 -1
View File
@@ -700,7 +700,7 @@ metadata make_metadata(const char *fname, int minzoom, int maxzoom, double minla
m.strategies_json = stringify_strategies(strategies);
if (isinf(droprate)) {
if (std::isinf(droprate)) {
droprate = LLONG_MAX;
}
if (basezoom != maxzoom || droprate != 2.5 || retain_points_multiplier != 1) {
+22 -2
View File
@@ -9,6 +9,7 @@
#include <vector>
#include <optional>
#include <memory>
#include <cmath>
#include "errors.hpp"
#include "text.hpp"
@@ -76,6 +77,9 @@ enum mvt_value_type {
mvt_no_such_key,
};
struct mvt_value;
double mvt_value_to_double(mvt_value const &v);
struct mvt_value {
mvt_value_type type;
std::shared_ptr<std::string> s;
@@ -95,7 +99,11 @@ struct mvt_value {
} numeric_value;
std::string get_string_value() const {
return std::string(*s, numeric_value.string_value.off, numeric_value.string_value.len);
if (type == mvt_string) {
return std::string(*s, numeric_value.string_value.off, numeric_value.string_value.len);
} else {
return toString();
}
}
std::string_view get_string_view() const {
@@ -126,6 +134,10 @@ struct mvt_value {
type == mvt_sint;
}
double to_double() const {
return mvt_value_to_double(*this);
}
bool operator<(const mvt_value &o) const;
bool operator==(const mvt_value &o) const;
std::string toString() const;
@@ -134,6 +146,11 @@ struct mvt_value {
this->type = mvt_double;
this->numeric_value.double_value = 0;
}
mvt_value(double v) {
this->type = mvt_double;
this->numeric_value.double_value = v;
}
};
template <>
@@ -185,6 +202,10 @@ struct mvt_layer {
// For tracking the key-value constants already used in this layer
std::vector<ssize_t> key_dedup = std::vector<ssize_t>(65536, -1);
std::vector<ssize_t> value_dedup = std::vector<ssize_t>(65536, -1);
int detail() const {
return std::round(std::log(extent) / std::log(2));
}
};
struct mvt_tile {
@@ -201,7 +222,6 @@ int dezig(unsigned n);
mvt_value stringified_to_mvt_value(int type, const char *s, std::shared_ptr<std::string> const &tile_stringpool);
long long mvt_value_to_long_long(mvt_value const &v);
double mvt_value_to_double(mvt_value const &v);
bool is_integer(const char *s, long long *v);
bool is_unsigned_integer(const char *s, unsigned long long *v);
+64 -2
View File
@@ -10,6 +10,7 @@
#include "attribute.hpp"
#include "text.hpp"
#include "read_json.hpp"
#include "projection.hpp"
extern char *optarg;
extern int optind;
@@ -17,6 +18,8 @@ extern int optind;
int detail = 12; // tippecanoe-style: mvt extent == 1 << detail
int buffer = 5; // tippecanoe-style: mvt buffer == extent * buffer / 256;
bool demultiply = false;
bool do_compress = true;
std::string filter;
bool preserve_input_order = false;
std::unordered_map<std::string, attribute_op> attribute_accum;
@@ -27,6 +30,7 @@ std::string accumulate_numeric;
std::set<std::string> keep;
std::set<std::string> exclude;
std::vector<std::string> exclude_prefix;
std::vector<clipbbox> 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]);
@@ -65,6 +69,9 @@ int main(int argc, char **argv) {
{"assign-to-bins", required_argument, 0, 'b' & 0x1F},
{"bin-by-id-list", required_argument, 0, 'c' & 0x1F},
{"accumulate-numeric-attributes", required_argument, 0, 'a' & 0x1F},
{"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},
};
@@ -151,6 +158,29 @@ int main(int argc, char **argv) {
accumulate_numeric = optarg;
break;
case 'd' & 0x1F:
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);
@@ -221,10 +251,42 @@ int main(int argc, char **argv) {
exit(EXIT_OPEN);
}
bins = parse_layers(f, nz, nx, ny, 1LL << detail, true);
int det = detail;
if (det < 0) {
det = 12;
}
bins = parse_layers(f, nz, nx, ny, 1LL << det, true);
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());
@@ -251,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, true, NULL, demultiply, json_filter, preserve_input_order, attribute_accum, unidecode_data, simplification, tiny_polygon_size, bins, bin_by_id_list, accumulate_numeric);
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) {
+4 -4
View File
@@ -55,7 +55,7 @@ void *run_writer(void *a) {
json_writer state(fp);
for (size_t i = 0; i < wa->layers->size(); i++) {
layer_to_geojson((*(wa->layers))[i], wa->z, wa->x, wa->y, false, true, false, true, 0, 0, 0, true, state, 0);
layer_to_geojson((*(wa->layers))[i], wa->z, wa->x, wa->y, false, true, false, true, 0, 0, 0, true, state, 0, std::set<std::string>());
}
if (fclose(fp) != 0) {
@@ -145,7 +145,7 @@ std::vector<mvt_layer> parse_layers(int fd, int z, unsigned x, unsigned y, std::
}
// Reads from the prefilter
serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::vector<std::map<std::string, layermap_entry>> *layermaps, size_t tiling_seg, std::vector<std::vector<std::string>> *layer_unmaps, bool postfilter) {
serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::vector<std::map<std::string, layermap_entry>> *layermaps, size_t tiling_seg, std::vector<std::vector<std::string>> *layer_unmaps, bool postfilter, key_pool &key_pool) {
serial_feature sf;
while (1) {
@@ -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);
}
@@ -354,7 +354,7 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::
// would have already run before prefiltering
if (v.type != mvt_null) {
sf.full_keys.push_back(std::string(properties->value.object.keys[i]->value.string.string));
sf.full_keys.push_back(key_pool.pool(std::string(properties->value.object.keys[i]->value.string.string)));
sf.full_values.push_back(v);
if (!postfilter) {
+2 -1
View File
@@ -1,3 +1,4 @@
struct key_pool;
std::vector<mvt_layer> filter_layers(const char *filter, std::vector<mvt_layer> &layer, unsigned z, unsigned x, unsigned y, std::vector<std::map<std::string, layermap_entry>> *layermaps, size_t tiling_seg, std::vector<std::vector<std::string>> *layer_unmaps, int extent);
void setup_filter(const char *filter, int *write_to, int *read_from, pid_t *pid, unsigned z, unsigned x, unsigned y);
serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::vector<std::map<std::string, layermap_entry>> *layermaps, size_t tiling_seg, std::vector<std::vector<std::string>> *layer_unmaps, bool filters);
serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::vector<std::map<std::string, layermap_entry>> *layermaps, size_t tiling_seg, std::vector<std::vector<std::string>> *layer_unmaps, bool filters, key_pool &key_pool);
+134 -121
View File
@@ -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<mvt_geometry> to_feature(drawvec &geom) {
return out;
}
std::pair<int, drawvec> 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<int, drawvec>(t, dv);
}
std::vector<mvt_layer> parse_layers(FILE *fp, int z, unsigned x, unsigned y, int extent, bool fix_longitudes) {
std::map<std::string, mvt_layer> ret;
std::shared_ptr<std::string> tile_stringpool = std::make_shared<std::string>();
@@ -208,14 +331,6 @@ std::vector<mvt_layer> 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<mvt_layer> 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<mvt_layer> 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);
}
}
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);
}
if (mb_geometry[t] == VT_POLYGON) {
dv = fix_polygon(dv, false, false);
}
std::pair<int, drawvec> parsed_geometry = parse_geometry(geometry, jp, j, z, x, y, extent, fix_longitudes, true);
// Offset and scale geometry from global to tile
for (size_t i = 0; i < dv.size(); i++) {
long long scale = 1LL << (32 - z);
// offset to tile
dv[i].x -= scale * x;
dv[i].y -= scale * y;
// scale to tile
dv[i].x = std::round(dv[i].x * extent / (double) scale);
dv[i].y = std::round(dv[i].y * extent / (double) scale);
}
if (mb_geometry[t] == VT_POLYGON) {
// don't try scaling up because we may have coordinates
// on the other side of the world
dv = clean_or_clip_poly(dv, z, 256, true, false);
if (dv.size() < 3) {
dv.clear();
}
}
dv = remove_noop(dv, mb_geometry[t], 0);
if (mb_geometry[t] == VT_POLYGON) {
dv = close_poly(dv);
}
int t = parsed_geometry.first;
drawvec &dv = parsed_geometry.second;
if (dv.size() > 0) {
mvt_feature feature;
+3 -1
View File
@@ -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<int, drawvec> 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<mvt_layer> 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);
+11 -10
View File
@@ -415,6 +415,7 @@ static void add_scaled_node(struct reader *r, serialization_state *sst, draw g)
// called from frontends
int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::string const &layername) {
struct reader *r = &(*sst->readers)[sst->segment];
key_pool key_pool;
sf.bbox[0] = LLONG_MAX;
sf.bbox[1] = LLONG_MAX;
@@ -714,7 +715,7 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
bbox_index = encode_index(midx, midy);
if (additional[A_CALCULATE_INDEX]) {
sf.full_keys.push_back("tippecanoe:index");
sf.full_keys.push_back(key_pool.pool("tippecanoe:index"));
serial_val sv;
sv.type = mvt_double;
@@ -776,7 +777,7 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
for (auto &kv : set_attributes) {
bool found = false;
for (size_t i = 0; i < sf.full_keys.size(); i++) {
if (sf.full_keys[i] == kv.first) {
if (*sf.full_keys[i] == kv.first) {
sf.full_values[i] = kv.second;
found = true;
break;
@@ -784,13 +785,13 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
}
if (!found) {
sf.full_keys.push_back(kv.first);
sf.full_keys.push_back(key_pool.pool(kv.first));
sf.full_values.push_back(kv.second);
}
}
for (ssize_t i = (ssize_t) sf.full_keys.size() - 1; i >= 0; i--) {
coerce_value(sf.full_keys[i], sf.full_values[i].type, sf.full_values[i].s, sst->attribute_types);
coerce_value(*sf.full_keys[i], sf.full_values[i].type, sf.full_values[i].s, sst->attribute_types);
if (prevent[P_SINGLE_PRECISION]) {
if (sf.full_values[i].type == mvt_double) {
@@ -801,12 +802,12 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
}
}
if (sf.full_keys[i] == attribute_for_id) {
if (*sf.full_keys[i] == attribute_for_id) {
if (sf.full_values[i].type != mvt_double && !additional[A_CONVERT_NUMERIC_IDS]) {
static bool warned = false;
if (!warned) {
fprintf(stderr, "Warning: Attribute \"%s\"=\"%s\" as feature ID is not a number\n", sf.full_keys[i].c_str(), sf.full_values[i].s.c_str());
fprintf(stderr, "Warning: Attribute \"%s\"=\"%s\" as feature ID is not a number\n", sf.full_keys[i]->c_str(), sf.full_values[i].s.c_str());
warned = true;
}
} else {
@@ -839,12 +840,12 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
}
if (sst->exclude_all) {
if (sst->include->count(sf.full_keys[i]) == 0) {
if (sst->include->count(*sf.full_keys[i]) == 0) {
sf.full_keys.erase(sf.full_keys.begin() + i);
sf.full_values.erase(sf.full_values.begin() + i);
continue;
}
} else if (sst->exclude->count(sf.full_keys[i]) != 0) {
} else if (sst->exclude->count(*sf.full_keys[i]) != 0) {
sf.full_keys.erase(sf.full_keys.begin() + i);
sf.full_values.erase(sf.full_values.begin() + i);
continue;
@@ -854,7 +855,7 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
if (!sst->filters) {
for (size_t i = 0; i < sf.full_keys.size(); i++) {
auto ts = sst->layermap->find(layername);
add_to_tilestats(ts->second.tilestats, sf.full_keys[i], sf.full_values[i]);
add_to_tilestats(ts->second.tilestats, *sf.full_keys[i], sf.full_values[i]);
}
}
@@ -867,7 +868,7 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
}
for (size_t i = 0; i < sf.full_keys.size(); i++) {
sf.keys.push_back(addpool(r->poolfile, r->treefile, sf.full_keys[i].c_str(), mvt_string, r->key_dedup));
sf.keys.push_back(addpool(r->poolfile, r->treefile, sf.full_keys[i]->c_str(), mvt_string, r->key_dedup));
sf.values.push_back(addpool(r->poolfile, r->treefile, sf.full_values[i].s.c_str(), sf.full_values[i].type, r->value_dedup));
}
+38 -1
View File
@@ -6,6 +6,7 @@
#include <string.h>
#include <vector>
#include <atomic>
#include <memory>
#include <sys/stat.h>
#include "geometry.hpp"
#include "mbtiles.hpp"
@@ -49,6 +50,42 @@ struct serial_val {
serial_val(int t, const std::string &val)
: type(t), s(val) {
}
// These functions for interface compatibility with mvt_value:
serial_val(double val) {
type = mvt_double;
s = milo::dtoa_milo(val);
}
double to_double() const {
return atof(s.c_str());
}
std::string get_string_value() const {
return s;
}
void set_string_value(std::string const &val) {
type = mvt_string;
s = val;
}
};
struct key_pool {
std::unordered_map<std::string, std::shared_ptr<std::string>> mapping;
std::shared_ptr<std::string> pool(std::string const &s) {
auto f = mapping.find(s);
if (f != mapping.end()) {
return f->second;
}
std::shared_ptr<std::string> p = std::make_shared<std::string>();
*p = s;
mapping.emplace(s, p);
return p;
}
};
struct serial_feature {
@@ -75,7 +112,7 @@ struct serial_feature {
// to create the keys and values references into the string pool
// during initial serialization
std::vector<std::string> full_keys{};
std::vector<std::shared_ptr<std::string>> full_keys{};
std::vector<serial_val> full_values{};
// These fields are generated from full_keys and full_values
+565
View File
@@ -0,0 +1,565 @@
ޢx
parsed(�  felt:h3_index SCALERANKNATSCALE LABELRANK
FEATURECLANAME NAMEASCIIADM0CAP WORLDCITYMEGACITYSOV0NAMESOV_A3ADM0NAMEADM0_A3ADM1NAMEISO_A2LATITUDE LONGITUDEPOP_MAXPOP_MIN POP_OTHERRANK_MAXRANK_MINLS_NAME MAX_POP10 MAX_POP20 MAX_POP50
MAX_POP300
MAX_POP310
MAX_NATSCA
MIN_AREAKM
MAX_AREAKM
MIN_AREAMI
MAX_AREAMI MIN_PERKM MAX_PERKM MIN_PERMI MAX_PERMI
MIN_BBXMIN
MAX_BBXMIN
MIN_BBXMAX
MAX_BBXMAX
MIN_BBYMIN
MAX_BBYMIN
MIN_BBYMAX
MAX_BBYMAX MEAN_BBXC MEAN_BBYCUN_FIDPOP1950POP1955POP1960POP1965POP1970POP1975POP1980POP1985POP1990POP1995POP2000POP2005POP2010POP2015POP2020POP2025POP2050MIN_ZOOM
WIKIDATAIDWOF_IDCAPALTNAME_ENNAME_DENAME_ESNAME_FRNAME_PTNAME_RUNAME_ZHNAME_ARNAME_BNNAME_ELNAME_HINAME_HUNAME_IDNAME_ITNAME_JANAME_KONAME_NLNAME_PLNAME_SVNAME_TRNAME_VINE_IDNAME_FANAME_HENAME_UKNAME_URNAME_ZHT
GEONAMESIDfelt:cluster_size,tippecanoe:retain_points_multiplier_sequence)tippecanoe:retain_points_multiplier_firstPOP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990NAMEALTPOP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINTIMEZONEPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990POP_MINPOP1990NAMEPARPOP_MINPOP1990POP_MINPOP1990POP_MINPOP1990"
CA"
RU"
US"
CAN"
RUS"
USA"
Kobuk"
Alaska"
Ambler"
Barrow"
Canada"
Holman"
Inuvik"
Q79333"
Q79350"
Q79395"
Q79408"
Q79714"
Q79717"
Q79809"
Q79810"
Q79813"
Q80033"
Q80133"
Russia"
巴罗"
巴羅"
배로"
코북"
홀만"
Atqasuk"
Nunavut"
Q338686"
Q465235"
Q602422"
Q606622"
Q718822"
Q719547"
Q719585"
Q719605"
Q719611"
Q719707"
Q924763"
Selawik"
Wiseman"
İnuvik"
Enurmino"
Kaktovik"
Kivalina"
Kotzebue"
Paulatuk"
Q1013046"
Q1014088"
Q1014119"
Q1020259"
Q1938137"
Q2305684"
Resolute"
Taloyoak"
Zvezdnyi"
Zvezdnyj"
Zvezdnyy"
Zvjozdny"
בארו"
بارو"
بیرو"
کوبک"
Allakaket"
Enoermino"
Enourmino"
Kugluktuk"
Utqiagvik"
Zvëzdnyj"
コブク"
バロー"
剑桥湾"
劍橋灣"
安布勒"
懷斯曼"
温赖特"
科伯克"
科策布"
約阿港"
育空堡"
셀라윅"
앰블러"
앳쿼석"
이누빅"
코체부"
Fort Yukon"
Gjoa Haven"
Point Hope"
Ulukhaktok"
Utqiaġvik"
Wainwright"
Кобук"
אלקקט"
אמבלר"
חולמן"
קובוק"
امبلر"
انوئک"
رزلوت"
كوبوك"
کوبوک"
Fort Yukón"
Mys Chmidta"
Mys Shmidta"
Mys Sjmidta"
Mys Szmidta"
Mys Šmidta"
Prudhoe Bay"
Tuktoyaktuk"
Ikaluktutiak"
Mys Schmidta"
Resolute Bay"
Tsiigehtchic"
Άμπλερ"
Χόλμαν"
Інувік"
Амблер"
Барроу"
Инувик"
Коцебу"
וויזמן"
טלויאק"
קוצביו"
רזולוט"
أمبلير"
إنوفيك"
ایمبلر"
سلاویک"
سیلاوک"
سیگیچک"
هولمان"
وایزمن"
پالتاک"
پولاٹک"
ہولمان"
努勒維特"
因纽维克"
基瓦利纳"
塔洛約克"
塞拉威克"
施密特岬"
波拉圖克"
雷索卢特"
齊格奇克"
뚝토약툭"
리솔루트"
알라카켓"
와이즈맨"
치이게치"
키발리나"
탈로요크"
파울라툭"
Cambridge Bay"
United States"
포트 유콘"
America/Inuvik"
America/Juneau"
Campbridge Bay"
Fort McPherson"
Prudhoe-öböl"
Ινούβικ"
Κομπούκ"
Μπάροου"
Σελαβίκ"
Аткасук"
Вайзмен"
Полатук"
Селавик"
Селавік"
Уайзмен"
Цігечик"
אטקאסוק"
אינוויק"
סלאוויק"
קקטוביק"
آتکاسوک"
آلاکاکت"
اینوویک"
ایٹقاسک"
بولاتوك"
تالویوک"
تسیگچیک"
زویزڈنج"
سيلاويك"
كوتزبيو"
نورمینو"
وائزمین"
وينرايت"
وینرائٹ"
وینرایت"
ٹالویوک"
کگ لک تک"
کیکٹووک"
Populated place"
جوا ہیون"
وايز مان"
پرودو بی"
कोबुक"
কসেভো"
কোবুক"
アンブラー"
エヌルミノ"
カクトビク"
キバリーナ"
セラウィク"
タロヨーク"
ワイズマン"
卡克托维克"
普拉德霍湾"
普拉德霍灣"
波因特霍普"
烏路卡托克"
艾奴爾米諾"
艾特跨萨克"
茲韋茲德尼"
迈斯施密达"
阿拉卡基特"
麥克弗森堡"
麦克弗森堡"
에누르미노"
웨인라이트"
카크토비크"
쿠글룩투크"
America/Resolute"
Vịnh Cambridge"
Αλακάκετ"
Ατκασούκ"
Ζβέζντιγ"
Κάκτοβικ"
Κιβαλίνα"
Ρεσολούτ"
Вейнрайт"
Енурміно"
Звёздный"
Кактовик"
Кактовік"
Кивалина"
Паулатук"
Резольют"
Талойоак"
Уэйнрайт"
Цигетчик"
Энурмино"
אנורמינו"
ויינרייט"
פאולאטוק"
ציג'טצ'יק"
קיוולינה"
أتكيوسوك"
ألاكاكيت"
إنورمينو"
انورمینو"
تالويواك"
ریسولوتی"
زووزدنیج"
زيفازدني"
كاكتوفيك"
كيفالينا"
کاکتوویک"
کوتزابیو"
کوتزهبیو"
کیوالینا"
미스 슈미타"
조아 헤이븐"
포인트 호프"
포트 맥퍼슨"
프루도 베이"
Форт-Юкон"
פוינט הופ"
פרודו ביי"
بوينت هوب"
پروڈہو بے"
پوینت هوپ"
کمبریج بی"
کیمبرج بے"
Γουάιζμαν"
Ενουρμίνο"
Ταλογιοάκ"
Аллакакет"
Звьоздний"
Куглуктук"
זביוזדניי"
ایلاکاکیٹ"
كوغلوكتوك"
مایسشمیتا"
ٹکٹویاکٹک"
کوگلاکتوک"
इनुविक"
होलमैन"
ইনুভিক"
アラカキット"
イヌヴィック"
コッツビュー"
シュミット岬"
ズヴョズニィ"
パウラトゥク"
プルードー湾"
レゾリュート"
伊尔库茨克州"
图克托亚图克"
圖克托亞圖克"
库格鲁克图克"
庫格魯克圖克"
즈베즈드니이"
Μις Σμίντα"
Йоа-Гейвен"
Йоа-Хейвен"
Мис Барроу"
Мис Шмідта"
Мыс Шмидта"
Пойнт-Гоуп"
Пойнт-Хоуп"
Прадхо-Бей"
מיס שמידטה"
פורט יוקון"
جیجوی هیون"
فورت يوكون"
فورت یوکان"
فورٹ یوکون"
ميس شميدتا"
پوائنٹ ہوپ"
캠브리지 베이"
Γουέινραϊτ"
Κοτζέμπουε"
Παουλατούκ"
Тактояктук"
Туктояктук"
Улукхакток"
גג'ואה האבן"
טוקטויאטוק"
קוגלולקטוק"
اولاکاکچوک"
تسيجيهتشيك"
Northwest Territories"
Γκόα Χέιβεν"
Πόιντ Χόουπ"
خليج برودهو"
فورٹ مکفرسن"
مئیس شمیدتا"
ऐम्ब्लर"
पॉलातुक"
रेसोलूट"
वेनराइट"
सेलाविक"
ওয়েনরিট"
তালোয়াক"
সেলাউইক"
アットカサック"
ウェインライト"
クグルクトゥク"
ポイントホープ"
توكتوياكتوك"
توکتویاکتوک"
Προύντο Μπέι"
Φορτ Γιούκον"
פורט מקפרסון"
خليج كامبردج"
قرية ريزولوت"
Chukchi Autonomous Okrug"
United States of America"
Τσιγκέχτσιτς"
فورت مک فرسون"
قرية غوا هافن"
अत्कासुक"
अलाकाकेट"
इनर्मिनो"
किवालिना"
टालोयोआक"
वाइज़मैन"
কাকতোভিক"
কিভালিনা"
পাউলাটুক"
রেজোলিউট"
সিগেটছিক"
হোলম্যান"
ウルクハクトーク"
ジョア・ヘイヴン"
トサイイジチック"
フォートユーコン"
Кеймбридж-Бей"
Кеймбрідж-Бей"
فورت ماكفرسون"
पॉइंट होप"
Κουγκλουκτούκ"
קיימברדיג' ביי"
Κέιμπριτζ Μπέι"
Φορτ ΜακΦέρσον"
Форт-Макферсон"
काक्तोविक"
এনিউরমিনো"
ケンブリッジ・ベイ"
トゥクトヤクトゥク"
Τουκτογιάκτουκ"
ज़ोआ हेवेन"
प्रुदहो बे"
मिस श्मिता"
পয়েন্ট হোপ"
ফোর্ট ইউকন"
उत्कीग्विक"
कुग्लुकटूक"
कोटज़ेबूये"
অ্যাম্বলার"
আল্লাকাকেত"
উৎকিয়াভিক"
ওয়াইজম্যান"
কুগ্লুকটুক"!
গজোয়া হাভেন"!
প্রুদোহে বে"#
!त्सीगेत्चिक"#
!フォートマクファーソン"$
"कैम्ब्रिज बे"$
"फ़ोर्ट यूकॉन"$
"কেম্ব্রিজ বে"$
"মাইস শ্মিদতা"&
$অ্যাটকোয়াসুক"&
$জেভেজদিনিয়াজ"&
$তুকতোইয়াকতুক")
'ज़्वेज़्दनिज़")
'तुक्तोयाक्तुक"0
.फ़ोर्ट मैकफ़र्सन"0
.ফোর্ট ম্যাকফারসন" �B"@�B"��" ~�$AQ@" ��ek�b�" b��!bQ@" �J�8�Q@"  �v�Q@"  �v�P@"  IJ��W�"  �a���P@" �Z�Ld�" �Z�̼P@" ^d�" ^)b�" ^�d�" 4���^�" Z��!ze�" ����W�" �""�a�" ��N�c�" #�3���P@" %�I(}�P@" *8� "Q@" *8� "bQ@" *8� "bW�" *8� "�P@" *8� "�Q@" -����c�" 6=((E�P@" 9 �/��P@" <.�ED�Q@" <.�ED�P@" >ϟ6��c�" HO�CDd�" HO�CD(b�" HO�CD�d�" HO�CD�a�" HR����P@" QۆQ�P@" S�1���`�" `YiR
�Q@" `�5�!bW�" fffffQ@" fffffbQ@" ffffff@" jܛ�0�P@" n���\�" p����P@" rP�L��d�" u�]Q@" uʣ�rf�" y��n��Q@" {��vw'b�" {��vwSd�" }[�TSd�" �};��d�" ��5|GQ@" ��"���Q@" ��"���Q@" ��"���P@" ���҇(Q@" �:���;Q@" �u�X�XQ@" �����Rd�" �����aW�" ������ @" ������c�" �j-��(b�" ������Q@" �ajK�P@" ����bQ@" �P�>�c�" �
F%u�P@" �Σ���`�" ���¨Q@" �*4K�a�" ������R@" �k���Q@" ������d�" ��鲘�Q@" �r��of�" �uŌp�b�" ��U���P@" ��U���Q@" ��N��o]�" ǽ� ��`�" �iO�9d�" �����d�" ����̨Q@" ������@" �����Q@" �Y�eQ@" ��C��Q@" ��C��aW�" ��C�ݥP@" ��<�!BZ�" ��*��Qd�" �/-��d�" �p��0�c�" ��r���d�" ��TOf�`�" ������c�" �� <�c�" ����#�P@" �����P@" " " " " " " " " "
" " " " " " " " 2" a" d" e" n" ����" ��ܨ" �" �"
��㩋���" ����" �"
��������"
��Ʉ�õ�" �" ����" ��ۨ"
��������" �" � " ����" ���" ����" �"
��������" ����" � " �"
�����ݵ�" � "
�����Ӷ�" �
" �" ���("
��ᵅ���" ����" ����"
��Ҩ����" �"
���ޡ���"
��������" ��ܨ" �
"
�����ص�" ��ܨ" �" �" �" �"
�æ��˵�" �"
���ᤶ��" ��ܨ" ��ۨ" �" �" �" �" �" �" �" �" � " ���" ����" �" � " ����" ���"
�ְ�����" ���0" � " �"
��Ɲ����" ��ۨ" ����" ��ۨ" ����" �" ����" ��ۨ" ���" ��ۨ" ���0" � " ��ۨ" �"
��ビ���" �" ���" ��ܨ" �" � " �" ��ܨ" �" �" ώܨ" Ѧ�" ѻ��"
�𰲡���" �"
әհÕ��" ��ܨ"
Ե���Ű�"
Ժ�ं��" �" ��ܨ" և�" ��ܨ" �ގ" ���"
ے�і���" ��ܨ" �" �" ݻۨ" ����" ߷�0" ߻��" ��ܨ" ��ܨ" ��ڐ" ��ۨ" �" �" ���" ����" ���" �" ����" �" ���"
�ڪ�����"
����̄��" ����" �" ��ۨ" ��ۨ" �" ���" ����" ���0" �!"
��������" ����" ��ܨ"
������"
󀼆�ð�" �"
��Œ����" ��ܨ" �" ���" �" ���" ��ۨ" �" ���" �" �" � " ��ܨ" �" ���("0"8��������� �
�  � ��������������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�9�:�;�<�=�>�?�@�A�B�CD�E�FGHIJK�L�M�N�O�P�QRST�UVVWXYZ[�\�]�^�_�`�a�b�c�d��" ��8��������� �
�  � ���e������������ �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�f�:�;�<�=�>�?�@�A�B�C D�E�FGHIJK_LPMgN�O�P�QRSTIUVWXYZ[�\h]c^__B`Pa�b�c�d��" ��?�������++�� �
�  � ���g����+�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�h�:�;�<�=�>�?�@�A�B�CD�E�F+G+H+I+J+K�L�M�N�O�P�Q+R+S+T�UTV+W+X+Y+Z+[�\�]�^�_�`�a�b�c�d��" ��?�������CC�� �
�  � ���i����C�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�j�:�;�<�=�>�?�@�A�B�CD�E�FCGCHCICJCK�L�M�N�O�P�QCRCSCT�U�VCWCXCYCZC[�\�]`^�_�`�a�b�c�d��" ��?�������..�� �
   ����k����.�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�l�:�;�<�=�>�?�@�A�B�C7D�E�F.G.H.IEJ.K�L�M�N�O�P�Q.R.S.T�U�VDW.X.Y.Z.[�\�]�^�_�`�a�b�c�d��" ��?�������Hm=<�� �
   ����n����=�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�o�:�;�<�=�>�?�@�A�B�C8D�E�FHGHHHIHJHK�L�M�N�O�P�QHR<SHT�U�V>W;XHYHZH[�\�]�^�_�`�a�b�c�d��" &�7�������22�� �

����p����2�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�q�:�;�<�=�>�?�@�A�B�C!D�E�F2G2H2I2J2K�L�M�N�O�P�Q2R2S2T�U�V2W2X2Y2Z2[�\�]�^�_�`�a�b�c�d�� " �'�:�������tt�� �

����r����t�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�s�:�;�<�=�>�?�@�A�B�C4D�E�FtGtHtItJtK�L�M�N�O�P�QtRtStT�U�VtWtXtYtZt[�\�]�^�_�`�a�b�c�d�� " � �>�������00�� �
�  � ���t����0�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�u�:�;�<�=�>�?�@�A�B�CD�E�F0G0H0I0J0K�L�M�N�O�P�Q0R0S0T�U�V0W0X0Y0Z0[�\�]�^�_�`�a�b�c�d��" � �=��������� �
�  � ���v������������ �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�w�:�;�<�=�>�?�@�A�B�C"D�E�FGHIJKxLMM�N�OuP�QRST�UUVWXYZ[�\d]a^x_�`Ma�b�c�d��" ��>�������11�� �
�  � ���x����1�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�y�0�1�2�3�4�5�6�7�8�z�:�;�<�=�>�?�@�A�B�CD�E�F1G1H1I1J1K{LQM�N�O�P�Q1R1S1T�UXV1W1X1Y1Z1[�\�]~^{_�`Qa�b�c�d��" � �?�������,,�� �
�  � ���{����,�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�|�:�;�<�=�>�?�@�A�B�C*D�E�F,G,H,I,J,K�LNM�N�O�P�Q,R,S,T�U�V,W,X,Y,Z,[�\�]|^�_�`Na�b�c�d��" ��>�������kk�� �
   ����}����k�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8�~�:�;�<�=�>�?�@�A�B�C6D�E�FkGrHkIjJkK�L�M�N�O�P�QkRkSnT�U�VlWmXlYkZk[�\�]�^�_�`�a�b�c�d��" .�;����������� �

����������������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�y�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C5D�E�F�G�H�I�J�K�L�M�N�O�P�Q�R�S�T�U�V�W�X�Y�Z�[�\�]�^�_�`�a�b�c�d��!" � �>�������^^�� �
�  � ��������^�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�CD�E�F^G^H^I^J^K�LOM�N�O�P�Q^R^S^T�U�V^W^X^Y^Z^[�\�]�^�_�`Oa�b�c�d��*" ��7�������//�� �
�  � ��������/�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�CD�E�F/G/H/I/J/K�L�M�N�O�P�Q/R/S/T�U�V/W/X/Y/Z/[�\�]�^�_�`�a�b�c�d��*" ��9�������YY�� �
�  � ��������Y�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�CD�E�FYGYHiIYJYK�LSM�N�O�P�QYRYSYT�U�VYWYXYYYZY[�\�]�^�_�`Sa�b�c�d��*" ��?�������  �� �

��������� �������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C$D�E�F\G\H I\J\K�L�M�N�OvP�Q R S\T�UV\W X\Y\Z [�\�]b^�_�`�a�b�c�d��+" �,�7�������ZZ�� �

��������Z�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�y�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C&D�E�FZGZHZIZJZK�LRM�N�O�P�QZRZSZT�U�VZWZXZYZZZ[�\�]�^�_�`Ra�b�c�d��/" �;�<�������  �� �

��������� �������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�y�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C D�E�F G H I J KzL�M�N�O�P�Q R S T�UWV W X Y-Z [�\�]�^w_e`�a�b�c�d��/" � �<�������pp�� �

���������p�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C%D�E�FpGpHpIpJpK�L�M�N�O�P�QpRpSpT�U�VpWpXpYpZp[�\�]�^�_�`�a�b�c�d��/" �!�:����������� �

����������������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C(D�E�F�G�H�IqJ�K�LKM�N�O�P�Q�R�S�T�U�V�W�X�Y�Z�[�\�]�^�_�`La�b�c�d��4" �5�;�������FF�� �

��������F�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�y�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C)D�E�FFGFHFIFJFK�L�M�N�O�P�QFRFSFT�U�VFWFXFYFZF[�\�]�^�_�`�a�b�c�d��4" �.�=�������::�� �

��������:�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C'D�E�F:G:H:I:J:K�L�M�N�O�P�Q:R:S:T�U�V:W:X:Y:Z:[�\�]}^�_�`�a�b�c�d��4" �=�:�������[[�� �
�  � ��������[�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�CD�E�F[G[H[I[J[K�L�M�N�O�P�Q[R[S[T�U�V[W[X[Y[Z[[�\�]�^�_�`�a�b�c�d��5" � �<�������]� ]�� �
�  � �������� �������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�y�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�CD�E�FGG]HGIGJ KyLM@N�O�P�Q]R S]TJUV W X Y ZG[�\@]?^�_A`a�b�c�d��5" ��6�������oo�� �
�  � ��������o�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C3D�E�FoGoHoIoJoK�L�M�N�O�P�Q�RoSoT�U�VoWoXoYoZo[�\�]�^�_�`�a�b�c�d��5" ��8�������99�� �

��������9�������� �!�"�#�$�%�&�'�(�)�*�+�,�-�.�/�0�1�2�3�4�5�6�7�8���:�;�<�=�>�?�@�A�B�C#D�E�F9GsH9I9J9K�L�M�N�O�P�Q9R9S9T�U�V9W9X9Y9Z9[�\f]^�_�`�a�b�c�d��6" �<�.
File diff suppressed because one or more lines are too long
+68 -70
View File
@@ -9,8 +9,8 @@
"maxzoom": "13",
"minzoom": "11",
"name": "tests/muni/out/-Z11_-z13_-rf2000.json.check.mbtiles",
"strategies": "[{},{},{},{},{},{},{},{},{},{},{},{\"dropped_by_rate\":2542},{\"dropped_by_rate\":1547},{}]",
"tippecanoe_decisions": "{\"basezoom\":13,\"droprate\":1.4510341140028376,\"retain_points_multiplier\":1}",
"strategies": "[{},{},{},{},{},{},{},{},{},{},{},{\"dropped_by_rate\":2544},{\"dropped_by_rate\":1546},{}]",
"tippecanoe_decisions": "{\"basezoom\":13,\"droprate\":1.45103,\"retain_points_multiplier\":1}",
"type": "overlay",
"version": "2"
}, "features": [
@@ -58,7 +58,7 @@
,
{ "type": "Feature", "properties": { "name": "19th Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.475286, 37.721102 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Avenue & Holloway St" }, "geometry": { "type": "Point", "coordinates": [ -122.475071, 37.721204 ] } }
{ "type": "Feature", "properties": { "name": "19th Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.475071, 37.721238 ] } }
,
{ "type": "Feature", "properties": { "name": "19TH AVE & HOLLOWAY" }, "geometry": { "type": "Point", "coordinates": [ -122.475114, 37.720967 ] } }
,
@@ -90,8 +90,6 @@
,
{ "type": "Feature", "properties": { "name": "GRAFTON AVE & PLYMOUTH AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.457047, 37.720118 ] } }
,
{ "type": "Feature", "properties": { "name": "Plymouth Ave & Grafton Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456231, 37.720118 ] } }
,
{ "type": "Feature", "properties": { "name": "Grafton Ave & Plymouth Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456231, 37.719982 ] } }
,
{ "type": "Feature", "properties": { "name": "Grafton Ave & Brighton Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.454987, 37.720084 ] } }
@@ -150,7 +148,7 @@
,
{ "type": "Feature", "properties": { "name": "Brazil Ave & Moscow St" }, "geometry": { "type": "Point", "coordinates": [ -122.427478, 37.721238 ] } }
,
{ "type": "Feature", "properties": { "name": "Persia Ave & Moscow St" }, "geometry": { "type": "Point", "coordinates": [ -122.428679, 37.719745 ] } }
{ "type": "Feature", "properties": { "name": "Moscow St & Persia Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428765, 37.719812 ] } }
,
{ "type": "Feature", "properties": { "name": "Brazil Ave & Prague St" }, "geometry": { "type": "Point", "coordinates": [ -122.426147, 37.720525 ] } }
,
@@ -218,7 +216,7 @@
,
{ "type": "Feature", "properties": { "name": "Gonzalez Dr & Font Blvd" }, "geometry": { "type": "Point", "coordinates": [ -122.475886, 37.716689 ] } }
,
{ "type": "Feature", "properties": { "name": "Gonzalez Dr & Josepha Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.477174, 37.715976 ] } }
{ "type": "Feature", "properties": { "name": "Garces Dr & Gonzalez Dr" }, "geometry": { "type": "Point", "coordinates": [ -122.478333, 37.715841 ] } }
,
{ "type": "Feature", "properties": { "name": "Cambon Dr & Castelo Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.474427, 37.717266 ] } }
,
@@ -248,7 +246,7 @@
,
{ "type": "Feature", "properties": { "name": "Junipero Serra Blvd & Brotherhood Way" }, "geometry": { "type": "Point", "coordinates": [ -122.471251, 37.713532 ] } }
,
{ "type": "Feature", "properties": { "name": "Junipero Serra Blvd & Palmetto Av" }, "geometry": { "type": "Point", "coordinates": [ -122.470994, 37.710918 ] } }
{ "type": "Feature", "properties": { "name": "19th Ave & Randolph St" }, "geometry": { "type": "Point", "coordinates": [ -122.470007, 37.714415 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Ave & Randolph St" }, "geometry": { "type": "Point", "coordinates": [ -122.470007, 37.714449 ] } }
,
@@ -256,7 +254,7 @@
,
{ "type": "Feature", "properties": { "name": "Broad St & Arch St" }, "geometry": { "type": "Point", "coordinates": [ -122.467389, 37.712514 ] } }
,
{ "type": "Feature", "properties": { "name": "Randolph St & Arch St" }, "geometry": { "type": "Point", "coordinates": [ -122.467217, 37.714211 ] } }
{ "type": "Feature", "properties": { "name": "Alemany Blvd & St Charles Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.469449, 37.710341 ] } }
,
{ "type": "Feature", "properties": { "name": "Brotherhood Way & Arch ST" }, "geometry": { "type": "Point", "coordinates": [ -122.466874, 37.712344 ] } }
,
@@ -318,7 +316,7 @@
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Broad St" }, "geometry": { "type": "Point", "coordinates": [ -122.453141, 37.713294 ] } }
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Farallones St" }, "geometry": { "type": "Point", "coordinates": [ -122.452240, 37.714177 ] } }
{ "type": "Feature", "properties": { "name": "San Jose Ave & Farallones St" }, "geometry": { "type": "Point", "coordinates": [ -122.452154, 37.714143 ] } }
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Farallones St" }, "geometry": { "type": "Point", "coordinates": [ -122.452068, 37.714075 ] } }
,
@@ -332,7 +330,7 @@
,
{ "type": "Feature", "properties": { "name": "Mission St & Sickles Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.453313, 37.708643 ] } }
,
{ "type": "Feature", "properties": { "name": "Mission St & Lawrence Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.450867, 37.709492 ] } }
{ "type": "Feature", "properties": { "name": "Mission St & Acton St" }, "geometry": { "type": "Point", "coordinates": [ -122.452197, 37.708881 ] } }
,
{ "type": "Feature", "properties": { "name": "Alemany Blvd & Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.442369, 37.717640 ] } }
,
@@ -388,7 +386,7 @@
,
{ "type": "Feature", "properties": { "name": "South Hill Blvd & Chicago Way" }, "geometry": { "type": "Point", "coordinates": [ -122.431512, 37.710714 ] } }
,
{ "type": "Feature", "properties": { "name": "1650 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428164, 37.711868 ] } }
{ "type": "Feature", "properties": { "name": "1650 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428293, 37.711733 ] } }
,
{ "type": "Feature", "properties": { "name": "1721 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.426276, 37.711088 ] } }
,
@@ -458,7 +456,7 @@
,
{ "type": "Feature", "properties": { "name": "Delta St & Wilde Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.407436, 37.717776 ] } }
,
{ "type": "Feature", "properties": { "name": "Tioga Ave & Delta St" }, "geometry": { "type": "Point", "coordinates": [ -122.407608, 37.717165 ] } }
{ "type": "Feature", "properties": { "name": "Delta St & Tioga Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.407737, 37.717300 ] } }
,
{ "type": "Feature", "properties": { "name": "Tioga Ave & Rutland St" }, "geometry": { "type": "Point", "coordinates": [ -122.405806, 37.716655 ] } }
,
@@ -528,7 +526,7 @@
,
{ "type": "Feature", "properties": { "name": "Bay Shore Blvd & Sunnydale Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.405033, 37.708949 ] } }
,
{ "type": "Feature", "properties": { "name": "Bay Shore Blvd & Sunnydale Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.404861, 37.709085 ] } }
{ "type": "Feature", "properties": { "name": "Not a public stop" }, "geometry": { "type": "Point", "coordinates": [ -122.404647, 37.709526 ] } }
,
{ "type": "Feature", "properties": { "name": "SUNNYDALE AVE & BAYSHORE BLVD" }, "geometry": { "type": "Point", "coordinates": [ -122.405248, 37.708813 ] } }
,
@@ -1074,7 +1072,7 @@
,
{ "type": "Feature", "properties": { "name": "Ortega St & 48th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.507515, 37.750935 ] } }
,
{ "type": "Feature", "properties": { "name": "46th Ave & Noriega St" }, "geometry": { "type": "Point", "coordinates": [ -122.505498, 37.752835 ] } }
{ "type": "Feature", "properties": { "name": "Noriega St & 46th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.505584, 37.752903 ] } }
,
{ "type": "Feature", "properties": { "name": "46th Ave & Noriega St" }, "geometry": { "type": "Point", "coordinates": [ -122.505326, 37.752835 ] } }
,
@@ -1450,7 +1448,7 @@
,
{ "type": "Feature", "properties": { "name": "9th Ave & Irving St" }, "geometry": { "type": "Point", "coordinates": [ -122.466230, 37.764269 ] } }
,
{ "type": "Feature", "properties": { "name": "Irving St & 9th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.466145, 37.764099 ] } }
{ "type": "Feature", "properties": { "name": "Lincoln Way & 7th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.464600, 37.766101 ] } }
,
{ "type": "Feature", "properties": { "name": "Irving St. & 9th Ave." }, "geometry": { "type": "Point", "coordinates": [ -122.466145, 37.764099 ] } }
,
@@ -1610,7 +1608,7 @@
,
{ "type": "Feature", "properties": { "name": "Mcallister St & Central Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.444773, 37.776922 ] } }
,
{ "type": "Feature", "properties": { "name": "McAllister St & Lyon St" }, "geometry": { "type": "Point", "coordinates": [ -122.443399, 37.777092 ] } }
{ "type": "Feature", "properties": { "name": "Mcallister St & Lyon St" }, "geometry": { "type": "Point", "coordinates": [ -122.443314, 37.777160 ] } }
,
{ "type": "Feature", "properties": { "name": "Hayes St & Ashbury St" }, "geometry": { "type": "Point", "coordinates": [ -122.447562, 37.773802 ] } }
,
@@ -1882,7 +1880,7 @@
,
{ "type": "Feature", "properties": { "name": "Castro St & 20th St" }, "geometry": { "type": "Point", "coordinates": [ -122.434645, 37.757619 ] } }
,
{ "type": "Feature", "properties": { "name": "Castro St & 22nd St" }, "geometry": { "type": "Point", "coordinates": [ -122.434473, 37.754633 ] } }
{ "type": "Feature", "properties": { "name": "Castro St & 21st St" }, "geometry": { "type": "Point", "coordinates": [ -122.434473, 37.755957 ] } }
,
{ "type": "Feature", "properties": { "name": "16th Ave & Ortega St" }, "geometry": { "type": "Point", "coordinates": [ -122.473097, 37.752394 ] } }
,
@@ -1920,7 +1918,7 @@
,
{ "type": "Feature", "properties": { "name": "Ulloa St. & 17th Ave." }, "geometry": { "type": "Point", "coordinates": [ -122.473526, 37.741196 ] } }
,
{ "type": "Feature", "properties": { "name": "14th Ave & Taraval St" }, "geometry": { "type": "Point", "coordinates": [ -122.470307, 37.743402 ] } }
{ "type": "Feature", "properties": { "name": "15th Ave & Taraval St" }, "geometry": { "type": "Point", "coordinates": [ -122.471380, 37.743062 ] } }
,
{ "type": "Feature", "properties": { "name": "14th Ave & Taraval St" }, "geometry": { "type": "Point", "coordinates": [ -122.470179, 37.743164 ] } }
,
@@ -2070,7 +2068,7 @@
,
{ "type": "Feature", "properties": { "name": "19th Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.475286, 37.721102 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Avenue & Holloway St" }, "geometry": { "type": "Point", "coordinates": [ -122.475071, 37.721170 ] } }
{ "type": "Feature", "properties": { "name": "19th Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.475071, 37.721238 ] } }
,
{ "type": "Feature", "properties": { "name": "19TH AVE & HOLLOWAY" }, "geometry": { "type": "Point", "coordinates": [ -122.475114, 37.720967 ] } }
,
@@ -2140,7 +2138,7 @@
,
{ "type": "Feature", "properties": { "name": "GRAFTON AVE & PLYMOUTH AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.457047, 37.720084 ] } }
,
{ "type": "Feature", "properties": { "name": "Plymouth Ave & Grafton Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456231, 37.720118 ] } }
{ "type": "Feature", "properties": { "name": "Plymouth Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456017, 37.721747 ] } }
,
{ "type": "Feature", "properties": { "name": "Grafton Ave & Plymouth Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456231, 37.719948 ] } }
,
@@ -2356,7 +2354,7 @@
,
{ "type": "Feature", "properties": { "name": "Ocean Ave&I-280 on-ramp NE-NS/SB" }, "geometry": { "type": "Point", "coordinates": [ -122.446918, 37.723037 ] } }
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Ocean Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.444687, 37.723071 ] } }
{ "type": "Feature", "properties": { "name": "Ocean Ave & San Jose Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.444944, 37.723003 ] } }
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Ocean Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.444386, 37.723207 ] } }
,
@@ -2394,7 +2392,7 @@
,
{ "type": "Feature", "properties": { "name": "Green Yard-San Jose & Ocean" }, "geometry": { "type": "Point", "coordinates": [ -122.445030, 37.722732 ] } }
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Ocean Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.444730, 37.722800 ] } }
{ "type": "Feature", "properties": { "name": "San Jose Ave & Ocean Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.444901, 37.722935 ] } }
,
{ "type": "Feature", "properties": { "name": "Ocean Ave & San Jose St" }, "geometry": { "type": "Point", "coordinates": [ -122.444386, 37.722901 ] } }
,
@@ -2604,7 +2602,7 @@
,
{ "type": "Feature", "properties": { "name": "California St & Van Ness Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.422028, 37.790421 ] } }
,
{ "type": "Feature", "properties": { "name": "Van Ness Ave & Pine St" }, "geometry": { "type": "Point", "coordinates": [ -122.422285, 37.789506 ] } }
{ "type": "Feature", "properties": { "name": "California St & Polk St" }, "geometry": { "type": "Point", "coordinates": [ -122.420826, 37.790489 ] } }
,
{ "type": "Feature", "properties": { "name": "Bush St &Van ness Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.421813, 37.788387 ] } }
,
@@ -2676,7 +2674,7 @@
,
{ "type": "Feature", "properties": { "name": "Pacific Ave & Larkin St" }, "geometry": { "type": "Point", "coordinates": [ -122.420011, 37.795135 ] } }
,
{ "type": "Feature", "properties": { "name": "Hyde St & Broadway" }, "geometry": { "type": "Point", "coordinates": [ -122.418551, 37.796492 ] } }
{ "type": "Feature", "properties": { "name": "Hyde St & Broadway" }, "geometry": { "type": "Point", "coordinates": [ -122.418380, 37.796356 ] } }
,
{ "type": "Feature", "properties": { "name": "Pacific Ave & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.418380, 37.795373 ] } }
,
@@ -2830,7 +2828,7 @@
,
{ "type": "Feature", "properties": { "name": "Battery St & Jackson St" }, "geometry": { "type": "Point", "coordinates": [ -122.400784, 37.796865 ] } }
,
{ "type": "Feature", "properties": { "name": "Stockton St & Jackson St" }, "geometry": { "type": "Point", "coordinates": [ -122.408295, 37.795746 ] } }
{ "type": "Feature", "properties": { "name": "Pacific Ave & Stockton St" }, "geometry": { "type": "Point", "coordinates": [ -122.408595, 37.796729 ] } }
,
{ "type": "Feature", "properties": { "name": "Stockton St & Pacific Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.408252, 37.796255 ] } }
,
@@ -3062,7 +3060,7 @@
,
{ "type": "Feature", "properties": { "name": "Avenue H & California St" }, "geometry": { "type": "Point", "coordinates": [ -122.366409, 37.819921 ] } }
,
{ "type": "Feature", "properties": { "name": "California St & Avenue H" }, "geometry": { "type": "Point", "coordinates": [ -122.366109, 37.819921 ] } }
{ "type": "Feature", "properties": { "name": "California St & Avenue C" }, "geometry": { "type": "Point", "coordinates": [ -122.370143, 37.818328 ] } }
,
{ "type": "Feature", "properties": { "name": "Treasure Island Rd & Macalla Rd" }, "geometry": { "type": "Point", "coordinates": [ -122.371130, 37.813073 ] } }
,
@@ -3132,7 +3130,7 @@
,
{ "type": "Feature", "properties": { "name": "Mcallister St & Laguna St" }, "geometry": { "type": "Point", "coordinates": [ -122.426705, 37.779331 ] } }
,
{ "type": "Feature", "properties": { "name": "Hayes St & Buchanan St" }, "geometry": { "type": "Point", "coordinates": [ -122.428250, 37.776244 ] } }
{ "type": "Feature", "properties": { "name": "Hayes St & Buchanan St" }, "geometry": { "type": "Point", "coordinates": [ -122.427564, 37.776244 ] } }
,
{ "type": "Feature", "properties": { "name": "Laguna St & Hayes St" }, "geometry": { "type": "Point", "coordinates": [ -122.426276, 37.776753 ] } }
,
@@ -3202,7 +3200,7 @@
,
{ "type": "Feature", "properties": { "name": "Hyde St & Turk St" }, "geometry": { "type": "Point", "coordinates": [ -122.415805, 37.782655 ] } }
,
{ "type": "Feature", "properties": { "name": "Larkin St & Mcallister St" }, "geometry": { "type": "Point", "coordinates": [ -122.416878, 37.780552 ] } }
{ "type": "Feature", "properties": { "name": "Larkin St&Mcallister St" }, "geometry": { "type": "Point", "coordinates": [ -122.416835, 37.780382 ] } }
,
{ "type": "Feature", "properties": { "name": "Mcallister St & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.415848, 37.780620 ] } }
,
@@ -3220,7 +3218,7 @@
,
{ "type": "Feature", "properties": { "name": "O'Farrell St & Jones St" }, "geometry": { "type": "Point", "coordinates": [ -122.412500, 37.785809 ] } }
,
{ "type": "Feature", "properties": { "name": "Geary Blvd & Taylor St" }, "geometry": { "type": "Point", "coordinates": [ -122.411685, 37.786962 ] } }
{ "type": "Feature", "properties": { "name": "Eddy St & Jones St" }, "geometry": { "type": "Point", "coordinates": [ -122.412415, 37.783876 ] } }
,
{ "type": "Feature", "properties": { "name": "Geary Blvd & Mason St" }, "geometry": { "type": "Point", "coordinates": [ -122.410269, 37.787166 ] } }
,
@@ -3256,6 +3254,8 @@
,
{ "type": "Feature", "properties": { "name": "Market St & Van Ness Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.419367, 37.775226 ] } }
,
{ "type": "Feature", "properties": { "name": "Market St & Van Ness Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.419195, 37.775226 ] } }
,
{ "type": "Feature", "properties": { "name": "11th St/btw Market & Mission" }, "geometry": { "type": "Point", "coordinates": [ -122.418637, 37.775498 ] } }
,
{ "type": "Feature", "properties": { "name": "11th St & Market St" }, "geometry": { "type": "Point", "coordinates": [ -122.418509, 37.775498 ] } }
@@ -3290,7 +3290,7 @@
,
{ "type": "Feature", "properties": { "name": "8th St & Market St" }, "geometry": { "type": "Point", "coordinates": [ -122.414603, 37.778483 ] } }
,
{ "type": "Feature", "properties": { "name": "8th St & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.413015, 37.777228 ] } }
{ "type": "Feature", "properties": { "name": "Market St & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.414389, 37.779093 ] } }
,
{ "type": "Feature", "properties": { "name": "Mission St & 8th St" }, "geometry": { "type": "Point", "coordinates": [ -122.412715, 37.777703 ] } }
,
@@ -3586,7 +3586,7 @@
,
{ "type": "Feature", "properties": { "name": "2nd St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.394991, 37.784079 ] } }
,
{ "type": "Feature", "properties": { "name": "3rd St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.397437, 37.782621 ] } }
{ "type": "Feature", "properties": { "name": "Harrison St & 3rd St" }, "geometry": { "type": "Point", "coordinates": [ -122.397652, 37.782417 ] } }
,
{ "type": "Feature", "properties": { "name": "Bryant St & 4th St" }, "geometry": { "type": "Point", "coordinates": [ -122.398081, 37.779466 ] } }
,
@@ -3646,7 +3646,7 @@
,
{ "type": "Feature", "properties": { "name": "4th St & 3rd St" }, "geometry": { "type": "Point", "coordinates": [ -122.389669, 37.772954 ] } }
,
{ "type": "Feature", "properties": { "name": "Mission Bay North & 3rd St" }, "geometry": { "type": "Point", "coordinates": [ -122.389627, 37.771156 ] } }
{ "type": "Feature", "properties": { "name": "Third Street & Mission Rock St" }, "geometry": { "type": "Point", "coordinates": [ -122.389712, 37.772818 ] } }
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & Alameda St" }, "geometry": { "type": "Point", "coordinates": [ -122.407651, 37.768238 ] } }
,
@@ -3656,7 +3656,7 @@
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & 16th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407651, 37.765694 ] } }
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & 17th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407522, 37.764235 ] } }
{ "type": "Feature", "properties": { "name": "Potrero Ave & 17th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407351, 37.764744 ] } }
,
{ "type": "Feature", "properties": { "name": "16th St & San Bruno Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.405505, 37.765864 ] } }
,
@@ -3722,11 +3722,11 @@
,
{ "type": "Feature", "properties": { "name": "20th St & Rhode Island St" }, "geometry": { "type": "Point", "coordinates": [ -122.402244, 37.759621 ] } }
,
{ "type": "Feature", "properties": { "name": "Rhode Island St & Southern Heights Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.402072, 37.758501 ] } }
{ "type": "Feature", "properties": { "name": "Rhode Island St & 20th St" }, "geometry": { "type": "Point", "coordinates": [ -122.401986, 37.759587 ] } }
,
{ "type": "Feature", "properties": { "name": "De Haro St & 19th St" }, "geometry": { "type": "Point", "coordinates": [ -122.401128, 37.760944 ] } }
,
{ "type": "Feature", "properties": { "name": "Southern Heights Ave & De Haro St" }, "geometry": { "type": "Point", "coordinates": [ -122.400784, 37.758094 ] } }
{ "type": "Feature", "properties": { "name": "Southern Heights Ave & De Haro St" }, "geometry": { "type": "Point", "coordinates": [ -122.401128, 37.758128 ] } }
,
{ "type": "Feature", "properties": { "name": "De Haro St & Southern Heights Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.400870, 37.758026 ] } }
,
@@ -3760,7 +3760,7 @@
,
{ "type": "Feature", "properties": { "name": "18th St & Pennsylvania Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.393231, 37.762742 ] } }
,
{ "type": "Feature", "properties": { "name": "16th St & 4th St" }, "geometry": { "type": "Point", "coordinates": [ -122.390699, 37.766746 ] } }
{ "type": "Feature", "properties": { "name": "Mission Bay South & 4th St SE-FS/ BZ" }, "geometry": { "type": "Point", "coordinates": [ -122.391043, 37.770511 ] } }
,
{ "type": "Feature", "properties": { "name": "1731 3RD ST" }, "geometry": { "type": "Point", "coordinates": [ -122.389283, 37.769697 ] } }
,
@@ -4050,7 +4050,7 @@
,
{ "type": "Feature", "properties": { "name": "Brazil Ave & Moscow St" }, "geometry": { "type": "Point", "coordinates": [ -122.427478, 37.721204 ] } }
,
{ "type": "Feature", "properties": { "name": "Persia Ave & Moscow St" }, "geometry": { "type": "Point", "coordinates": [ -122.428679, 37.719711 ] } }
{ "type": "Feature", "properties": { "name": "Moscow St & Persia Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428765, 37.719812 ] } }
,
{ "type": "Feature", "properties": { "name": "Brazil Ave & Prague St" }, "geometry": { "type": "Point", "coordinates": [ -122.426147, 37.720525 ] } }
,
@@ -4120,7 +4120,7 @@
,
{ "type": "Feature", "properties": { "name": "University St & Wayland St" }, "geometry": { "type": "Point", "coordinates": [ -122.412887, 37.723818 ] } }
,
{ "type": "Feature", "properties": { "name": "Woolsey St & Dartmouth St" }, "geometry": { "type": "Point", "coordinates": [ -122.410612, 37.723105 ] } }
{ "type": "Feature", "properties": { "name": "Woolsey St & Colby St" }, "geometry": { "type": "Point", "coordinates": [ -122.411427, 37.722935 ] } }
,
{ "type": "Feature", "properties": { "name": "University St & Woolsey St" }, "geometry": { "type": "Point", "coordinates": [ -122.412543, 37.722732 ] } }
,
@@ -4192,11 +4192,11 @@
,
{ "type": "Feature", "properties": { "name": "Connecticut St & 26th St" }, "geometry": { "type": "Point", "coordinates": [ -122.396321, 37.751410 ] } }
,
{ "type": "Feature", "properties": { "name": "Evans Ave & Cesar Chavez St" }, "geometry": { "type": "Point", "coordinates": [ -122.397051, 37.749035 ] } }
{ "type": "Feature", "properties": { "name": "Evans Ave & Cesar Chavez St" }, "geometry": { "type": "Point", "coordinates": [ -122.396879, 37.749069 ] } }
,
{ "type": "Feature", "properties": { "name": "Connecticut St & Cesar Chavez St" }, "geometry": { "type": "Point", "coordinates": [ -122.396364, 37.749849 ] } }
,
{ "type": "Feature", "properties": { "name": "25th St & Dakota St" }, "geometry": { "type": "Point", "coordinates": [ -122.394819, 37.752496 ] } }
{ "type": "Feature", "properties": { "name": "Dakota St & 25th St" }, "geometry": { "type": "Point", "coordinates": [ -122.394691, 37.752665 ] } }
,
{ "type": "Feature", "properties": { "name": "Evans Ave & Napoleon St" }, "geometry": { "type": "Point", "coordinates": [ -122.396235, 37.747338 ] } }
,
@@ -4234,7 +4234,7 @@
,
{ "type": "Feature", "properties": { "name": "3rd St & Evans Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.388124, 37.742451 ] } }
,
{ "type": "Feature", "properties": { "name": "Phelps St & Mckinnon Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.392974, 37.738073 ] } }
{ "type": "Feature", "properties": { "name": "Jerrold Ave & Phelps St" }, "geometry": { "type": "Point", "coordinates": [ -122.391429, 37.739838 ] } }
,
{ "type": "Feature", "properties": { "name": "Phelps St & Mckinnon Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.392974, 37.737870 ] } }
,
@@ -4262,7 +4262,7 @@
,
{ "type": "Feature", "properties": { "name": "Silver Ave & San Bruno Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.405677, 37.732338 ] } }
,
{ "type": "Feature", "properties": { "name": "Silver Ave & Charter Oak Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.404304, 37.733254 ] } }
{ "type": "Feature", "properties": { "name": "Bay Shore Blvd & Silver Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.404733, 37.733220 ] } }
,
{ "type": "Feature", "properties": { "name": "Bay Shore Blvd & Silver Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.404819, 37.732983 ] } }
,
@@ -4546,8 +4546,6 @@
,
{ "type": "Feature", "properties": { "name": "Gonzalez Dr & Font Blvd" }, "geometry": { "type": "Point", "coordinates": [ -122.475886, 37.716689 ] } }
,
{ "type": "Feature", "properties": { "name": "Gonzalez Dr & Josepha Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.477174, 37.715976 ] } }
,
{ "type": "Feature", "properties": { "name": "Cambon Dr & Castelo Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.474427, 37.717266 ] } }
,
{ "type": "Feature", "properties": { "name": "Cambon Dr & Castelo Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.474256, 37.717436 ] } }
@@ -4596,7 +4594,7 @@
,
{ "type": "Feature", "properties": { "name": "Delta St & Wilde Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.407436, 37.717776 ] } }
,
{ "type": "Feature", "properties": { "name": "Tioga Ave & Delta St" }, "geometry": { "type": "Point", "coordinates": [ -122.407608, 37.717165 ] } }
{ "type": "Feature", "properties": { "name": "Delta St & Tioga Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.407737, 37.717300 ] } }
,
{ "type": "Feature", "properties": { "name": "Tioga Ave & Rutland St" }, "geometry": { "type": "Point", "coordinates": [ -122.405806, 37.716655 ] } }
,
@@ -4634,8 +4632,6 @@
,
{ "type": "Feature", "properties": { "name": "Van Ness Station Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.419324, 37.775226 ] } }
,
{ "type": "Feature", "properties": { "name": "Metro Van Ness Station/Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.419238, 37.775125 ] } }
,
{ "type": "Feature", "properties": { "name": "Metro Civic Center Station/Outbd" }, "geometry": { "type": "Point", "coordinates": [ -122.414989, 37.778686 ] } }
,
{ "type": "Feature", "properties": { "name": "Metro Church Station/Outbound" }, "geometry": { "type": "Point", "coordinates": [ -122.429323, 37.767322 ] } }
@@ -4822,7 +4818,7 @@
,
{ "type": "Feature", "properties": { "name": "Junipero Serra Blvd & Brotherhood Way" }, "geometry": { "type": "Point", "coordinates": [ -122.471251, 37.713549 ] } }
,
{ "type": "Feature", "properties": { "name": "Junipero Serra Blvd & Palmetto Av" }, "geometry": { "type": "Point", "coordinates": [ -122.470994, 37.710901 ] } }
{ "type": "Feature", "properties": { "name": "JUNIPERO SERRA BLVD/S.F. Golf Club" }, "geometry": { "type": "Point", "coordinates": [ -122.471316, 37.710697 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Ave & Randolph St" }, "geometry": { "type": "Point", "coordinates": [ -122.470028, 37.714398 ] } }
,
@@ -4924,7 +4920,7 @@
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Broad St" }, "geometry": { "type": "Point", "coordinates": [ -122.453141, 37.713294 ] } }
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Farallones St" }, "geometry": { "type": "Point", "coordinates": [ -122.452219, 37.714160 ] } }
{ "type": "Feature", "properties": { "name": "San Jose Ave & Farallones St" }, "geometry": { "type": "Point", "coordinates": [ -122.452283, 37.713939 ] } }
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Farallones St" }, "geometry": { "type": "Point", "coordinates": [ -122.452133, 37.714143 ] } }
,
@@ -5498,7 +5494,7 @@
,
{ "type": "Feature", "properties": { "name": "Noriega St & 46th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.505713, 37.753022 ] } }
,
{ "type": "Feature", "properties": { "name": "46th Ave & Noriega St" }, "geometry": { "type": "Point", "coordinates": [ -122.505476, 37.752835 ] } }
{ "type": "Feature", "properties": { "name": "Noriega St & 46th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.505562, 37.752886 ] } }
,
{ "type": "Feature", "properties": { "name": "46th Ave & Noriega St" }, "geometry": { "type": "Point", "coordinates": [ -122.505326, 37.752818 ] } }
,
@@ -6274,7 +6270,7 @@
,
{ "type": "Feature", "properties": { "name": "Mcallister St & Central Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.444751, 37.776939 ] } }
,
{ "type": "Feature", "properties": { "name": "McAllister St & Lyon St" }, "geometry": { "type": "Point", "coordinates": [ -122.443421, 37.777092 ] } }
{ "type": "Feature", "properties": { "name": "Central Ave & McAllister St" }, "geometry": { "type": "Point", "coordinates": [ -122.444837, 37.776804 ] } }
,
{ "type": "Feature", "properties": { "name": "Mcallister St & Lyon St" }, "geometry": { "type": "Point", "coordinates": [ -122.443314, 37.777160 ] } }
,
@@ -6942,7 +6938,7 @@
,
{ "type": "Feature", "properties": { "name": "19TH AVE & HOLLOWAY Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.475092, 37.721255 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Avenue & Holloway St" }, "geometry": { "type": "Point", "coordinates": [ -122.475092, 37.721187 ] } }
{ "type": "Feature", "properties": { "name": "19th Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.475092, 37.721238 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.475221, 37.721068 ] } }
,
@@ -7044,7 +7040,7 @@
,
{ "type": "Feature", "properties": { "name": "Plymouth Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456231, 37.721934 ] } }
,
{ "type": "Feature", "properties": { "name": "Plymouth Ave & Grafton Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456210, 37.720101 ] } }
{ "type": "Feature", "properties": { "name": "Plymouth Ave & Holloway Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456038, 37.721764 ] } }
,
{ "type": "Feature", "properties": { "name": "Grafton Ave & Plymouth Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456231, 37.719965 ] } }
,
@@ -7988,7 +7984,7 @@
{ "type": "FeatureCollection", "properties": { "layer": "muni", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { "name": "Naples St & Russia Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.432413, 37.719201 ] } }
,
{ "type": "Feature", "properties": { "name": "Persia Ave & Moscow St" }, "geometry": { "type": "Point", "coordinates": [ -122.428679, 37.719728 ] } }
{ "type": "Feature", "properties": { "name": "Moscow St & Persia Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428765, 37.719829 ] } }
,
{ "type": "Feature", "properties": { "name": "Persia Ave & Prague St" }, "geometry": { "type": "Point", "coordinates": [ -122.427349, 37.718930 ] } }
,
@@ -8044,7 +8040,7 @@
,
{ "type": "Feature", "properties": { "name": "Chicago Way & South Hill Blvd" }, "geometry": { "type": "Point", "coordinates": [ -122.431383, 37.710561 ] } }
,
{ "type": "Feature", "properties": { "name": "1650 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428186, 37.711868 ] } }
{ "type": "Feature", "properties": { "name": "1650 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428293, 37.711733 ] } }
,
{ "type": "Feature", "properties": { "name": "1701 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.426770, 37.711105 ] } }
,
@@ -8146,7 +8142,7 @@
,
{ "type": "Feature", "properties": { "name": "Wilde Ave & Delta St" }, "geometry": { "type": "Point", "coordinates": [ -122.407179, 37.717810 ] } }
,
{ "type": "Feature", "properties": { "name": "Tioga Ave & Delta St" }, "geometry": { "type": "Point", "coordinates": [ -122.407629, 37.717148 ] } }
{ "type": "Feature", "properties": { "name": "Delta St & Tioga Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.407715, 37.717283 ] } }
,
{ "type": "Feature", "properties": { "name": "Tioga Ave & Rutland St" }, "geometry": { "type": "Point", "coordinates": [ -122.405784, 37.716655 ] } }
,
@@ -8248,7 +8244,7 @@
,
{ "type": "Feature", "properties": { "name": "BAY SHORE BLVD & SUNNYDALE AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.405055, 37.708830 ] } }
,
{ "type": "Feature", "properties": { "name": "Bay Shore Blvd & Sunnydale Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.404840, 37.709085 ] } }
{ "type": "Feature", "properties": { "name": "Not a public stop" }, "geometry": { "type": "Point", "coordinates": [ -122.404625, 37.709526 ] } }
,
{ "type": "Feature", "properties": { "name": "SUNNYDALE AVE & BAYSHORE BLVD" }, "geometry": { "type": "Point", "coordinates": [ -122.405248, 37.708796 ] } }
,
@@ -8474,7 +8470,7 @@
,
{ "type": "Feature", "properties": { "name": "Mcallister St & Laguna St" }, "geometry": { "type": "Point", "coordinates": [ -122.426705, 37.779331 ] } }
,
{ "type": "Feature", "properties": { "name": "Hayes St & Buchanan St" }, "geometry": { "type": "Point", "coordinates": [ -122.428272, 37.776261 ] } }
{ "type": "Feature", "properties": { "name": "Grove St & Laguna St" }, "geometry": { "type": "Point", "coordinates": [ -122.426319, 37.777380 ] } }
,
{ "type": "Feature", "properties": { "name": "Hayes St & Buchanan St" }, "geometry": { "type": "Point", "coordinates": [ -122.427542, 37.776244 ] } }
,
@@ -8576,7 +8572,7 @@
,
{ "type": "Feature", "properties": { "name": "Mcallister St & Larkin St" }, "geometry": { "type": "Point", "coordinates": [ -122.417414, 37.780501 ] } }
,
{ "type": "Feature", "properties": { "name": "Larkin St & Mcallister St" }, "geometry": { "type": "Point", "coordinates": [ -122.416856, 37.780569 ] } }
{ "type": "Feature", "properties": { "name": "Larkin St & Mcallister St" }, "geometry": { "type": "Point", "coordinates": [ -122.416964, 37.780755 ] } }
,
{ "type": "Feature", "properties": { "name": "Larkin St&Mcallister St" }, "geometry": { "type": "Point", "coordinates": [ -122.416835, 37.780382 ] } }
,
@@ -9128,7 +9124,7 @@
,
{ "type": "Feature", "properties": { "name": "3rd St & Perry St" }, "geometry": { "type": "Point", "coordinates": [ -122.397459, 37.782706 ] } }
,
{ "type": "Feature", "properties": { "name": "3rd St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.397437, 37.782638 ] } }
{ "type": "Feature", "properties": { "name": "Harrison St & 3rd St" }, "geometry": { "type": "Point", "coordinates": [ -122.397673, 37.782434 ] } }
,
{ "type": "Feature", "properties": { "name": "Bryant St & 4th St" }, "geometry": { "type": "Point", "coordinates": [ -122.398059, 37.779466 ] } }
,
@@ -9230,7 +9226,7 @@
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & 16th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407479, 37.766033 ] } }
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & 17th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407544, 37.764218 ] } }
{ "type": "Feature", "properties": { "name": "Potrero Ave & 17th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407351, 37.764727 ] } }
,
{ "type": "Feature", "properties": { "name": "16th St & San Bruno Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.405505, 37.765864 ] } }
,
@@ -9332,7 +9328,7 @@
,
{ "type": "Feature", "properties": { "name": "De Haro St & 20th St" }, "geometry": { "type": "Point", "coordinates": [ -122.401021, 37.759655 ] } }
,
{ "type": "Feature", "properties": { "name": "Southern Heights Ave & De Haro St" }, "geometry": { "type": "Point", "coordinates": [ -122.400784, 37.758094 ] } }
{ "type": "Feature", "properties": { "name": "Southern Heights Ave & De Haro St" }, "geometry": { "type": "Point", "coordinates": [ -122.401106, 37.758128 ] } }
,
{ "type": "Feature", "properties": { "name": "De Haro St & Southern Heights Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.400870, 37.758009 ] } }
,
@@ -9802,7 +9798,7 @@
,
{ "type": "Feature", "properties": { "name": "Brazil Ave & Munich St" }, "geometry": { "type": "Point", "coordinates": [ -122.426984, 37.720899 ] } }
,
{ "type": "Feature", "properties": { "name": "Persia Ave & Moscow St" }, "geometry": { "type": "Point", "coordinates": [ -122.428679, 37.719728 ] } }
{ "type": "Feature", "properties": { "name": "Moscow St & Persia Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428765, 37.719812 ] } }
,
{ "type": "Feature", "properties": { "name": "Brazil Ave & Prague St" }, "geometry": { "type": "Point", "coordinates": [ -122.426147, 37.720508 ] } }
,
@@ -9904,7 +9900,7 @@
,
{ "type": "Feature", "properties": { "name": "Woolsey St & Colby St" }, "geometry": { "type": "Point", "coordinates": [ -122.411449, 37.722935 ] } }
,
{ "type": "Feature", "properties": { "name": "Woolsey St & Dartmouth St" }, "geometry": { "type": "Point", "coordinates": [ -122.410591, 37.723122 ] } }
{ "type": "Feature", "properties": { "name": "Woolsey St & Dartmouth St" }, "geometry": { "type": "Point", "coordinates": [ -122.410419, 37.723241 ] } }
,
{ "type": "Feature", "properties": { "name": "University St & Woolsey St" }, "geometry": { "type": "Point", "coordinates": [ -122.412522, 37.722732 ] } }
,
@@ -10006,7 +10002,7 @@
,
{ "type": "Feature", "properties": { "name": "Connecticut St & 26th St" }, "geometry": { "type": "Point", "coordinates": [ -122.396343, 37.751427 ] } }
,
{ "type": "Feature", "properties": { "name": "Evans Ave & Cesar Chavez St" }, "geometry": { "type": "Point", "coordinates": [ -122.397072, 37.749018 ] } }
{ "type": "Feature", "properties": { "name": "26th St & Wisconsin St" }, "geometry": { "type": "Point", "coordinates": [ -122.398660, 37.751105 ] } }
,
{ "type": "Feature", "properties": { "name": "Evans Ave & Cesar Chavez St" }, "geometry": { "type": "Point", "coordinates": [ -122.396879, 37.749069 ] } }
,
@@ -10108,7 +10104,7 @@
,
{ "type": "Feature", "properties": { "name": "Silver Ave & San Bruno Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.405698, 37.732338 ] } }
,
{ "type": "Feature", "properties": { "name": "Silver Ave & Charter Oak Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.404282, 37.733271 ] } }
{ "type": "Feature", "properties": { "name": "San Bruno Ave & Silver Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.405548, 37.732168 ] } }
,
{ "type": "Feature", "properties": { "name": "Bay Shore Blvd & Silver Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.404711, 37.733203 ] } }
,
@@ -10514,6 +10510,8 @@
,
{ "type": "Feature", "properties": { "name": "Wilde Ave & Delta St" }, "geometry": { "type": "Point", "coordinates": [ -122.407179, 37.717810 ] } }
,
{ "type": "Feature", "properties": { "name": "Delta St & Tioga Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.407715, 37.717283 ] } }
,
{ "type": "Feature", "properties": { "name": "Gilman Ave & Griffith St" }, "geometry": { "type": "Point", "coordinates": [ -122.388275, 37.718234 ] } }
,
{ "type": "Feature", "properties": { "name": "Gilman Ave & Bill Walsh Way" }, "geometry": { "type": "Point", "coordinates": [ -122.386987, 37.717504 ] } }
@@ -10760,7 +10758,7 @@
,
{ "type": "Feature", "properties": { "name": "Polk St & California St" }, "geometry": { "type": "Point", "coordinates": [ -122.420783, 37.790642 ] } }
,
{ "type": "Feature", "properties": { "name": "Van Ness Ave & Pine St" }, "geometry": { "type": "Point", "coordinates": [ -122.422307, 37.789506 ] } }
{ "type": "Feature", "properties": { "name": "California St & Polk St" }, "geometry": { "type": "Point", "coordinates": [ -122.420826, 37.790489 ] } }
,
{ "type": "Feature", "properties": { "name": "Bush St &Van ness Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.421834, 37.788404 ] } }
,
@@ -10862,7 +10860,7 @@
,
{ "type": "Feature", "properties": { "name": "Pacific Ave & Larkin St" }, "geometry": { "type": "Point", "coordinates": [ -122.420032, 37.795152 ] } }
,
{ "type": "Feature", "properties": { "name": "Hyde St & Broadway" }, "geometry": { "type": "Point", "coordinates": [ -122.418573, 37.796492 ] } }
{ "type": "Feature", "properties": { "name": "Pacific Ave & Larkin St" }, "geometry": { "type": "Point", "coordinates": [ -122.419860, 37.795322 ] } }
,
{ "type": "Feature", "properties": { "name": "Hyde St & Broadway" }, "geometry": { "type": "Point", "coordinates": [ -122.418380, 37.796339 ] } }
,
@@ -11424,7 +11422,7 @@
,
{ "type": "Feature", "properties": { "name": "Avenue H & California St" }, "geometry": { "type": "Point", "coordinates": [ -122.366409, 37.819938 ] } }
,
{ "type": "Feature", "properties": { "name": "California St & Avenue H" }, "geometry": { "type": "Point", "coordinates": [ -122.366130, 37.819921 ] } }
{ "type": "Feature", "properties": { "name": "Avenue H & California St" }, "geometry": { "type": "Point", "coordinates": [ -122.366323, 37.819989 ] } }
,
{ "type": "Feature", "properties": { "name": "California St & Avenue C" }, "geometry": { "type": "Point", "coordinates": [ -122.370143, 37.818328 ] } }
,
+81 -83
View File
@@ -9,8 +9,8 @@
"maxzoom": "13",
"minzoom": "11",
"name": "tests/muni/out/-Z11_-z13_-rf2000_-g2.json.check.mbtiles",
"strategies": "[{},{},{},{},{},{},{},{},{},{},{},{\"dropped_by_rate\":1349,\"dropped_by_gamma\":963},{\"dropped_by_rate\":747,\"dropped_by_gamma\":752},{\"dropped_by_gamma\":514}]",
"tippecanoe_decisions": "{\"basezoom\":13,\"droprate\":1.176222768016331,\"retain_points_multiplier\":1}",
"strategies": "[{},{},{},{},{},{},{},{},{},{},{},{\"dropped_by_rate\":1349,\"dropped_by_gamma\":964},{\"dropped_by_rate\":748,\"dropped_by_gamma\":751},{\"dropped_by_gamma\":514}]",
"tippecanoe_decisions": "{\"basezoom\":13,\"droprate\":1.17622,\"retain_points_multiplier\":1}",
"type": "overlay",
"version": "2"
}, "features": [
@@ -124,9 +124,7 @@
,
{ "type": "Feature", "properties": { "name": "SAN JOSE AVE & GENEVA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.446575, 37.720627 ] } }
,
{ "type": "Feature", "properties": { "name": "SAN JOSE AVE & GENEVA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.446575, 37.720627 ] } }
,
{ "type": "Feature", "properties": { "name": "SAN JOSE AVE & GENEVA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.446704, 37.720457 ] } }
{ "type": "Feature", "properties": { "name": "CAMERON BEACH YARD" }, "geometry": { "type": "Point", "coordinates": [ -122.446532, 37.720627 ] } }
,
{ "type": "Feature", "properties": { "name": "Geneva Ave & Delano Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.445374, 37.720288 ] } }
,
@@ -158,8 +156,6 @@
,
{ "type": "Feature", "properties": { "name": "Mansell St & Visitacion Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.411342, 37.718760 ] } }
,
{ "type": "Feature", "properties": { "name": "Mansell St & Dartmouth St" }, "geometry": { "type": "Point", "coordinates": [ -122.409067, 37.719371 ] } }
,
{ "type": "Feature", "properties": { "name": "Mansell St & Hamilton St" }, "geometry": { "type": "Point", "coordinates": [ -122.407093, 37.719880 ] } }
,
{ "type": "Feature", "properties": { "name": "Mansell St & Goettingen St" }, "geometry": { "type": "Point", "coordinates": [ -122.404346, 37.720763 ] } }
@@ -180,6 +176,8 @@
,
{ "type": "Feature", "properties": { "name": "Third Street & Le Conte Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.397480, 37.718828 ] } }
,
{ "type": "Feature", "properties": { "name": "3rd St & Key St" }, "geometry": { "type": "Point", "coordinates": [ -122.396708, 37.719778 ] } }
,
{ "type": "Feature", "properties": { "name": "Fitzgerald Ave & Ingalls St" }, "geometry": { "type": "Point", "coordinates": [ -122.391429, 37.720967 ] } }
,
{ "type": "Feature", "properties": { "name": "Fitzgerald Ave & Hawes St" }, "geometry": { "type": "Point", "coordinates": [ -122.389584, 37.719914 ] } }
@@ -238,7 +236,7 @@
,
{ "type": "Feature", "properties": { "name": "Brotherhood Way & Summit Way SE-FS/SB" }, "geometry": { "type": "Point", "coordinates": [ -122.474470, 37.713600 ] } }
,
{ "type": "Feature", "properties": { "name": "Chumasero Dr & Galindo Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.473140, 37.714041 ] } }
{ "type": "Feature", "properties": { "name": "Chumasero Dr & Galindo Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.473140, 37.714075 ] } }
,
{ "type": "Feature", "properties": { "name": "Chumasero Dr & Brotherhood Way" }, "geometry": { "type": "Point", "coordinates": [ -122.472925, 37.713294 ] } }
,
@@ -356,7 +354,7 @@
,
{ "type": "Feature", "properties": { "name": "Alemany Blvd & Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.442369, 37.717640 ] } }
,
{ "type": "Feature", "properties": { "name": "Geneva Ave & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.441168, 37.716520 ] } }
{ "type": "Feature", "properties": { "name": "Geneva Ave & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.441082, 37.716723 ] } }
,
{ "type": "Feature", "properties": { "name": "Geneva Ave & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.440867, 37.716486 ] } }
,
@@ -410,7 +408,7 @@
,
{ "type": "Feature", "properties": { "name": "1650 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428293, 37.711733 ] } }
,
{ "type": "Feature", "properties": { "name": "1721 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.426276, 37.711088 ] } }
{ "type": "Feature", "properties": { "name": "1701 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.426748, 37.711122 ] } }
,
{ "type": "Feature", "properties": { "name": "MANSELL ST & PERSIA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.425675, 37.718285 ] } }
,
@@ -438,7 +436,7 @@
,
{ "type": "Feature", "properties": { "name": "SUNNYDALE AVE & PERSIA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.419066, 37.712615 ] } }
,
{ "type": "Feature", "properties": { "name": "Santos St & Velasco Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.419410, 37.710035 ] } }
{ "type": "Feature", "properties": { "name": "Santos St & Brookdale Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.418680, 37.711868 ] } }
,
{ "type": "Feature", "properties": { "name": "Santos St & Blythdale Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.418766, 37.710612 ] } }
,
@@ -464,7 +462,7 @@
,
{ "type": "Feature", "properties": { "name": "Sunnydale Ave & Garrison Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.412758, 37.711054 ] } }
,
{ "type": "Feature", "properties": { "name": "Visitacion Ave & Britton St" }, "geometry": { "type": "Point", "coordinates": [ -122.412372, 37.712751 ] } }
{ "type": "Feature", "properties": { "name": "Sunnydale Ave & Garrison Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.413015, 37.710986 ] } }
,
{ "type": "Feature", "properties": { "name": "Visitacion Ave & Schwerin St" }, "geometry": { "type": "Point", "coordinates": [ -122.410483, 37.712242 ] } }
,
@@ -560,9 +558,9 @@
,
{ "type": "Feature", "properties": { "name": "Bay Shore Blvd & Sunnydale Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.405119, 37.708983 ] } }
,
{ "type": "Feature", "properties": { "name": "SUNNYDALE AVE & BAYSHORE BLVD" }, "geometry": { "type": "Point", "coordinates": [ -122.405248, 37.708813 ] } }
{ "type": "Feature", "properties": { "name": "Not a public stop" }, "geometry": { "type": "Point", "coordinates": [ -122.404647, 37.709526 ] } }
,
{ "type": "Feature", "properties": { "name": "Blanken Ave & Nueva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.397480, 37.711189 ] } }
{ "type": "Feature", "properties": { "name": "SUNNYDALE AVE & BAYSHORE BLVD" }, "geometry": { "type": "Point", "coordinates": [ -122.405248, 37.708813 ] } }
,
{ "type": "Feature", "properties": { "name": "Blanken Ave & Nueva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.397223, 37.711189 ] } }
,
@@ -894,7 +892,7 @@
,
{ "type": "Feature", "properties": { "name": "Balboa St & 40th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.500391, 37.775633 ] } }
,
{ "type": "Feature", "properties": { "name": "Fulton St & 40th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.500348, 37.771868 ] } }
{ "type": "Feature", "properties": { "name": "Geary Blvd & 39th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.499833, 37.779297 ] } }
,
{ "type": "Feature", "properties": { "name": "Fulton St & 40th Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.500091, 37.771902 ] } }
,
@@ -1176,7 +1174,7 @@
,
{ "type": "Feature", "properties": { "name": "Noriega St & 23rd Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.480865, 37.753955 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Ave & Moraga St" }, "geometry": { "type": "Point", "coordinates": [ -122.476702, 37.756228 ] } }
{ "type": "Feature", "properties": { "name": "22nd Ave & Noriega St" }, "geometry": { "type": "Point", "coordinates": [ -122.479620, 37.754328 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Ave & Moraga St" }, "geometry": { "type": "Point", "coordinates": [ -122.476401, 37.755991 ] } }
,
@@ -1788,7 +1786,9 @@
,
{ "type": "Feature", "properties": { "name": "Hayes St & Clayton St" }, "geometry": { "type": "Point", "coordinates": [ -122.449150, 37.773598 ] } }
,
{ "type": "Feature", "properties": { "name": "Turk St & Masonic Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.447219, 37.778652 ] } }
{ "type": "Feature", "properties": { "name": "Turk St & Masonic Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.447133, 37.778551 ] } }
,
{ "type": "Feature", "properties": { "name": "Masonic Ave & Golden Gate Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.446918, 37.777533 ] } }
,
{ "type": "Feature", "properties": { "name": "Turk St & Central Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.445416, 37.778754 ] } }
,
@@ -1820,8 +1820,6 @@
,
{ "type": "Feature", "properties": { "name": "Hayes St & Lyon St" }, "geometry": { "type": "Point", "coordinates": [ -122.442842, 37.774277 ] } }
,
{ "type": "Feature", "properties": { "name": "California St & Divisadero St" }, "geometry": { "type": "Point", "coordinates": [ -122.440696, 37.787946 ] } }
,
{ "type": "Feature", "properties": { "name": "Divisadero St & Pine St" }, "geometry": { "type": "Point", "coordinates": [ -122.440310, 37.786996 ] } }
,
{ "type": "Feature", "properties": { "name": "Divisadero St & Bush St" }, "geometry": { "type": "Point", "coordinates": [ -122.440009, 37.786284 ] } }
@@ -2096,7 +2094,7 @@
,
{ "type": "Feature", "properties": { "name": "Grand View Ave & 21st St" }, "geometry": { "type": "Point", "coordinates": [ -122.440438, 37.755041 ] } }
,
{ "type": "Feature", "properties": { "name": "Hoffman Ave & 22nd St" }, "geometry": { "type": "Point", "coordinates": [ -122.440867, 37.754023 ] } }
{ "type": "Feature", "properties": { "name": "Grand View Ave & 22nd St" }, "geometry": { "type": "Point", "coordinates": [ -122.441125, 37.754057 ] } }
,
{ "type": "Feature", "properties": { "name": "20th St & Eureka St" }, "geometry": { "type": "Point", "coordinates": [ -122.437820, 37.757551 ] } }
,
@@ -2228,7 +2226,9 @@
,
{ "type": "Feature", "properties": { "name": "Laguna Honda Blvd & Vasquez Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.458162, 37.746015 ] } }
,
{ "type": "Feature", "properties": { "name": "Laguna Honda Blvd & Balceta Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.457089, 37.745370 ] } }
{ "type": "Feature", "properties": { "name": "Woodside Ave & Balceta Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.456446, 37.746490 ] } }
,
{ "type": "Feature", "properties": { "name": "Laguna Honda Blvd & Balceta Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.457175, 37.745302 ] } }
,
{ "type": "Feature", "properties": { "name": "Woodside Ave & Hernandez Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.455330, 37.746388 ] } }
,
@@ -2362,7 +2362,7 @@
,
{ "type": "Feature", "properties": { "name": "Monterey Blvd & Valdez Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.455630, 37.731455 ] } }
,
{ "type": "Feature", "properties": { "name": "Ocean Ave & Victoria St" }, "geometry": { "type": "Point", "coordinates": [ -122.464342, 37.726024 ] } }
{ "type": "Feature", "properties": { "name": "Ocean Ave & Victoria St" }, "geometry": { "type": "Point", "coordinates": [ -122.464342, 37.725990 ] } }
,
{ "type": "Feature", "properties": { "name": "Ocean Ave & Jules Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.461381, 37.724938 ] } }
,
@@ -2658,9 +2658,7 @@
,
{ "type": "Feature", "properties": { "name": "SAN JOSE AVE & GENEVA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.446575, 37.720593 ] } }
,
{ "type": "Feature", "properties": { "name": "SAN JOSE AVE & GENEVA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.446575, 37.720627 ] } }
,
{ "type": "Feature", "properties": { "name": "SAN JOSE AVE & GENEVA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.446704, 37.720457 ] } }
{ "type": "Feature", "properties": { "name": "CAMERON BEACH YARD" }, "geometry": { "type": "Point", "coordinates": [ -122.446532, 37.720593 ] } }
,
{ "type": "Feature", "properties": { "name": "Green Yard-San Jose & Ocean" }, "geometry": { "type": "Point", "coordinates": [ -122.445030, 37.722732 ] } }
,
@@ -2918,7 +2916,7 @@
,
{ "type": "Feature", "properties": { "name": "Columbus Ave & Chestnut St" }, "geometry": { "type": "Point", "coordinates": [ -122.415118, 37.803782 ] } }
,
{ "type": "Feature", "properties": { "name": "Columbus Ave & Taylor St" }, "geometry": { "type": "Point", "coordinates": [ -122.414646, 37.803274 ] } }
{ "type": "Feature", "properties": { "name": "COLUMBUS AVE & CHESTNUT ST" }, "geometry": { "type": "Point", "coordinates": [ -122.413960, 37.802833 ] } }
,
{ "type": "Feature", "properties": { "name": "Columbus Ave & Lombard St" }, "geometry": { "type": "Point", "coordinates": [ -122.413659, 37.802596 ] } }
,
@@ -2984,7 +2982,7 @@
,
{ "type": "Feature", "properties": { "name": "California St & Larkin St" }, "geometry": { "type": "Point", "coordinates": [ -122.418895, 37.790862 ] } }
,
{ "type": "Feature", "properties": { "name": "Pine St & Polk St" }, "geometry": { "type": "Point", "coordinates": [ -122.420611, 37.789675 ] } }
{ "type": "Feature", "properties": { "name": "Polk St & Pine St" }, "geometry": { "type": "Point", "coordinates": [ -122.420397, 37.789540 ] } }
,
{ "type": "Feature", "properties": { "name": "Sacramento St & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.417436, 37.791982 ] } }
,
@@ -3092,7 +3090,7 @@
,
{ "type": "Feature", "properties": { "name": "BROADWAY & GRANT AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.407351, 37.797848 ] } }
,
{ "type": "Feature", "properties": { "name": "Union St & Kearny St" }, "geometry": { "type": "Point", "coordinates": [ -122.406106, 37.800765 ] } }
{ "type": "Feature", "properties": { "name": "Union St & Kearny St" }, "geometry": { "type": "Point", "coordinates": [ -122.405977, 37.800900 ] } }
,
{ "type": "Feature", "properties": { "name": "Union St & Montgomery St" }, "geometry": { "type": "Point", "coordinates": [ -122.404518, 37.800968 ] } }
,
@@ -3228,7 +3226,7 @@
,
{ "type": "Feature", "properties": { "name": "Sansome St & Pine St" }, "geometry": { "type": "Point", "coordinates": [ -122.400870, 37.792015 ] } }
,
{ "type": "Feature", "properties": { "name": "Bush St & Sansome St" }, "geometry": { "type": "Point", "coordinates": [ -122.400956, 37.791066 ] } }
{ "type": "Feature", "properties": { "name": "Pine St & Battery St" }, "geometry": { "type": "Point", "coordinates": [ -122.400098, 37.792287 ] } }
,
{ "type": "Feature", "properties": { "name": "Sutter St & Sansome St" }, "geometry": { "type": "Point", "coordinates": [ -122.400656, 37.790286 ] } }
,
@@ -3492,7 +3490,7 @@
,
{ "type": "Feature", "properties": { "name": "Page St & Gough St" }, "geometry": { "type": "Point", "coordinates": [ -122.422500, 37.774039 ] } }
,
{ "type": "Feature", "properties": { "name": "Haight St & Gough St" }, "geometry": { "type": "Point", "coordinates": [ -122.422285, 37.773089 ] } }
{ "type": "Feature", "properties": { "name": "Haight St & Gough St" }, "geometry": { "type": "Point", "coordinates": [ -122.422543, 37.773191 ] } }
,
{ "type": "Feature", "properties": { "name": "Page St & Franklin St" }, "geometry": { "type": "Point", "coordinates": [ -122.420955, 37.774175 ] } }
,
@@ -3518,7 +3516,7 @@
,
{ "type": "Feature", "properties": { "name": "O'Farrell St & Larkin St" }, "geometry": { "type": "Point", "coordinates": [ -122.417994, 37.785097 ] } }
,
{ "type": "Feature", "properties": { "name": "Post St & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.416234, 37.787233 ] } }
{ "type": "Feature", "properties": { "name": "Geary Blvd & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.416620, 37.786352 ] } }
,
{ "type": "Feature", "properties": { "name": "Larkin St & O'Farrell St" }, "geometry": { "type": "Point", "coordinates": [ -122.417779, 37.785063 ] } }
,
@@ -3590,6 +3588,8 @@
,
{ "type": "Feature", "properties": { "name": "McAllister St & Leavenworth St" }, "geometry": { "type": "Point", "coordinates": [ -122.413573, 37.780891 ] } }
,
{ "type": "Feature", "properties": { "name": "Mcallister St & 7th St" }, "geometry": { "type": "Point", "coordinates": [ -122.413058, 37.781061 ] } }
,
{ "type": "Feature", "properties": { "name": "Market St & 7th St" }, "geometry": { "type": "Point", "coordinates": [ -122.412415, 37.780552 ] } }
,
{ "type": "Feature", "properties": { "name": "Market St & 7th St" }, "geometry": { "type": "Point", "coordinates": [ -122.413187, 37.779806 ] } }
@@ -3794,7 +3794,7 @@
,
{ "type": "Feature", "properties": { "name": "Bryant St & Alameda St" }, "geometry": { "type": "Point", "coordinates": [ -122.410784, 37.768103 ] } }
,
{ "type": "Feature", "properties": { "name": "16th St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.412972, 37.765524 ] } }
{ "type": "Feature", "properties": { "name": "16th St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.413273, 37.765389 ] } }
,
{ "type": "Feature", "properties": { "name": "Folsom St & 18th St" }, "geometry": { "type": "Point", "coordinates": [ -122.414904, 37.762200 ] } }
,
@@ -3866,7 +3866,7 @@
,
{ "type": "Feature", "properties": { "name": "Stockton St & Ellis St" }, "geometry": { "type": "Point", "coordinates": [ -122.406235, 37.785741 ] } }
,
{ "type": "Feature", "properties": { "name": "Market St & 4th St" }, "geometry": { "type": "Point", "coordinates": [ -122.405891, 37.785639 ] } }
{ "type": "Feature", "properties": { "name": "Market St & Stockton St" }, "geometry": { "type": "Point", "coordinates": [ -122.405720, 37.785843 ] } }
,
{ "type": "Feature", "properties": { "name": "Mission St & 4th St" }, "geometry": { "type": "Point", "coordinates": [ -122.404518, 37.784351 ] } }
,
@@ -3968,7 +3968,7 @@
,
{ "type": "Feature", "properties": { "name": "Brannan St & 3rd St" }, "geometry": { "type": "Point", "coordinates": [ -122.394562, 37.779975 ] } }
,
{ "type": "Feature", "properties": { "name": "Harrison St & 1st St" }, "geometry": { "type": "Point", "coordinates": [ -122.392931, 37.786182 ] } }
{ "type": "Feature", "properties": { "name": "3RD ST & BRANNAN ST" }, "geometry": { "type": "Point", "coordinates": [ -122.393489, 37.779568 ] } }
,
{ "type": "Feature", "properties": { "name": "Harrison St & Main St" }, "geometry": { "type": "Point", "coordinates": [ -122.390614, 37.788014 ] } }
,
@@ -4050,9 +4050,9 @@
,
{ "type": "Feature", "properties": { "name": "Kansas St & 17th St" }, "geometry": { "type": "Point", "coordinates": [ -122.403617, 37.764812 ] } }
,
{ "type": "Feature", "properties": { "name": "Rhode Island St & 16th St" }, "geometry": { "type": "Point", "coordinates": [ -122.402802, 37.766169 ] } }
{ "type": "Feature", "properties": { "name": "17TH ST & KANSAS ST" }, "geometry": { "type": "Point", "coordinates": [ -122.403445, 37.764812 ] } }
,
{ "type": "Feature", "properties": { "name": "16th St& Rhode Island St" }, "geometry": { "type": "Point", "coordinates": [ -122.402587, 37.765999 ] } }
{ "type": "Feature", "properties": { "name": "Rhode Island St & 16th St" }, "geometry": { "type": "Point", "coordinates": [ -122.402630, 37.766305 ] } }
,
{ "type": "Feature", "properties": { "name": "De Haro St & 16th St" }, "geometry": { "type": "Point", "coordinates": [ -122.401643, 37.766067 ] } }
,
@@ -4062,18 +4062,16 @@
,
{ "type": "Feature", "properties": { "name": "Rhode Island St & Mariposa St" }, "geometry": { "type": "Point", "coordinates": [ -122.402501, 37.763251 ] } }
,
{ "type": "Feature", "properties": { "name": "16th Street & Wisconsin St" }, "geometry": { "type": "Point", "coordinates": [ -122.399840, 37.766271 ] } }
,
{ "type": "Feature", "properties": { "name": "17th St & Wisconsin St" }, "geometry": { "type": "Point", "coordinates": [ -122.399969, 37.764981 ] } }
,
{ "type": "Feature", "properties": { "name": "17th St & Wisconsin St" }, "geometry": { "type": "Point", "coordinates": [ -122.399282, 37.764914 ] } }
,
{ "type": "Feature", "properties": { "name": "De Haro St & Mariposa St" }, "geometry": { "type": "Point", "coordinates": [ -122.401342, 37.763489 ] } }
,
{ "type": "Feature", "properties": { "name": "De Haro St & 18th St" }, "geometry": { "type": "Point", "coordinates": [ -122.401257, 37.762200 ] } }
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & 18th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407265, 37.761623 ] } }
,
{ "type": "Feature", "properties": { "name": "Bryant St & 20th St" }, "geometry": { "type": "Point", "coordinates": [ -122.409668, 37.759112 ] } }
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & 20th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407050, 37.759078 ] } }
,
{ "type": "Feature", "properties": { "name": "Vermont St & 18th St" }, "geometry": { "type": "Point", "coordinates": [ -122.404175, 37.762030 ] } }
@@ -4260,8 +4258,6 @@
,
{ "type": "Feature", "properties": { "name": "Church St & Day St" }, "geometry": { "type": "Point", "coordinates": [ -122.426662, 37.742791 ] } }
,
{ "type": "Feature", "properties": { "name": "30th St & Sanchez St" }, "geometry": { "type": "Point", "coordinates": [ -122.428594, 37.742010 ] } }
,
{ "type": "Feature", "properties": { "name": "30th St & Church St" }, "geometry": { "type": "Point", "coordinates": [ -122.426748, 37.742044 ] } }
,
{ "type": "Feature", "properties": { "name": "30th St & Church St" }, "geometry": { "type": "Point", "coordinates": [ -122.426362, 37.742146 ] } }
@@ -4328,7 +4324,7 @@
,
{ "type": "Feature", "properties": { "name": "Cesar Chavez St. & Valencia St." }, "geometry": { "type": "Point", "coordinates": [ -122.420053, 37.748051 ] } }
,
{ "type": "Feature", "properties": { "name": "Cesar Chavez St & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.418380, 37.748220 ] } }
{ "type": "Feature", "properties": { "name": "Mission St & 26th St" }, "geometry": { "type": "Point", "coordinates": [ -122.418165, 37.748560 ] } }
,
{ "type": "Feature", "properties": { "name": "Mission St & Precita Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.419109, 37.746931 ] } }
,
@@ -4348,7 +4344,9 @@
,
{ "type": "Feature", "properties": { "name": "26th St & Folsom St" }, "geometry": { "type": "Point", "coordinates": [ -122.413874, 37.749238 ] } }
,
{ "type": "Feature", "properties": { "name": "24th St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.412028, 37.752699 ] } }
{ "type": "Feature", "properties": { "name": "Folsom St & 26th St" }, "geometry": { "type": "Point", "coordinates": [ -122.413702, 37.749204 ] } }
,
{ "type": "Feature", "properties": { "name": "24th St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.411728, 37.752598 ] } }
,
{ "type": "Feature", "properties": { "name": "Folsom St & Cesar Chavez St" }, "geometry": { "type": "Point", "coordinates": [ -122.413788, 37.748492 ] } }
,
@@ -4356,7 +4354,7 @@
,
{ "type": "Feature", "properties": { "name": "Folsom St & Bessie St" }, "geometry": { "type": "Point", "coordinates": [ -122.413616, 37.746863 ] } }
,
{ "type": "Feature", "properties": { "name": "Folsom St & Stoneman St" }, "geometry": { "type": "Point", "coordinates": [ -122.413359, 37.745302 ] } }
{ "type": "Feature", "properties": { "name": "Folsom St & Stoneman St" }, "geometry": { "type": "Point", "coordinates": [ -122.413445, 37.745200 ] } }
,
{ "type": "Feature", "properties": { "name": "Cesar Chavez St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.411900, 37.748390 ] } }
,
@@ -4648,7 +4646,9 @@
,
{ "type": "Feature", "properties": { "name": "Evans Ave & Selby St" }, "geometry": { "type": "Point", "coordinates": [ -122.393918, 37.746150 ] } }
,
{ "type": "Feature", "properties": { "name": "Pennsylvania Avenue & 25th Street" }, "geometry": { "type": "Point", "coordinates": [ -122.392759, 37.752631 ] } }
{ "type": "Feature", "properties": { "name": "Evans Ave & Selby St" }, "geometry": { "type": "Point", "coordinates": [ -122.393832, 37.745981 ] } }
,
{ "type": "Feature", "properties": { "name": "Pennsylvania Avenue & 25th Street" }, "geometry": { "type": "Point", "coordinates": [ -122.392759, 37.752462 ] } }
,
{ "type": "Feature", "properties": { "name": "3rd St & 25th St" }, "geometry": { "type": "Point", "coordinates": [ -122.387867, 37.752530 ] } }
,
@@ -4664,7 +4664,7 @@
,
{ "type": "Feature", "properties": { "name": "Phelps St & Oakdale Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.394090, 37.736852 ] } }
,
{ "type": "Feature", "properties": { "name": "Evans Ave & Quint St" }, "geometry": { "type": "Point", "coordinates": [ -122.390485, 37.744046 ] } }
{ "type": "Feature", "properties": { "name": "Evans Ave & Quint St" }, "geometry": { "type": "Point", "coordinates": [ -122.390528, 37.744250 ] } }
,
{ "type": "Feature", "properties": { "name": "Jerrold Ave & Quint St" }, "geometry": { "type": "Point", "coordinates": [ -122.392974, 37.740890 ] } }
,
@@ -4756,8 +4756,6 @@
,
{ "type": "Feature", "properties": { "name": "Bacon St & Goettingen St" }, "geometry": { "type": "Point", "coordinates": [ -122.406664, 37.726805 ] } }
,
{ "type": "Feature", "properties": { "name": "Mansell St & Dartmouth St" }, "geometry": { "type": "Point", "coordinates": [ -122.409067, 37.719371 ] } }
,
{ "type": "Feature", "properties": { "name": "Mansell St & Hamilton St" }, "geometry": { "type": "Point", "coordinates": [ -122.407093, 37.719880 ] } }
,
{ "type": "Feature", "properties": { "name": "Mansell St & Goettingen St" }, "geometry": { "type": "Point", "coordinates": [ -122.404346, 37.720763 ] } }
@@ -4852,11 +4850,11 @@
,
{ "type": "Feature", "properties": { "name": "Third Street & Le Conte Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.397480, 37.718828 ] } }
,
{ "type": "Feature", "properties": { "name": "3rd St & Key St" }, "geometry": { "type": "Point", "coordinates": [ -122.396708, 37.719778 ] } }
,
{ "type": "Feature", "properties": { "name": "Third Street/Gilman/Paul" }, "geometry": { "type": "Point", "coordinates": [ -122.395635, 37.722392 ] } }
,
{ "type": "Feature", "properties": { "name": "3rd St & Gilman Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.395420, 37.722630 ] } }
,
{ "type": "Feature", "properties": { "name": "3rd St & Gilman Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.395635, 37.722358 ] } }
{ "type": "Feature", "properties": { "name": "Gilman Ave & 3rd St" }, "geometry": { "type": "Point", "coordinates": [ -122.395420, 37.722460 ] } }
,
{ "type": "Feature", "properties": { "name": "Fitzgerald Ave & Jennings St" }, "geometry": { "type": "Point", "coordinates": [ -122.393317, 37.722019 ] } }
,
@@ -4908,7 +4906,7 @@
,
{ "type": "Feature", "properties": { "name": "EVANS AVE/Opposite US Post Office" }, "geometry": { "type": "Point", "coordinates": [ -122.382803, 37.739702 ] } }
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Keith St" }, "geometry": { "type": "Point", "coordinates": [ -122.384133, 37.737598 ] } }
{ "type": "Feature", "properties": { "name": "Hudson Ave & Keith St" }, "geometry": { "type": "Point", "coordinates": [ -122.384133, 37.737700 ] } }
,
{ "type": "Feature", "properties": { "name": "Fairfax Ave & Keith St" }, "geometry": { "type": "Point", "coordinates": [ -122.381773, 37.738175 ] } }
,
@@ -4932,7 +4930,7 @@
,
{ "type": "Feature", "properties": { "name": "Newcomb Ave & La Salle Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.385035, 37.733186 ] } }
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Ardath Ct" }, "geometry": { "type": "Point", "coordinates": [ -122.383060, 37.734680 ] } }
{ "type": "Feature", "properties": { "name": "Cashmere St & Hudson Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.383533, 37.735732 ] } }
,
{ "type": "Feature", "properties": { "name": "Newcomb Ave & La Salle Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.384863, 37.733050 ] } }
,
@@ -4958,7 +4956,7 @@
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Whitney Young Cir" }, "geometry": { "type": "Point", "coordinates": [ -122.382116, 37.733356 ] } }
,
{ "type": "Feature", "properties": { "name": "Ingalls St & Harbor Rd" }, "geometry": { "type": "Point", "coordinates": [ -122.380013, 37.733458 ] } }
{ "type": "Feature", "properties": { "name": "Ingalls St & Harbor Rd" }, "geometry": { "type": "Point", "coordinates": [ -122.379842, 37.733288 ] } }
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Ingalls St" }, "geometry": { "type": "Point", "coordinates": [ -122.379885, 37.732507 ] } }
,
@@ -5056,7 +5054,7 @@
,
{ "type": "Feature", "properties": { "name": "Alemany Blvd & Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.442369, 37.717640 ] } }
,
{ "type": "Feature", "properties": { "name": "Geneva Ave & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.441168, 37.716520 ] } }
{ "type": "Feature", "properties": { "name": "Geneva Ave & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.441082, 37.716723 ] } }
,
{ "type": "Feature", "properties": { "name": "Geneva Ave & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.440867, 37.716486 ] } }
,
@@ -5976,7 +5974,7 @@
,
{ "type": "Feature", "properties": { "name": "23rd Ave & Noriega St" }, "geometry": { "type": "Point", "coordinates": [ -122.480865, 37.754141 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Ave & Moraga St" }, "geometry": { "type": "Point", "coordinates": [ -122.476680, 37.756211 ] } }
{ "type": "Feature", "properties": { "name": "22nd Ave & Noriega St" }, "geometry": { "type": "Point", "coordinates": [ -122.479599, 37.754328 ] } }
,
{ "type": "Feature", "properties": { "name": "19th Ave & Moraga St" }, "geometry": { "type": "Point", "coordinates": [ -122.476423, 37.755991 ] } }
,
@@ -6776,7 +6774,7 @@
,
{ "type": "Feature", "properties": { "name": "Hayes St & Clayton St" }, "geometry": { "type": "Point", "coordinates": [ -122.449450, 37.773412 ] } }
,
{ "type": "Feature", "properties": { "name": "Turk St & Masonic Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.447197, 37.778652 ] } }
{ "type": "Feature", "properties": { "name": "Masonic Ave & Turk St" }, "geometry": { "type": "Point", "coordinates": [ -122.447155, 37.778754 ] } }
,
{ "type": "Feature", "properties": { "name": "Masonic Ave & Turk St" }, "geometry": { "type": "Point", "coordinates": [ -122.447004, 37.778771 ] } }
,
@@ -7174,7 +7172,7 @@
,
{ "type": "Feature", "properties": { "name": "Grand View Ave & 21st St" }, "geometry": { "type": "Point", "coordinates": [ -122.440417, 37.755041 ] } }
,
{ "type": "Feature", "properties": { "name": "Hoffman Ave & 22nd St" }, "geometry": { "type": "Point", "coordinates": [ -122.440889, 37.754006 ] } }
{ "type": "Feature", "properties": { "name": "Grand View Ave & 22nd St" }, "geometry": { "type": "Point", "coordinates": [ -122.441146, 37.754040 ] } }
,
{ "type": "Feature", "properties": { "name": "20th St & Eureka St" }, "geometry": { "type": "Point", "coordinates": [ -122.437842, 37.757551 ] } }
,
@@ -7524,7 +7522,7 @@
,
{ "type": "Feature", "properties": { "name": "Monterey Blvd & Valdez Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.455652, 37.731438 ] } }
,
{ "type": "Feature", "properties": { "name": "Ocean Ave & Victoria St" }, "geometry": { "type": "Point", "coordinates": [ -122.464342, 37.726024 ] } }
{ "type": "Feature", "properties": { "name": "Ocean Ave & Victoria St" }, "geometry": { "type": "Point", "coordinates": [ -122.464364, 37.725973 ] } }
,
{ "type": "Feature", "properties": { "name": "Ocean Ave & Fairfield Way" }, "geometry": { "type": "Point", "coordinates": [ -122.464063, 37.726007 ] } }
,
@@ -7914,9 +7912,7 @@
,
{ "type": "Feature", "properties": { "name": "SAN JOSE AVE & GENEVA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.446575, 37.720610 ] } }
,
{ "type": "Feature", "properties": { "name": "SAN JOSE AVE & GENEVA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.446554, 37.720610 ] } }
,
{ "type": "Feature", "properties": { "name": "San Jose Ave & Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.446682, 37.720457 ] } }
{ "type": "Feature", "properties": { "name": "CAMERON BEACH YARD" }, "geometry": { "type": "Point", "coordinates": [ -122.446532, 37.720610 ] } }
,
{ "type": "Feature", "properties": { "name": "Green Yard-San Jose & Ocean" }, "geometry": { "type": "Point", "coordinates": [ -122.445030, 37.722749 ] } }
,
@@ -8566,7 +8562,7 @@
,
{ "type": "Feature", "properties": { "name": "1650 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.428186, 37.711868 ] } }
,
{ "type": "Feature", "properties": { "name": "1721 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.426255, 37.711071 ] } }
{ "type": "Feature", "properties": { "name": "1701 Geneva Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.426770, 37.711105 ] } }
,
{ "type": "Feature", "properties": { "name": "MANSELL ST & PERSIA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.425675, 37.718285 ] } }
,
@@ -8600,7 +8596,7 @@
,
{ "type": "Feature", "properties": { "name": "SUNNYDALE AVE & PERSIA AVE" }, "geometry": { "type": "Point", "coordinates": [ -122.419088, 37.712598 ] } }
,
{ "type": "Feature", "properties": { "name": "Santos St & Velasco Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.419431, 37.710018 ] } }
{ "type": "Feature", "properties": { "name": "Sunnydale Ave & Santos St" }, "geometry": { "type": "Point", "coordinates": [ -122.418165, 37.712412 ] } }
,
{ "type": "Feature", "properties": { "name": "Santos St & Brookdale Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.418680, 37.711852 ] } }
,
@@ -9068,7 +9064,7 @@
,
{ "type": "Feature", "properties": { "name": "Page St & Gough St" }, "geometry": { "type": "Point", "coordinates": [ -122.422521, 37.774022 ] } }
,
{ "type": "Feature", "properties": { "name": "Haight St & Gough St" }, "geometry": { "type": "Point", "coordinates": [ -122.422285, 37.773072 ] } }
{ "type": "Feature", "properties": { "name": "Haight St & Gough St" }, "geometry": { "type": "Point", "coordinates": [ -122.422543, 37.773174 ] } }
,
{ "type": "Feature", "properties": { "name": "Page St & Franklin St" }, "geometry": { "type": "Point", "coordinates": [ -122.420955, 37.774192 ] } }
,
@@ -9100,7 +9096,7 @@
,
{ "type": "Feature", "properties": { "name": "Post St & Larkin St" }, "geometry": { "type": "Point", "coordinates": [ -122.417715, 37.787047 ] } }
,
{ "type": "Feature", "properties": { "name": "Post St & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.416255, 37.787233 ] } }
{ "type": "Feature", "properties": { "name": "Geary Blvd & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.416599, 37.786352 ] } }
,
{ "type": "Feature", "properties": { "name": "Larkin St & O'Farrell St" }, "geometry": { "type": "Point", "coordinates": [ -122.417779, 37.785080 ] } }
,
@@ -9468,7 +9464,7 @@
,
{ "type": "Feature", "properties": { "name": "Bryant St & Alameda St" }, "geometry": { "type": "Point", "coordinates": [ -122.410805, 37.768103 ] } }
,
{ "type": "Feature", "properties": { "name": "16th St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.412972, 37.765524 ] } }
{ "type": "Feature", "properties": { "name": "16th St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.413294, 37.765372 ] } }
,
{ "type": "Feature", "properties": { "name": "Folsom St & 18th St" }, "geometry": { "type": "Point", "coordinates": [ -122.414904, 37.762216 ] } }
,
@@ -9824,9 +9820,9 @@
,
{ "type": "Feature", "properties": { "name": "17th St & Kansas St" }, "geometry": { "type": "Point", "coordinates": [ -122.403467, 37.764812 ] } }
,
{ "type": "Feature", "properties": { "name": "Rhode Island St & 16th St" }, "geometry": { "type": "Point", "coordinates": [ -122.402802, 37.766152 ] } }
{ "type": "Feature", "properties": { "name": "Rhode Island St & 16th St" }, "geometry": { "type": "Point", "coordinates": [ -122.402630, 37.766322 ] } }
,
{ "type": "Feature", "properties": { "name": "16th Street & Rhode Islandi St" }, "geometry": { "type": "Point", "coordinates": [ -122.402630, 37.766118 ] } }
{ "type": "Feature", "properties": { "name": "16th St& Rhode Island St" }, "geometry": { "type": "Point", "coordinates": [ -122.402587, 37.765999 ] } }
,
{ "type": "Feature", "properties": { "name": "De Haro St & 16th St" }, "geometry": { "type": "Point", "coordinates": [ -122.401621, 37.766050 ] } }
,
@@ -9850,7 +9846,7 @@
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & 18th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407286, 37.761640 ] } }
,
{ "type": "Feature", "properties": { "name": "Bryant St & 20th St" }, "geometry": { "type": "Point", "coordinates": [ -122.409647, 37.759112 ] } }
{ "type": "Feature", "properties": { "name": "Potrero Ave & 18th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407050, 37.761843 ] } }
,
{ "type": "Feature", "properties": { "name": "Potrero Ave & 20th St" }, "geometry": { "type": "Point", "coordinates": [ -122.407050, 37.759078 ] } }
,
@@ -10184,7 +10180,7 @@
,
{ "type": "Feature", "properties": { "name": "Cesar Chavez & Bartlett" }, "geometry": { "type": "Point", "coordinates": [ -122.419024, 37.748203 ] } }
,
{ "type": "Feature", "properties": { "name": "Cesar Chavez St & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.418358, 37.748237 ] } }
{ "type": "Feature", "properties": { "name": "Mission St & 26th St" }, "geometry": { "type": "Point", "coordinates": [ -122.418165, 37.748560 ] } }
,
{ "type": "Feature", "properties": { "name": "Cesar Chavez St & Mission St" }, "geometry": { "type": "Point", "coordinates": [ -122.418079, 37.748101 ] } }
,
@@ -10210,7 +10206,9 @@
,
{ "type": "Feature", "properties": { "name": "26th St & Folsom St" }, "geometry": { "type": "Point", "coordinates": [ -122.413874, 37.749221 ] } }
,
{ "type": "Feature", "properties": { "name": "24th St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.412050, 37.752682 ] } }
{ "type": "Feature", "properties": { "name": "Folsom St & 26th St" }, "geometry": { "type": "Point", "coordinates": [ -122.413702, 37.749221 ] } }
,
{ "type": "Feature", "properties": { "name": "24th St & Harrison St" }, "geometry": { "type": "Point", "coordinates": [ -122.411728, 37.752581 ] } }
,
{ "type": "Feature", "properties": { "name": "Folsom St & Cesar Chavez St" }, "geometry": { "type": "Point", "coordinates": [ -122.413788, 37.748475 ] } }
,
@@ -10598,7 +10596,9 @@
,
{ "type": "Feature", "properties": { "name": "Evans Ave & Selby St" }, "geometry": { "type": "Point", "coordinates": [ -122.393918, 37.746167 ] } }
,
{ "type": "Feature", "properties": { "name": "Pennsylvania Avenue & 25th Street" }, "geometry": { "type": "Point", "coordinates": [ -122.392759, 37.752614 ] } }
{ "type": "Feature", "properties": { "name": "Evans Ave & Selby St" }, "geometry": { "type": "Point", "coordinates": [ -122.393832, 37.745964 ] } }
,
{ "type": "Feature", "properties": { "name": "Pennsylvania Avenue & 25th Street" }, "geometry": { "type": "Point", "coordinates": [ -122.392759, 37.752462 ] } }
,
{ "type": "Feature", "properties": { "name": "3rd St & 25th St" }, "geometry": { "type": "Point", "coordinates": [ -122.387846, 37.752547 ] } }
,
@@ -10624,7 +10624,7 @@
,
{ "type": "Feature", "properties": { "name": "Palou Ave & Phelps St" }, "geometry": { "type": "Point", "coordinates": [ -122.394540, 37.736088 ] } }
,
{ "type": "Feature", "properties": { "name": "Evans Ave & Quint St" }, "geometry": { "type": "Point", "coordinates": [ -122.390463, 37.744029 ] } }
{ "type": "Feature", "properties": { "name": "Evans Ave & Quint St" }, "geometry": { "type": "Point", "coordinates": [ -122.390528, 37.744233 ] } }
,
{ "type": "Feature", "properties": { "name": "Jerrold Ave & Quint St" }, "geometry": { "type": "Point", "coordinates": [ -122.392974, 37.740890 ] } }
,
@@ -10942,7 +10942,7 @@
,
{ "type": "Feature", "properties": { "name": "EVANS AVE/Opposite US Post Office" }, "geometry": { "type": "Point", "coordinates": [ -122.382803, 37.739719 ] } }
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Keith St" }, "geometry": { "type": "Point", "coordinates": [ -122.384155, 37.737581 ] } }
{ "type": "Feature", "properties": { "name": "Hudson Ave & Keith St" }, "geometry": { "type": "Point", "coordinates": [ -122.384112, 37.737700 ] } }
,
{ "type": "Feature", "properties": { "name": "Fairfax Ave & Keith St" }, "geometry": { "type": "Point", "coordinates": [ -122.381794, 37.738158 ] } }
,
@@ -10972,8 +10972,6 @@
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Cashmere St" }, "geometry": { "type": "Point", "coordinates": [ -122.383533, 37.735952 ] } }
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Ardath Ct" }, "geometry": { "type": "Point", "coordinates": [ -122.383039, 37.734680 ] } }
,
{ "type": "Feature", "properties": { "name": "Newcomb Ave & La Salle Ave" }, "geometry": { "type": "Point", "coordinates": [ -122.384863, 37.733033 ] } }
,
{ "type": "Feature", "properties": { "name": "Whitney Young Cir & Progress St" }, "geometry": { "type": "Point", "coordinates": [ -122.383318, 37.733339 ] } }
@@ -11002,7 +11000,9 @@
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Whitney Young Cir" }, "geometry": { "type": "Point", "coordinates": [ -122.382116, 37.733356 ] } }
,
{ "type": "Feature", "properties": { "name": "Ingalls St & Harbor Rd" }, "geometry": { "type": "Point", "coordinates": [ -122.380013, 37.733458 ] } }
{ "type": "Feature", "properties": { "name": "Hudson Ave & Whitney Young Cir" }, "geometry": { "type": "Point", "coordinates": [ -122.381837, 37.733322 ] } }
,
{ "type": "Feature", "properties": { "name": "Ingalls St & Harbor Rd" }, "geometry": { "type": "Point", "coordinates": [ -122.379842, 37.733288 ] } }
,
{ "type": "Feature", "properties": { "name": "Hudson Ave & Ingalls St" }, "geometry": { "type": "Point", "coordinates": [ -122.379906, 37.732490 ] } }
,
@@ -11384,7 +11384,7 @@
,
{ "type": "Feature", "properties": { "name": "Columbus Ave & Chestnut St" }, "geometry": { "type": "Point", "coordinates": [ -122.415140, 37.803782 ] } }
,
{ "type": "Feature", "properties": { "name": "Columbus Ave & Chestnut St" }, "geometry": { "type": "Point", "coordinates": [ -122.414582, 37.803409 ] } }
{ "type": "Feature", "properties": { "name": "Columbus Ave & Taylor St" }, "geometry": { "type": "Point", "coordinates": [ -122.414646, 37.803274 ] } }
,
{ "type": "Feature", "properties": { "name": "COLUMBUS AVE & CHESTNUT ST" }, "geometry": { "type": "Point", "coordinates": [ -122.413981, 37.802833 ] } }
,
@@ -11788,7 +11788,7 @@
,
{ "type": "Feature", "properties": { "name": "Sansome St & Pine St" }, "geometry": { "type": "Point", "coordinates": [ -122.400849, 37.792015 ] } }
,
{ "type": "Feature", "properties": { "name": "Bush St & Sansome St" }, "geometry": { "type": "Point", "coordinates": [ -122.400935, 37.791066 ] } }
{ "type": "Feature", "properties": { "name": "Pine St & Battery St" }, "geometry": { "type": "Point", "coordinates": [ -122.400076, 37.792287 ] } }
,
{ "type": "Feature", "properties": { "name": "Sutter St & Sansome St" }, "geometry": { "type": "Point", "coordinates": [ -122.400677, 37.790286 ] } }
,
@@ -12040,8 +12040,6 @@
,
{ "type": "Feature", "properties": { "name": "Post St & Larkin St" }, "geometry": { "type": "Point", "coordinates": [ -122.417715, 37.787047 ] } }
,
{ "type": "Feature", "properties": { "name": "Post St & Hyde St" }, "geometry": { "type": "Point", "coordinates": [ -122.416255, 37.787233 ] } }
,
{ "type": "Feature", "properties": { "name": "Leavenworth St & Post St" }, "geometry": { "type": "Point", "coordinates": [ -122.414882, 37.787352 ] } }
,
{ "type": "Feature", "properties": { "name": "Post St & Leavenworth St" }, "geometry": { "type": "Point", "coordinates": [ -122.414582, 37.787454 ] } }
@@ -10,7 +10,7 @@
"minzoom": "0",
"name": "tests/ne_110m_populated_places/out/--smallest-maximum-zoom-guess_2_-Bf20_-rf20_-pb.json.check.mbtiles",
"strategies": "[{\"dropped_by_rate\":237},{\"dropped_by_rate\":229},{}]",
"tippecanoe_decisions": "{\"basezoom\":2,\"droprate\":6.599999999999999,\"retain_points_multiplier\":1}",
"tippecanoe_decisions": "{\"basezoom\":2,\"droprate\":6.6,\"retain_points_multiplier\":1}",
"type": "overlay",
"version": "2"
}, "features": [
@@ -10,7 +10,7 @@
"minzoom": "0",
"name": "tests/ne_110m_populated_places/out/--smallest-maximum-zoom-guess_3_-rp.json.check.mbtiles",
"strategies": "[{\"dropped_by_rate\":230},{\"dropped_by_rate\":231},{\"dropped_by_rate\":160},{}]",
"tippecanoe_decisions": "{\"basezoom\":3,\"droprate\":2.6582825467008166,\"retain_points_multiplier\":1}",
"tippecanoe_decisions": "{\"basezoom\":3,\"droprate\":2.65828,\"retain_points_multiplier\":1}",
"type": "overlay",
"version": "2"
}, "features": [
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,4 +1,4 @@
{ "type": "FeatureCollection", "properties": { "zoom": 13, "x": 1310, "y": 3166 }, "features": [
{ "type": "FeatureCollection", "properties": { "zoom": 13, "x": 1310, "y": 3166, "compressed": false }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "ne_10m_land", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { "featurecla": "Land", "scalerank": 0, "min_zoom": 0 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.387760, 37.788760 ], [ -122.387094, 37.778754 ], [ -122.386837, 37.778517 ], [ -122.386837, 37.752665 ], [ -122.432499, 37.752665 ], [ -122.432499, 37.788760 ], [ -122.387760, 37.788760 ] ] ] } }
] }
@@ -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 ] ] ] ] } }
] }
] }
@@ -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": { "ZCTA5CE10": "94129", "tippecanoe:count": 4 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -122.477818, 37.811005 ], [ -122.476444, 37.810869 ], [ -122.476101, 37.809648 ], [ -122.474728, 37.809241 ], [ -122.472668, 37.808970 ], [ -122.470608, 37.808563 ], [ -122.469234, 37.807750 ], [ -122.468719, 37.807071 ], [ -122.468376, 37.806800 ], [ -122.468204, 37.806936 ], [ -122.468204, 37.806665 ], [ -122.466660, 37.805851 ], [ -122.463570, 37.804901 ], [ -122.461681, 37.804901 ], [ -122.458420, 37.805444 ], [ -122.454472, 37.806529 ], [ -122.452412, 37.806258 ], [ -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.470951, 37.787267 ], [ -122.473354, 37.787132 ], [ -122.475586, 37.786725 ], [ -122.479877, 37.786860 ], [ -122.483826, 37.787674 ], [ -122.484512, 37.789167 ], [ -122.483997, 37.789709 ], [ -122.484341, 37.790116 ], [ -122.484341, 37.789709 ], [ -122.485027, 37.789574 ], [ -122.485886, 37.790795 ], [ -122.483654, 37.794050 ], [ -122.482109, 37.798527 ], [ -122.481766, 37.798527 ], [ -122.481937, 37.798798 ], [ -122.481594, 37.798798 ], [ -122.481766, 37.798933 ], [ -122.480221, 37.801375 ], [ -122.479877, 37.802867 ], [ -122.478676, 37.805444 ], [ -122.478333, 37.808156 ], [ -122.477818, 37.808428 ], [ -122.477989, 37.810598 ], [ -122.477646, 37.810598 ], [ -122.477818, 37.811005 ] ], [ [ -122.452583, 37.803274 ], [ -122.452412, 37.803138 ], [ -122.450008, 37.802460 ], [ -122.451210, 37.803138 ], [ -122.452583, 37.803274 ] ] ], [ [ [ -122.466145, 37.806393 ], [ -122.465973, 37.806258 ], [ -122.466660, 37.805851 ], [ -122.466145, 37.806393 ] ] ], [ [ [ -122.469921, 37.809377 ], [ -122.469406, 37.809106 ], [ -122.470093, 37.809241 ], [ -122.469921, 37.809377 ] ] ] ] } }
,
{ "type": "Feature", "properties": { "ZCTA5CE10": "94123", "tippecanoe:count": 2 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -122.443142, 37.809784 ], [ -122.439537, 37.808835 ], [ -122.440910, 37.806936 ], [ -122.435760, 37.807614 ], [ -122.435589, 37.807207 ], [ -122.435589, 37.806936 ], [ -122.433014, 37.807343 ], [ -122.433014, 37.807071 ], [ -122.434387, 37.806936 ], [ -122.434044, 37.806800 ], [ -122.433014, 37.806936 ], [ -122.432842, 37.806800 ], [ -122.434044, 37.806665 ], [ -122.434044, 37.806393 ], [ -122.433872, 37.806122 ], [ -122.433872, 37.805851 ], [ -122.433701, 37.805580 ], [ -122.432671, 37.805715 ], [ -122.432327, 37.805986 ], [ -122.431641, 37.803274 ], [ -122.425289, 37.804088 ], [ -122.424946, 37.803138 ], [ -122.426491, 37.803003 ], [ -122.426319, 37.802053 ], [ -122.424774, 37.802324 ], [ -122.424603, 37.801239 ], [ -122.426147, 37.801104 ], [ -122.425976, 37.800154 ], [ -122.424431, 37.800426 ], [ -122.423744, 37.796628 ], [ -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.443142, 37.809784 ] ] ], [ [ [ -122.432842, 37.805986 ], [ -122.432842, 37.805851 ], [ -122.433872, 37.805851 ], [ -122.432842, 37.805986 ] ] ], [ [ [ -122.433529, 37.807614 ], [ -122.433529, 37.807478 ], [ -122.435589, 37.807207 ], [ -122.433529, 37.807614 ] ] ], [ [ [ -122.452583, 37.803274 ], [ -122.451210, 37.803138 ], [ -122.450008, 37.802460 ], [ -122.452583, 37.803274 ] ] ], [ [ [ -122.432842, 37.806393 ], [ -122.432842, 37.806122 ], [ -122.433872, 37.806122 ], [ -122.432842, 37.806393 ] ] ], [ [ [ -122.432842, 37.806665 ], [ -122.432842, 37.806529 ], [ -122.434044, 37.806393 ], [ -122.432842, 37.806665 ] ] ], [ [ [ -122.433701, 37.808156 ], [ -122.433701, 37.807885 ], [ -122.433872, 37.807885 ], [ -122.433701, 37.808156 ] ] ] ] } }
] }
] }
@@ -3,7 +3,5 @@
{ "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": "MultiPolygon", "coordinates": [ [ [ [ -122.477818, 37.811005 ], [ -122.476444, 37.810869 ], [ -122.476101, 37.809648 ], [ -122.474728, 37.809241 ], [ -122.472668, 37.808970 ], [ -122.470608, 37.808563 ], [ -122.469234, 37.807750 ], [ -122.468719, 37.807071 ], [ -122.468376, 37.806800 ], [ -122.468204, 37.806936 ], [ -122.468204, 37.806665 ], [ -122.466660, 37.805851 ], [ -122.463570, 37.804901 ], [ -122.461681, 37.804901 ], [ -122.458420, 37.805444 ], [ -122.454472, 37.806529 ], [ -122.452412, 37.806258 ], [ -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.470951, 37.787267 ], [ -122.473354, 37.787132 ], [ -122.475586, 37.786725 ], [ -122.479877, 37.786860 ], [ -122.483826, 37.787674 ], [ -122.484512, 37.789167 ], [ -122.483997, 37.789709 ], [ -122.484341, 37.790116 ], [ -122.484341, 37.789709 ], [ -122.485027, 37.789574 ], [ -122.485886, 37.790795 ], [ -122.483654, 37.794050 ], [ -122.482109, 37.798527 ], [ -122.481766, 37.798527 ], [ -122.481937, 37.798798 ], [ -122.481594, 37.798798 ], [ -122.481766, 37.798933 ], [ -122.480221, 37.801375 ], [ -122.479877, 37.802867 ], [ -122.478676, 37.805444 ], [ -122.478333, 37.808156 ], [ -122.477818, 37.808428 ], [ -122.477989, 37.810598 ], [ -122.477646, 37.810598 ], [ -122.477818, 37.811005 ] ], [ [ -122.452583, 37.803274 ], [ -122.452412, 37.803138 ], [ -122.450008, 37.802460 ], [ -122.451210, 37.803138 ], [ -122.452583, 37.803274 ] ] ], [ [ [ -122.466145, 37.806393 ], [ -122.465973, 37.806258 ], [ -122.466660, 37.805851 ], [ -122.466145, 37.806393 ] ] ], [ [ [ -122.469921, 37.809377 ], [ -122.469406, 37.809106 ], [ -122.470093, 37.809241 ], [ -122.469921, 37.809377 ] ] ] ] } }
,
{ "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.443142, 37.809784 ], [ -122.439537, 37.808835 ], [ -122.440910, 37.806936 ], [ -122.435760, 37.807614 ], [ -122.435589, 37.807207 ], [ -122.435589, 37.806936 ], [ -122.433014, 37.807343 ], [ -122.433014, 37.807071 ], [ -122.434387, 37.806936 ], [ -122.434044, 37.806800 ], [ -122.433014, 37.806936 ], [ -122.432842, 37.806800 ], [ -122.434044, 37.806665 ], [ -122.434044, 37.806393 ], [ -122.433872, 37.806122 ], [ -122.433872, 37.805851 ], [ -122.433701, 37.805580 ], [ -122.432671, 37.805715 ], [ -122.432327, 37.805986 ], [ -122.431641, 37.803274 ], [ -122.425289, 37.804088 ], [ -122.424946, 37.803138 ], [ -122.426491, 37.803003 ], [ -122.426319, 37.802053 ], [ -122.424774, 37.802324 ], [ -122.424603, 37.801239 ], [ -122.426147, 37.801104 ], [ -122.425976, 37.800154 ], [ -122.424431, 37.800426 ], [ -122.423744, 37.796628 ], [ -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.443142, 37.809784 ] ] ], [ [ [ -122.432842, 37.805986 ], [ -122.432842, 37.805851 ], [ -122.433872, 37.805851 ], [ -122.432842, 37.805986 ] ] ], [ [ [ -122.433529, 37.807614 ], [ -122.433529, 37.807478 ], [ -122.435589, 37.807207 ], [ -122.433529, 37.807614 ] ] ], [ [ [ -122.452583, 37.803274 ], [ -122.451210, 37.803138 ], [ -122.450008, 37.802460 ], [ -122.452583, 37.803274 ] ] ], [ [ [ -122.432842, 37.806393 ], [ -122.432842, 37.806122 ], [ -122.433872, 37.806122 ], [ -122.432842, 37.806393 ] ] ], [ [ [ -122.432842, 37.806665 ], [ -122.432842, 37.806529 ], [ -122.434044, 37.806393 ], [ -122.432842, 37.806665 ] ] ], [ [ [ -122.433701, 37.808156 ], [ -122.433701, 37.807885 ], [ -122.433872, 37.807885 ], [ -122.433701, 37.808156 ] ] ] ] } }
,
{ "type": "Feature", "properties": { "ZCTA5CE10": "94107", "GEOID10": "94107", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 4647665, "AWATER10": 227634, "INTPTLAT10": "+37.7604596", "INTPTLON10": "-122.3997237", "tippecanoe:count": 5 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -122.385120, 37.791337 ], [ -122.381687, 37.783469 ], [ -122.384777, 37.782790 ], [ -122.384777, 37.782519 ], [ -122.387867, 37.782248 ], [ -122.387695, 37.781841 ], [ -122.385635, 37.781976 ], [ -122.385464, 37.781841 ], [ -122.384777, 37.781841 ], [ -122.385464, 37.781705 ], [ -122.385464, 37.781569 ], [ -122.387695, 37.781434 ], [ -122.387524, 37.781027 ], [ -122.384777, 37.781298 ], [ -122.384777, 37.781027 ], [ -122.387524, 37.780891 ], [ -122.387524, 37.780484 ], [ -122.387524, 37.780077 ], [ -122.387524, 37.779670 ], [ -122.387352, 37.779263 ], [ -122.387352, 37.778992 ], [ -122.384777, 37.779127 ], [ -122.384777, 37.778992 ], [ -122.387352, 37.778856 ], [ -122.387352, 37.778585 ], [ -122.387352, 37.778313 ], [ -122.387695, 37.778313 ], [ -122.387695, 37.778177 ], [ -122.390442, 37.777092 ], [ -122.390442, 37.776956 ], [ -122.390270, 37.776685 ], [ -122.392502, 37.775192 ], [ -122.394218, 37.776414 ], [ -122.396450, 37.774650 ], [ -122.396107, 37.774514 ], [ -122.397480, 37.773429 ], [ -122.397823, 37.772343 ], [ -122.398510, 37.772886 ], [ -122.400742, 37.771122 ], [ -122.396622, 37.767865 ], [ -122.393875, 37.766101 ], [ -122.393703, 37.764065 ], [ -122.387867, 37.764337 ], [ -122.387524, 37.760537 ], [ -122.386665, 37.760673 ], [ -122.386322, 37.758094 ], [ -122.385464, 37.758094 ], [ -122.384777, 37.757687 ], [ -122.381344, 37.757959 ], [ -122.381344, 37.756466 ], [ -122.381172, 37.755923 ], [ -122.380829, 37.755516 ], [ -122.380829, 37.755244 ], [ -122.384090, 37.754973 ], [ -122.384090, 37.754701 ], [ -122.383404, 37.754701 ], [ -122.382889, 37.754430 ], [ -122.381516, 37.754566 ], [ -122.380142, 37.754566 ], [ -122.379971, 37.753344 ], [ -122.386837, 37.752937 ], [ -122.386494, 37.750358 ], [ -122.393188, 37.749951 ], [ -122.393188, 37.751444 ], [ -122.395248, 37.751308 ], [ -122.395248, 37.749815 ], [ -122.403831, 37.749408 ], [ -122.402973, 37.752801 ], [ -122.403316, 37.756194 ], [ -122.403831, 37.757144 ], [ -122.406063, 37.759180 ], [ -122.406578, 37.760673 ], [ -122.405376, 37.763116 ], [ -122.405033, 37.764608 ], [ -122.401600, 37.764880 ], [ -122.401428, 37.763523 ], [ -122.400570, 37.763658 ], [ -122.400742, 37.766237 ], [ -122.399712, 37.766237 ], [ -122.399712, 37.766644 ], [ -122.400742, 37.767458 ], [ -122.401772, 37.767458 ], [ -122.402115, 37.769901 ], [ -122.403488, 37.769765 ], [ -122.403831, 37.770036 ], [ -122.399368, 37.773564 ], [ -122.402458, 37.776007 ], [ -122.401943, 37.776414 ], [ -122.403145, 37.777363 ], [ -122.403660, 37.776956 ], [ -122.405548, 37.778449 ], [ -122.395592, 37.786318 ], [ -122.394047, 37.785232 ], [ -122.394218, 37.785097 ], [ -122.393360, 37.784961 ], [ -122.391815, 37.785504 ], [ -122.391472, 37.785639 ], [ -122.391472, 37.785097 ], [ -122.392330, 37.784283 ], [ -122.392159, 37.784147 ], [ -122.388554, 37.786996 ], [ -122.387695, 37.787132 ], [ -122.387867, 37.788760 ], [ -122.386322, 37.790252 ], [ -122.385464, 37.790523 ], [ -122.385635, 37.790930 ], [ -122.385120, 37.791337 ] ] ], [ [ [ -122.384777, 37.779941 ], [ -122.384777, 37.779670 ], [ -122.387524, 37.779670 ], [ -122.384777, 37.779941 ] ] ], [ [ [ -122.384777, 37.780348 ], [ -122.384777, 37.780077 ], [ -122.387524, 37.780077 ], [ -122.384777, 37.780348 ] ] ], [ [ [ -122.384777, 37.780755 ], [ -122.384777, 37.780484 ], [ -122.387524, 37.780484 ], [ -122.384777, 37.780755 ] ] ], [ [ [ -122.384777, 37.779534 ], [ -122.384777, 37.779263 ], [ -122.387352, 37.779263 ], [ -122.384777, 37.779534 ] ] ], [ [ [ -122.385120, 37.778856 ], [ -122.385120, 37.778585 ], [ -122.387352, 37.778585 ], [ -122.385120, 37.778856 ] ] ] ] } }
] }
] }
+4 -4
View File
@@ -1,12 +1,12 @@
{ "type": "FeatureCollection", "properties": { "zoom": 11, "x": 327, "y": 791 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "muni", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { "ZCTA5CE10": "94132", "GEOID10": "94132", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 8078894, "AWATER10": 1299131, "INTPTLAT10": "+37.7222142", "INTPTLON10": "-122.4840831", "tippecanoe:count": 163 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.490005, 37.738006 ], [ -122.488461, 37.737055 ], [ -122.486229, 37.736784 ], [ -122.483311, 37.737463 ], [ -122.482452, 37.737463 ], [ -122.481766, 37.737191 ], [ -122.475414, 37.737463 ], [ -122.475243, 37.734612 ], [ -122.475071, 37.734747 ], [ -122.471638, 37.734747 ], [ -122.471981, 37.731082 ], [ -122.472153, 37.731082 ], [ -122.472496, 37.721578 ], [ -122.464428, 37.721713 ], [ -122.463913, 37.722392 ], [ -122.462196, 37.723071 ], [ -122.462196, 37.721713 ], [ -122.462711, 37.721713 ], [ -122.462711, 37.718590 ], [ -122.462540, 37.711257 ], [ -122.460823, 37.710578 ], [ -122.464256, 37.710578 ], [ -122.465973, 37.710171 ], [ -122.467690, 37.709220 ], [ -122.468891, 37.708270 ], [ -122.497730, 37.708134 ], [ -122.498245, 37.708134 ], [ -122.498245, 37.710714 ], [ -122.498417, 37.714924 ], [ -122.498760, 37.715875 ], [ -122.499962, 37.717504 ], [ -122.500305, 37.718590 ], [ -122.500477, 37.720627 ], [ -122.502708, 37.723343 ], [ -122.503052, 37.724022 ], [ -122.503052, 37.725244 ], [ -122.503567, 37.725379 ], [ -122.505283, 37.726330 ], [ -122.506313, 37.727416 ], [ -122.507172, 37.732575 ], [ -122.506828, 37.735426 ], [ -122.505283, 37.735426 ], [ -122.505283, 37.735562 ], [ -122.502022, 37.735562 ], [ -122.500477, 37.735155 ], [ -122.498589, 37.734204 ], [ -122.496872, 37.733933 ], [ -122.491379, 37.734069 ], [ -122.491379, 37.737327 ], [ -122.490349, 37.737870 ], [ -122.490005, 37.738006 ] ] ] } }
{ "type": "Feature", "properties": { "ZCTA5CE10": "94132", "GEOID10": "94132", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 8078894, "AWATER10": 1299131, "INTPTLAT10": "+37.7222142", "INTPTLON10": "-122.4840831", "tippecanoe:count": 163 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.490005, 37.738006 ], [ -122.488461, 37.737055 ], [ -122.486229, 37.736784 ], [ -122.483311, 37.737463 ], [ -122.482452, 37.737463 ], [ -122.481766, 37.737191 ], [ -122.475414, 37.737463 ], [ -122.475243, 37.734612 ], [ -122.475071, 37.734747 ], [ -122.471638, 37.734747 ], [ -122.471981, 37.731082 ], [ -122.472153, 37.731082 ], [ -122.472496, 37.721578 ], [ -122.464428, 37.721713 ], [ -122.463913, 37.722392 ], [ -122.462196, 37.723071 ], [ -122.462196, 37.721713 ], [ -122.462711, 37.721713 ], [ -122.462711, 37.718590 ], [ -122.462668, 37.715875 ], [ -122.498760, 37.715875 ], [ -122.499962, 37.717504 ], [ -122.500305, 37.718590 ], [ -122.500477, 37.720627 ], [ -122.502708, 37.723343 ], [ -122.503052, 37.724022 ], [ -122.503052, 37.725244 ], [ -122.503567, 37.725379 ], [ -122.505283, 37.726330 ], [ -122.506313, 37.727416 ], [ -122.507172, 37.732575 ], [ -122.506828, 37.735426 ], [ -122.505283, 37.735426 ], [ -122.505283, 37.735562 ], [ -122.502022, 37.735562 ], [ -122.500477, 37.735155 ], [ -122.498589, 37.734204 ], [ -122.496872, 37.733933 ], [ -122.491379, 37.734069 ], [ -122.491379, 37.737327 ], [ -122.490349, 37.737870 ], [ -122.490005, 37.738006 ] ] ] } }
,
{ "type": "Feature", "properties": { "ZCTA5CE10": "94112", "GEOID10": "94112", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 8720166, "AWATER10": 0, "INTPTLAT10": "+37.7203669", "INTPTLON10": "-122.4429361", "tippecanoe:count": 259 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.426662, 37.736376 ], [ -122.426491, 37.736241 ], [ -122.427349, 37.735698 ], [ -122.424946, 37.735562 ], [ -122.423916, 37.734612 ], [ -122.422886, 37.734340 ], [ -122.422199, 37.735155 ], [ -122.421856, 37.735155 ], [ -122.421856, 37.734612 ], [ -122.420139, 37.732983 ], [ -122.418251, 37.732983 ], [ -122.418938, 37.732847 ], [ -122.418938, 37.732168 ], [ -122.415161, 37.732168 ], [ -122.421684, 37.731761 ], [ -122.421684, 37.731082 ], [ -122.420139, 37.731489 ], [ -122.420483, 37.728910 ], [ -122.423744, 37.728774 ], [ -122.423058, 37.727280 ], [ -122.424088, 37.725923 ], [ -122.423573, 37.725651 ], [ -122.422886, 37.723886 ], [ -122.423744, 37.723750 ], [ -122.424774, 37.722121 ], [ -122.424603, 37.721713 ], [ -122.426319, 37.718590 ], [ -122.427349, 37.715060 ], [ -122.425632, 37.714517 ], [ -122.426662, 37.711257 ], [ -122.427177, 37.711257 ], [ -122.426147, 37.710986 ], [ -122.426662, 37.710171 ], [ -122.429924, 37.711529 ], [ -122.430096, 37.710850 ], [ -122.429237, 37.709628 ], [ -122.428379, 37.709220 ], [ -122.428379, 37.708405 ], [ -122.434044, 37.708134 ], [ -122.440395, 37.708405 ], [ -122.452240, 37.708134 ], [ -122.468891, 37.708270 ], [ -122.467690, 37.709220 ], [ -122.465973, 37.710171 ], [ -122.464256, 37.710578 ], [ -122.460823, 37.710578 ], [ -122.462540, 37.711257 ], [ -122.462711, 37.718590 ], [ -122.462711, 37.721713 ], [ -122.462196, 37.721713 ], [ -122.462196, 37.725244 ], [ -122.462711, 37.725515 ], [ -122.462540, 37.727145 ], [ -122.462025, 37.727416 ], [ -122.460823, 37.727552 ], [ -122.460995, 37.728638 ], [ -122.459965, 37.728774 ], [ -122.459965, 37.729860 ], [ -122.459278, 37.730810 ], [ -122.457390, 37.730675 ], [ -122.457561, 37.731082 ], [ -122.453442, 37.731625 ], [ -122.453442, 37.730675 ], [ -122.444344, 37.730675 ], [ -122.444344, 37.728231 ], [ -122.443657, 37.728366 ], [ -122.439537, 37.730131 ], [ -122.435932, 37.731625 ], [ -122.435074, 37.731489 ], [ -122.432156, 37.732983 ], [ -122.431984, 37.732983 ], [ -122.432327, 37.733254 ], [ -122.428551, 37.735019 ], [ -122.426662, 37.736376 ] ] ] } }
{ "type": "Feature", "properties": { "ZCTA5CE10": "94112", "GEOID10": "94112", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 8720166, "AWATER10": 0, "INTPTLAT10": "+37.7203669", "INTPTLON10": "-122.4429361", "tippecanoe:count": 259 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.426662, 37.736376 ], [ -122.426491, 37.736241 ], [ -122.427349, 37.735698 ], [ -122.424946, 37.735562 ], [ -122.423916, 37.734612 ], [ -122.422886, 37.734340 ], [ -122.422199, 37.735155 ], [ -122.421856, 37.735155 ], [ -122.421856, 37.734612 ], [ -122.420139, 37.732983 ], [ -122.418251, 37.732983 ], [ -122.418938, 37.732847 ], [ -122.418938, 37.732168 ], [ -122.415161, 37.732168 ], [ -122.421684, 37.731761 ], [ -122.421684, 37.731082 ], [ -122.420139, 37.731489 ], [ -122.420483, 37.728910 ], [ -122.423744, 37.728774 ], [ -122.423058, 37.727280 ], [ -122.424088, 37.725923 ], [ -122.423573, 37.725651 ], [ -122.422886, 37.723886 ], [ -122.423744, 37.723750 ], [ -122.424774, 37.722121 ], [ -122.424603, 37.721713 ], [ -122.426319, 37.718590 ], [ -122.427092, 37.715875 ], [ -122.462668, 37.715875 ], [ -122.462711, 37.718590 ], [ -122.462711, 37.721713 ], [ -122.462196, 37.721713 ], [ -122.462196, 37.725244 ], [ -122.462711, 37.725515 ], [ -122.462540, 37.727145 ], [ -122.462025, 37.727416 ], [ -122.460823, 37.727552 ], [ -122.460995, 37.728638 ], [ -122.459965, 37.728774 ], [ -122.459965, 37.729860 ], [ -122.459278, 37.730810 ], [ -122.457390, 37.730675 ], [ -122.457561, 37.731082 ], [ -122.453442, 37.731625 ], [ -122.453442, 37.730675 ], [ -122.444344, 37.730675 ], [ -122.444344, 37.728231 ], [ -122.443657, 37.728366 ], [ -122.439537, 37.730131 ], [ -122.435932, 37.731625 ], [ -122.435074, 37.731489 ], [ -122.432156, 37.732983 ], [ -122.431984, 37.732983 ], [ -122.432327, 37.733254 ], [ -122.428551, 37.735019 ], [ -122.426662, 37.736376 ] ] ] } }
,
{ "type": "Feature", "properties": { "ZCTA5CE10": "94134", "GEOID10": "94134", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 6210550, "AWATER10": 90877, "INTPTLAT10": "+37.7210461", "INTPTLON10": "-122.4135554", "tippecanoe:count": 124 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.406921, 37.738006 ], [ -122.406578, 37.735698 ], [ -122.405033, 37.733661 ], [ -122.402802, 37.729317 ], [ -122.398853, 37.718590 ], [ -122.397995, 37.715467 ], [ -122.398510, 37.715467 ], [ -122.396450, 37.712887 ], [ -122.395763, 37.710850 ], [ -122.394047, 37.711257 ], [ -122.390785, 37.711122 ], [ -122.390957, 37.710307 ], [ -122.393703, 37.708270 ], [ -122.423744, 37.708270 ], [ -122.428379, 37.708405 ], [ -122.428379, 37.709220 ], [ -122.429237, 37.709628 ], [ -122.430096, 37.710850 ], [ -122.429924, 37.711529 ], [ -122.426662, 37.710171 ], [ -122.426147, 37.710986 ], [ -122.427177, 37.711257 ], [ -122.426662, 37.711257 ], [ -122.425632, 37.714517 ], [ -122.427349, 37.715060 ], [ -122.426319, 37.718590 ], [ -122.424603, 37.721713 ], [ -122.424774, 37.722121 ], [ -122.423744, 37.723750 ], [ -122.422886, 37.723886 ], [ -122.423573, 37.725651 ], [ -122.424088, 37.725923 ], [ -122.423058, 37.727280 ], [ -122.423744, 37.728774 ], [ -122.420483, 37.728910 ], [ -122.420139, 37.731489 ], [ -122.421684, 37.731082 ], [ -122.421684, 37.731761 ], [ -122.419453, 37.732032 ], [ -122.416019, 37.732032 ], [ -122.414474, 37.732439 ], [ -122.409496, 37.735019 ], [ -122.408466, 37.736241 ], [ -122.408295, 37.737598 ], [ -122.406921, 37.738006 ] ] ] } }
{ "type": "Feature", "properties": { "ZCTA5CE10": "94134", "GEOID10": "94134", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 6210550, "AWATER10": 90877, "INTPTLAT10": "+37.7210461", "INTPTLON10": "-122.4135554", "tippecanoe:count": 124 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.406921, 37.738006 ], [ -122.406578, 37.735698 ], [ -122.405033, 37.733661 ], [ -122.402802, 37.729317 ], [ -122.398853, 37.718590 ], [ -122.398124, 37.715875 ], [ -122.427092, 37.715875 ], [ -122.426319, 37.718590 ], [ -122.424603, 37.721713 ], [ -122.424774, 37.722121 ], [ -122.423744, 37.723750 ], [ -122.422886, 37.723886 ], [ -122.423573, 37.725651 ], [ -122.424088, 37.725923 ], [ -122.423058, 37.727280 ], [ -122.423744, 37.728774 ], [ -122.420483, 37.728910 ], [ -122.420139, 37.731489 ], [ -122.421684, 37.731082 ], [ -122.421684, 37.731761 ], [ -122.419453, 37.732032 ], [ -122.416019, 37.732032 ], [ -122.414474, 37.732439 ], [ -122.409496, 37.735019 ], [ -122.408466, 37.736241 ], [ -122.408295, 37.737598 ], [ -122.406921, 37.738006 ] ] ] } }
,
{ "type": "Feature", "properties": { "ZCTA5CE10": "94124", "GEOID10": "94124", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 12765980, "AWATER10": 2804039, "INTPTLAT10": "+37.7288947", "INTPTLON10": "-122.3827787", "tippecanoe:count": 314 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.377911, 37.753615 ], [ -122.376022, 37.752530 ], [ -122.373104, 37.746015 ], [ -122.367611, 37.740178 ], [ -122.368298, 37.739770 ], [ -122.373447, 37.739635 ], [ -122.373962, 37.739499 ], [ -122.373447, 37.738684 ], [ -122.372761, 37.738277 ], [ -122.367439, 37.738277 ], [ -122.370701, 37.737327 ], [ -122.371216, 37.737055 ], [ -122.372932, 37.737055 ], [ -122.373619, 37.737191 ], [ -122.375679, 37.738413 ], [ -122.376366, 37.738413 ], [ -122.376537, 37.738277 ], [ -122.376022, 37.738006 ], [ -122.375164, 37.737870 ], [ -122.374821, 37.737327 ], [ -122.375164, 37.736241 ], [ -122.376022, 37.735833 ], [ -122.375851, 37.735019 ], [ -122.375336, 37.735426 ], [ -122.374821, 37.734883 ], [ -122.375164, 37.734612 ], [ -122.374821, 37.734476 ], [ -122.374992, 37.733933 ], [ -122.375679, 37.732711 ], [ -122.375164, 37.732983 ], [ -122.374992, 37.732711 ], [ -122.374649, 37.732847 ], [ -122.374821, 37.732575 ], [ -122.374134, 37.732575 ], [ -122.373447, 37.732983 ], [ -122.372589, 37.733933 ], [ -122.371902, 37.734204 ], [ -122.369671, 37.732304 ], [ -122.367096, 37.735426 ], [ -122.367439, 37.735426 ], [ -122.367096, 37.735562 ], [ -122.366753, 37.735426 ], [ -122.366924, 37.734883 ], [ -122.369499, 37.732439 ], [ -122.369499, 37.732168 ], [ -122.368813, 37.731896 ], [ -122.368641, 37.732304 ], [ -122.368298, 37.732304 ], [ -122.367439, 37.731896 ], [ -122.366753, 37.732168 ], [ -122.365208, 37.733797 ], [ -122.366581, 37.732168 ], [ -122.365379, 37.732983 ], [ -122.366238, 37.731896 ], [ -122.366066, 37.731896 ], [ -122.365036, 37.732847 ], [ -122.365723, 37.731761 ], [ -122.365723, 37.731625 ], [ -122.364864, 37.732575 ], [ -122.365036, 37.732032 ], [ -122.363663, 37.731218 ], [ -122.362804, 37.732168 ], [ -122.362633, 37.732032 ], [ -122.363319, 37.731082 ], [ -122.362804, 37.730810 ], [ -122.362118, 37.731625 ], [ -122.361774, 37.731489 ], [ -122.362633, 37.730675 ], [ -122.361946, 37.730131 ], [ -122.360916, 37.729860 ], [ -122.360744, 37.730267 ], [ -122.359886, 37.730267 ], [ -122.358856, 37.729724 ], [ -122.359028, 37.729453 ], [ -122.361946, 37.728774 ], [ -122.362289, 37.728502 ], [ -122.361431, 37.728502 ], [ -122.357655, 37.729453 ], [ -122.357483, 37.729181 ], [ -122.357826, 37.728910 ], [ -122.360401, 37.728231 ], [ -122.359886, 37.728095 ], [ -122.357140, 37.728774 ], [ -122.356968, 37.728774 ], [ -122.357140, 37.727959 ], [ -122.356796, 37.727959 ], [ -122.358170, 37.718590 ], [ -122.358513, 37.715875 ], [ -122.360401, 37.708270 ], [ -122.381001, 37.708405 ], [ -122.393703, 37.708270 ], [ -122.390957, 37.710307 ], [ -122.390785, 37.711122 ], [ -122.394047, 37.711257 ], [ -122.395763, 37.710850 ], [ -122.396450, 37.712887 ], [ -122.398510, 37.715467 ], [ -122.397995, 37.715467 ], [ -122.398853, 37.718590 ], [ -122.402802, 37.729317 ], [ -122.405033, 37.733661 ], [ -122.406578, 37.735698 ], [ -122.406921, 37.738006 ], [ -122.407780, 37.737734 ], [ -122.407951, 37.737870 ], [ -122.407951, 37.739227 ], [ -122.407436, 37.741399 ], [ -122.405891, 37.743435 ], [ -122.406235, 37.743571 ], [ -122.405376, 37.744521 ], [ -122.405205, 37.744386 ], [ -122.404003, 37.748322 ], [ -122.405033, 37.749136 ], [ -122.402973, 37.749544 ], [ -122.402115, 37.749408 ], [ -122.395248, 37.749815 ], [ -122.395248, 37.751308 ], [ -122.393188, 37.751444 ], [ -122.393188, 37.749951 ], [ -122.386494, 37.750358 ], [ -122.386837, 37.752937 ], [ -122.381001, 37.753208 ], [ -122.377911, 37.753615 ] ] ] } }
{ "type": "Feature", "properties": { "ZCTA5CE10": "94124", "GEOID10": "94124", "CLASSFP10": "B5", "MTFCC10": "G6350", "FUNCSTAT10": "S", "ALAND10": 12765980, "AWATER10": 2804039, "INTPTLAT10": "+37.7288947", "INTPTLON10": "-122.3827787", "tippecanoe:count": 314 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -122.377911, 37.753615 ], [ -122.376022, 37.752530 ], [ -122.373104, 37.746015 ], [ -122.367611, 37.740178 ], [ -122.368298, 37.739770 ], [ -122.373447, 37.739635 ], [ -122.373962, 37.739499 ], [ -122.373447, 37.738684 ], [ -122.372761, 37.738277 ], [ -122.367439, 37.738277 ], [ -122.370701, 37.737327 ], [ -122.371216, 37.737055 ], [ -122.372932, 37.737055 ], [ -122.373619, 37.737191 ], [ -122.375679, 37.738413 ], [ -122.376366, 37.738413 ], [ -122.376537, 37.738277 ], [ -122.376022, 37.738006 ], [ -122.375164, 37.737870 ], [ -122.374821, 37.737327 ], [ -122.375164, 37.736241 ], [ -122.376022, 37.735833 ], [ -122.375851, 37.735019 ], [ -122.375336, 37.735426 ], [ -122.374821, 37.734883 ], [ -122.375164, 37.734612 ], [ -122.374821, 37.734476 ], [ -122.374992, 37.733933 ], [ -122.375679, 37.732711 ], [ -122.375164, 37.732983 ], [ -122.374992, 37.732711 ], [ -122.374649, 37.732847 ], [ -122.374821, 37.732575 ], [ -122.374134, 37.732575 ], [ -122.373447, 37.732983 ], [ -122.372589, 37.733933 ], [ -122.371902, 37.734204 ], [ -122.369671, 37.732304 ], [ -122.367096, 37.735426 ], [ -122.367439, 37.735426 ], [ -122.367096, 37.735562 ], [ -122.366753, 37.735426 ], [ -122.366924, 37.734883 ], [ -122.369499, 37.732439 ], [ -122.369499, 37.732168 ], [ -122.368813, 37.731896 ], [ -122.368641, 37.732304 ], [ -122.368298, 37.732304 ], [ -122.367439, 37.731896 ], [ -122.366753, 37.732168 ], [ -122.365208, 37.733797 ], [ -122.366581, 37.732168 ], [ -122.365379, 37.732983 ], [ -122.366238, 37.731896 ], [ -122.366066, 37.731896 ], [ -122.365036, 37.732847 ], [ -122.365723, 37.731761 ], [ -122.365723, 37.731625 ], [ -122.364864, 37.732575 ], [ -122.365036, 37.732032 ], [ -122.363663, 37.731218 ], [ -122.362804, 37.732168 ], [ -122.362633, 37.732032 ], [ -122.363319, 37.731082 ], [ -122.362804, 37.730810 ], [ -122.362118, 37.731625 ], [ -122.361774, 37.731489 ], [ -122.362633, 37.730675 ], [ -122.361946, 37.730131 ], [ -122.360916, 37.729860 ], [ -122.360744, 37.730267 ], [ -122.359886, 37.730267 ], [ -122.358856, 37.729724 ], [ -122.359028, 37.729453 ], [ -122.361946, 37.728774 ], [ -122.362289, 37.728502 ], [ -122.361431, 37.728502 ], [ -122.357655, 37.729453 ], [ -122.357483, 37.729181 ], [ -122.357826, 37.728910 ], [ -122.360401, 37.728231 ], [ -122.359886, 37.728095 ], [ -122.357140, 37.728774 ], [ -122.356968, 37.728774 ], [ -122.357140, 37.727959 ], [ -122.356796, 37.727959 ], [ -122.358170, 37.718590 ], [ -122.358513, 37.715875 ], [ -122.398124, 37.715875 ], [ -122.398853, 37.718590 ], [ -122.402802, 37.729317 ], [ -122.405033, 37.733661 ], [ -122.406578, 37.735698 ], [ -122.406921, 37.738006 ], [ -122.407780, 37.737734 ], [ -122.407951, 37.737870 ], [ -122.407951, 37.739227 ], [ -122.407436, 37.741399 ], [ -122.405891, 37.743435 ], [ -122.406235, 37.743571 ], [ -122.405376, 37.744521 ], [ -122.405205, 37.744386 ], [ -122.404003, 37.748322 ], [ -122.405033, 37.749136 ], [ -122.402973, 37.749544 ], [ -122.402115, 37.749408 ], [ -122.395248, 37.749815 ], [ -122.395248, 37.751308 ], [ -122.393188, 37.751444 ], [ -122.393188, 37.749951 ], [ -122.386494, 37.750358 ], [ -122.386837, 37.752937 ], [ -122.381001, 37.753208 ], [ -122.377911, 37.753615 ] ] ] } }
,
{ "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": 70 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -122.477818, 37.811005 ], [ -122.476444, 37.810869 ], [ -122.476101, 37.809648 ], [ -122.474728, 37.809241 ], [ -122.472668, 37.808970 ], [ -122.470608, 37.808563 ], [ -122.469234, 37.807750 ], [ -122.468719, 37.807071 ], [ -122.468376, 37.806800 ], [ -122.468204, 37.806936 ], [ -122.468204, 37.806665 ], [ -122.466660, 37.805851 ], [ -122.463570, 37.804901 ], [ -122.461681, 37.804901 ], [ -122.458420, 37.805444 ], [ -122.454472, 37.806529 ], [ -122.452412, 37.806258 ], [ -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.470951, 37.787267 ], [ -122.473354, 37.787132 ], [ -122.475586, 37.786725 ], [ -122.479877, 37.786860 ], [ -122.483826, 37.787674 ], [ -122.484512, 37.789167 ], [ -122.483997, 37.789709 ], [ -122.484341, 37.790116 ], [ -122.484341, 37.789709 ], [ -122.485027, 37.789574 ], [ -122.485886, 37.790795 ], [ -122.483654, 37.794050 ], [ -122.482109, 37.798527 ], [ -122.481766, 37.798527 ], [ -122.481937, 37.798798 ], [ -122.481594, 37.798798 ], [ -122.481766, 37.798933 ], [ -122.480221, 37.801375 ], [ -122.479877, 37.802867 ], [ -122.478676, 37.805444 ], [ -122.478333, 37.808156 ], [ -122.477818, 37.808428 ], [ -122.477989, 37.810598 ], [ -122.477646, 37.810598 ], [ -122.477818, 37.811005 ] ], [ [ -122.452583, 37.803274 ], [ -122.452412, 37.803138 ], [ -122.450008, 37.802460 ], [ -122.451210, 37.803138 ], [ -122.452583, 37.803274 ] ] ], [ [ [ -122.466145, 37.806393 ], [ -122.465973, 37.806258 ], [ -122.466660, 37.805851 ], [ -122.466145, 37.806393 ] ] ], [ [ [ -122.469921, 37.809377 ], [ -122.469406, 37.809106 ], [ -122.470093, 37.809241 ], [ -122.469921, 37.809377 ] ] ] ] } }
,
@@ -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 ] ] ] ] } }
] }
] }
+35
View File
@@ -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 ] ] ] } }
] }
] }
Binary file not shown.
@@ -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 ] ] ] } }
] }
] }
+211
View File
@@ -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 ] } }
] }
] }
Binary file not shown.
+135
View File
@@ -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"
}
File diff suppressed because it is too large Load Diff
Binary file not shown.
@@ -0,0 +1,7 @@
{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "parsed", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "id": 510, "properties": { "bldgsqft": 1765, "felt:sum:bldgsqft": 4857699 }, "geometry": { "type": "Point", "coordinates": [ -122.343750, 37.718590 ] } }
,
{ "type": "Feature", "id": 514, "properties": { "bldgsqft": 3050 }, "geometry": { "type": "Point", "coordinates": [ -122.343750, 37.718590 ] } }
] }
] }
+67
View File
@@ -0,0 +1,67 @@
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17212", "USER_OWNER": "CITY VINTNERS SAN FRANCISCO WINERY LLC", "USER_OPERA": null, "USER_STREE": "53 BLUXOME ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "City Vintners San Francisco Winery Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.396824, 37.776482 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21516", "USER_OWNER": "WEBSTER GRANGER MARQUEZ", "USER_OPERA": "PEDRO GOMEZ INDUSTRIES", "USER_STREE": "53 BLUXOME ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": null, "Owner_cln": "Webster Granger Marquez", "Oper_cln": "Pedro Gomez Industries" }, "geometry": { "type": "Point", "coordinates": [ -122.396824, 37.776482 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21912", "USER_OWNER": "PHILIP C. BOWERS", "USER_OPERA": "CB WINE CELLARS", "USER_STREE": "1225 MINNESOTA ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": null, "Owner_cln": "Philip C. Bowers", "Oper_cln": "Cb Wine Cellars" }, "geometry": { "type": "Point", "coordinates": [ -122.389455, 37.75494 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21396", "USER_OWNER": "KYLE ROEMER AND SAMANTHA ROEMER", "USER_OPERA": "NICHOLAS & RAE WINERY", "USER_STREE": "2455 THIRD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": null, "Owner_cln": "Kyle Roemer And Samantha Roemer", "Oper_cln": "Nicholas & Rae Winery" }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21066", "USER_OWNER": "THE SAN FRANCISCO MEAD COMPANY, LLC", "USER_OPERA": "THE SAN FRANCISCO MEADERY", "USER_STREE": "1180 SHAFTER AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "USA", "Owner_cln": "The San Francisco Mead Company, Llc", "Oper_cln": "The San Francisco Meadery" }, "geometry": { "type": "Point", "coordinates": [ -122.382693, 37.726785 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-23922", "USER_OWNER": "OTTAVINO WINES LLC", "USER_OPERA": null, "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": null, "Owner_cln": "Ottavino Wines Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21933", "USER_OWNER": "PHILIP CUADRA", "USER_OPERA": "HIGHLAWN WINE COMPANY", "USER_STREE": "540 BARNEVELD AVE STE K & L", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": null, "Owner_cln": "Philip Cuadra", "Oper_cln": "Highlawn Wine Company" }, "geometry": { "type": "Point", "coordinates": [ -122.404604, 37.74056 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22828", "USER_OWNER": "SURFACE AREA, LLC", "USER_OPERA": "WOODS BEER CO.", "USER_STREE": "422 CLIPPER COVE WAY", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": null, "Owner_cln": "Surface Area, Llc", "Oper_cln": "Woods Beer Co." }, "geometry": { "type": "Point", "coordinates": [ -122.3698481, 37.8168703 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17266", "USER_OWNER": "DAN BALDWIN", "USER_OPERA": "THE SAN FRANCISCO BAY WINERY", "USER_STREE": "2029 RESEARCH DR", "USER_CITY": "LIVERMORE", "USER_STATE": "CA", "USER_ZIP": 94550, "USER_COUNT": "ALAMEDA", "Owner_cln": "Dan Baldwin", "Oper_cln": "The San Francisco Bay Winery" }, "geometry": { "type": "Point", "coordinates": [ -121.721474, 37.679387 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "NM-W-21035", "USER_OWNER": "DH WINERY - 139 WSF, LLC", "USER_OPERA": null, "USER_STREE": "139 W SAN FRANCISCO ST", "USER_CITY": "SANTA FE", "USER_STATE": "NM", "USER_ZIP": 87501, "USER_COUNT": "SANTA FE", "Owner_cln": "Dh Winery - 139 Wsf, Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -105.940259, 35.687807 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-23988", "USER_OWNER": "47 HILLS BREWING COMPANY, LLC", "USER_OPERA": "47 HILLS BREWING COMPANY", "USER_STREE": "137 S LINDEN AVE", "USER_CITY": "SOUTH SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94080, "USER_COUNT": "SAN MATEO", "Owner_cln": "47 Hills Brewing Company, Llc", "Oper_cln": "47 Hills Brewing Company" }, "geometry": { "type": "Point", "coordinates": [ -122.413615, 37.644257 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17487", "USER_OWNER": "WAIT CELLARS, LLC", "USER_OPERA": "WAIT CELLARS", "USER_STREE": "53 BLUXOME ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Wait Cellars, Llc", "Oper_cln": "Wait Cellars" }, "geometry": { "type": "Point", "coordinates": [ -122.396824, 37.776482 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17398", "USER_OWNER": "MICHAEL JAMES WINES, INC.", "USER_OPERA": "MICHAEL JAMES WINES", "USER_STREE": "2455 3RD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Michael James Wines, Inc.", "Oper_cln": "Michael James Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17354", "USER_OWNER": "PUG WINE, LLC", "USER_OPERA": "PUG WINE", "USER_STREE": "2455 3RD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Pug Wine, Llc", "Oper_cln": "Pug Wine" }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21880", "USER_OWNER": "SMASHING GRAPES, LLC", "USER_OPERA": "TIMARK WINES", "USER_STREE": "2455 3RD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Smashing Grapes, Llc", "Oper_cln": "Timark Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-24229", "USER_OWNER": "WILLIAM LANE WINE COMPANY LLC", "USER_OPERA": "WILLIAM LANE WINE COMPANY", "USER_STREE": "995 9TH ST BLDG 201\/RM 104", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94103, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "William Lane Wine Company Llc", "Oper_cln": "William Lane Wine Company" }, "geometry": { "type": "Point", "coordinates": [ -122.3689769, 37.8257667 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22659", "USER_OWNER": "HACKBERRY HILL CELLARS, LLC", "USER_OPERA": null, "USER_STREE": "2455 THIRD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Hackberry Hill Cellars, Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17377", "USER_OWNER": "ALCHEMIST CELLARS LLC", "USER_OPERA": "ALCHEMIST CELLARS", "USER_STREE": "53 BLUXOME ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Alchemist Cellars Llc", "Oper_cln": "Alchemist Cellars" }, "geometry": { "type": "Point", "coordinates": [ -122.396824, 37.776482 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21270", "USER_OWNER": "HARDBALL CELLARS INC.", "USER_OPERA": "HARDBALL CELLARS", "USER_STREE": "2455 THIRD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Hardball Cellars Inc.", "Oper_cln": "Hardball Cellars" }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17609", "USER_OWNER": "SEAMUS WINES, LLC", "USER_OPERA": "SEAMUS WINES", "USER_STREE": "2455 3RD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Seamus Wines, Llc", "Oper_cln": "Seamus Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21743", "USER_OWNER": "FORTUNATUS, LLC", "USER_OPERA": "BRAVIUM", "USER_STREE": "1225 MINNESOTA ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Fortunatus, Llc", "Oper_cln": "Bravium" }, "geometry": { "type": "Point", "coordinates": [ -122.389455, 37.75494 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21846", "USER_OWNER": "COSENZA CELLARS LLC", "USER_OPERA": null, "USER_STREE": "5361 BLUXOME ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Cosenza Cellars Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.3961401, 37.777432 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21120", "USER_OWNER": "VOLEURS DE VIN, LLC", "USER_OPERA": "VOLEURS DE VIN", "USER_STREE": "53 BLUXOME ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Voleurs De Vin, Llc", "Oper_cln": "Voleurs De Vin" }, "geometry": { "type": "Point", "coordinates": [ -122.396824, 37.776482 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17719", "USER_OWNER": "CHRISTOPHER VON HOLT AND PAMELA VON HOLT", "USER_OPERA": "VON HOLT WINES", "USER_STREE": "1225 MINNESOTA ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Christopher Von Holt And Pamela Von Holt", "Oper_cln": "Von Holt Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.389455, 37.75494 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17212", "USER_OWNER": "CITY VINTNERS SAN FRANCISCO WINERY LLC", "USER_OPERA": null, "USER_STREE": "53 BLUXOME ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "City Vintners San Francisco Winery Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.396824, 37.776482 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17424", "USER_OWNER": "FURTHERMORE, LLC", "USER_OPERA": "FURTHERMORE PINOT NOIR", "USER_STREE": "1225 MINNESOTA ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Furthermore, Llc", "Oper_cln": "Furthermore Pinot Noir" }, "geometry": { "type": "Point", "coordinates": [ -122.389455, 37.75494 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21023", "USER_OWNER": "ARAN O. HEALY AND DAVID G. GREGA", "USER_OPERA": "CARLOTTA CELLARS", "USER_STREE": "2455 3RD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Aran O. Healy And David G. Grega", "Oper_cln": "Carlotta Cellars" }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21253", "USER_OWNER": "WINEDOCTORS, LLC", "USER_OPERA": null, "USER_STREE": "2455 3RD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Winedoctors, Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21217", "USER_OWNER": "LOOS FAMILY WINERY, LLC", "USER_OPERA": null, "USER_STREE": "2455 THIRD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Loos Family Winery, Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-15734", "USER_OWNER": "CARL E. & SHARON H. SUTTON", "USER_OPERA": "SUTTON CELLARS", "USER_STREE": "601 22ND ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Carl E. & Sharon H. Sutton", "Oper_cln": "Sutton Cellars" }, "geometry": { "type": "Point", "coordinates": [ -122.387697, 37.757076 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17319", "USER_OWNER": "ERISTAVI WINERY LLC", "USER_OPERA": null, "USER_STREE": "1300 POTRERO AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94110, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Eristavi Winery Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.40646, 37.751125 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-23518", "USER_OWNER": "BAREBOTTLE BREWING COMPANY, INC.", "USER_OPERA": "BAREBOTTLE BREWING COMPANY", "USER_STREE": "1525 CORTLAND AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94110, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Barebottle Brewing Company, Inc.", "Oper_cln": "Barebottle Brewing Company" }, "geometry": { "type": "Point", "coordinates": [ -122.409057, 37.740083 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-23463", "USER_OWNER": "LES AMERICAINES LLC", "USER_OPERA": "CLAIRE HILL WINES", "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Les Americaines Llc", "Oper_cln": "Claire Hill Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22655", "USER_OWNER": "BRAZEN VENTURES LLC", "USER_OPERA": "BRAZEN VENTURES", "USER_STREE": "2455 THIRD ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94107, "USER_COUNT": "SAN FRANCISO", "Owner_cln": "Brazen Ventures Llc", "Oper_cln": "Brazen Ventures" }, "geometry": { "type": "Point", "coordinates": [ -122.387918, 37.759243 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21050", "USER_OWNER": "TANK WINES LLC", "USER_OPERA": "TANK WINES", "USER_STREE": "18 DORE ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94117, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Tank Wines Llc", "Oper_cln": "Tank Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.413548, 37.774095 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17327", "USER_OWNER": "WAITS-MAST FAMILY CELLARS, LLC", "USER_OPERA": null, "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Waits-mast Family Cellars, Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22193", "USER_OWNER": "URBAN CELLARS LLC", "USER_OPERA": "URBAN CELLARS", "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Urban Cellars Llc", "Oper_cln": "Urban Cellars" }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22454", "USER_OWNER": "ESS EFF WINES, LLC", "USER_OPERA": "ESS EFF WINES", "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCCO", "Owner_cln": "Ess Eff Wines, Llc", "Oper_cln": "Ess Eff Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-3592", "USER_OWNER": "AUGUST WEST WINES, LLC", "USER_OPERA": "AUGUST WEST", "USER_STREE": "540 BARNEVELD AVE SUITES K A", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "August West Wines, Llc", "Oper_cln": "August West" }, "geometry": { "type": "Point", "coordinates": [ -122.404604, 37.74056 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-23055", "USER_OWNER": "MANSFIELD-DUNNE WINES, LLC", "USER_OPERA": null, "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Mansfield-dunne Wines, Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-15425", "USER_OWNER": "BARBARA J. GRATTA", "USER_OPERA": "GRATTA WINES", "USER_STREE": "1469 HUDSON AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Barbara J. Gratta", "Oper_cln": "Gratta Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.385892, 37.738472 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-15292", "USER_OWNER": "BRYAN RULISON HARRINGTON", "USER_OPERA": "HARRINGTON WINES", "USER_STREE": "1559 CUSTER AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Bryan Rulison Harrington", "Oper_cln": "Harrington Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.390741, 37.745662 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22247", "USER_OWNER": "CJM WINE GROUP LLC", "USER_OPERA": "FALLON PLACE WINES", "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Cjm Wine Group Llc", "Oper_cln": "Fallon Place Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21774", "USER_OWNER": "HERSLY WINES LLC", "USER_OPERA": "HERSLY WINES", "USER_STREE": "540 BARNEVELD AVE STE K, L", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Hersly Wines Llc", "Oper_cln": "Hersly Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.404604, 37.74056 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22069", "USER_OWNER": "RUSSE WINE PARTNERS, LLC", "USER_OPERA": "MONTAGNE RUSSE", "USER_STREE": "540 BARNEVELD AVE STE K & L", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Russe Wine Partners, Llc", "Oper_cln": "Montagne Russe" }, "geometry": { "type": "Point", "coordinates": [ -122.404604, 37.74056 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22595", "USER_OWNER": "JOHN DAVID LOUIS BRY", "USER_OPERA": "PERFUSION VINEYARD", "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "John David Louis Bry", "Oper_cln": "Perfusion Vineyard" }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-24254", "USER_OWNER": "DEMEO VINEYARDS INC.", "USER_OPERA": "DEMEO VINEYARDS", "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Demeo Vineyards Inc.", "Oper_cln": "Demeo Vineyards" }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17490", "USER_OWNER": "33RD STREET CELLARS, LLC", "USER_OPERA": "CELLARS 33", "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "33rd Street Cellars, Llc", "Oper_cln": "Cellars 33" }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21765", "USER_OWNER": "MAGIC BAG MEADERY LLC", "USER_OPERA": "MAGIC BAG MEADERY", "USER_STREE": "1180 SHAFTER AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Magic Bag Meadery Llc", "Oper_cln": "Magic Bag Meadery" }, "geometry": { "type": "Point", "coordinates": [ -122.382693, 37.726785 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21705", "USER_OWNER": "CATHERINE COCHRANE, COURTNEY COCHRANE, AND SEAN COCHRANE", "USER_OPERA": "RYAN COCHRANE WINES", "USER_STREE": "540 BARNEVELD AVE STE K & L", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Catherine Cochrane, Courtney Cochrane, And Sean Cochrane", "Oper_cln": "Ryan Cochrane Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.404604, 37.74056 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-24286", "USER_OWNER": "OUROBOROS WINES LLC", "USER_OPERA": "OUROBOROS WINES", "USER_STREE": "495 BARNEVELD AVE", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Ouroboros Wines Llc", "Oper_cln": "Ouroboros Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.403411, 37.740376 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21034", "USER_OWNER": "EDWARD S. KURTZMAN", "USER_OPERA": "SANDLER WINE COMPANY", "USER_STREE": "540 BARNEVELD AVE STE K AND L", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Edward S. Kurtzman", "Oper_cln": "Sandler Wine Company" }, "geometry": { "type": "Point", "coordinates": [ -122.404604, 37.74056 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-22040", "USER_OWNER": "THEOPOLIS ENTERPRISES, LLC", "USER_OPERA": "THEOPOLIS VINEYARDS", "USER_STREE": "540 BARNEVELD AVE STE K & L", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94124, "USER_COUNT": "SAN FRANCISCO COUNTY", "Owner_cln": "Theopolis Enterprises, Llc", "Oper_cln": "Theopolis Vineyards" }, "geometry": { "type": "Point", "coordinates": [ -122.404604, 37.74056 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-16651", "USER_OWNER": "PB WINES, INC.", "USER_OPERA": null, "USER_STREE": "1080 AVENUE M UNIT C", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Pb Wines, Inc.", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.368843, 37.829147 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17548", "USER_OWNER": "HDC WINE COMPANY LLC", "USER_OPERA": "HDC WINE COMPANY", "USER_STREE": "995 9TH ST BLDG 201,", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Hdc Wine Company Llc", "Oper_cln": "Hdc Wine Company" }, "geometry": { "type": "Point", "coordinates": [ -122.3689769, 37.8257667 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-15779", "USER_OWNER": "KENDRIC VINEYARDS, LLC", "USER_OPERA": "KENDRIC VINEYARDS", "USER_STREE": "401 13TH ST BUILDING 3", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Kendric Vineyards, Llc", "Oper_cln": "Kendric Vineyards" }, "geometry": { "type": "Point", "coordinates": [ -122.3738416, 37.8276279 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-15973", "USER_OWNER": "SOL ROUGE LLC", "USER_OPERA": "SOL ROUGE", "USER_STREE": "200 CALIFORNIA AVE BLDG 180 N", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Sol Rouge Llc", "Oper_cln": "Sol Rouge" }, "geometry": { "type": "Point", "coordinates": [ -122.3692839, 37.8185833 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-24253", "USER_OWNER": "MAYEAUX GRAPE CLINIC LLC", "USER_OPERA": "STAGIAIRE WINE", "USER_STREE": "995 9TH ST BLDG 201 RM 104", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Mayeaux Grape Clinic Llc", "Oper_cln": "Stagiaire Wine" }, "geometry": { "type": "Point", "coordinates": [ -122.3689769, 37.8257667 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21125", "USER_OWNER": "PASSAGGIO WINES LLC", "USER_OPERA": "PASSAGGIO WINES", "USER_STREE": "995 9TH ST BLDG 201", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Passaggio Wines Llc", "Oper_cln": "Passaggio Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.3689769, 37.8257667 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17549", "USER_OWNER": "MORGAN FAMILY WINES LLC", "USER_OPERA": "MORGAN FAMILY WINES", "USER_STREE": "995 9TH ST BLDG 201,", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Morgan Family Wines Llc", "Oper_cln": "Morgan Family Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.3689769, 37.8257667 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17516", "USER_OWNER": "CASA NO COMPRENDE, INC.", "USER_OPERA": "TREASURE ISLAND WINES", "USER_STREE": "995 NINTH", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Casa No Comprende, Inc.", "Oper_cln": "Treasure Island Wines" }, "geometry": { "type": "Point", "coordinates": [ -122.3689769, 37.8257667 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-16641", "USER_OWNER": "YERBA BUENA BEVERAGE, LLC", "USER_OPERA": "TREASURE ISLAND BRANDS", "USER_STREE": "750 6TH ST", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Yerba Buena Beverage, Llc", "Oper_cln": "Treasure Island Brands" }, "geometry": { "type": "Point", "coordinates": [ -122.3671488, 37.8243095 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-24193", "USER_OWNER": "DE VIN, LLC", "USER_OPERA": null, "USER_STREE": "995 9TH ST BLDG 201 RM 104", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "De Vin, Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.3689769, 37.8257667 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-23993", "USER_OWNER": "JUST ENOUGH WINES LLC", "USER_OPERA": null, "USER_STREE": "995 9TH ST UNIT 201 RM104", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 94130, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Just Enough Wines Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.3689769, 37.8257667 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17110", "USER_OWNER": "FORTUNATUS, LLC", "USER_OPERA": "BRAVIUM", "USER_STREE": "16370 DYERVILLE LOOP RD BLDG 201,", "USER_CITY": "MYERS FLAT", "USER_STATE": "CA", "USER_ZIP": 95554, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Fortunatus, Llc", "Oper_cln": "Bravium" }, "geometry": { "type": "Point", "coordinates": [ -123.7657329, 40.2465359 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-21971", "USER_OWNER": "SEVEN HILL LLC", "USER_OPERA": null, "USER_STREE": "28740 INWOOD RD", "USER_CITY": "SHINGLETOWN", "USER_STATE": "CA", "USER_ZIP": 96088, "USER_COUNT": "SAN FRANCISCO", "Owner_cln": "Seven Hill Llc", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -121.982482, 40.511239 ] } }
{ "type": "Feature", "properties": { "USER_PERMI": "CA-W-17255", "USER_OWNER": "MORNINGWOOD VINEYARDS AND WINERY, INC.", "USER_OPERA": null, "USER_STREE": "NOT PROVIDED", "USER_CITY": "SAN FRANCISCO", "USER_STATE": "CA", "USER_ZIP": 0, "USER_COUNT": "Geocoded_city_Center", "Owner_cln": "Morningwood Vineyards And Winery, Inc.", "Oper_cln": null }, "geometry": { "type": "Point", "coordinates": [ -122.372965, 37.82457 ] } }
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -719,7 +719,8 @@ struct tileset_reader {
std::set<std::string>(), std::set<std::string>(), std::vector<std::string>(),
false, &next_overzoomed_tiles, false, NULL, false,
std::unordered_map<std::string, attribute_op>(), unidecode_data, 0, 0,
std::vector<mvt_layer>(), "", "");
std::vector<mvt_layer>(), "", "", SIZE_MAX,
std::vector<clipbbox>());
return ret;
}
+52 -49
View File
@@ -143,9 +143,9 @@ static int coalcmp(const void *v1, const void *v2) {
}
for (size_t i = 0; i < c1->full_keys.size(); i++) {
if (c1->full_keys[i] < c2->full_keys[i]) {
if (*c1->full_keys[i] < *c2->full_keys[i]) {
return -1;
} else if (c1->full_keys[i] > c2->full_keys[i]) {
} else if (*c1->full_keys[i] > *c2->full_keys[i]) {
return 1;
}
@@ -302,7 +302,7 @@ static mvt_value find_attribute_value(const serial_feature *c1, std::string cons
}
for (size_t i = 0; i < c1->full_keys.size(); i++) {
if (c1->full_keys[i] == key) {
if (*c1->full_keys[i] == key) {
return stringified_to_mvt_value(c1->full_values[i].type, c1->full_values[i].s.c_str(), c1->tile_stringpool);
}
}
@@ -384,7 +384,7 @@ static std::vector<std::vector<serial_feature>> assemble_multiplier_clusters(std
bool is_cluster_start = false;
for (size_t i = 0; i < feature.full_keys.size(); i++) {
if (feature.full_keys[i] == "tippecanoe:retain_points_multiplier_first") {
if (*feature.full_keys[i] == "tippecanoe:retain_points_multiplier_first") {
is_cluster_start = true;
break;
}
@@ -412,7 +412,7 @@ static std::vector<serial_feature> disassemble_multiplier_clusters(std::vector<s
// gets the marker attribute
for (size_t i = 0; i < cluster.size(); i++) {
for (size_t j = 0; j < cluster[i].full_keys.size(); j++) {
if (cluster[i].full_keys[j] == "tippecanoe:retain_points_multiplier_first") {
if (*cluster[i].full_keys[j] == "tippecanoe:retain_points_multiplier_first") {
cluster[0].full_keys.push_back(std::move(cluster[i].full_keys[j]));
cluster[0].full_values.push_back(std::move(cluster[i].full_values[j]));
@@ -1012,7 +1012,7 @@ static void remove_attributes(serial_feature &sf, std::set<std::string> const &e
}
for (ssize_t i = sf.full_keys.size() - 1; i >= 0; i--) {
std::string key = sf.full_keys[i];
std::string key = *sf.full_keys[i];
if (exclude_attributes.count(key) > 0) {
sf.full_keys.erase(sf.full_keys.begin() + i);
sf.full_values.erase(sf.full_values.begin() + i);
@@ -1063,6 +1063,7 @@ struct next_feature_state {
// geometry type set to -2.
static serial_feature next_feature(decompressor *geoms, std::atomic<long long> *geompos_in, int z, unsigned tx, unsigned ty, unsigned *initial_x, unsigned *initial_y, long long *original_features, long long *unclipped_features, int nextzoom, int maxzoom, int minzoom, int max_zoom_increment, size_t pass, std::atomic<long long> *along, long long alongminus, int buffer, std::atomic<bool> *within, compressor **geomfile, std::atomic<long long> *geompos, long long start_geompos[], std::atomic<double> *oprogress, double todo, const char *fname, int child_shards, json_object *filter, const char *global_stringpool, long long *pool_off, std::vector<std::vector<std::string>> *layer_unmaps, bool first_time, bool compressed, multiplier_state *multiplier_state, std::shared_ptr<std::string> &tile_stringpool, std::vector<std::string> const &unidecode_data, next_feature_state &next_feature_state, double droprate) {
double extra_multiplier_zooms = log(retain_points_multiplier) / log(droprate);
while (1) {
serial_feature sf;
long long len;
@@ -1183,7 +1184,7 @@ static serial_feature next_feature(decompressor *geoms, std::atomic<long long> *
}
for (size_t i = 0; i < sf.full_keys.size(); i++) {
std::string key = sf.full_keys[i];
std::string key = *sf.full_keys[i];
mvt_value val = stringified_to_mvt_value(sf.full_values[i].type, sf.full_values[i].s.c_str(), tile_stringpool);
attributes.insert(std::pair<std::string, mvt_value>(key, val));
@@ -1357,7 +1358,7 @@ void *run_prefilter(void *v) {
decode_meta(sf, tmp_layer, tmp_feature);
tmp_layer.features.push_back(tmp_feature);
layer_to_geojson(tmp_layer, 0, 0, 0, false, true, false, true, sf.index, sf.seq, sf.extent, true, state, 0);
layer_to_geojson(tmp_layer, 0, 0, 0, false, true, false, true, sf.index, sf.seq, sf.extent, true, state, 0, std::set<std::string>());
}
if (fclose(rpa->prefilter_fp) != 0) {
@@ -1399,7 +1400,7 @@ void add_tilestats(std::string const &layername, int z, std::vector<std::map<std
add_to_tilestats(ts->second.tilestats, key, val);
}
void promote_attribute(std::string const &key, serial_feature &p) {
void promote_attribute(std::string const &key, serial_feature &p, key_pool &key_pool) {
if (p.need_tilestats.count(key) == 0) {
p.need_tilestats.insert(key);
}
@@ -1413,7 +1414,7 @@ void promote_attribute(std::string const &key, serial_feature &p) {
sv.s = p.stringpool + p.values[i] + 1;
sv.type = p.stringpool[p.values[i]];
p.full_keys.push_back(key);
p.full_keys.push_back(key_pool.pool(key));
p.full_values.push_back(std::move(sv));
p.keys.erase(p.keys.begin() + i);
@@ -1424,7 +1425,7 @@ void promote_attribute(std::string const &key, serial_feature &p) {
}
}
void promote_attribute_prefix(std::string const &key, std::string const &prefixed_key, serial_feature &p) {
void promote_attribute_prefix(std::string const &key, std::string const &prefixed_key, serial_feature &p, key_pool &key_pool) {
if (p.need_tilestats.count(prefixed_key) == 0) {
p.need_tilestats.insert(prefixed_key);
}
@@ -1432,18 +1433,18 @@ void promote_attribute_prefix(std::string const &key, std::string const &prefixe
// does the prefixed attribute already exist as a full key?
ssize_t found_as = -1;
for (size_t i = 0; i < p.full_keys.size(); i++) {
if (prefixed_key == p.full_keys[i]) {
if (prefixed_key == *p.full_keys[i]) {
// yes, so we're done
return;
}
if (key == p.full_keys[i]) {
if (key == *p.full_keys[i]) {
found_as = i;
}
}
// or did we find the source as a full key? then copy it
if (found_as >= 0) {
p.full_keys.push_back(prefixed_key);
p.full_keys.push_back(key_pool.pool(prefixed_key));
p.full_values.push_back(p.full_values[found_as]);
return;
}
@@ -1457,7 +1458,7 @@ void promote_attribute_prefix(std::string const &key, std::string const &prefixe
sv.s = p.stringpool + p.values[i] + 1;
sv.type = p.stringpool[p.values[i]];
p.full_keys.push_back(prefixed_key);
p.full_keys.push_back(key_pool.pool(prefixed_key));
p.full_values.push_back(std::move(sv));
p.keys.erase(p.keys.begin() + i);
@@ -1475,7 +1476,7 @@ void promote_attribute_prefix(std::string const &key, std::string const &prefixe
sv.s = p.stringpool + p.values[found_as] + 1;
sv.type = p.stringpool[p.values[found_as]];
p.full_keys.push_back(prefixed_key);
p.full_keys.push_back(key_pool.pool(prefixed_key));
p.full_values.push_back(std::move(sv));
return;
@@ -1485,7 +1486,7 @@ void promote_attribute_prefix(std::string const &key, std::string const &prefixe
}
// accumulate attribute values from sf onto p
void preserve_attributes(std::unordered_map<std::string, attribute_op> const *attribute_accum, const serial_feature &sf, serial_feature &p) {
void preserve_attributes(std::unordered_map<std::string, attribute_op> const *attribute_accum, const serial_feature &sf, serial_feature &p, key_pool &key_pool) {
std::string accumulate_numeric_colon = accumulate_numeric + ":";
for (size_t i = 0; i < sf.keys.size(); i++) {
@@ -1498,8 +1499,8 @@ void preserve_attributes(std::unordered_map<std::string, attribute_op> const *at
sv.type = sf.stringpool[sf.values[i]];
sv.s = sf.stringpool + sf.values[i] + 1;
promote_attribute(key, p);
preserve_attribute(f->second, key, sv, p.full_keys, p.full_values, p.attribute_accum_state);
promote_attribute(key, p, key_pool);
preserve_attribute(f->second, key, sv, p.full_keys, p.full_values, p.attribute_accum_state, key_pool);
} else if (type == mvt_double && accumulate_numeric.size() > 0 && !starts_with(key, accumulate_numeric_colon)) {
for (auto const &operation : numeric_operations) {
serial_val sv;
@@ -1507,26 +1508,26 @@ void preserve_attributes(std::unordered_map<std::string, attribute_op> const *at
sv.s = sf.stringpool + sf.values[i] + 1;
std::string prefixed_key = accumulate_numeric + ":" + operation.first + ":" + key;
promote_attribute_prefix(key, prefixed_key, p);
preserve_attribute(operation.second, prefixed_key, sv, p.full_keys, p.full_values, p.attribute_accum_state);
promote_attribute_prefix(key, prefixed_key, p, key_pool);
preserve_attribute(operation.second, prefixed_key, sv, p.full_keys, p.full_values, p.attribute_accum_state, key_pool);
}
}
}
for (size_t i = 0; i < sf.full_keys.size(); i++) {
const std::string &key = sf.full_keys[i];
const std::string key = *sf.full_keys[i];
int type = sf.full_values[i].type;
auto f = attribute_accum->find(key);
if (f != attribute_accum->end()) {
const serial_val &sv = sf.full_values[i];
promote_attribute(key, p); // promotes it in the target feature
preserve_attribute(f->second, key, sv, p.full_keys, p.full_values, p.attribute_accum_state);
promote_attribute(key, p, key_pool); // promotes it in the target feature
preserve_attribute(f->second, key, sv, p.full_keys, p.full_values, p.attribute_accum_state, key_pool);
} else if (type == mvt_double && accumulate_numeric.size() > 0 && !starts_with(key, accumulate_numeric_colon)) {
for (auto const &operation : numeric_operations) {
std::string prefixed_key = accumulate_numeric + ":" + operation.first + ":" + key;
promote_attribute_prefix(key, prefixed_key, p);
preserve_attribute(operation.second, prefixed_key, sf.full_values[i], p.full_keys, p.full_values, p.attribute_accum_state);
promote_attribute_prefix(key, prefixed_key, p, key_pool);
preserve_attribute(operation.second, prefixed_key, sf.full_values[i], p.full_keys, p.full_values, p.attribute_accum_state, key_pool);
}
}
}
@@ -1620,7 +1621,7 @@ struct layer_features {
size_t multiplier_cluster_size = 0; // The feature count of the current multiplier cluster
};
bool drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer_features &layer, serial_feature &sf, std::vector<std::vector<std::string>> *layer_unmaps, strategy &strategy, bool &drop_rest, std::unordered_map<std::string, attribute_op> const *attribute_accum) {
bool drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer_features &layer, serial_feature &sf, std::vector<std::vector<std::string>> *layer_unmaps, strategy &strategy, bool &drop_rest, std::unordered_map<std::string, attribute_op> const *attribute_accum, key_pool &key_pool) {
ssize_t which_serial_feature;
if (find_feature_to_accumulate_onto(layer.features, sf, which_serial_feature, layer_unmaps, LLONG_MAX)) {
@@ -1631,7 +1632,7 @@ bool drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer_features
sf.dropped = layer.multiplier_cluster_size + 1;
return false; // converted rather than dropped
} else {
preserve_attributes(attribute_accum, sf, layer.features[which_serial_feature]);
preserve_attributes(attribute_accum, sf, layer.features[which_serial_feature], key_pool);
drop_rest = true;
return true; // dropped
}
@@ -1741,6 +1742,8 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
bool too_many_features = false;
bool too_many_bytes = false;
key_pool key_pool;
std::atomic<bool> within[child_shards];
long long start_geompos[child_shards];
for (size_t i = 0; i < (size_t) child_shards; i++) {
@@ -1857,7 +1860,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
if (prefilter == NULL) {
sf = next_feature(geoms, geompos_in, z, tx, ty, initial_x, initial_y, &original_features, &unclipped_features, nextzoom, maxzoom, minzoom, max_zoom_increment, pass, along, alongminus, buffer, within, geomfile, geompos, start_geompos, &oprogress, todo, fname, child_shards, filter, global_stringpool, pool_off, layer_unmaps, first_time, compressed_input, &multiplier_state, tile_stringpool, unidecode_data, next_feature_state, arg->droprate);
} else {
sf = parse_feature(prefilter_jp, z, tx, ty, layermaps, tiling_seg, layer_unmaps, postfilter != NULL);
sf = parse_feature(prefilter_jp, z, tx, ty, layermaps, tiling_seg, layer_unmaps, postfilter != NULL, key_pool);
}
if (sf.t < 0) {
@@ -1918,7 +1921,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
if (sf.dropped == FEATURE_DROPPED || drop_rest) {
if (find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature], key_pool);
strategy.dropped_by_rate++;
can_stop_early = false;
continue;
@@ -1931,7 +1934,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
if (sf.dropped == FEATURE_KEPT) {
if (gamma > 0) {
if (manage_gap(sf.index, &previndex, scale, gamma, &gap) && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature], key_pool);
strategy.dropped_by_gamma++;
drop_rest = true;
can_stop_early = false;
@@ -1959,7 +1962,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
features[which_serial_feature].geometry[0].y = y / (features[which_serial_feature].clustered + 1);
}
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature], key_pool);
strategy.coalesced_as_needed++;
drop_rest = true;
can_stop_early = false;
@@ -1969,7 +1972,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
add_sample_to(gaps, sf.gap, gaps_increment, seq);
if (sf.gap < mingap) {
can_stop_early = false;
if (drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer, sf, layer_unmaps, strategy, drop_rest, arg->attribute_accum)) {
if (drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer, sf, layer_unmaps, strategy, drop_rest, arg->attribute_accum, key_pool)) {
continue;
}
}
@@ -1991,7 +1994,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
features[which_serial_feature].geometry[0].y = y / (features[which_serial_feature].clustered + 1);
}
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature], key_pool);
strategy.coalesced_as_needed++;
drop_rest = true;
continue;
@@ -2002,7 +2005,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
coalesce_geometry(features[which_serial_feature], sf);
features[which_serial_feature].coalesced = true;
coalesced_area += sf.extent;
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature], key_pool);
strategy.coalesced_as_needed++;
drop_rest = true;
can_stop_early = false;
@@ -2014,7 +2017,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
// so we shouldn't expect to find anything small that we can related this feature to.
if (minextent != 0 && sf.extent + coalesced_area <= minextent) {
can_stop_early = false;
if (drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer, sf, layer_unmaps, strategy, drop_rest, arg->attribute_accum)) {
if (drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer, sf, layer_unmaps, strategy, drop_rest, arg->attribute_accum, key_pool)) {
continue;
}
}
@@ -2024,7 +2027,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
coalesce_geometry(features[which_serial_feature], sf);
features[which_serial_feature].coalesced = true;
coalesced_area += sf.extent;
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature], key_pool);
strategy.coalesced_as_needed++;
drop_rest = true;
can_stop_early = false;
@@ -2034,7 +2037,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
add_sample_to(drop_sequences, drop_sequence, drop_sequences_increment, seq);
if (mindrop_sequence != 0 && drop_sequence <= mindrop_sequence) {
can_stop_early = false;
if (drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer, sf, layer_unmaps, strategy, drop_rest, arg->attribute_accum)) {
if (drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer, sf, layer_unmaps, strategy, drop_rest, arg->attribute_accum, key_pool)) {
continue;
}
}
@@ -2043,7 +2046,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
if (mindrop_sequence != 0 && drop_sequence <= mindrop_sequence && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX)) {
coalesce_geometry(features[which_serial_feature], sf);
features[which_serial_feature].coalesced = true;
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature], key_pool);
strategy.coalesced_as_needed++;
drop_rest = true;
can_stop_early = false;
@@ -2143,7 +2146,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
}
if (sf.dropped == FEATURE_KEPT && retain_points_multiplier > 1) {
sf.full_keys.push_back("tippecanoe:retain_points_multiplier_first");
sf.full_keys.push_back(key_pool.pool("tippecanoe:retain_points_multiplier_first"));
sf.full_values.emplace_back(mvt_bool, "true");
}
@@ -2313,10 +2316,10 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
size_t j = feature_sequences[i].second;
serial_val sv(mvt_double, std::to_string(i));
features[j].full_keys.push_back("tippecanoe:retain_points_multiplier_sequence");
features[j].full_keys.push_back(key_pool.pool("tippecanoe:retain_points_multiplier_sequence"));
features[j].full_values.push_back(sv);
add_tilestats(layername, z, layermaps, tiling_seg, layer_unmaps, features[j].full_keys.back(), sv);
add_tilestats(layername, z, layermaps, tiling_seg, layer_unmaps, *features[j].full_keys.back(), sv);
}
}
@@ -2328,28 +2331,28 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
long long point_count = p.clustered + 1;
char abbrev[20]; // to_string(LLONG_MAX).length() / 1000 + 1;
p.full_keys.push_back("clustered");
p.full_keys.push_back(key_pool.pool("clustered"));
sv.type = mvt_bool;
sv.s = "true";
p.full_values.push_back(sv);
add_tilestats(layername, z, layermaps, tiling_seg, layer_unmaps, "clustered", sv);
p.full_keys.push_back("point_count");
p.full_keys.push_back(key_pool.pool("point_count"));
sv2.type = mvt_double;
sv2.s = std::to_string(point_count);
p.full_values.push_back(sv2);
add_tilestats(layername, z, layermaps, tiling_seg, layer_unmaps, "point_count", sv2);
p.full_keys.push_back("sqrt_point_count");
p.full_keys.push_back(key_pool.pool("sqrt_point_count"));
sv3.type = mvt_double;
sv3.s = std::to_string(round(100 * sqrt(point_count)) / 100.0);
p.full_values.push_back(sv3);
add_tilestats(layername, z, layermaps, tiling_seg, layer_unmaps, "sqrt_point_count", sv3);
p.full_keys.push_back("point_count_abbreviated");
p.full_keys.push_back(key_pool.pool("point_count_abbreviated"));
sv4.type = mvt_string;
if (point_count >= 10000) {
snprintf(abbrev, sizeof(abbrev), "%.0fk", point_count / 1000.0);
@@ -2366,8 +2369,8 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
if (p.need_tilestats.size() > 0) {
for (size_t j = 0; j < p.full_keys.size(); j++) {
if (p.need_tilestats.count(p.full_keys[j]) > 0) {
add_tilestats(layername, z, layermaps, tiling_seg, layer_unmaps, p.full_keys[j], p.full_values[j]);
if (p.need_tilestats.count(*p.full_keys[j]) > 0) {
add_tilestats(layername, z, layermaps, tiling_seg, layer_unmaps, *p.full_keys[j], p.full_values[j]);
}
}
}
@@ -2559,7 +2562,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
for (size_t a = 0; a < layer_features[x].full_keys.size(); a++) {
serial_val sv = layer_features[x].full_values[a];
mvt_value v = stringified_to_mvt_value(sv.type, sv.s.c_str(), tile_stringpool);
layer.tag(feature, layer_features[x].full_keys[a], v);
layer.tag(feature, *layer_features[x].full_keys[a], v);
}
if (additional[A_CALCULATE_FEATURE_DENSITY]) {
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef VERSION_HPP
#define VERSION_HPP
#define VERSION "v2.65.0"
#define VERSION "v2.71.0"
#endif
+5 -1
View File
@@ -268,7 +268,7 @@ void write_coords(json_writer &state, lonlat const &ll, double scale) {
}
}
void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, bool write_dropped, unsigned long long index, long long sequence, long long extent, bool complain, json_writer &state, double scale) {
void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, bool write_dropped, unsigned long long index, long long sequence, long long extent, bool complain, json_writer &state, double scale, std::set<std::string> const &include_attr) {
for (size_t f = 0; f < layer.features.size(); f++) {
mvt_feature const &feat = layer.features[f];
@@ -334,6 +334,10 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y
exit(EXIT_IMPOSSIBLE);
}
if (include_attr.size() > 0 && include_attr.find(layer.keys[feat.tags[t]]) == include_attr.end()) {
continue;
}
const char *key = layer.keys[feat.tags[t]].c_str();
mvt_value const &val = layer.values[feat.tags[t + 1]];
+2 -1
View File
@@ -4,6 +4,7 @@
#include <string>
#include <vector>
#include <stdio.h>
#include <set>
enum json_write_tok {
JSON_WRITE_HASH,
@@ -61,7 +62,7 @@ struct json_writer {
void adds(std::string const &s);
};
void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, bool dropped, unsigned long long index, long long sequence, long long extent, bool complain, json_writer &state, double scale);
void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, bool dropped, unsigned long long index, long long sequence, long long extent, bool complain, json_writer &state, double scale, std::set<std::string> const &include_attr);
void fprintq(FILE *f, const char *s);
#endif