Using `<TiledLayer>` in `<layerStack>`.
This commit is contained in:
parent
ef35ffca32
commit
b0c7801cd1
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -24,14 +24,14 @@ export interface TiledLayerProperties {
|
|||
* @param props
|
||||
* @returns A layer of tiles.
|
||||
* This component wraps a `<TileSet>` in an SVG `<g>` element taking care of the scale and translation.
|
||||
*
|
||||
*
|
||||
*/
|
||||
export const TiledLayer: react.FC<TiledLayerProperties> = (
|
||||
props: TiledLayerProperties
|
||||
) => {
|
||||
const [coordinateSystem] = useAtom(coordinateSystemAtom);
|
||||
const viewPort =
|
||||
props.zoom === 1
|
||||
props.zoom === 256
|
||||
? {
|
||||
topLeft: {
|
||||
x:
|
||||
|
|
Loading…
Reference in New Issue