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 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
})`}
key={key}
data-testid={key}
>
<TileSet
key={key}
keyObject={keyObject} keyObject={keyObject}
viewPort={i === activeTiledLayer ? viewPort : undefined} shift={shift}
zoom={zoom * 256}
/> />
</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>

View File

@ -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;
} }
@ -31,7 +31,7 @@ export const TiledLayer: react.FC<TiledLayerProperties> = (
) => { ) => {
const [coordinateSystem] = useAtom(coordinateSystemAtom); const [coordinateSystem] = useAtom(coordinateSystemAtom);
const viewPort = const viewPort =
props.zoom === 1 props.zoom === 256
? { ? {
topLeft: { topLeft: {
x: x: