import react, { useCallback, useEffect, useRef, useState } from 'react'; import { atom, useAtom } from 'jotai'; import { TileFactory, TileKeyObject } from './types'; import { coordinateSystemAtom } from './Map'; import TiledLayer from './TiledLayer'; import Tile from './Tile'; import _, { floor, range } from 'lodash'; import tileUri from './uris'; export interface LayerStackProperties { /** * A key identifying the initial top left tile */ keyObject: TileKeyObject; /** * Number of {@link components/map/TiledLayer!TiledLayer}. */ numberOfTiledLayers?: number; } /** * * @param props * @returns A stack of layers embedded in an SVG element * * This component does the conversion between the {@link components/map/Map!CoordinateSystem} stored * in the {@link components/map/Map!coordinateSystemAtom} atom and the {@link components/map/TiledLayer!TiledLayer} * components which units are in tiles. * */ export const LayerStack: react.FC = ( props: LayerStackProperties ) => { const [coordinateSystem] = useAtom(coordinateSystemAtom); const simpleTileFactory: TileFactory = useCallback( (keyObject) => ( ), [] ); const numberOfTiledLayers = props.numberOfTiledLayers === undefined ? 1 : props.numberOfTiledLayers; const [activeTiledLayer, setActiveTiledLayer] = useState( Math.floor(numberOfTiledLayers / 2) ); const viewPort = { topLeft: { x: Math.floor(-coordinateSystem.shift.x / coordinateSystem.zoom / 256), y: Math.floor(-coordinateSystem.shift.y / coordinateSystem.zoom / 256), }, bottomRight: { x: Math.ceil( (-coordinateSystem.shift.x + window.innerWidth) / coordinateSystem.zoom / 256 ), y: Math.ceil( (-coordinateSystem.shift.y + window.innerHeight) / coordinateSystem.zoom / 256 ), }, }; const getTiledLayer = (i: number) => { const relativeZoomLevel = i - activeTiledLayer; const zoom = 2 ** relativeZoomLevel; const origin = { x: props.keyObject.x * zoom, y: props.keyObject.y * zoom, }; const keyObject = { provider: props.keyObject.provider, zoomLevel: props.keyObject.zoomLevel + relativeZoomLevel, x: Math.floor(origin.x), y: Math.floor(origin.y), }; const shift = { x: origin.x - floor(origin.x), y: origin.y - floor(origin.y), }; return ( ); }; const tileLayers = range(0, numberOfTiledLayers).map((i) => {}); // console.log(`tiledLayers: ${JSON.stringify(tiledLayers)}`); return ( { // Tiled layers with less detail range(0, activeTiledLayer).map(getTiledLayer) } { // Tiled layers with more details range(numberOfTiledLayers, activeTiledLayer + 1, -1).map( getTiledLayer ) } { // And the active one getTiledLayer(activeTiledLayer) } ); }; export default LayerStack;