Drop or retain whole multiplier clusters when dropping as needed (#198)

* Prep to track conditions other than just "dropped" or "kept"

* Count up instead of down

* Drop or retain whole multiplier clusters based on their first feature

* Calculate a global feature dropping sequence

* Switch over to using the drop sequence for drop-fraction

* Remove unused arguments for the old drop-fraction implementation

* Fix copy-and-paste bugs, update tests

* Properly incorporate feature_minzoom into the drop sequence, I hope

* Rename drop_by to drop_sequence

* See if sorting within clusters fixes filter stability between zooms

* Remove very chatty debug print

* Update changelog and version

* Use named constants instead of numbers for feature dropping/keeping

* Add comment to explain purpose and method of bit reversal
This commit is contained in:
Erica Fischer
2024-02-12 10:58:49 -08:00
committed by GitHub
parent e2a7a409c7
commit 4e52cbd957
20 changed files with 7402 additions and 9064 deletions
+6
View File
@@ -1,3 +1,9 @@
# 2.43.0
* Change -fraction-as-needed feature dropping to be consistent across tiles and zoom levels, and to follow the same pattern as point dropping by zoom level
* With -as-needed feature dropping, drop or retain entire multiplier clusters instead of individual features
* Sort the features within each multiplier cluster by its retention priority, for more consistency between zoom levels in filtered feature choice
# 2.42.0
* Improve tiling speed
+1 -1
View File
@@ -54,7 +54,7 @@ struct mvt_feature {
int /* mvt_geometry_type */ type = 0;
unsigned long long id = 0;
bool has_id = false;
bool dropped = false;
int dropped = 0;
size_t seq = 0; // used for ordering in overzoom
mvt_feature() {
+3 -1
View File
@@ -428,7 +428,9 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::
json_object *dropped = json_hash_get(tippecanoe, "dropped");
if (dropped != NULL && dropped->type == JSON_TRUE) {
sf.dropped = true;
sf.dropped = FEATURE_DROPPED; // dropped
} else {
sf.dropped = FEATURE_KEPT; // kept
}
}
+14 -1
View File
@@ -709,7 +709,20 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
}
}
if (additional[A_DROP_DENSEST_AS_NEEDED] || additional[A_COALESCE_DENSEST_AS_NEEDED] || additional[A_CLUSTER_DENSEST_AS_NEEDED] || additional[A_CALCULATE_FEATURE_DENSITY] || additional[A_DROP_SMALLEST_AS_NEEDED] || additional[A_COALESCE_SMALLEST_AS_NEEDED] || additional[A_INCREASE_GAMMA_AS_NEEDED] || additional[A_GENERATE_POLYGON_LABEL_POINTS] || sst->uses_gamma || cluster_distance != 0) {
if (additional[A_DROP_DENSEST_AS_NEEDED] ||
additional[A_COALESCE_DENSEST_AS_NEEDED] ||
additional[A_CLUSTER_DENSEST_AS_NEEDED] ||
additional[A_CALCULATE_FEATURE_DENSITY] ||
additional[A_DROP_SMALLEST_AS_NEEDED] ||
additional[A_COALESCE_SMALLEST_AS_NEEDED] ||
additional[A_DROP_FRACTION_AS_NEEDED] ||
additional[A_COALESCE_FRACTION_AS_NEEDED] ||
prevent[P_DYNAMIC_DROP] ||
additional[A_INCREASE_GAMMA_AS_NEEDED] ||
additional[A_GENERATE_POLYGON_LABEL_POINTS] ||
sst->uses_gamma ||
retain_points_multiplier > 1 ||
cluster_distance != 0) {
sf.index = bbox_index;
} else {
sf.index = 0;
+9 -2
View File
@@ -89,9 +89,16 @@ struct serial_feature {
// to be provided by frontends:
long long bbox[4] = {0, 0, 0, 0};
bool dropped = false; // was this feature dropped by rate?
drawvec edge_nodes; // what nodes at the tile edge were added during clipping?
drawvec edge_nodes; // what nodes at the tile edge were added during clipping?
#define FEATURE_DROPPED -1
#define FEATURE_KEPT 0
// <0: dropped
// 0: kept
// >0: sequence number of additional feature kept by retain-points-multiplier
int dropped = FEATURE_DROPPED; // was this feature dropped by rate?
// unsigned long long drop_by; // dot-dropping priority
bool reduced; // is polygon dust
bool coalesced; // was coalesced from multiple features
int line_detail; // current tile resolution being used for simplification
@@ -9,389 +9,13 @@
"maxzoom": "0",
"minzoom": "0",
"name": "tests/loop/out/-z0_-O200_--drop-fraction-as-needed.json.check.mbtiles",
"strategies": "[{\"dropped_as_needed\":811,\"feature_count_desired\":1000}]",
"strategies": "[{\"dropped_as_needed\":999,\"feature_count_desired\":1000}]",
"type": "overlay",
"version": "2"
}, "features": [
{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
,
{ "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 0.966797, 0.966751 ] } }
] }
] }
] }
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
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
@@ -18,10 +18,10 @@
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { "NAME": "Astana", "tippecanoe:retain_points_multiplier_sequence": 41, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 71.455078, 51.179343 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Tashkent", "tippecanoe:retain_points_multiplier_sequence": 67 }, "geometry": { "type": "Point", "coordinates": [ 69.257812, 41.310824 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bishkek", "tippecanoe:retain_points_multiplier_sequence": 29 }, "geometry": { "type": "Point", "coordinates": [ 74.619141, 42.875964 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Tashkent", "tippecanoe:retain_points_multiplier_sequence": 67 }, "geometry": { "type": "Point", "coordinates": [ 69.257812, 41.310824 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bangkok", "tippecanoe:retain_points_multiplier_sequence": 68, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 100.546875, 13.752725 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Vientiane", "tippecanoe:retain_points_multiplier_sequence": 42 }, "geometry": { "type": "Point", "coordinates": [ 102.568359, 17.978733 ] } }
@@ -30,22 +30,22 @@
,
{ "type": "Feature", "properties": { "NAME": "Berlin", "tippecanoe:retain_points_multiplier_sequence": 72, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 13.359375, 52.536273 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Prague", "tippecanoe:retain_points_multiplier_sequence": 59 }, "geometry": { "type": "Point", "coordinates": [ 14.501953, 50.064192 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Warsaw", "tippecanoe:retain_points_multiplier_sequence": 55 }, "geometry": { "type": "Point", "coordinates": [ 21.005859, 52.268157 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Prague", "tippecanoe:retain_points_multiplier_sequence": 59 }, "geometry": { "type": "Point", "coordinates": [ 14.501953, 50.064192 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bir Lehlou", "tippecanoe:retain_points_multiplier_sequence": 3, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -9.667969, 26.115986 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dakar", "tippecanoe:retain_points_multiplier_sequence": 70 }, "geometry": { "type": "Point", "coordinates": [ -17.490234, 14.689881 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Nouakchott", "tippecanoe:retain_points_multiplier_sequence": 39 }, "geometry": { "type": "Point", "coordinates": [ -15.996094, 18.062312 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dakar", "tippecanoe:retain_points_multiplier_sequence": 70 }, "geometry": { "type": "Point", "coordinates": [ -17.490234, 14.689881 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bucharest", "tippecanoe:retain_points_multiplier_sequence": 53, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 26.103516, 44.465151 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Chisinau", "tippecanoe:retain_points_multiplier_sequence": 26 }, "geometry": { "type": "Point", "coordinates": [ 28.828125, 46.980252 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Istanbul", "tippecanoe:retain_points_multiplier_sequence": 83 }, "geometry": { "type": "Point", "coordinates": [ 29.003906, 41.112469 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Chisinau", "tippecanoe:retain_points_multiplier_sequence": 26 }, "geometry": { "type": "Point", "coordinates": [ 28.828125, 46.980252 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Cairo", "tippecanoe:retain_points_multiplier_sequence": 87, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 31.289062, 30.069094 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Tel Aviv-Yafo", "tippecanoe:retain_points_multiplier_sequence": 61 }, "geometry": { "type": "Point", "coordinates": [ 34.804688, 32.101190 ] } }
@@ -60,10 +60,10 @@
,
{ "type": "Feature", "properties": { "NAME": "Funafuti", "tippecanoe:retain_points_multiplier_sequence": 1, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 179.208984, -8.494105 ], [ -180.791016, -8.494105 ] ] } }
,
{ "type": "Feature", "properties": { "NAME": "Suva", "tippecanoe:retain_points_multiplier_sequence": 37 }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 178.417969, -18.145852 ], [ -181.582031, -18.145852 ] ] } }
,
{ "type": "Feature", "properties": { "NAME": "Auckland", "tippecanoe:retain_points_multiplier_sequence": 71 }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 174.726562, -36.879621 ], [ -185.273438, -36.879621 ] ] } }
,
{ "type": "Feature", "properties": { "NAME": "Suva", "tippecanoe:retain_points_multiplier_sequence": 37 }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 178.417969, -18.145852 ], [ -181.582031, -18.145852 ] ] } }
,
{ "type": "Feature", "properties": { "NAME": "Guatemala", "tippecanoe:retain_points_multiplier_sequence": 35, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -90.527344, 14.604847 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Chicago", "tippecanoe:retain_points_multiplier_sequence": 65 }, "geometry": { "type": "Point", "coordinates": [ -87.714844, 41.836828 ] } }
@@ -72,16 +72,16 @@
,
{ "type": "Feature", "properties": { "NAME": "Hong Kong", "tippecanoe:retain_points_multiplier_sequence": 92, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 114.169922, 22.268764 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Shanghai", "tippecanoe:retain_points_multiplier_sequence": 88 }, "geometry": { "type": "Point", "coordinates": [ 121.464844, 31.203405 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Taipei", "tippecanoe:retain_points_multiplier_sequence": 79 }, "geometry": { "type": "Point", "coordinates": [ 121.552734, 25.005973 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Shanghai", "tippecanoe:retain_points_multiplier_sequence": 88 }, "geometry": { "type": "Point", "coordinates": [ 121.464844, 31.203405 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Jakarta", "tippecanoe:retain_points_multiplier_sequence": 86, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 106.787109, -6.140555 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dili", "tippecanoe:retain_points_multiplier_sequence": 19 }, "geometry": { "type": "Point", "coordinates": [ 125.595703, -8.581021 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Port Moresby", "tippecanoe:retain_points_multiplier_sequence": 25 }, "geometry": { "type": "Point", "coordinates": [ 147.216797, -9.449062 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dili", "tippecanoe:retain_points_multiplier_sequence": 19 }, "geometry": { "type": "Point", "coordinates": [ 125.595703, -8.581021 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Kabul", "tippecanoe:retain_points_multiplier_sequence": 78, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 69.169922, 34.524661 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Islamabad", "tippecanoe:retain_points_multiplier_sequence": 23 }, "geometry": { "type": "Point", "coordinates": [ 73.125000, 33.724340 ] } }
@@ -90,10 +90,10 @@
,
{ "type": "Feature", "properties": { "NAME": "Khartoum", "tippecanoe:retain_points_multiplier_sequence": 54, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 32.519531, 15.623037 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Juba", "tippecanoe:retain_points_multiplier_sequence": 6 }, "geometry": { "type": "Point", "coordinates": [ 31.552734, 4.828260 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Kampala", "tippecanoe:retain_points_multiplier_sequence": 21 }, "geometry": { "type": "Point", "coordinates": [ 32.607422, 0.351560 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Juba", "tippecanoe:retain_points_multiplier_sequence": 6 }, "geometry": { "type": "Point", "coordinates": [ 31.552734, 4.828260 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Kingston", "tippecanoe:retain_points_multiplier_sequence": 31, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -76.728516, 17.978733 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Port-au-Prince", "tippecanoe:retain_points_multiplier_sequence": 20 }, "geometry": { "type": "Point", "coordinates": [ -72.333984, 18.562947 ] } }
@@ -120,28 +120,28 @@
,
{ "type": "Feature", "properties": { "NAME": "Luxembourg", "tippecanoe:retain_points_multiplier_sequence": 0, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 6.152344, 49.610710 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Paris", "tippecanoe:retain_points_multiplier_sequence": 89 }, "geometry": { "type": "Point", "coordinates": [ 2.373047, 48.864715 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Andorra", "tippecanoe:retain_points_multiplier_sequence": 4 }, "geometry": { "type": "Point", "coordinates": [ 1.494141, 42.488302 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Paris", "tippecanoe:retain_points_multiplier_sequence": 89 }, "geometry": { "type": "Point", "coordinates": [ 2.373047, 48.864715 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Malabo", "tippecanoe:retain_points_multiplier_sequence": 33, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 8.789062, 3.776559 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Libreville", "tippecanoe:retain_points_multiplier_sequence": 36 }, "geometry": { "type": "Point", "coordinates": [ 9.492188, 0.351560 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Ndjamena", "tippecanoe:retain_points_multiplier_sequence": 32 }, "geometry": { "type": "Point", "coordinates": [ 15.029297, 12.125264 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Libreville", "tippecanoe:retain_points_multiplier_sequence": 36 }, "geometry": { "type": "Point", "coordinates": [ 9.492188, 0.351560 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Male", "tippecanoe:retain_points_multiplier_sequence": 48, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 73.476562, 4.127285 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Colombo", "tippecanoe:retain_points_multiplier_sequence": 27 }, "geometry": { "type": "Point", "coordinates": [ 79.892578, 6.926427 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Sri Jawewardenepura Kotte", "tippecanoe:retain_points_multiplier_sequence": 9 }, "geometry": { "type": "Point", "coordinates": [ 79.980469, 6.926427 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Colombo", "tippecanoe:retain_points_multiplier_sequence": 27 }, "geometry": { "type": "Point", "coordinates": [ 79.892578, 6.926427 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Manama", "tippecanoe:retain_points_multiplier_sequence": 16, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 50.625000, 26.273714 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Doha", "tippecanoe:retain_points_multiplier_sequence": 8 }, "geometry": { "type": "Point", "coordinates": [ 51.503906, 25.324167 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dubai", "tippecanoe:retain_points_multiplier_sequence": 66 }, "geometry": { "type": "Point", "coordinates": [ 55.283203, 25.244696 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Doha", "tippecanoe:retain_points_multiplier_sequence": 8 }, "geometry": { "type": "Point", "coordinates": [ 51.503906, 25.324167 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Maseru", "tippecanoe:retain_points_multiplier_sequence": 30, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 27.509766, -29.305561 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Pretoria", "tippecanoe:retain_points_multiplier_sequence": 24 }, "geometry": { "type": "Point", "coordinates": [ 28.212891, -25.720735 ] } }
@@ -156,10 +156,10 @@
,
{ "type": "Feature", "properties": { "NAME": "Nairobi", "tippecanoe:retain_points_multiplier_sequence": 85, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 36.826172, -1.318243 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dodoma", "tippecanoe:retain_points_multiplier_sequence": 10 }, "geometry": { "type": "Point", "coordinates": [ 35.771484, -6.140555 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dar es Salaam", "tippecanoe:retain_points_multiplier_sequence": 56 }, "geometry": { "type": "Point", "coordinates": [ 39.287109, -6.839170 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dodoma", "tippecanoe:retain_points_multiplier_sequence": 10 }, "geometry": { "type": "Point", "coordinates": [ 35.771484, -6.140555 ] } }
,
{ "type": "Feature", "properties": { "NAME": "New York", "tippecanoe:retain_points_multiplier_sequence": 81, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -74.003906, 40.780541 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Nassau", "tippecanoe:retain_points_multiplier_sequence": 50 }, "geometry": { "type": "Point", "coordinates": [ -77.343750, 25.085599 ] } }
@@ -168,28 +168,28 @@
,
{ "type": "Feature", "properties": { "NAME": "Ouagadougou", "tippecanoe:retain_points_multiplier_sequence": 46, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -1.494141, 12.382928 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Monrovia", "tippecanoe:retain_points_multiplier_sequence": 58 }, "geometry": { "type": "Point", "coordinates": [ -10.810547, 6.315299 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Yamoussoukro", "tippecanoe:retain_points_multiplier_sequence": 43 }, "geometry": { "type": "Point", "coordinates": [ -5.273438, 6.839170 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Monrovia", "tippecanoe:retain_points_multiplier_sequence": 58 }, "geometry": { "type": "Point", "coordinates": [ -10.810547, 6.315299 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Rome", "tippecanoe:retain_points_multiplier_sequence": 84, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 12.480469, 41.902277 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bratislava", "tippecanoe:retain_points_multiplier_sequence": 7 }, "geometry": { "type": "Point", "coordinates": [ 17.138672, 48.166085 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Budapest", "tippecanoe:retain_points_multiplier_sequence": 52 }, "geometry": { "type": "Point", "coordinates": [ 19.072266, 47.517201 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bratislava", "tippecanoe:retain_points_multiplier_sequence": 7 }, "geometry": { "type": "Point", "coordinates": [ 17.138672, 48.166085 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Sao Paulo", "tippecanoe:retain_points_multiplier_sequence": 91, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -46.669922, -23.563987 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Montevideo", "tippecanoe:retain_points_multiplier_sequence": 17 }, "geometry": { "type": "Point", "coordinates": [ -56.162109, -34.885931 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Rio de Janeiro", "tippecanoe:retain_points_multiplier_sequence": 90 }, "geometry": { "type": "Point", "coordinates": [ -43.242188, -22.917923 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Montevideo", "tippecanoe:retain_points_multiplier_sequence": 17 }, "geometry": { "type": "Point", "coordinates": [ -56.162109, -34.885931 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Skopje", "tippecanoe:retain_points_multiplier_sequence": 12, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 21.445312, 41.967659 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Helsinki", "tippecanoe:retain_points_multiplier_sequence": 62 }, "geometry": { "type": "Point", "coordinates": [ 24.960938, 60.196156 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Tallinn", "tippecanoe:retain_points_multiplier_sequence": 34 }, "geometry": { "type": "Point", "coordinates": [ 24.697266, 59.445075 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Helsinki", "tippecanoe:retain_points_multiplier_sequence": 62 }, "geometry": { "type": "Point", "coordinates": [ 24.960938, 60.196156 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Valletta", "tippecanoe:retain_points_multiplier_sequence": 47, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 14.501953, 35.889050 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Niamey", "tippecanoe:retain_points_multiplier_sequence": 22 }, "geometry": { "type": "Point", "coordinates": [ 2.109375, 13.496473 ] } }
@@ -18,16 +18,16 @@
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { "NAME": "Luxembourg", "tippecanoe:retain_points_multiplier_sequence": 0, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 6.152344, 49.610710 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Paris", "tippecanoe:retain_points_multiplier_sequence": 89 }, "geometry": { "type": "Point", "coordinates": [ 2.373047, 48.864715 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Andorra", "tippecanoe:retain_points_multiplier_sequence": 4 }, "geometry": { "type": "Point", "coordinates": [ 1.494141, 42.488302 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Paris", "tippecanoe:retain_points_multiplier_sequence": 89 }, "geometry": { "type": "Point", "coordinates": [ 2.373047, 48.864715 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Funafuti", "tippecanoe:retain_points_multiplier_sequence": 1, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 179.208984, -8.494105 ], [ -180.791016, -8.494105 ] ] } }
,
{ "type": "Feature", "properties": { "NAME": "Suva", "tippecanoe:retain_points_multiplier_sequence": 37 }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 178.417969, -18.145852 ], [ -181.582031, -18.145852 ] ] } }
,
{ "type": "Feature", "properties": { "NAME": "Auckland", "tippecanoe:retain_points_multiplier_sequence": 71 }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 174.726562, -36.879621 ], [ -185.273438, -36.879621 ] ] } }
,
{ "type": "Feature", "properties": { "NAME": "Suva", "tippecanoe:retain_points_multiplier_sequence": 37 }, "geometry": { "type": "MultiPoint", "coordinates": [ [ 178.417969, -18.145852 ], [ -181.582031, -18.145852 ] ] } }
,
{ "type": "Feature", "properties": { "NAME": "Melekeok", "tippecanoe:retain_points_multiplier_sequence": 2, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 134.648438, 7.449624 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Osaka", "tippecanoe:retain_points_multiplier_sequence": 73 }, "geometry": { "type": "Point", "coordinates": [ 135.439453, 34.741612 ] } }
@@ -36,16 +36,16 @@
,
{ "type": "Feature", "properties": { "NAME": "Bir Lehlou", "tippecanoe:retain_points_multiplier_sequence": 3, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -9.667969, 26.115986 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dakar", "tippecanoe:retain_points_multiplier_sequence": 70 }, "geometry": { "type": "Point", "coordinates": [ -17.490234, 14.689881 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Nouakchott", "tippecanoe:retain_points_multiplier_sequence": 39 }, "geometry": { "type": "Point", "coordinates": [ -15.996094, 18.062312 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dakar", "tippecanoe:retain_points_multiplier_sequence": 70 }, "geometry": { "type": "Point", "coordinates": [ -17.490234, 14.689881 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Skopje", "tippecanoe:retain_points_multiplier_sequence": 12, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 21.445312, 41.967659 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Helsinki", "tippecanoe:retain_points_multiplier_sequence": 62 }, "geometry": { "type": "Point", "coordinates": [ 24.960938, 60.196156 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Tallinn", "tippecanoe:retain_points_multiplier_sequence": 34 }, "geometry": { "type": "Point", "coordinates": [ 24.697266, 59.445075 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Helsinki", "tippecanoe:retain_points_multiplier_sequence": 62 }, "geometry": { "type": "Point", "coordinates": [ 24.960938, 60.196156 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Kingstown", "tippecanoe:retain_points_multiplier_sequence": 14, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -61.171875, 13.154376 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Saint George's", "tippecanoe:retain_points_multiplier_sequence": 15 }, "geometry": { "type": "Point", "coordinates": [ -61.699219, 12.039321 ] } }
@@ -54,10 +54,10 @@
,
{ "type": "Feature", "properties": { "NAME": "Manama", "tippecanoe:retain_points_multiplier_sequence": 16, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 50.625000, 26.273714 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Doha", "tippecanoe:retain_points_multiplier_sequence": 8 }, "geometry": { "type": "Point", "coordinates": [ 51.503906, 25.324167 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dubai", "tippecanoe:retain_points_multiplier_sequence": 66 }, "geometry": { "type": "Point", "coordinates": [ 55.283203, 25.244696 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Doha", "tippecanoe:retain_points_multiplier_sequence": 8 }, "geometry": { "type": "Point", "coordinates": [ 51.503906, 25.324167 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Maseru", "tippecanoe:retain_points_multiplier_sequence": 30, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 27.509766, -29.305561 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Pretoria", "tippecanoe:retain_points_multiplier_sequence": 24 }, "geometry": { "type": "Point", "coordinates": [ 28.212891, -25.720735 ] } }
@@ -72,10 +72,10 @@
,
{ "type": "Feature", "properties": { "NAME": "Malabo", "tippecanoe:retain_points_multiplier_sequence": 33, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 8.789062, 3.776559 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Libreville", "tippecanoe:retain_points_multiplier_sequence": 36 }, "geometry": { "type": "Point", "coordinates": [ 9.492188, 0.351560 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Ndjamena", "tippecanoe:retain_points_multiplier_sequence": 32 }, "geometry": { "type": "Point", "coordinates": [ 15.029297, 12.125264 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Libreville", "tippecanoe:retain_points_multiplier_sequence": 36 }, "geometry": { "type": "Point", "coordinates": [ 9.492188, 0.351560 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Guatemala", "tippecanoe:retain_points_multiplier_sequence": 35, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -90.527344, 14.604847 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Chicago", "tippecanoe:retain_points_multiplier_sequence": 65 }, "geometry": { "type": "Point", "coordinates": [ -87.714844, 41.836828 ] } }
@@ -84,16 +84,16 @@
,
{ "type": "Feature", "properties": { "NAME": "Astana", "tippecanoe:retain_points_multiplier_sequence": 41, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 71.455078, 51.179343 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Tashkent", "tippecanoe:retain_points_multiplier_sequence": 67 }, "geometry": { "type": "Point", "coordinates": [ 69.257812, 41.310824 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bishkek", "tippecanoe:retain_points_multiplier_sequence": 29 }, "geometry": { "type": "Point", "coordinates": [ 74.619141, 42.875964 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Tashkent", "tippecanoe:retain_points_multiplier_sequence": 67 }, "geometry": { "type": "Point", "coordinates": [ 69.257812, 41.310824 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Ouagadougou", "tippecanoe:retain_points_multiplier_sequence": 46, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -1.494141, 12.382928 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Monrovia", "tippecanoe:retain_points_multiplier_sequence": 58 }, "geometry": { "type": "Point", "coordinates": [ -10.810547, 6.315299 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Yamoussoukro", "tippecanoe:retain_points_multiplier_sequence": 43 }, "geometry": { "type": "Point", "coordinates": [ -5.273438, 6.839170 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Monrovia", "tippecanoe:retain_points_multiplier_sequence": 58 }, "geometry": { "type": "Point", "coordinates": [ -10.810547, 6.315299 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Valletta", "tippecanoe:retain_points_multiplier_sequence": 47, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 14.501953, 35.889050 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Niamey", "tippecanoe:retain_points_multiplier_sequence": 22 }, "geometry": { "type": "Point", "coordinates": [ 2.109375, 13.496473 ] } }
@@ -102,22 +102,22 @@
,
{ "type": "Feature", "properties": { "NAME": "Male", "tippecanoe:retain_points_multiplier_sequence": 48, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 73.476562, 4.127285 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Colombo", "tippecanoe:retain_points_multiplier_sequence": 27 }, "geometry": { "type": "Point", "coordinates": [ 79.892578, 6.926427 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Sri Jawewardenepura Kotte", "tippecanoe:retain_points_multiplier_sequence": 9 }, "geometry": { "type": "Point", "coordinates": [ 79.980469, 6.926427 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Colombo", "tippecanoe:retain_points_multiplier_sequence": 27 }, "geometry": { "type": "Point", "coordinates": [ 79.892578, 6.926427 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bucharest", "tippecanoe:retain_points_multiplier_sequence": 53, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 26.103516, 44.465151 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Chisinau", "tippecanoe:retain_points_multiplier_sequence": 26 }, "geometry": { "type": "Point", "coordinates": [ 28.828125, 46.980252 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Istanbul", "tippecanoe:retain_points_multiplier_sequence": 83 }, "geometry": { "type": "Point", "coordinates": [ 29.003906, 41.112469 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Chisinau", "tippecanoe:retain_points_multiplier_sequence": 26 }, "geometry": { "type": "Point", "coordinates": [ 28.828125, 46.980252 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Khartoum", "tippecanoe:retain_points_multiplier_sequence": 54, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 32.519531, 15.623037 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Juba", "tippecanoe:retain_points_multiplier_sequence": 6 }, "geometry": { "type": "Point", "coordinates": [ 31.552734, 4.828260 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Kampala", "tippecanoe:retain_points_multiplier_sequence": 21 }, "geometry": { "type": "Point", "coordinates": [ 32.607422, 0.351560 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Juba", "tippecanoe:retain_points_multiplier_sequence": 6 }, "geometry": { "type": "Point", "coordinates": [ 31.552734, 4.828260 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dublin", "tippecanoe:retain_points_multiplier_sequence": 57, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -6.240234, 53.330873 ] } }
,
{ "type": "Feature", "properties": { "NAME": "London", "tippecanoe:retain_points_multiplier_sequence": 82 }, "geometry": { "type": "Point", "coordinates": [ -0.087891, 51.508742 ] } }
@@ -138,10 +138,10 @@
,
{ "type": "Feature", "properties": { "NAME": "Berlin", "tippecanoe:retain_points_multiplier_sequence": 72, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 13.359375, 52.536273 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Prague", "tippecanoe:retain_points_multiplier_sequence": 59 }, "geometry": { "type": "Point", "coordinates": [ 14.501953, 50.064192 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Warsaw", "tippecanoe:retain_points_multiplier_sequence": 55 }, "geometry": { "type": "Point", "coordinates": [ 21.005859, 52.268157 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Prague", "tippecanoe:retain_points_multiplier_sequence": 59 }, "geometry": { "type": "Point", "coordinates": [ 14.501953, 50.064192 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Kinshasa", "tippecanoe:retain_points_multiplier_sequence": 74, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 15.292969, -4.302591 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Luanda", "tippecanoe:retain_points_multiplier_sequence": 63 }, "geometry": { "type": "Point", "coordinates": [ 13.271484, -8.841651 ] } }
@@ -168,22 +168,22 @@
,
{ "type": "Feature", "properties": { "NAME": "Rome", "tippecanoe:retain_points_multiplier_sequence": 84, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 12.480469, 41.902277 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bratislava", "tippecanoe:retain_points_multiplier_sequence": 7 }, "geometry": { "type": "Point", "coordinates": [ 17.138672, 48.166085 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Budapest", "tippecanoe:retain_points_multiplier_sequence": 52 }, "geometry": { "type": "Point", "coordinates": [ 19.072266, 47.517201 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Bratislava", "tippecanoe:retain_points_multiplier_sequence": 7 }, "geometry": { "type": "Point", "coordinates": [ 17.138672, 48.166085 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Nairobi", "tippecanoe:retain_points_multiplier_sequence": 85, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 36.826172, -1.318243 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dodoma", "tippecanoe:retain_points_multiplier_sequence": 10 }, "geometry": { "type": "Point", "coordinates": [ 35.771484, -6.140555 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dar es Salaam", "tippecanoe:retain_points_multiplier_sequence": 56 }, "geometry": { "type": "Point", "coordinates": [ 39.287109, -6.839170 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dodoma", "tippecanoe:retain_points_multiplier_sequence": 10 }, "geometry": { "type": "Point", "coordinates": [ 35.771484, -6.140555 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Jakarta", "tippecanoe:retain_points_multiplier_sequence": 86, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 106.787109, -6.140555 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dili", "tippecanoe:retain_points_multiplier_sequence": 19 }, "geometry": { "type": "Point", "coordinates": [ 125.595703, -8.581021 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Port Moresby", "tippecanoe:retain_points_multiplier_sequence": 25 }, "geometry": { "type": "Point", "coordinates": [ 147.216797, -9.449062 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Dili", "tippecanoe:retain_points_multiplier_sequence": 19 }, "geometry": { "type": "Point", "coordinates": [ 125.595703, -8.581021 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Cairo", "tippecanoe:retain_points_multiplier_sequence": 87, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 31.289062, 30.069094 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Tel Aviv-Yafo", "tippecanoe:retain_points_multiplier_sequence": 61 }, "geometry": { "type": "Point", "coordinates": [ 34.804688, 32.101190 ] } }
@@ -192,15 +192,15 @@
,
{ "type": "Feature", "properties": { "NAME": "Sao Paulo", "tippecanoe:retain_points_multiplier_sequence": 91, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ -46.669922, -23.563987 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Montevideo", "tippecanoe:retain_points_multiplier_sequence": 17 }, "geometry": { "type": "Point", "coordinates": [ -56.162109, -34.885931 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Rio de Janeiro", "tippecanoe:retain_points_multiplier_sequence": 90 }, "geometry": { "type": "Point", "coordinates": [ -43.242188, -22.917923 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Montevideo", "tippecanoe:retain_points_multiplier_sequence": 17 }, "geometry": { "type": "Point", "coordinates": [ -56.162109, -34.885931 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Hong Kong", "tippecanoe:retain_points_multiplier_sequence": 92, "tippecanoe:retain_points_multiplier_first": true }, "geometry": { "type": "Point", "coordinates": [ 114.169922, 22.268764 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Shanghai", "tippecanoe:retain_points_multiplier_sequence": 88 }, "geometry": { "type": "Point", "coordinates": [ 121.464844, 31.203405 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Taipei", "tippecanoe:retain_points_multiplier_sequence": 79 }, "geometry": { "type": "Point", "coordinates": [ 121.552734, 25.005973 ] } }
,
{ "type": "Feature", "properties": { "NAME": "Shanghai", "tippecanoe:retain_points_multiplier_sequence": 88 }, "geometry": { "type": "Point", "coordinates": [ 121.464844, 31.203405 ] } }
] }
] }
] }
+28
View File
@@ -225,3 +225,31 @@ unsigned long long fnv1a(size_t size, void *p) {
}
return h;
}
// This function reverses the order of the bits in a 64-bit word.
// Instead of shifting individual bits in a loop, it shifts them
// in blocks, starting with swapping the halfwords, and working downward
// until it is swapping individual pairs of adjacent bits.
//
// The purpose is to permute the order in which features are visited:
// instead of working in an orderly fashion from the top left to the
// bottom right of the tile, instead jump around to minimize adjacency,
// like a hash function, but taking advantage of the knowledge that we
// are operating on a fixed-size input that can be directly inverted.
// https://en.wikipedia.org/wiki/Bit-reversal_permutation
//
// This allows calculating an appropriate set of features to appear
// at a fractional zoom level: at what is effectively z4.25, for example,
// we can bring in a quarter of the features that will be added in the
// transition from z4 to z5, and have them be spatially distributed
// across the tile rather than clumped together.
unsigned long long bit_reverse(unsigned long long v) {
v = ((v & 0x00000000FFFFFFFF) << 32) | ((v & 0xFFFFFFFF00000000) >> 32);
v = ((v & 0x0000FFFF0000FFFF) << 16) | ((v & 0xFFFF0000FFFF0000) >> 16);
v = ((v & 0x00FF00FF00FF00FF) << 8) | ((v & 0xFF00FF00FF00FF00) >> 8);
v = ((v & 0x0F0F0F0F0F0F0F0F) << 4) | ((v & 0xF0F0F0F0F0F0F0F0) >> 4);
v = ((v & 0x3333333333333333) << 2) | ((v & 0xCCCCCCCCCCCCCCCC) >> 2);
v = ((v & 0x5555555555555555) << 1) | ((v & 0xAAAAAAAAAAAAAAAA) >> 1);
return v;
}
+1
View File
@@ -11,5 +11,6 @@ std::string format_commandline(int argc, char **argv);
unsigned long long fnv1a(std::string const &s);
unsigned long long fnv1a(const char *s, char additional);
unsigned long long fnv1a(size_t size, void *p);
unsigned long long bit_reverse(unsigned long long v);
#endif
+234 -154
View File
@@ -199,6 +199,22 @@ struct coalindexcmp_comparator {
}
};
static unsigned long long calculate_drop_sequence(serial_feature const &sf);
struct drop_sequence_cmp {
bool operator()(const serial_feature &a, const serial_feature &b) {
unsigned long long a_seq = calculate_drop_sequence(a);
unsigned long long b_seq = calculate_drop_sequence(b);
// sorts backwards, to put the features that would be dropped last, first here
if (a_seq > b_seq) {
return true;
} else {
return false;
}
}
};
// retrieve an attribute key or value from the string pool and return it as mvt_value
static mvt_value retrieve_string(long long off, const char *stringpool, std::shared_ptr<std::string> const &tile_stringpool) {
int type = stringpool[off];
@@ -408,6 +424,11 @@ static std::vector<serial_feature> disassemble_multiplier_clusters(std::vector<s
}
}
// sort the other features by their drop sequence, for consistency across zoom levels
if (cluster.size() > 1) {
std::sort(cluster.begin() + 1, cluster.end(), drop_sequence_cmp());
}
for (auto const &feature : cluster) {
out.push_back(std::move(feature));
}
@@ -673,7 +694,9 @@ static void *simplification_worker(void *v) {
to_tile_scale(geom, z, out_detail);
}
(*features)[i].index = i;
if ((*features)[i].index == 0) {
(*features)[i].index = i;
}
(*features)[i].geometry = std::move(geom);
}
@@ -801,6 +824,28 @@ static long long choose_minextent(std::vector<long long> &extents, double f, lon
return extents[ix];
}
static unsigned long long choose_mindrop_sequence(std::vector<unsigned long long> &drop_sequences, double f, unsigned long long existing_drop_sequence) {
if (drop_sequences.size() == 0) {
return ULLONG_MAX;
}
std::sort(drop_sequences.begin(), drop_sequences.end());
size_t ix = (drop_sequences.size() - 1) * (1 - f);
while (ix + 1 < drop_sequences.size() && drop_sequences[ix] == existing_drop_sequence) {
ix++;
}
return drop_sequences[ix];
}
static unsigned long long calculate_drop_sequence(serial_feature const &sf) {
unsigned long long zoom = std::min(std::max((unsigned long long) sf.feature_minzoom, 0ULL), 31ULL);
unsigned long long out = zoom << (64 - 5); // top bits are the zoom level: top-priority features are those that appear in the low zooms
out |= bit_reverse(sf.index) & ~(31ULL << (64 - 5)); // remaining bits are from the inverted indes, which should incrementally fill in spatially
return ~out; // lowest numbered feature gets dropped first
}
// This is the block of parameters that are passed to write_tile() to read a tile
// from the serialized form, do whatever needs to be done to it, and to write the
// MVT-format output to the output tileset.
@@ -846,8 +891,8 @@ struct write_tile_args {
unsigned long long mingap_out = 0;
long long minextent = 0;
long long minextent_out = 0;
double fraction = 0;
double fraction_out = 0;
unsigned long long mindrop_sequence = 0;
unsigned long long mindrop_sequence_out = 0;
size_t tile_size_out = 0;
size_t feature_count_out = 0;
const char *prefilter = NULL;
@@ -976,7 +1021,7 @@ static void remove_attributes(serial_feature &sf, std::set<std::string> const &e
// --accumulate-attribute option so that features' attributes can be averaged in
// without knowing their total count in advance.
struct multiplier_state {
std::map<std::string, size_t> count;
std::map<std::string, int> count;
};
// This function is called repeatedly from write_tile() to retrieve the next feature
@@ -1113,30 +1158,29 @@ static serial_feature next_feature(decompressor *geoms, std::atomic<long long> *
}
if (sf.tippecanoe_minzoom == -1) {
bool keep = false;
sf.dropped = FEATURE_DROPPED; // dropped
std::string &layername = (*layer_unmaps)[sf.segment][sf.layer];
auto count = multiplier_state->count.find(layername);
if (count == multiplier_state->count.end()) {
multiplier_state->count.emplace(layername, 0);
count = multiplier_state->count.find(layername);
keep = true; // the first feature in each layer in each tile is always kept
sf.dropped = FEATURE_KEPT; // the first feature in each tile is always kept
}
sf.dropped = true;
if (z >= sf.feature_minzoom || keep) {
count->second = retain_points_multiplier;
if (z >= sf.feature_minzoom || sf.dropped == FEATURE_KEPT) {
count->second = 0;
sf.dropped = FEATURE_KEPT; // feature is kept
if (retain_points_multiplier > 1) {
sf.full_keys.push_back("tippecanoe:retain_points_multiplier_first");
sf.full_values.emplace_back(mvt_bool, "true");
}
}
if (count->second > 0) {
sf.dropped = false;
count->second -= 1;
} else if (count->second + 1 < retain_points_multiplier) {
count->second++;
sf.dropped = count->second;
} else {
sf.dropped = FEATURE_DROPPED;
}
}
@@ -1402,16 +1446,16 @@ void add_sample_to(std::vector<T> &vals, T val, size_t &increment, size_t seq) {
}
void coalesce_geometry(serial_feature &p, serial_feature &sf) {
// XXX need another way to deduplicate here
// XXX need another way to deduplicate here
#if 0
// if the geometry being coalesced on is an exact duplicate
// of an existing geometry, just drop it
// if the geometry being coalesced on is an exact duplicate
// of an existing geometry, just drop it
for (size_t i = 0; i < p.geometries.size(); i++) {
if (p.geometries[i] == sf.geometry) {
return;
}
}
for (size_t i = 0; i < p.geometries.size(); i++) {
if (p.geometries[i] == sf.geometry) {
return;
}
}
#endif
size_t s = p.geometry.size();
@@ -1421,10 +1465,11 @@ void coalesce_geometry(serial_feature &p, serial_feature &sf) {
}
}
long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, char *global_stringpool, int z, const unsigned tx, const unsigned ty, const int detail, int min_detail, sqlite3 *outdb, const char *outdir, int buffer, const char *fname, compressor **geomfile, int minzoom, int maxzoom, double todo, std::atomic<long long> *along, long long alongminus, double gamma, int child_shards, long long *pool_off, unsigned *initial_x, unsigned *initial_y, std::atomic<int> *running, double simplification, std::vector<std::map<std::string, layermap_entry>> *layermaps, std::vector<std::vector<std::string>> *layer_unmaps, size_t tiling_seg, size_t pass, unsigned long long mingap, long long minextent, double fraction, const char *prefilter, const char *postfilter, json_object *filter, write_tile_args *arg, atomic_strategy *strategy, bool compressed_input, node *shared_nodes_map, size_t nodepos) {
long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, char *global_stringpool, int z, const unsigned tx, const unsigned ty, const int detail, int min_detail, sqlite3 *outdb, const char *outdir, int buffer, const char *fname, compressor **geomfile, int minzoom, int maxzoom, double todo, std::atomic<long long> *along, long long alongminus, double gamma, int child_shards, long long *pool_off, unsigned *initial_x, unsigned *initial_y, std::atomic<int> *running, double simplification, std::vector<std::map<std::string, layermap_entry>> *layermaps, std::vector<std::vector<std::string>> *layer_unmaps, size_t tiling_seg, size_t pass, unsigned long long mingap, long long minextent, unsigned long long mindrop_sequence, const char *prefilter, const char *postfilter, json_object *filter, write_tile_args *arg, atomic_strategy *strategy, bool compressed_input, node *shared_nodes_map, size_t nodepos) {
double merge_fraction = 1;
double mingap_fraction = 1;
double minextent_fraction = 1;
double mindrop_sequence_fraction = 1;
// allow larger tile sizes at low zooms when the retain-points-multiplier
// is intended to allow more points through. scale back down toward a
@@ -1471,8 +1516,6 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
long long count = 0;
double accum_area = 0;
double fraction_accum = 0;
unsigned long long previndex = 0, density_previndex = 0, merge_previndex = 0;
unsigned long long extent_previndex = 0;
double scale = (double) (1LL << (64 - 2 * (z + 8)));
@@ -1487,6 +1530,8 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
std::vector<unsigned long long> indices;
std::vector<long long> extents;
size_t extents_increment = 1;
std::vector<unsigned long long> drop_sequences;
size_t drop_sequences_increment = 1;
double coalesced_area = 0;
drawvec shared_nodes;
@@ -1599,6 +1644,8 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
struct multiplier_state multiplier_state;
size_t multiplier_seq = retain_points_multiplier - 1;
bool drop_rest = false; // are we dropping the remainder of a multiplier cluster whose first point was dropped?
for (size_t seq = 0;; seq++) {
serial_feature sf;
ssize_t which_serial_feature = -1;
@@ -1633,7 +1680,18 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
extent_previndex = sf.index;
}
if (sf.dropped) {
unsigned long long drop_sequence = 0;
if (additional[A_COALESCE_FRACTION_AS_NEEDED] || additional[A_DROP_FRACTION_AS_NEEDED] || prevent[P_DYNAMIC_DROP]) {
drop_sequence = calculate_drop_sequence(sf);
}
if (sf.dropped == FEATURE_KEPT) {
// this is a new multiplier cluster, so stop dropping features
// that were dropped because the previous lead feature was dropped
drop_rest = false;
}
if (sf.dropped == FEATURE_DROPPED || drop_rest) {
multiplier_seq = (multiplier_seq + 1) % retain_points_multiplier;
if (find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
@@ -1645,83 +1703,114 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
multiplier_seq = retain_points_multiplier - 1;
}
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, multiplier_seq)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->dropped_by_gamma++;
continue;
}
}
// Cap the indices, rather than sampling them like extents (areas),
// because choose_mingap cares about the distance between *surviving*
// features, not between *original* features, so we can't just store
// gaps rather than indices to be able to downsample them fairly.
// Hopefully the first 100K features in the tile are reasonably
// representative of the other features in the tile.
const size_t MAX_INDICES = 100000;
if (z <= cluster_maxzoom && (additional[A_CLUSTER_DENSEST_AS_NEEDED] || cluster_distance != 0)) {
if (indices.size() < MAX_INDICES) {
indices.push_back(sf.index);
}
if ((sf.index < merge_previndex || sf.index - merge_previndex < mingap) && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
features[which_serial_feature].clustered++;
if (features[which_serial_feature].t == VT_POINT &&
features[which_serial_feature].geometry.size() == 1 &&
sf.geometry.size() == 1) {
double x = (double) features[which_serial_feature].geometry[0].x * features[which_serial_feature].clustered;
double y = (double) features[which_serial_feature].geometry[0].y * features[which_serial_feature].clustered;
x += sf.geometry[0].x;
y += sf.geometry[0].y;
features[which_serial_feature].geometry[0].x = x / (features[which_serial_feature].clustered + 1);
features[which_serial_feature].geometry[0].y = y / (features[which_serial_feature].clustered + 1);
// only the first point of a multiplier cluster can be dropped
// by any of these mechanisms. (but if one is, it drags the whole
// cluster down with it by setting drop_rest).
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, multiplier_seq)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->dropped_by_gamma++;
drop_rest = true;
continue;
}
}
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->coalesced_as_needed++;
continue;
}
} else if (additional[A_DROP_DENSEST_AS_NEEDED]) {
if (indices.size() < MAX_INDICES) {
indices.push_back(sf.index);
}
if (sf.index - merge_previndex < mingap && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->dropped_as_needed++;
continue;
}
} else if (additional[A_COALESCE_DENSEST_AS_NEEDED]) {
if (indices.size() < MAX_INDICES) {
indices.push_back(sf.index);
}
if (sf.index - merge_previndex < mingap && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
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]);
strategy->coalesced_as_needed++;
continue;
}
} else if (additional[A_DROP_SMALLEST_AS_NEEDED]) {
add_sample_to(extents, sf.extent, extents_increment, seq);
// search here is for LLONG_MAX, not minextent, because we are dropping features, not coalescing them,
// so we shouldn't expect to find anything small that we can related this feature to.
if (minextent != 0 && sf.extent + coalesced_area <= minextent && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->dropped_as_needed++;
continue;
}
} else if (additional[A_COALESCE_SMALLEST_AS_NEEDED]) {
add_sample_to(extents, sf.extent, extents_increment, seq);
if (minextent != 0 && sf.extent + coalesced_area <= minextent && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, minextent, multiplier_seq)) {
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]);
strategy->coalesced_as_needed++;
continue;
// Cap the indices, rather than sampling them like extents (areas),
// because choose_mingap cares about the distance between *surviving*
// features, not between *original* features, so we can't just store
// gaps rather than indices to be able to downsample them fairly.
// Hopefully the first 100K features in the tile are reasonably
// representative of the other features in the tile.
const size_t MAX_INDICES = 100000;
if (z <= cluster_maxzoom && (additional[A_CLUSTER_DENSEST_AS_NEEDED] || cluster_distance != 0)) {
if (indices.size() < MAX_INDICES) {
indices.push_back(sf.index);
}
if ((sf.index < merge_previndex || sf.index - merge_previndex < mingap) && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
features[which_serial_feature].clustered++;
if (features[which_serial_feature].t == VT_POINT &&
features[which_serial_feature].geometry.size() == 1 &&
sf.geometry.size() == 1) {
double x = (double) features[which_serial_feature].geometry[0].x * features[which_serial_feature].clustered;
double y = (double) features[which_serial_feature].geometry[0].y * features[which_serial_feature].clustered;
x += sf.geometry[0].x;
y += sf.geometry[0].y;
features[which_serial_feature].geometry[0].x = x / (features[which_serial_feature].clustered + 1);
features[which_serial_feature].geometry[0].y = y / (features[which_serial_feature].clustered + 1);
}
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->coalesced_as_needed++;
drop_rest = true;
continue;
}
} else if (additional[A_DROP_DENSEST_AS_NEEDED]) {
if (indices.size() < MAX_INDICES) {
indices.push_back(sf.index);
}
if (sf.index - merge_previndex < mingap && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->dropped_as_needed++;
drop_rest = true;
continue;
}
} else if (additional[A_COALESCE_DENSEST_AS_NEEDED]) {
if (indices.size() < MAX_INDICES) {
indices.push_back(sf.index);
}
if (sf.index - merge_previndex < mingap && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
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]);
strategy->coalesced_as_needed++;
drop_rest = true;
continue;
}
} else if (additional[A_DROP_SMALLEST_AS_NEEDED]) {
add_sample_to(extents, sf.extent, extents_increment, seq);
// search here is for LLONG_MAX, not minextent, because we are dropping features, not coalescing them,
// so we shouldn't expect to find anything small that we can related this feature to.
if (minextent != 0 && sf.extent + coalesced_area <= minextent && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->dropped_as_needed++;
drop_rest = true;
continue;
}
} else if (additional[A_COALESCE_SMALLEST_AS_NEEDED]) {
add_sample_to(extents, sf.extent, extents_increment, seq);
if (minextent != 0 && sf.extent + coalesced_area <= minextent && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, minextent, multiplier_seq)) {
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]);
strategy->coalesced_as_needed++;
drop_rest = true;
continue;
}
} else if (additional[A_DROP_FRACTION_AS_NEEDED] || prevent[P_DYNAMIC_DROP]) {
add_sample_to(drop_sequences, drop_sequence, drop_sequences_increment, seq);
// search here is for LLONG_MAX, not minextent, because we are dropping features, not coalescing them,
// so we shouldn't expect to find anything small that we can related this feature to.
if (mindrop_sequence != 0 && drop_sequence <= mindrop_sequence && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->dropped_as_needed++;
drop_rest = true;
continue;
}
} else if (additional[A_COALESCE_FRACTION_AS_NEEDED]) {
add_sample_to(drop_sequences, drop_sequence, drop_sequences_increment, seq);
if (mindrop_sequence != 0 && drop_sequence <= mindrop_sequence && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
coalesce_geometry(features[which_serial_feature], sf);
features[which_serial_feature].coalesced = true;
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
strategy->coalesced_as_needed++;
drop_rest = true;
continue;
}
}
}
@@ -1737,21 +1826,6 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
}
}
fraction_accum += fraction;
if (fraction_accum < 1 && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
if (additional[A_COALESCE_FRACTION_AS_NEEDED]) {
coalesce_geometry(features[which_serial_feature], sf);
features[which_serial_feature].coalesced = true;
coalesced_area += sf.extent;
strategy->coalesced_as_needed++;
} else {
strategy->dropped_as_needed++;
}
preserve_attributes(arg->attribute_accum, sf, features[which_serial_feature]);
continue;
}
fraction_accum -= 1;
bool still_need_simplification_after_reduction = false;
if (sf.t == VT_POLYGON) {
bool simplified_away_by_reduction = false;
@@ -2271,22 +2345,26 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
line_detail++;
continue;
}
} else if (totalsize > layers.size() && (prevent[P_DYNAMIC_DROP] || additional[A_DROP_FRACTION_AS_NEEDED] || additional[A_COALESCE_FRACTION_AS_NEEDED])) {
} else if (totalsize > layers.size() && (additional[A_DROP_FRACTION_AS_NEEDED] || additional[A_COALESCE_FRACTION_AS_NEEDED] || prevent[P_DYNAMIC_DROP])) {
// The 95% is a guess to avoid too many retries
// and probably actually varies based on how much duplicated metadata there is
fraction = fraction * max_tile_features / totalsize * 0.95;
if (!quiet) {
fprintf(stderr, "Going to try keeping %0.2f%% of the features to make it fit\n", fraction * 100);
mindrop_sequence_fraction = mindrop_sequence_fraction * max_tile_features / totalsize * 0.95;
unsigned long long m = choose_mindrop_sequence(drop_sequences, mindrop_sequence_fraction, mindrop_sequence);
if (m != mindrop_sequence) {
mindrop_sequence = m;
if (mindrop_sequence > arg->mindrop_sequence_out) {
if (!prevent[P_DYNAMIC_DROP]) {
arg->mindrop_sequence_out = mindrop_sequence;
}
arg->still_dropping = true;
}
if (!quiet) {
fprintf(stderr, "Going to try keeping %0.2f%% of the features to make it fit\n", mindrop_sequence_fraction * 100.0);
}
line_detail++; // to keep it the same when the loop decrements it
continue;
}
if ((additional[A_DROP_FRACTION_AS_NEEDED] || additional[A_COALESCE_FRACTION_AS_NEEDED]) && fraction < arg->fraction_out) {
arg->fraction_out = fraction;
arg->still_dropping = true;
} else if (prevent[P_DYNAMIC_DROP]) {
arg->still_dropping = true;
}
line_detail++; // to keep it the same when the loop decrements it
continue;
} else {
fprintf(stderr, "Try using --drop-fraction-as-needed or --drop-densest-as-needed.\n");
return -1;
@@ -2379,21 +2457,23 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
line_detail++;
continue;
}
} else if (totalsize > layers.size() && (prevent[P_DYNAMIC_DROP] || additional[A_DROP_FRACTION_AS_NEEDED] || additional[A_COALESCE_FRACTION_AS_NEEDED])) {
// The 95% is a guess to avoid too many retries
// and probably actually varies based on how much duplicated metadata there is
fraction = fraction * scaled_max_tile_size / (kept_adjust * compressed.size()) * 0.95;
if (!quiet) {
fprintf(stderr, "Going to try keeping %0.2f%% of the features to make it fit\n", fraction * 100);
} else if (totalsize > layers.size() && (additional[A_DROP_FRACTION_AS_NEEDED] || additional[A_COALESCE_FRACTION_AS_NEEDED] || prevent[P_DYNAMIC_DROP])) {
mindrop_sequence_fraction = mindrop_sequence_fraction * scaled_max_tile_size / (kept_adjust * compressed.size()) * 0.75;
unsigned long long m = choose_mindrop_sequence(drop_sequences, mindrop_sequence_fraction, mindrop_sequence);
if (m != mindrop_sequence) {
mindrop_sequence = m;
if (mindrop_sequence > arg->mindrop_sequence_out) {
if (!prevent[P_DYNAMIC_DROP]) {
arg->mindrop_sequence_out = mindrop_sequence;
}
arg->still_dropping = true;
}
if (!quiet) {
fprintf(stderr, "Going to try keeping %0.2f%% of the features to make it fit\n", mindrop_sequence_fraction * 100.0);
}
line_detail++;
continue;
}
if ((additional[A_DROP_FRACTION_AS_NEEDED] || additional[A_COALESCE_FRACTION_AS_NEEDED]) && fraction < arg->fraction_out) {
arg->fraction_out = fraction;
arg->still_dropping = true;
} else if (prevent[P_DYNAMIC_DROP]) {
arg->still_dropping = true;
}
line_detail++; // to keep it the same when the loop decrements it
} else {
strategy->detail_reduced++;
}
@@ -2480,11 +2560,11 @@ void *run_thread(void *vargs) {
dc.deserialize_uint(&x, &geompos);
dc.deserialize_uint(&y, &geompos);
#if 0
// currently broken because also requires tracking nextzoom when skipping zooms
if (z != arg->zoom) {
fprintf(stderr, "Expected zoom %d, found zoom %d\n", arg->zoom, z);
exit(EXIT_IMPOSSIBLE);
}
// currently broken because also requires tracking nextzoom when skipping zooms
if (z != arg->zoom) {
fprintf(stderr, "Expected zoom %d, found zoom %d\n", arg->zoom, z);
exit(EXIT_IMPOSSIBLE);
}
#endif
if (arg->compressed) {
@@ -2495,7 +2575,7 @@ void *run_thread(void *vargs) {
// fprintf(stderr, "%d/%u/%u\n", z, x, y);
long long len = write_tile(&dc, &geompos, arg->global_stringpool, z, x, y, z == arg->maxzoom ? arg->full_detail : arg->low_detail, arg->min_detail, arg->outdb, arg->outdir, arg->buffer, arg->fname, arg->geomfile, arg->minzoom, arg->maxzoom, arg->todo, arg->along, geompos, arg->gamma, arg->child_shards, arg->pool_off, arg->initial_x, arg->initial_y, arg->running, arg->simplification, arg->layermaps, arg->layer_unmaps, arg->tiling_seg, arg->pass, arg->mingap, arg->minextent, arg->fraction, arg->prefilter, arg->postfilter, arg->filter, arg, arg->strategy, arg->compressed, arg->shared_nodes_map, arg->nodepos);
long long len = write_tile(&dc, &geompos, arg->global_stringpool, z, x, y, z == arg->maxzoom ? arg->full_detail : arg->low_detail, arg->min_detail, arg->outdb, arg->outdir, arg->buffer, arg->fname, arg->geomfile, arg->minzoom, arg->maxzoom, arg->todo, arg->along, geompos, arg->gamma, arg->child_shards, arg->pool_off, arg->initial_x, arg->initial_y, arg->running, arg->simplification, arg->layermaps, arg->layer_unmaps, arg->tiling_seg, arg->pass, arg->mingap, arg->minextent, arg->mindrop_sequence, arg->prefilter, arg->postfilter, arg->filter, arg, arg->strategy, arg->compressed, arg->shared_nodes_map, arg->nodepos);
if (pthread_mutex_lock(&var_lock) != 0) {
perror("pthread_mutex_lock");
@@ -2697,7 +2777,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *global_stringpool, std::
double zoom_gamma = gamma;
unsigned long long zoom_mingap = ((1LL << (32 - z)) / 256 * cluster_distance) * ((1LL << (32 - z)) / 256 * cluster_distance);
long long zoom_minextent = 0;
double zoom_fraction = 1;
unsigned long long zoom_mindrop_sequence = 0;
size_t zoom_tile_size = 0;
size_t zoom_feature_count = 0;
@@ -2725,8 +2805,8 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *global_stringpool, std::
args[thread].mingap_out = zoom_mingap;
args[thread].minextent = zoom_minextent;
args[thread].minextent_out = zoom_minextent;
args[thread].fraction = zoom_fraction;
args[thread].fraction_out = zoom_fraction;
args[thread].mindrop_sequence = zoom_mindrop_sequence;
args[thread].mindrop_sequence_out = zoom_mindrop_sequence;
args[thread].tile_size_out = 0;
args[thread].feature_count_out = 0;
args[thread].child_shards = TEMP_FILES / threads;
@@ -2801,8 +2881,8 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *global_stringpool, std::
zoom_minextent = args[thread].minextent_out;
again = true;
}
if (args[thread].fraction_out < zoom_fraction) {
zoom_fraction = args[thread].fraction_out;
if (args[thread].mindrop_sequence_out > zoom_mindrop_sequence) {
zoom_mindrop_sequence = args[thread].mindrop_sequence_out;
again = true;
}
if (args[thread].tile_size_out > zoom_tile_size) {
+6
View File
@@ -99,3 +99,9 @@ TEST_CASE("Tile-join cache", "tile cache") {
REQUIRE(tc.overzoom_cache.size() == 5);
REQUIRE(tc.overzoom_cache.find(zxy(11, 5, 8)) == tc.overzoom_cache.end());
}
TEST_CASE("Bit reversal", "bit reversal") {
REQUIRE(bit_reverse(1) == 0x8000000000000000);
REQUIRE(bit_reverse(0x1234567812489BCF) == 0xF3D912481E6A2C48);
REQUIRE(bit_reverse(0xF3D912481E6A2C48) == 0x1234567812489BCF);
}
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef VERSION_HPP
#define VERSION_HPP
#define VERSION "v2.42.0"
#define VERSION "v2.43.0"
#endif
+4 -3
View File
@@ -15,6 +15,7 @@
#include "write_json.hpp"
#include "milo/dtoa_milo.h"
#include "errors.hpp"
#include "serial.hpp"
void json_writer::json_adjust() {
if (state.size() == 0) {
@@ -267,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 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) {
for (size_t f = 0; f < layer.features.size(); f++) {
mvt_feature const &feat = layer.features[f];
@@ -297,9 +298,9 @@ void layer_to_geojson(mvt_layer const &layer, unsigned z, unsigned x, unsigned y
state.json_write_unsigned(z);
}
if (dropped) {
if (write_dropped) {
state.json_write_string("dropped");
state.json_write_bool(feat.dropped);
state.json_write_bool(feat.dropped == FEATURE_DROPPED);
}
if (index != 0) {