Using `<TiledLayer>` in `<layerStack>`.

This commit is contained in:
Eric van der Vlist 2022-10-30 22:06:55 +01:00
parent ef35ffca32
commit b0c7801cd1
2 changed files with 22 additions and 62 deletions

View File

@ -7,10 +7,11 @@ import { coordinateSystemAtom } from './Map';
import TileSet from './TileSet';
import _, { floor, range } from 'lodash';
import tileUri from './uris';
import TiledLayer from './TiledLayer';
export interface LayerStackProperties {
/**
* A key identifying the initial top left tile
* A key identifying the top left tile
*/
keyObject: TileKeyObject;
/**
@ -37,46 +38,10 @@ export const LayerStack: react.FC<LayerStackProperties> = (
const numberOfTiledLayers =
props.numberOfTiledLayers === undefined ? 1 : props.numberOfTiledLayers;
const activeTiledLayer = Math.min(
Math.max(
Math.round(Math.log2(coordinateSystem.zoom)) +
Math.floor(numberOfTiledLayers / 2),
0
),
numberOfTiledLayers - 1
);
const activeTiledLayer = Math.floor(numberOfTiledLayers / 2);
const viewPort = {
topLeft: {
x:
props.keyObject.x +
Math.floor(-coordinateSystem.shift.x / coordinateSystem.zoom / 256),
y:
props.keyObject.y +
Math.floor(-coordinateSystem.shift.y / coordinateSystem.zoom / 256),
},
bottomRight: {
x:
props.keyObject.x +
Math.ceil(
(-coordinateSystem.shift.x + window.innerWidth) /
coordinateSystem.zoom /
256
) -
1,
y:
props.keyObject.y +
Math.ceil(
(-coordinateSystem.shift.y + window.innerHeight) /
coordinateSystem.zoom /
256
) -
1,
},
};
const getTileSet = (i: number) => {
const relativeZoomLevel = i - Math.floor(numberOfTiledLayers / 2);
const getTiledLayer = (i: number) => {
const relativeZoomLevel = i - activeTiledLayer;
const zoom = 2 ** relativeZoomLevel;
const origin = {
x: props.keyObject.x * zoom,
@ -89,8 +54,8 @@ export const LayerStack: react.FC<LayerStackProperties> = (
y: Math.floor(origin.y),
};
const shift = {
x: origin.x - floor(origin.x),
y: origin.y - floor(origin.y),
x: -origin.x,
y: -origin.y,
};
const key = tileUri({
provider: keyObject.provider,
@ -98,19 +63,12 @@ export const LayerStack: react.FC<LayerStackProperties> = (
});
return (
<g
transform={`scale(${256 / zoom}) translate(${shift.x - keyObject.x}, ${
shift.y - keyObject.y
})`}
key={key}
data-testid={key}
>
<TileSet
key={key}
keyObject={keyObject}
viewPort={i === activeTiledLayer ? viewPort : undefined}
/>
</g>
<TiledLayer
key={tileUri(keyObject)}
keyObject={keyObject}
shift={shift}
zoom={zoom * 256}
/>
);
};
@ -127,15 +85,17 @@ export const LayerStack: react.FC<LayerStackProperties> = (
>
{
// Tiled layers with less detail
range(0, activeTiledLayer).map(getTileSet)
range(0, activeTiledLayer).map(getTiledLayer)
}
{
// Tiled layers with more details
range(numberOfTiledLayers - 1, activeTiledLayer, -1).map(getTileSet)
range(numberOfTiledLayers - 1, activeTiledLayer, -1).map(
getTiledLayer
)
}
{
// And the active one
getTileSet(activeTiledLayer)
getTiledLayer(activeTiledLayer)
}
</g>
</svg>

View File

@ -10,11 +10,11 @@ export interface TiledLayerProperties {
*/
keyObject: TileKeyObject;
/**
* A flag to indicate if the layer is active and should add tiles which are in its viewport or if it is "only" a backup.
* The translation to apply.
*/
shift: Point;
/**
* The zoom to apply. If equal to 1, the layer is considered active and should add tiles which are in its viewport
* The zoom to apply. If equal to 256 (the tile size), the layer is considered active and should add tiles which are in its viewport
*/
zoom: number;
}
@ -31,7 +31,7 @@ export const TiledLayer: react.FC<TiledLayerProperties> = (
) => {
const [coordinateSystem] = useAtom(coordinateSystemAtom);
const viewPort =
props.zoom === 1
props.zoom === 256
? {
topLeft: {
x: