UNPKG

@deck.gl/carto

Version:

CARTO official integration with Deck.gl. Build geospatial applications using CARTO and Deck.gl.

94 lines (81 loc) 3.32 kB
// deck.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import {CompositeLayer, CompositeLayerProps, DefaultProps} from '@deck.gl/core'; import {H3HexagonLayer, H3HexagonLayerProps} from '@deck.gl/geo-layers'; import H3Tileset2D, {getHexagonResolution} from './h3-tileset-2d'; import SpatialIndexTileLayer, {SpatialIndexTileLayerProps} from './spatial-index-tile-layer'; import type {TilejsonResult} from '@carto/api-client'; import {TilejsonPropType, mergeLoadOptions} from './utils'; import {DEFAULT_TILE_SIZE} from '../constants'; export const renderSubLayers = props => { const {data} = props; const {index} = props.tile; if (!data || !data.length) return null; return new H3HexagonLayer(props, { getHexagon: d => d.id, centerHexagon: index, highPrecision: true }); }; const defaultProps: DefaultProps<H3TileLayerProps> = { data: TilejsonPropType, tileSize: DEFAULT_TILE_SIZE }; /** All properties supported by H3TileLayer. */ export type H3TileLayerProps<DataT = unknown> = _H3TileLayerProps<DataT> & CompositeLayerProps; /** Properties added by H3TileLayer. */ type _H3TileLayerProps<DataT> = Omit<H3HexagonLayerProps<DataT>, 'data'> & Omit<SpatialIndexTileLayerProps<DataT>, 'data'> & { data: null | TilejsonResult | Promise<TilejsonResult>; }; export default class H3TileLayer<DataT = any, ExtraPropsT extends {} = {}> extends CompositeLayer< ExtraPropsT & Required<_H3TileLayerProps<DataT>> > { static layerName = 'H3TileLayer'; static defaultProps = defaultProps; initializeState(): void { H3HexagonLayer._checkH3Lib(); } getLoadOptions(): any { const tileJSON = this.props.data as TilejsonResult; return mergeLoadOptions(super.getLoadOptions(), { fetch: {headers: {Authorization: `Bearer ${tileJSON.accessToken}`}}, cartoSpatialTile: {scheme: 'h3'} }); } renderLayers(): SpatialIndexTileLayer | null { const tileJSON = this.props.data as TilejsonResult; if (!tileJSON) return null; const {tiles: data} = tileJSON; let {minresolution, maxresolution} = tileJSON; // Convert Mercator zooms provided in props into H3 res levels // and clip into valid range provided from the tilejson if (this.props.minZoom) { minresolution = Math.max( minresolution, getHexagonResolution({zoom: this.props.minZoom, latitude: 0}, this.props.tileSize) ); } if (this.props.maxZoom) { maxresolution = Math.min( maxresolution, getHexagonResolution({zoom: this.props.maxZoom, latitude: 0}, this.props.tileSize) ); } const SubLayerClass = this.getSubLayerClass('spatial-index-tile', SpatialIndexTileLayer); // The naming is unfortunate, but minZoom & maxZoom in the context // of a Tileset2D refer to the resolution levels, not the Mercator zooms return new SubLayerClass(this.props, { id: `h3-tile-layer-${this.props.id}`, data, // TODO: Tileset2D should be generic over TileIndex type TilesetClass: H3Tileset2D as any, renderSubLayers, // minZoom and maxZoom are H3 resolutions, however we must use this naming as that is what the Tileset2D class expects minZoom: minresolution, maxZoom: maxresolution, loadOptions: this.getLoadOptions() }); } }