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 {
|
struct next_feature_state {
|
||||||
unsigned long long previndex = 0;
|
unsigned long long previndex = 0;
|
||||||
unsigned long long prev_not_dropped_index = 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
|
// 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 != -1 && z < sf.tippecanoe_minzoom) {
|
||||||
|
if (sf.tippecanoe_minzoom > z + 1) {
|
||||||
|
next_feature_state.minzoom_feature_pending = true;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sf.tippecanoe_maxzoom != -1 && z > sf.tippecanoe_maxzoom) {
|
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]) {
|
if (within[j]) {
|
||||||
long long estimated_complexity_out = geompos[j] - start_geompos[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
|
// large enough to make it not try to stop early
|
||||||
estimated_complexity_out = 1LL << 32;
|
estimated_complexity_out = 1LL << 32;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user