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 TileSet from './TileSet';
|
||||||
import _, { floor, range } from 'lodash';
|
import _, { floor, range } from 'lodash';
|
||||||
import tileUri from './uris';
|
import tileUri from './uris';
|
||||||
|
import TiledLayer from './TiledLayer';
|
||||||
|
|
||||||
export interface LayerStackProperties {
|
export interface LayerStackProperties {
|
||||||
/**
|
/**
|
||||||
* A key identifying the initial top left tile
|
* A key identifying the top left tile
|
||||||
*/
|
*/
|
||||||
keyObject: TileKeyObject;
|
keyObject: TileKeyObject;
|
||||||
/**
|
/**
|
||||||
|
@ -37,46 +38,10 @@ export const LayerStack: react.FC<LayerStackProperties> = (
|
||||||
const numberOfTiledLayers =
|
const numberOfTiledLayers =
|
||||||
props.numberOfTiledLayers === undefined ? 1 : props.numberOfTiledLayers;
|
props.numberOfTiledLayers === undefined ? 1 : props.numberOfTiledLayers;
|
||||||
|
|
||||||
const activeTiledLayer = Math.min(
|
const activeTiledLayer = Math.floor(numberOfTiledLayers / 2);
|
||||||
Math.max(
|
|
||||||
Math.round(Math.log2(coordinateSystem.zoom)) +
|
|
||||||
Math.floor(numberOfTiledLayers / 2),
|
|
||||||
0
|
|
||||||
),
|
|
||||||
numberOfTiledLayers - 1
|
|
||||||
);
|
|
||||||
|
|
||||||
const viewPort = {
|
const getTiledLayer = (i: number) => {
|
||||||
topLeft: {
|
const relativeZoomLevel = i - activeTiledLayer;
|
||||||
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 zoom = 2 ** relativeZoomLevel;
|
const zoom = 2 ** relativeZoomLevel;
|
||||||
const origin = {
|
const origin = {
|
||||||
x: props.keyObject.x * zoom,
|
x: props.keyObject.x * zoom,
|
||||||
|
@ -89,8 +54,8 @@ export const LayerStack: react.FC<LayerStackProperties> = (
|
||||||
y: Math.floor(origin.y),
|
y: Math.floor(origin.y),
|
||||||
};
|
};
|
||||||
const shift = {
|
const shift = {
|
||||||
x: origin.x - floor(origin.x),
|
x: -origin.x,
|
||||||
y: origin.y - floor(origin.y),
|
y: -origin.y,
|
||||||
};
|
};
|
||||||
const key = tileUri({
|
const key = tileUri({
|
||||||
provider: keyObject.provider,
|
provider: keyObject.provider,
|
||||||
|
@ -98,19 +63,12 @@ export const LayerStack: react.FC<LayerStackProperties> = (
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g
|
<TiledLayer
|
||||||
transform={`scale(${256 / zoom}) translate(${shift.x - keyObject.x}, ${
|
key={tileUri(keyObject)}
|
||||||
shift.y - keyObject.y
|
keyObject={keyObject}
|
||||||
})`}
|
shift={shift}
|
||||||
key={key}
|
zoom={zoom * 256}
|
||||||
data-testid={key}
|
/>
|
||||||
>
|
|
||||||
<TileSet
|
|
||||||
key={key}
|
|
||||||
keyObject={keyObject}
|
|
||||||
viewPort={i === activeTiledLayer ? viewPort : undefined}
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,15 +85,17 @@ export const LayerStack: react.FC<LayerStackProperties> = (
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
// Tiled layers with less detail
|
// Tiled layers with less detail
|
||||||
range(0, activeTiledLayer).map(getTileSet)
|
range(0, activeTiledLayer).map(getTiledLayer)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Tiled layers with more details
|
// Tiled layers with more details
|
||||||
range(numberOfTiledLayers - 1, activeTiledLayer, -1).map(getTileSet)
|
range(numberOfTiledLayers - 1, activeTiledLayer, -1).map(
|
||||||
|
getTiledLayer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// And the active one
|
// And the active one
|
||||||
getTileSet(activeTiledLayer)
|
getTiledLayer(activeTiledLayer)
|
||||||
}
|
}
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -10,11 +10,11 @@ export interface TiledLayerProperties {
|
||||||
*/
|
*/
|
||||||
keyObject: TileKeyObject;
|
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;
|
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;
|
zoom: number;
|
||||||
}
|
}
|
||||||
|
@ -24,14 +24,14 @@ export interface TiledLayerProperties {
|
||||||
* @param props
|
* @param props
|
||||||
* @returns A layer of tiles.
|
* @returns A layer of tiles.
|
||||||
* This component wraps a `<TileSet>` in an SVG `<g>` element taking care of the scale and translation.
|
* This component wraps a `<TileSet>` in an SVG `<g>` element taking care of the scale and translation.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export const TiledLayer: react.FC<TiledLayerProperties> = (
|
export const TiledLayer: react.FC<TiledLayerProperties> = (
|
||||||
props: TiledLayerProperties
|
props: TiledLayerProperties
|
||||||
) => {
|
) => {
|
||||||
const [coordinateSystem] = useAtom(coordinateSystemAtom);
|
const [coordinateSystem] = useAtom(coordinateSystemAtom);
|
||||||
const viewPort =
|
const viewPort =
|
||||||
props.zoom === 1
|
props.zoom === 256
|
||||||
? {
|
? {
|
||||||
topLeft: {
|
topLeft: {
|
||||||
x:
|
x:
|
||||||
|
|
Loading…
Reference in New Issue