Skip to content

Batch elevation tile downloads to avoid stalling on large bboxes#1060

Open
TonyD365 wants to merge 3 commits into
louis-e:mainfrom
TonyD365:patch-1
Open

Batch elevation tile downloads to avoid stalling on large bboxes#1060
TonyD365 wants to merge 3 commits into
louis-e:mainfrom
TonyD365:patch-1

Conversation

@TonyD365
Copy link
Copy Markdown

Problem

When generating a large bbox in a USGS 3DEP-covered area, the elevation
step ([3/7] Fetching elevation) can stall for a very long time in a
flood of retries.

For example, a Greater Toronto Area bbox at 1 m resolution enumerates
6231 fixed-grid tiles (67 × 93 at level r1). The current downloader
fires all of them through a single par_iter() at a fixed concurrency
(MAX_CONCURRENT_DOWNLOADS = 4). The sustained pressure trips rate
limiting on the USGS ArcGIS ImageServer, and the run fills the console
with:

usgs_3dep: fetching 6231 fixed-grid tiles at r1 (1.00 m/px), 512 px/tile
Elevation request retry 1/2 after 643ms...
Elevation request retry 2/2 after 1665ms...
... (repeats for thousands of tiles)

Change

This PR paces the tile downloads in fetch_fixed_tile_grid
(src/elevation/providers/fixed_tile.rs): tiles are downloaded in
batches with a short pause between batches, giving strict upstreams
(USGS ArcGIS) room to breathe instead of being hammered continuously.

Three new FixedTileProvider associated constants make this tunable
per-provider (and a no-op when disabled):

  • DOWNLOAD_BATCH_SIZE (default 256; 0 disables batching)
  • BATCH_PAUSE_MS (default 1000)

The pause is applied only between batches — never before the first
or after the last — and only when batching is enabled.

Why this is safe

Batching changes only when requests are issued, not what is
fetched:

  • Already-cached tiles still short-circuit inside fetch_tile_raster
    (the cache_path.exists() check in fetch_or_cache), so a re-run
    with a warm cache is unaffected.
  • The set of (TileKey, Result) pairs collected is identical to the
    previous single-pass par_iter() — same keys, same Ok/Err values —
    so the downstream tile_cache build, AWS Terrarium fallback, and
    bilinear sampling are untouched.
  • Sampling still runs on Rayon's global pool, unchanged.

Testing

  • cargo build / cargo test pass locally.
  • Existing fixed_tile unit tests
    (covering_tiles_matches_expected_rectangle,
    level_selection_follows_cell_size, etc.) still pass.
  • Verified manually with the GTA bbox above: the elevation step now
    progresses in batches (downloading tile batch N/M (...)) instead of
    stalling.

Notes / open questions

  • This paces load but does not reduce the total number of tiles. For
    very large 1 m bboxes the elevation step is still lengthy; a
    follow-up could add a per-request tile budget that steps down to a
    coarser resolution level when the covering-tile count is excessive.
    Happy to split that into a separate PR if useful.
  • DOWNLOAD_BATCH_SIZE / BATCH_PAUSE_MS defaults are conservative;
    open to tuning them based on what the maintainers consider polite to
    the upstream services.

@TonyD365 TonyD365 marked this pull request as draft May 23, 2026 16:48
@TonyD365 TonyD365 marked this pull request as ready for review May 23, 2026 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant