UNPKG

@deck.gl-community/layers

Version:

Addon layers for deck.gl

110 lines (109 loc) 3.83 kB
// deck.gl-community // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import { CompositeLayer } from '@deck.gl/core'; import { TileLayer } from '@deck.gl/geo-layers'; import { BitmapLayer, GeoJsonLayer, PathLayer } from '@deck.gl/layers'; /* global window */ const devicePixelRatio = (typeof window !== 'undefined' && window.devicePixelRatio) || 1; /** * A Deck.gl layer that renders a tile source * Autodiscovers type of content (vector tile, bitmap, ...) * Can render debug borders around tiles * TODO - Change debug border color based on zoom level */ export class TileSourceLayer extends CompositeLayer { static layerName = 'TileSourceLayer'; static defaultProps = { ...TileLayer.defaultProps, showTileBorders: true }; state = undefined; initializeState() { this.setState({ tileSource: null }); } updateState({ props, changeFlags }) { this.setState({ tileSource: props.tileSource }); } renderLayers() { const { tileSource, showTileBorders, metadata, onTilesLoad } = this.props; const minZoom = metadata?.minZoom || 0; const maxZoom = metadata?.maxZoom || 30; return [ new TileLayer({ // HACK: Trigger new layer via id prop to force clear tile cache id: String(tileSource.url), getTileData: tileSource.getTileData, // Assume the pmtiles file support HTTP/2, so we aren't limited by the browser to a certain number per domain. maxRequests: 20, pickable: true, onViewportLoad: onTilesLoad, autoHighlight: showTileBorders, highlightColor: [60, 60, 60, 40], minZoom, maxZoom, tileSize: 256, // TOOD - why is this needed? zoomOffset: devicePixelRatio === 1 ? -1 : 0, renderSubLayers: renderSubLayers, // Custom prop tileSource, showTileBorders }) ]; } } function renderSubLayers(props) { const { tileSource, showTileBorders, minZoom, maxZoom, tile: { index: { z: zoom }, bbox: { west, south, east, north } } } = props; const layers = []; const borderColor = zoom <= minZoom || zoom >= maxZoom ? [255, 0, 0, 255] : [0, 0, 255, 255]; switch (tileSource.mimeType) { case 'application/vnd.mapbox-vector-tile': layers.push(new GeoJsonLayer({ id: `${props.id}-geojson`, data: props.data, pickable: true, getFillColor: [0, 190, 80, 255], lineWidthScale: 500, lineWidthMinPixels: 0.5 })); break; case 'image/png': case 'image/jpeg': case 'image/webp': case 'image/avif': layers.push(new BitmapLayer(props, { data: null, image: props.data, bounds: [west, south, east, north], pickable: true })); break; default: // eslint-disable-next-line no-console console.error('Unknown tile mimeType', tileSource?.mimeType); } // Debug tile borders if (showTileBorders) { layers.push(new PathLayer({ id: `${props.id}-border`, data: [ [ [west, north], [west, south], [east, south], [east, north], [west, north] ] ], getPath: (d) => d, getColor: borderColor, widthMinPixels: 4 })); } return layers; }