From 880df665f41d6e7c3d3c8c3d8f7aa5e5906692aa Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Tue, 5 Dec 2023 10:59:09 -0800 Subject: [PATCH] Drop duplicate geometries sooner in coalescing-as-needed --- tile.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tile.cpp b/tile.cpp index d94b1493a..ea76411b7 100644 --- a/tile.cpp +++ b/tile.cpp @@ -1898,6 +1898,19 @@ void add_sample_to(std::vector &vals, T val, size_t &increment, size_t seq) { } } +void coalesce_geometry(partial &p, serial_feature &sf) { + // if the geometry being coalesced on is an exact duplicate + // of an existing geometry, just drop it + + for (size_t i = 0; i < p.geoms.size(); i++) { + if (p.geoms[i] == sf.geometry) { + return; + } + } + + p.geoms.push_back(sf.geometry); +} + long long write_tile(decompressor *geoms, std::atomic *geompos_in, char *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 *along, long long alongminus, double gamma, int child_shards, long long *pool_off, unsigned *initial_x, unsigned *initial_y, std::atomic *running, double simplification, std::vector> *layermaps, std::vector> *layer_unmaps, size_t tiling_seg, size_t pass, unsigned long long mingap, long long minextent, double fraction, const char *prefilter, const char *postfilter, struct json_object *filter, write_tile_args *arg, atomic_strategy *strategy, bool compressed_input, struct node *shared_nodes_map, size_t nodepos) { double merge_fraction = 1; double mingap_fraction = 1; @@ -2145,7 +2158,7 @@ long long write_tile(decompressor *geoms, std::atomic *geompos_in, ch indices.push_back(sf.index); } if (sf.index - merge_previndex < mingap && find_partial(partials, sf, which_partial, layer_unmaps, LLONG_MAX)) { - partials[which_partial].geoms.push_back(sf.geometry); + coalesce_geometry(partials[which_partial], sf); partials[which_partial].coalesced = true; coalesced_area += sf.extent; preserve_attributes(arg->attribute_accum, sf, stringpool, pool_off, partials[which_partial]); @@ -2164,7 +2177,7 @@ long long write_tile(decompressor *geoms, std::atomic *geompos_in, ch } 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_partial(partials, sf, which_partial, layer_unmaps, minextent)) { - partials[which_partial].geoms.push_back(sf.geometry); + coalesce_geometry(partials[which_partial], sf); partials[which_partial].coalesced = true; coalesced_area += sf.extent; preserve_attributes(arg->attribute_accum, sf, stringpool, pool_off, partials[which_partial]); @@ -2188,7 +2201,7 @@ long long write_tile(decompressor *geoms, std::atomic *geompos_in, ch fraction_accum += fraction; if (fraction_accum < 1 && find_partial(partials, sf, which_partial, layer_unmaps, LLONG_MAX)) { if (additional[A_COALESCE_FRACTION_AS_NEEDED]) { - partials[which_partial].geoms.push_back(sf.geometry); + coalesce_geometry(partials[which_partial], sf); partials[which_partial].coalesced = true; coalesced_area += sf.extent; strategy->coalesced_as_needed++;