Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions docs/api-reference/geo-layers/shared-tile-2d-layer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# SharedTile2DLayer (Experimental)

`_SharedTile2DLayer` is an experimental composite layer for rendering 2D tiled data when multiple layer instances or viewports should reuse one tile-content cache. It is a parallel API to [`TileLayer`](./tile-layer.md), not a replacement for `TileLayer`, `MVTLayer`, or `TerrainLayer`.

Use `_SharedTile2DLayer` when the same tiled payload should feed multiple views, such as a main map and minimap. The layer keeps selection and visibility state per viewport, while [`_SharedTileset2D`](./shared-tileset-2d.md) owns loading, request scheduling, cache eviction, stats, and TileSource metadata.

```ts
import {Deck, MapView} from '@deck.gl/core';
import {BitmapLayer} from '@deck.gl/layers';
import {
_SharedTile2DLayer as SharedTile2DLayer,
_SharedTileset2D as SharedTileset2D,
sharedTile2DDeckAdapter
} from '@deck.gl/geo-layers';

const tileset = new SharedTileset2D<ImageBitmap>({
adapter: sharedTile2DDeckAdapter,
minZoom: 0,
maxZoom: 19,
getTileData: async ({index, signal}) => {
const {x, y, z} = index;
const response = await fetch(`https://tile.openstreetmap.org/${z}/${x}/${y}.png`, {signal});
return createImageBitmap(await response.blob());
}
});

const layer = new SharedTile2DLayer<ImageBitmap>({
id: 'shared-raster-tiles',
data: tileset,
renderSubLayers: props => {
const [[west, south], [east, north]] = props.tile.boundingBox;
return new BitmapLayer(props, {
data: null,
image: props.data,
bounds: [west, south, east, north]
});
}
});

new Deck({
views: [
new MapView({id: 'main', controller: true}),
new MapView({id: 'minimap', x: 16, y: 16, width: 240, height: 160})
],
initialViewState: {longitude: -122.4, latitude: 37.74, zoom: 11},
layers: [layer]
});
```

## Installation

```bash
npm install deck.gl
# or
npm install @deck.gl/core @deck.gl/layers @deck.gl/geo-layers
```

```ts
import {_SharedTile2DLayer as SharedTile2DLayer} from '@deck.gl/geo-layers';
import type {SharedTile2DLayerPickingInfo, SharedTile2DLayerProps} from '@deck.gl/geo-layers';

new SharedTile2DLayer<TileDataT>(...props: SharedTile2DLayerProps<TileDataT>[]);
```

## Properties

Inherits all properties from base [`Layer`](../core/layer.md). If using the default `renderSubLayers`, supports all [`GeoJSONLayer`](../layers/geojson-layer.md) properties.

### `data` (string | string[] | `_SharedTileset2D` | TileSource, optional) {#data}

- Default: `[]`

Accepts the same URL-template input as [`TileLayer`](./tile-layer.md#data), a loaders.gl `TileSource`, or an external `_SharedTileset2D`.

When `data` is a URL template, the layer creates and owns an internal tileset. When `data` is a `TileSource`, the internal tileset uses `TileSource.getTileData()` and adopts supported metadata such as `minZoom`, `maxZoom`, and `boundingBox` unless the layer explicitly overrides those props. When `data` is an external `_SharedTileset2D`, the caller owns and finalizes that tileset.

### `getTileData` (Function, optional) {#gettiledata}

Called for URL-template data with the same tile load props documented by [`TileLayer`](./tile-layer.md#gettiledata). This prop is ignored when `data` is a `TileSource` or external `_SharedTileset2D`.

### `renderSubLayers` (Function, optional) {#rendersublayers}

Receives the loaded tile payload as `props.data` and the shared tile header as `props.tile`. Return one layer, an array of layers, or `null`.

### Tile options

Owned tilesets accept the same core tile options as `TileLayer`: `extent`, `tileSize`, `maxZoom`, `minZoom`, `maxCacheSize`, `maxCacheByteSize`, `zRange`, `maxRequests`, `debounceTime`, `zoomOffset`, `visibleMinZoom`, and `visibleMaxZoom`.

`refinementStrategy` is intentionally narrower than `TileLayer`: supported values are `'best-available'`, `'no-overlap'`, and `'never'`. Custom refinement callbacks are not supported because tile visibility is view-specific in a shared cache.

### Callbacks

`onViewportLoad`, `onTileLoad`, `onTileUnload`, and `onTileError` follow the `TileLayer` callback shape, using `_SharedTile2DHeader` tile objects.

## Picking

Use `SharedTile2DLayerPickingInfo` for typed picking callbacks. It includes `tile`, `sourceTile`, and `sourceTileSubLayer`, matching `TileLayerPickingInfo`.
62 changes: 62 additions & 0 deletions docs/api-reference/geo-layers/shared-tileset-2d.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# SharedTileset2D (Experimental)

`_SharedTileset2D` is the experimental shared tile-content cache used by [`_SharedTile2DLayer`](./shared-tile-2d-layer.md). It owns tile headers, tile payloads, request scheduling, cache eviction, loaders.gl `TileSource` metadata, live stats, and lifecycle subscriptions. Per-viewport selection and visibility are intentionally owned by the layer's internal views instead of the tileset.

```ts
import {
_SharedTileset2D as SharedTileset2D,
sharedTile2DDeckAdapter
} from '@deck.gl/geo-layers';
import type {SharedTileset2DProps} from '@deck.gl/geo-layers';

const props: SharedTileset2DProps<ImageBitmap> = {
adapter: sharedTile2DDeckAdapter,
getTileData: async ({index, signal}) => {
const {x, y, z} = index;
const response = await fetch(`https://tile.openstreetmap.org/${z}/${x}/${y}.png`, {signal});
return createImageBitmap(await response.blob());
}
};

const tileset = new SharedTileset2D(props);
```

## Construction

```ts
import {_SharedTileset2D as SharedTileset2D} from '@deck.gl/geo-layers';
import type {
SharedRefinementStrategy,
SharedTileset2DAdapter,
SharedTileset2DBaseProps,
SharedTileset2DProps,
SharedTileset2DTileContext,
SharedTileset2DTraversalContext
} from '@deck.gl/geo-layers';

new SharedTileset2D<TileDataT, ViewStateT>(props: SharedTileset2DProps<TileDataT, ViewStateT>);
SharedTileset2D.fromTileSource<TileDataT>(tileSource, props);
```

Provide either `getTileData` or `tileSource`. A shared tileset also needs an adapter before traversal is used. `_SharedTile2DLayer` installs `sharedTile2DDeckAdapter` automatically for deck.gl viewport traversal; applications constructing the tileset directly should usually pass that adapter themselves.

## TileSource metadata

When created from a loaders.gl `TileSource`, `_SharedTileset2D` calls `getMetadata()` asynchronously and adopts supported `minZoom`, `maxZoom`, and `boundingBox` metadata. Explicit tileset options win over metadata. Replacing the `tileSource` ignores late metadata from the previous source.

## Ownership

An external `_SharedTileset2D` can be passed to one or more `_SharedTile2DLayer` instances. Those layers do not finalize the external tileset. The owner should call `tileset.finalize()` when the shared cache is no longer needed.

## Runtime API

- `tiles`, `selectedTiles`, `visibleTiles`, `loadingTiles`, and `cacheByteSize` expose current shared cache state.
- `stats` is a `@probe.gl/stats` `Stats` object with tile cache, visibility, loading, eviction, and consumer counters.
- `setOptions()` updates effective tileset options. Pass `{replace: true}` as the second argument to replace prior caller options instead of merging them.
- `reloadAll()` marks selected tiles stale and drops unselected cached tiles.
- `subscribe()` listens for tile load, tile error, tile unload, metadata/config update, metadata error, and stats change events.
- `finalize()` aborts in-flight requests and clears the shared cache.

## Refinement

`SharedRefinementStrategy` supports `'best-available'`, `'no-overlap'`, and `'never'`. Unlike `TileLayer`, `_SharedTileset2D` does not accept a custom refinement callback because one tile header may be selected or visible in one viewport and hidden in another.
2 changes: 2 additions & 0 deletions docs/api-reference/layers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ The [Geo Layers](https://www.npmjs.com/package/@deck.gl/geo-layers) collects lay
- [MVTLayer](../geo-layers/mvt-layer.md)
- [QuadkeyLayer](../geo-layers/quadkey-layer.md)
- [S2Layer](../geo-layers/s2-layer.md)
- [SharedTile2DLayer](../geo-layers/shared-tile-2d-layer.md) (experimental)
- [SharedTileset2D](../geo-layers/shared-tileset-2d.md) (experimental)
- [TerrainLayer](../geo-layers/terrain-layer.md)
- [TileLayer](../geo-layers/tile-layer.md)
- [Tile3DLayer](../geo-layers/tile-3d-layer.md)
Expand Down
25 changes: 24 additions & 1 deletion docs/developer-guide/views.md
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,30 @@ function App({carPose}: {
</Tabs>


Some layers, including `TileLayer`, `MVTLayer`, `HeatmapLayer` and `ScreenGridLayer`, perform expensive operations (data fetching and/or aggregation) on viewport change. Therefore, it is generally *NOT* recommended to render them into multiple views. If you do need to show e.g. tiled base map in multiple views, create one layer instance for each view and limit their rendering with `layerFilter`:
Some layers, including `TileLayer`, `MVTLayer`, `HeatmapLayer` and `ScreenGridLayer`, perform expensive operations (data fetching and/or aggregation) on viewport change. Therefore, it is generally *NOT* recommended to render them into multiple views.

For 2D tiled content that can share one payload cache, the experimental [`_SharedTile2DLayer`](../api-reference/geo-layers/shared-tile-2d-layer.md) and [`_SharedTileset2D`](../api-reference/geo-layers/shared-tileset-2d.md) support one shared tileset feeding multiple viewports:

```ts
import {
_SharedTile2DLayer as SharedTile2DLayer,
_SharedTileset2D as SharedTileset2D,
sharedTile2DDeckAdapter
} from '@deck.gl/geo-layers';

const tileset = new SharedTileset2D({
adapter: sharedTile2DDeckAdapter,
getTileData: ({index, signal}) => fetchTile(index, signal)
});

const layer = new SharedTile2DLayer({
id: 'shared-tiles',
data: tileset,
renderSubLayers
});
```

For tiled layers that do not use that experimental shared path, including `MVTLayer`, create one layer instance for each view and limit their rendering with `layerFilter`:

<Tabs groupId="language">
<TabItem value="js" label="JavaScript">
Expand Down
1 change: 1 addition & 0 deletions docs/developer-guide/webgpu.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ The table below covers the public layer exports from the layer packages. It is d
| `@deck.gl/geo-layers` | `S2Layer` | ✅ | ❌ |
| `@deck.gl/geo-layers` | `QuadkeyLayer` | ✅ | ❌ |
| `@deck.gl/geo-layers` | `TileLayer` | ✅ | ❌ |
| `@deck.gl/geo-layers` | `_SharedTile2DLayer` | ✅ | ❌ |
| `@deck.gl/geo-layers` | `TripsLayer` | ✅ | ❌ |
| `@deck.gl/geo-layers` | `H3ClusterLayer` | ✅ | ❌ |
| `@deck.gl/geo-layers` | `H3HexagonLayer` | ✅ | ❌ |
Expand Down
24 changes: 6 additions & 18 deletions docs/table-of-contents.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@
{
"type": "category",
"label": "Overview",
"items": [
"README",
"whats-new",
"upgrade-guide",
"contributing",
"faq"
]
"items": ["README", "whats-new", "upgrade-guide", "contributing", "faq"]
},
{
"type": "category",
Expand Down Expand Up @@ -120,6 +114,8 @@
"api-reference/layers/scatterplot-layer",
"api-reference/mesh-layers/scenegraph-layer",
"api-reference/aggregation-layers/screen-grid-layer",
"api-reference/geo-layers/shared-tile-2d-layer",
"api-reference/geo-layers/shared-tileset-2d",
"api-reference/mesh-layers/simple-mesh-layer",
"api-reference/layers/solid-polygon-layer",
"api-reference/geo-layers/terrain-layer",
Expand All @@ -144,9 +140,7 @@
{
"type": "category",
"label": "Scripting Interface",
"items": [
"api-reference/core/deckgl"
]
"items": ["api-reference/core/deckgl"]
},
{
"type": "category",
Expand Down Expand Up @@ -203,10 +197,7 @@
{
"type": "category",
"label": "Effects",
"items": [
"api-reference/core/lighting-effect",
"api-reference/core/post-process-effect"
]
"items": ["api-reference/core/lighting-effect", "api-reference/core/post-process-effect"]
},
{
"type": "category",
Expand Down Expand Up @@ -289,10 +280,7 @@
{
"type": "category",
"label": "@deck.gl/mapbox",
"items": [
"api-reference/mapbox/overview",
"api-reference/mapbox/mapbox-overlay"
]
"items": ["api-reference/mapbox/overview", "api-reference/mapbox/mapbox-overlay"]
},
{
"type": "category",
Expand Down
1 change: 1 addition & 0 deletions docs/whats-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Class-specific improvements:

- [TextLayer](./api-reference/layers/text-layer.md) now supports per-object clipping box; and making text "sticky" when its container is partially off-screen. See a demo with this [new example](https://deck.gl/examples/text-layer-clipping).
- [TileLayer](./api-reference/geo-layers/tile-layer.md) adds new `visibleMinZoom` and `visibleMaxZoom` props to control the zoom range at which tiles are drawn, independent of the zoom range at which data is loaded.
- Experimental [`_SharedTile2DLayer`](./api-reference/geo-layers/shared-tile-2d-layer.md) and [`_SharedTileset2D`](./api-reference/geo-layers/shared-tileset-2d.md) let 2D tiled layers reuse one tile-content cache across multiple views.
- Improvements to [Tile3DLayer](./api-reference/geo-layers/tile-3d-layer.md) including better performance and tile tracking.
- WebGPU now materializes constant layer attributes into full buffers through `AttributeManager`, improving compatibility for layers that rely on constant accessors.

Expand Down
22 changes: 22 additions & 0 deletions examples/website/shared-tile-2d-layer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
This is a standalone experimental SharedTile2DLayer example using one SharedTileset2D to feed
tiled BitmapLayer sublayers in a main view and minimap on the [deck.gl](http://deck.gl) website.

### Usage

Copy the content of this folder to your project.

```bash
# install dependencies
npm install
# or
yarn
# bundle and serve the app with vite
npm start
```

### Data Source

OpenStreetMap raster tiles from [OpenStreetMap contributors](https://www.openstreetmap.org/copyright).

For more information, check out the
[documentation of SharedTile2DLayer](../../../docs/api-reference/geo-layers/shared-tile-2d-layer.md).
Loading
Loading