sandbox/svgmap/src/components/map/TiledLayersConductor.tsx

70 lines
1.8 KiB
TypeScript

import react from 'react';
import TiledLayer from './TiledLayer';
interface Point {
x: number;
y: number;
}
interface TiledLayerConductorProperties {
height: number;
width: number;
shift: Point;
zoom: number;
tileSize: number;
numberOfZoomLevels?: number;
baseZoomLevel: number;
setBaseZoomLevel: (baseZoomLevel: number) => void;
}
const TiledLayerConductor: react.FC<TiledLayerConductorProperties> = (
props: TiledLayerConductorProperties
) => {
const nbTiles =
Math.ceil((Math.max(props.width, props.height) * 2) / 256) + 2;
const numberOfZoomLevels =
props.numberOfZoomLevels === undefined
? 1
: props.numberOfZoomLevels % 2 === 0
? props.numberOfZoomLevels + 1
: props.numberOfZoomLevels;
const layers = [];
const zoomLevel = Math.min(
Math.max(Math.round(Math.log2(props.zoom)), 0),
numberOfZoomLevels - 1
);
const getTiledLayer = (i: number, isActive: boolean) => {
return (
<TiledLayer
key={`layer${i + props.baseZoomLevel}`}
height={props.height * 2 ** i}
width={props.width * 2 ** i}
shift={{ x: props.shift.x * 2 ** i, y: props.shift.y * 2 ** i }}
zoom={props.zoom}
layerZoom={2 ** -i}
tileSize={256}
nbTiles={nbTiles * 2 ** i}
active={isActive}
/>
);
};
// First (ie last) dispay layers with less details (ascending order)
for (let i = 0; i < zoomLevel; i++) {
layers.push(getTiledLayer(i, false));
}
// then dispay layers with more details (descending order)
for (let i = numberOfZoomLevels - 1; i > zoomLevel; i--) {
layers.push(getTiledLayer(i, false));
}
// And then, of course, the active one
layers.push(getTiledLayer(zoomLevel, true));
return <>{layers}</>;
};
export default TiledLayerConductor;