diff --git a/main.cpp b/main.cpp index fffaea1..bdf33da 100644 --- a/main.cpp +++ b/main.cpp @@ -2206,6 +2206,7 @@ int main(int argc, char **argv) { {"drop-densest-as-needed", no_argument, &additional[A_DROP_DENSEST_AS_NEEDED], 1}, {"drop-fraction-as-needed", no_argument, &additional[A_DROP_FRACTION_AS_NEEDED], 1}, {"drop-smallest-as-needed", no_argument, &additional[A_DROP_SMALLEST_AS_NEEDED], 1}, + {"coalesce-smallest-as-needed", no_argument, &additional[A_COALESCE_SMALLEST_AS_NEEDED], 1}, {"force-feature-limit", no_argument, &prevent[P_DYNAMIC_DROP], 1}, {"Dropping tightly overlapping features", 0, 0, 0}, diff --git a/options.hpp b/options.hpp index 3ebc6e6..45cf828 100644 --- a/options.hpp +++ b/options.hpp @@ -15,6 +15,7 @@ #define A_DROP_DENSEST_AS_NEEDED ((int) 's') #define A_DROP_FRACTION_AS_NEEDED ((int) 'd') #define A_DROP_SMALLEST_AS_NEEDED ((int) 'n') +#define A_COALESCE_SMALLEST_AS_NEEDED ((int) 'N') #define A_GRID_LOW_ZOOMS ((int) 'L') #define A_DETECT_WRAPAROUND ((int) 'w') #define A_EXTEND_ZOOMS ((int) 'e') diff --git a/serial.cpp b/serial.cpp index adb23bc..b7c20b0 100644 --- a/serial.cpp +++ b/serial.cpp @@ -447,7 +447,7 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf) { } double extent = 0; - if (additional[A_DROP_SMALLEST_AS_NEEDED]) { + if (additional[A_DROP_SMALLEST_AS_NEEDED] || additional[A_COALESCE_SMALLEST_AS_NEEDED]) { if (sf.t == VT_POLYGON) { for (size_t i = 0; i < sf.geometry.size(); i++) { if (sf.geometry[i].op == VT_MOVETO) { diff --git a/tile.cpp b/tile.cpp index a495ee4..23ff153 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1449,6 +1449,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s std::map> layers; std::vector indices; std::vector extents; + std::vector coalesced_geometry; int within[child_shards]; long long geompos[child_shards]; @@ -1557,6 +1558,22 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s continue; } } + if (additional[A_COALESCE_SMALLEST_AS_NEEDED]) { + extents.push_back(sf.extent); + if (sf.extent <= minextent) { + coalesced_geometry.push_back(sf.geometry); + continue; + } + } + + if (coalesced_geometry.size() != 0) { + for (size_t i = 0; i < coalesced_geometry.size(); i++) { + for (size_t j = 0; j < coalesced_geometry[i].size(); j++) { + sf.geometry.push_back(coalesced_geometry[i][j]); + } + } + coalesced_geometry.clear(); + } if (additional[A_CALCULATE_FEATURE_DENSITY]) { // Gamma is always 1 for this calculation so there is a reasonable @@ -1916,7 +1933,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s } line_detail++; continue; - } else if (additional[A_DROP_SMALLEST_AS_NEEDED]) { + } else if (additional[A_DROP_SMALLEST_AS_NEEDED] || additional[A_COALESCE_SMALLEST_AS_NEEDED]) { minextent_fraction = minextent_fraction * 200000.0 / totalsize * 0.90; long long m = choose_minextent(extents, minextent_fraction); if (m != minextent) { @@ -1999,7 +2016,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s fprintf(stderr, "Going to try keeping the sparsest %0.2f%% of the features to make it fit\n", mingap_fraction * 100.0); } line_detail++; - } else if (additional[A_DROP_SMALLEST_AS_NEEDED]) { + } else if (additional[A_DROP_SMALLEST_AS_NEEDED] || additional[A_COALESCE_SMALLEST_AS_NEEDED]) { minextent_fraction = minextent_fraction * max_tile_size / compressed.size() * 0.90; long long m = choose_minextent(extents, minextent_fraction); if (m != minextent) { @@ -2290,7 +2307,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo int err = INT_MAX; size_t start = 1; - if (additional[A_INCREASE_GAMMA_AS_NEEDED] || additional[A_DROP_DENSEST_AS_NEEDED] || additional[A_DROP_FRACTION_AS_NEEDED] || additional[A_DROP_SMALLEST_AS_NEEDED]) { + if (additional[A_INCREASE_GAMMA_AS_NEEDED] || additional[A_DROP_DENSEST_AS_NEEDED] || additional[A_DROP_FRACTION_AS_NEEDED] || additional[A_DROP_SMALLEST_AS_NEEDED] || additional[A_COALESCE_SMALLEST_AS_NEEDED]) { start = 0; }