UNPKG

@deck.gl/geo-layers

Version:

deck.gl layers supporting geospatial use cases and GIS formats

282 lines (251 loc) 6.15 kB
import { CompositeLayer, _flatten as flatten } from '@deck.gl/core'; import { GeoJsonLayer } from '@deck.gl/layers'; import Tileset2D, { STRATEGY_DEFAULT } from './tileset-2d'; import { urlType, getURLFromTemplate } from './utils'; const defaultProps = { data: [], dataComparator: urlType.equals, renderSubLayers: { type: 'function', value: props => new GeoJsonLayer(props), compare: false }, getTileData: { type: 'function', optional: true, value: null, compare: false }, onViewportLoad: { type: 'function', optional: true, value: null, compare: false }, onTileLoad: { type: 'function', value: tile => {}, compare: false }, onTileUnload: { type: 'function', value: tile => {}, compare: false }, onTileError: { type: 'function', value: err => console.error(err), compare: false }, extent: { type: 'array', optional: true, value: null, compare: true }, tileSize: 512, maxZoom: null, minZoom: 0, maxCacheSize: null, maxCacheByteSize: null, refinementStrategy: STRATEGY_DEFAULT, zRange: null, maxRequests: 6, zoomOffset: 0 }; export default class TileLayer extends CompositeLayer { initializeState() { this.state = { tileset: null, isLoaded: false }; } finalizeState() { var _this$state$tileset; (_this$state$tileset = this.state.tileset) === null || _this$state$tileset === void 0 ? void 0 : _this$state$tileset.finalize(); } get isLoaded() { const { tileset } = this.state; return tileset.selectedTiles.every(tile => tile.isLoaded && tile.layers && tile.layers.every(layer => layer.isLoaded)); } shouldUpdateState({ changeFlags }) { return changeFlags.somethingChanged; } updateState({ props, changeFlags }) { let { tileset } = this.state; const propsChanged = changeFlags.propsOrDataChanged || changeFlags.updateTriggersChanged; const dataChanged = changeFlags.dataChanged || changeFlags.updateTriggersChanged && (changeFlags.updateTriggersChanged.all || changeFlags.updateTriggersChanged.getTileData); if (!tileset) { tileset = new Tileset2D(this._getTilesetOptions(props)); this.setState({ tileset }); } else if (propsChanged) { tileset.setOptions(this._getTilesetOptions(props)); if (dataChanged) { tileset.reloadAll(); } else { this.state.tileset.tiles.forEach(tile => { tile.layers = null; }); } } this._updateTileset(); } _getTilesetOptions(props) { const { tileSize, maxCacheSize, maxCacheByteSize, refinementStrategy, extent, maxZoom, minZoom, maxRequests, zoomOffset } = props; return { maxCacheSize, maxCacheByteSize, maxZoom, minZoom, tileSize, refinementStrategy, extent, maxRequests, zoomOffset, getTileData: this.getTileData.bind(this), onTileLoad: this._onTileLoad.bind(this), onTileError: this._onTileError.bind(this), onTileUnload: this._onTileUnload.bind(this) }; } _updateTileset() { const { tileset } = this.state; const { zRange, modelMatrix } = this.props; const frameNumber = tileset.update(this.context.viewport, { zRange, modelMatrix }); const { isLoaded } = tileset; const loadingStateChanged = this.state.isLoaded !== isLoaded; const tilesetChanged = this.state.frameNumber !== frameNumber; if (isLoaded && (loadingStateChanged || tilesetChanged)) { this._onViewportLoad(); } if (tilesetChanged) { this.setState({ frameNumber }); } this.state.isLoaded = isLoaded; } _onViewportLoad() { const { tileset } = this.state; const { onViewportLoad } = this.props; if (onViewportLoad) { onViewportLoad(tileset.selectedTiles); } } _onTileLoad(tile) { this.props.onTileLoad(tile); tile.layers = null; this.setNeedsUpdate(); } _onTileError(error, tile) { this.props.onTileError(error); tile.layers = null; this.setNeedsUpdate(); } _onTileUnload(tile) { this.props.onTileUnload(tile); } getTileData(tile) { const { data, getTileData, fetch } = this.props; const { signal } = tile; tile.url = getURLFromTemplate(data, tile); if (getTileData) { return getTileData(tile); } if (tile.url) { return fetch(tile.url, { propName: 'data', layer: this, signal }); } return null; } renderSubLayers(props) { return this.props.renderSubLayers(props); } getSubLayerPropsByTile(tile) { return null; } getPickingInfo({ info, sourceLayer }) { info.tile = sourceLayer.props.tile; return info; } _updateAutoHighlight(info) { if (info.sourceLayer) { info.sourceLayer.updateAutoHighlight(info); } } renderLayers() { return this.state.tileset.tiles.map(tile => { const subLayerProps = this.getSubLayerPropsByTile(tile); if (!tile.isLoaded && !tile.content) {} else if (!tile.layers) { const layers = this.renderSubLayers({ ...this.props, id: "".concat(this.id, "-").concat(tile.x, "-").concat(tile.y, "-").concat(tile.z), data: tile.content, _offset: 0, tile }); tile.layers = flatten(layers, Boolean).map(layer => layer.clone({ tile, ...subLayerProps })); } else if (subLayerProps && tile.layers[0] && Object.keys(subLayerProps).some(propName => tile.layers[0].props[propName] !== subLayerProps[propName])) { tile.layers = tile.layers.map(layer => layer.clone(subLayerProps)); } return tile.layers; }); } filterSubLayer({ layer }) { return layer.props.tile.isVisible; } } TileLayer.layerName = 'TileLayer'; TileLayer.defaultProps = defaultProps; //# sourceMappingURL=tile-layer.js.map