import react, { useState } from 'react'; import TiledLayer from './TiledLayer'; import { tileKeyToString } from './Map'; interface Point { x: number; y: number; } interface TiledLayersStackProperties { height: number; width: number; shift: Point; zoom: number; tileSize: number; numberOfZoomLevels?: number; } const TiledLayersStack: react.FC = ( props: TiledLayersStackProperties ) => { console.log(`Rendering TiledLayersStack`); const [tiledLayerKey, setTiledLayerKey] = useState({ provider: 'osm', zoomLevel: 16, x: 33488, y: 23939, }); const numberOfZoomLevels = props.numberOfZoomLevels === undefined ? 1 : props.numberOfZoomLevels % 2 === 0 ? props.numberOfZoomLevels + 1 : props.numberOfZoomLevels; const layers = []; const safetyZoomLevels = Math.floor(numberOfZoomLevels / 2); const nbTiles = Math.ceil( (Math.max(props.width, props.height) * 2 ** safetyZoomLevels) / 256 ) + 2; const activeZoomLevel = Math.min( Math.max(Math.round(Math.log2(props.zoom)) + safetyZoomLevels, 0), numberOfZoomLevels - 1 ); const getTiledLayer = (zoomLevel: number, isActive: boolean) => { const zoom = 2 ** (zoomLevel - safetyZoomLevels); const currentTiledLayerKey = { provider: tiledLayerKey.provider, zoomLevel: zoomLevel - safetyZoomLevels + tiledLayerKey.zoomLevel, x: Math.floor(tiledLayerKey.x * zoom), y: Math.floor(tiledLayerKey.y * zoom), }; return ( ); }; // First (ie last) dispay layers with less details (ascending order) for (let i = 0; i < activeZoomLevel; i++) { layers.push(getTiledLayer(i, false)); } // then dispay layers with more details (descending order) for (let i = numberOfZoomLevels - 1; i > activeZoomLevel; i--) { layers.push(getTiledLayer(i, false)); } // And then, of course, the active one layers.push(getTiledLayer(activeZoomLevel, true)); return <>{layers}; }; export default TiledLayersStack;