mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 08:25:40 +02:00
Keep variable-depth pyramids from pruning features above their minzoom (#397)
--generate-variable-depth-tile-pyramid decides a tile is a leaf once its geometry fits at full detail, then prunes the tile's entire subtree. The guard that prevents leafing while deeper content is still pending consults only feature_minzoom (the automatic dot-dropping zoom); it does not consult tippecanoe_minzoom, the explicit per-feature minzoom set via the tippecanoe.minzoom attribute. So a feature carrying an explicit minzoom deeper than where its region leafs is excluded from the leaf tile (z < minzoom) while its children are never generated. It ends up in no tile at any zoom, silently dropped. next_feature() excludes such a feature and continues without returning it, so the leaf-prevention guard in write_tile() never sees it. Carry a flag out of next_feature() when an excluded feature first appears beyond the next zoom, and feed it into the same estimated-complexity path feature_minzoom already uses, so the pyramid keeps subdividing down to the feature's minzoom. The flag only affects estimated_complexity_out, which is written solely under --generate-variable-depth-tile-pyramid, so builds without that flag are unchanged. make test passes with no fixture diffs.
This commit is contained in:
@@ -1097,6 +1097,9 @@ static bool skip_next_feature(decompressor *geoms, std::atomic<long long> *geomp
|
||||
struct next_feature_state {
|
||||
unsigned long long previndex = 0;
|
||||
unsigned long long prev_not_dropped_index = 0;
|
||||
// set when a feature excluded by tippecanoe_minzoom first appears beyond the next
|
||||
// zoom, so variable-depth pyramids don't leaf above the feature's minzoom and prune it away
|
||||
bool minzoom_feature_pending = false;
|
||||
};
|
||||
|
||||
// This function is called repeatedly from write_tile() to retrieve the next feature
|
||||
@@ -1202,6 +1205,9 @@ static serial_feature next_feature(decompressor *geoms, std::atomic<long long> *
|
||||
}
|
||||
|
||||
if (sf.tippecanoe_minzoom != -1 && z < sf.tippecanoe_minzoom) {
|
||||
if (sf.tippecanoe_minzoom > z + 1) {
|
||||
next_feature_state.minzoom_feature_pending = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sf.tippecanoe_maxzoom != -1 && z > sf.tippecanoe_maxzoom) {
|
||||
@@ -2315,7 +2321,7 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
|
||||
if (within[j]) {
|
||||
long long estimated_complexity_out = geompos[j] - start_geompos[j];
|
||||
|
||||
if (dropping_by_rate) {
|
||||
if (dropping_by_rate || next_feature_state.minzoom_feature_pending) {
|
||||
// large enough to make it not try to stop early
|
||||
estimated_complexity_out = 1LL << 32;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user