Skip to content

Commit 459aef1

Browse files
committed
Try adding --drop-sparsest-as-needed
1 parent d891ca7 commit 459aef1

File tree

4 files changed

+64
-7
lines changed

4 files changed

+64
-7
lines changed

main.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -3113,9 +3113,11 @@ int main(int argc, char **argv) {
31133113
{"drop-densest-as-needed", no_argument, &additional[A_DROP_DENSEST_AS_NEEDED], 1},
31143114
{"drop-fraction-as-needed", no_argument, &additional[A_DROP_FRACTION_AS_NEEDED], 1},
31153115
{"drop-smallest-as-needed", no_argument, &additional[A_DROP_SMALLEST_AS_NEEDED], 1},
3116+
{"drop-sparsest-as-needed", no_argument, &additional[A_DROP_SPARSEST_AS_NEEDED], 1},
31163117
{"coalesce-densest-as-needed", no_argument, &additional[A_COALESCE_DENSEST_AS_NEEDED], 1},
31173118
{"coalesce-fraction-as-needed", no_argument, &additional[A_COALESCE_FRACTION_AS_NEEDED], 1},
31183119
{"coalesce-smallest-as-needed", no_argument, &additional[A_COALESCE_SMALLEST_AS_NEEDED], 1},
3120+
{"coalesce-sparsest-as-needed", no_argument, &additional[A_COALESCE_SPARSEST_AS_NEEDED], 1},
31193121
{"force-feature-limit", no_argument, &prevent[P_DYNAMIC_DROP], 1},
31203122
{"cluster-densest-as-needed", no_argument, &additional[A_CLUSTER_DENSEST_AS_NEEDED], 1},
31213123

options.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
#define A_DROP_DENSEST_AS_NEEDED ((int) 's')
1515
#define A_DROP_FRACTION_AS_NEEDED ((int) 'd')
1616
#define A_DROP_SMALLEST_AS_NEEDED ((int) 'n')
17+
#define A_DROP_SPARSEST_AS_NEEDED ((int) 's' & 0x1F)
1718
#define A_COALESCE_DENSEST_AS_NEEDED ((int) 'S')
1819
#define A_COALESCE_SMALLEST_AS_NEEDED ((int) 'N')
1920
#define A_COALESCE_FRACTION_AS_NEEDED ((int) 'D')
21+
#define A_COALESCE_SPARSEST_AS_NEEDED ((int) 't' & 0x1F)
2022
#define A_GRID_LOW_ZOOMS ((int) 'L')
2123
#define A_DETECT_WRAPAROUND ((int) 'w')
2224
#define A_EXTEND_ZOOMS ((int) 'e')

serial.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
681681
// keep old behavior, which loses one bit of precision at the bottom
682682
midx = (sf.bbox[0] / 2 + sf.bbox[2] / 2) & ((1LL << 32) - 1);
683683
midy = (sf.bbox[1] / 2 + sf.bbox[3] / 2) & ((1LL << 32) - 1);
684-
} else if ((additional[A_DROP_DENSEST_AS_NEEDED] || additional[A_COALESCE_DENSEST_AS_NEEDED]) && sf.t == VT_POLYGON) {
684+
} else if ((additional[A_DROP_DENSEST_AS_NEEDED] || additional[A_COALESCE_DENSEST_AS_NEEDED] || additional[A_DROP_SPARSEST_AS_NEEDED] || additional[A_COALESCE_SPARSEST_AS_NEEDED]) && sf.t == VT_POLYGON) {
685685
// This probably should really apply to all polygons,
686686
// but I hate to change the feature sequence in all the
687687
// test fixtures again
@@ -725,6 +725,8 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf, std::
725725

726726
if (additional[A_DROP_DENSEST_AS_NEEDED] ||
727727
additional[A_COALESCE_DENSEST_AS_NEEDED] ||
728+
additional[A_DROP_SPARSEST_AS_NEEDED] ||
729+
additional[A_COALESCE_SPARSEST_AS_NEEDED] ||
728730
additional[A_CLUSTER_DENSEST_AS_NEEDED] ||
729731
additional[A_CALCULATE_FEATURE_DENSITY] ||
730732
additional[A_DROP_SMALLEST_AS_NEEDED] ||

tile.cpp

+57-6
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,17 @@ static unsigned long long choose_mingap(std::vector<unsigned long long> &gaps, d
772772
return gaps[ix];
773773
}
774774

775+
static unsigned long long choose_maxgap(std::vector<unsigned long long> &gaps, double f, unsigned long long existing_gap) {
776+
std::stable_sort(gaps.begin(), gaps.end());
777+
778+
size_t ix = (gaps.size() - 1) * f;
779+
while (ix > 0 && gaps[ix] == existing_gap) {
780+
ix--;
781+
}
782+
783+
return gaps[ix];
784+
}
785+
775786
// This function is called to choose the new "extent" threshold to try when a tile exceeds the
776787
// tile size limit or feature limit and `--drop-smallest-as-needed` or `--coalesce-smallest-as-needed`
777788
// has been set.
@@ -888,6 +899,8 @@ struct write_tile_args {
888899
size_t pass = 0;
889900
unsigned long long mingap = 0;
890901
unsigned long long mingap_out = 0;
902+
unsigned long long maxgap = 0;
903+
unsigned long long maxgap_out = 0;
891904
long long minextent = 0;
892905
long long minextent_out = 0;
893906
unsigned long long mindrop_sequence = 0;
@@ -1547,9 +1560,10 @@ void skip_tile(decompressor *geoms, std::atomic<long long> *geompos_in, bool com
15471560
}
15481561
}
15491562

1550-
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, std::atomic<long long> *geompos, 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_out, bool compressed_input, node *shared_nodes_map, size_t nodepos, std::string const &shared_nodes_bloom, std::vector<std::string> const &unidecode_data, long long estimated_complexity, std::set<zxy> &skip_children_out) {
1563+
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, std::atomic<long long> *geompos, 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, unsigned long long maxgap, long long minextent, unsigned long long mindrop_sequence, const char *prefilter, const char *postfilter, json_object *filter, write_tile_args *arg, atomic_strategy *strategy_out, bool compressed_input, node *shared_nodes_map, size_t nodepos, std::string const &shared_nodes_bloom, std::vector<std::string> const &unidecode_data, long long estimated_complexity, std::set<zxy> &skip_children_out) {
15511564
double merge_fraction = 1;
15521565
double mingap_fraction = 1;
1566+
double maxgap_fraction = 1;
15531567
double minextent_fraction = 1;
15541568
double mindrop_sequence_fraction = 1;
15551569

@@ -1864,9 +1878,9 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
18641878
can_stop_early = false;
18651879
continue;
18661880
}
1867-
} else if (additional[A_DROP_DENSEST_AS_NEEDED]) {
1881+
} else if (additional[A_DROP_DENSEST_AS_NEEDED] || additional[A_DROP_SPARSEST_AS_NEEDED]) {
18681882
add_sample_to(gaps, sf.gap, gaps_increment, seq);
1869-
if (sf.gap < mingap) {
1883+
if (sf.gap < mingap || sf.gap > maxgap) {
18701884
if (drop_feature_unless_it_can_be_added_to_a_multiplier_cluster(layer, sf, layer_unmaps, multiplier_seq, strategy, drop_rest, arg->attribute_accum)) {
18711885
can_stop_early = false;
18721886
continue;
@@ -1895,9 +1909,9 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
18951909
drop_rest = true;
18961910
continue;
18971911
}
1898-
} else if (additional[A_COALESCE_DENSEST_AS_NEEDED]) {
1912+
} else if (additional[A_COALESCE_DENSEST_AS_NEEDED] || additional[A_COALESCE_SPARSEST_AS_NEEDED]) {
18991913
add_sample_to(gaps, sf.gap, gaps_increment, seq);
1900-
if (sf.gap < mingap && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
1914+
if ((sf.gap < mingap || sf.gap > maxgap) && find_feature_to_accumulate_onto(features, sf, which_serial_feature, layer_unmaps, LLONG_MAX, multiplier_seq)) {
19011915
coalesce_geometry(features[which_serial_feature], sf);
19021916
features[which_serial_feature].coalesced = true;
19031917
coalesced_area += sf.extent;
@@ -2529,6 +2543,21 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
25292543
line_detail++;
25302544
continue;
25312545
}
2546+
} else if (maxgap > 0 && (additional[A_DROP_SPARSEST_AS_NEEDED] || additional[A_COALESCE_SPARSEST_AS_NEEDED])) {
2547+
maxgap_fraction = maxgap_fraction * scaled_max_tile_features / totalsize * 0.80;
2548+
unsigned long long m = choose_maxgap(gaps, maxgap_fraction, maxgap);
2549+
if (m != maxgap) {
2550+
maxgap = m;
2551+
if (maxgap < arg->maxgap_out) {
2552+
arg->maxgap_out = maxgap;
2553+
arg->still_dropping = true;
2554+
}
2555+
if (!quiet) {
2556+
fprintf(stderr, "Going to try keeping the densest %0.2f%% of the features to make it fit\n", maxgap_fraction * 100.0);
2557+
}
2558+
line_detail++;
2559+
continue;
2560+
}
25322561
} else if (additional[A_DROP_SMALLEST_AS_NEEDED] || additional[A_COALESCE_SMALLEST_AS_NEEDED]) {
25332562
minextent_fraction = minextent_fraction * scaled_max_tile_features / totalsize * 0.75;
25342563
long long m = choose_minextent(extents, minextent_fraction, minextent);
@@ -2641,6 +2670,21 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
26412670
line_detail++;
26422671
continue;
26432672
}
2673+
} else if (maxgap > 0 && (additional[A_DROP_SPARSEST_AS_NEEDED] || additional[A_COALESCE_SPARSEST_AS_NEEDED])) {
2674+
maxgap_fraction = maxgap_fraction * scaled_max_tile_size / (kept_adjust * compressed.size()) * 0.80;
2675+
unsigned long long m = choose_maxgap(gaps, maxgap_fraction, maxgap);
2676+
if (m != maxgap) {
2677+
maxgap = m;
2678+
if (maxgap < arg->maxgap_out) {
2679+
arg->maxgap_out = maxgap;
2680+
arg->still_dropping = true;
2681+
}
2682+
if (!quiet) {
2683+
fprintf(stderr, "Going to try keeping the densest %0.2f%% of the features to make it fit\n", maxgap_fraction * 100.0);
2684+
}
2685+
line_detail++;
2686+
continue;
2687+
}
26442688
} else if (additional[A_DROP_SMALLEST_AS_NEEDED] || additional[A_COALESCE_SMALLEST_AS_NEEDED]) {
26452689
minextent_fraction = minextent_fraction * scaled_max_tile_size / (kept_adjust * compressed.size()) * 0.75;
26462690
long long m = choose_minextent(extents, minextent_fraction, minextent);
@@ -2810,7 +2854,7 @@ exit(EXIT_IMPOSSIBLE);
28102854
skip_tile(&dc, &geompos, arg->compressed);
28112855
len = 1;
28122856
} else {
2813-
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->geompos, 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, *(arg->shared_nodes_bloom), (*arg->unidecode_data), estimated_complexity, arg->skip_children_out);
2857+
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->geompos, 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->maxgap, arg->minextent, arg->mindrop_sequence, arg->prefilter, arg->postfilter, arg->filter, arg, arg->strategy, arg->compressed, arg->shared_nodes_map, arg->nodepos, *(arg->shared_nodes_bloom), (*arg->unidecode_data), estimated_complexity, arg->skip_children_out);
28142858
}
28152859

28162860
if (pthread_mutex_lock(&var_lock) != 0) {
@@ -2987,6 +3031,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *global_stringpool, std::
29873031

29883032
double zoom_gamma = gamma;
29893033
unsigned long long zoom_mingap = 0;
3034+
unsigned long long zoom_maxgap = ULLONG_MAX;
29903035
long long zoom_minextent = 0;
29913036
unsigned long long zoom_mindrop_sequence = 0;
29923037
size_t zoom_tile_size = 0;
@@ -3020,7 +3065,9 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *global_stringpool, std::
30203065
args[thread].gamma = zoom_gamma;
30213066
args[thread].gamma_out = zoom_gamma;
30223067
args[thread].mingap = zoom_mingap;
3068+
args[thread].maxgap = zoom_maxgap;
30233069
args[thread].mingap_out = zoom_mingap;
3070+
args[thread].maxgap_out = zoom_maxgap;
30243071
args[thread].minextent = zoom_minextent;
30253072
args[thread].minextent_out = zoom_minextent;
30263073
args[thread].mindrop_sequence = zoom_mindrop_sequence;
@@ -3103,6 +3150,10 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *global_stringpool, std::
31033150
zoom_mingap = args[thread].mingap_out;
31043151
again = true;
31053152
}
3153+
if (args[thread].maxgap_out < zoom_maxgap) {
3154+
zoom_maxgap = args[thread].maxgap_out;
3155+
again = true;
3156+
}
31063157
if (args[thread].minextent_out > zoom_minextent) {
31073158
zoom_minextent = args[thread].minextent_out;
31083159
again = true;

0 commit comments

Comments
 (0)