mapbox / mapbox/mapbox-gl-js

Fix vector tile overdrawing with overlapping tiles from different zoom levels

Open
#6,768 7 comments 8 reactions 1 assignee View on GitHub

Nobody has claimed this yet.

bug :lady_beetle:
Dominant language
TypeScript
Stars
12.4k
Forks
2.4k
PR merge metrics
No merged PRs in 30d

Description

The tile loading logic in Mapbox GL JS attempts to load a parent tile in certain cases when a request for a child tile fails, e.g. the tile response is a 404, or a 200 with a content length of 0. This is intended to compensate for situations where tiles are not available at the current zoom level, but may be available at lower zoom levels, which could be overzoomed.

Unfortunately, this leads to overdraw in certain situations. I believe the primary situation (there may be others) involves:

  • A vector tileset that does not cover the whole world, i.e. tiles exist only for a certain bounding box. Outside that bounding box, the Mapbox tile API will respond with 404s.
  • Layers sourced from this tileset that use semi-transparent styling.
  • A map viewport that intersects the bounds of the tileset.

Under these conditions, the map succeeds in loading one or more tiles at zoom z inside the bounds, but fails on one or more tiles outside the bounds. This triggers requests for tiles at z-1 that succeed, returning tiles that overlap the child tiles. Both parent and child tiles are rendered, producing overdraw. (The fallback loading behavior was originally implemented for fully opaque raster tiles, and semi-transparent vector tiles was not taken into account.)

Multiple issues have been filed relating to this behavior:

  • #4691, involving a transparent circle layer (JSFiddle):
    mapbox-bug
  • #5829, similarly (demo):
    circle-zoom
  • #6386, similarly (jsbin
    v44dds
  • #6560, with a heatmap layer (example)
  • #6754, with a fill-extrusion layer (JSFiddle)

IIRC, we originally limited the parent tile fallback behavior to raster sources. This issue probably dates to when we expanded that behavior to vector sources as well. I can think of a few ways we might fix it:

  • Revert loading parent tiles for vector sources. We'd have to go back and look at the rationale for that change and see if there's a different way that doesn't trigger this bug.
  • Don't render parent tiles for vector sources when there's any successful child tile. Probably don't want this because parent tile rendering is important to avoid showing empty areas during pans and zooms.
  • Adjust the parent tile loading behavior to be smarter around tileset bounds. Something like: don't load a parent tile when a child tile is near the bounds or when the parent tile intersects the bounds.
  • Clip child tiles out of parent tiles during rendering. We did this for raster tiles in #5105.

@kkaefer, @mollymerp you're most familiar with tile loading / clipping behavior. What are your thoughts?

Making this high priority since it's affecting multiple customers. cc @lilykaiser

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.