Pushing map coordinated down to tiles.

This commit is contained in:
Eric van der Vlist 2022-10-16 14:52:26 +02:00
parent 4762156296
commit 26630439a4
4 changed files with 53 additions and 11 deletions

View File

@ -8,11 +8,22 @@ import SingleTouchHandler from './SingleTouchHandler';
import DoubleTouchHandler from './DoubleTouchHandler'; import DoubleTouchHandler from './DoubleTouchHandler';
import TiledLayersStack from './TiledLayersStack'; import TiledLayersStack from './TiledLayersStack';
export interface TiledLayerKey {
provider: string;
zoomLevel: number;
x: number;
y: number;
}
interface MapProperties { interface MapProperties {
height: number; height: number;
width: number; width: number;
} }
export const tiledLayerKeyToString = (tiledLayerKey: TiledLayerKey) => {
return `${tiledLayerKey.provider}/${tiledLayerKey.zoomLevel}/${tiledLayerKey.x}/${tiledLayerKey.y}`;
};
const Map: react.FC<MapProperties> = (props: MapProperties) => { const Map: react.FC<MapProperties> = (props: MapProperties) => {
const nbTiles = const nbTiles =
Math.ceil((Math.max(props.width, props.height) * 2) / 256) + 2; Math.ceil((Math.max(props.width, props.height) * 2) / 256) + 2;
@ -21,6 +32,13 @@ const Map: react.FC<MapProperties> = (props: MapProperties) => {
const [shift, setShift] = useState({ x: -boardSize / 2, y: -boardSize / 2 }); const [shift, setShift] = useState({ x: -boardSize / 2, y: -boardSize / 2 });
const [zoom, setZoom] = useState(1); const [zoom, setZoom] = useState(1);
const [tiledLayerKey, setTiledLayerKey] = useState({
provider: 'osm',
zoomLevel: 16,
x: 33488,
y: 23939,
});
const addShift = (deltaShift: { x: number; y: number }) => { const addShift = (deltaShift: { x: number; y: number }) => {
setShift({ x: shift.x + deltaShift.x, y: shift.y + deltaShift.y }); setShift({ x: shift.x + deltaShift.x, y: shift.y + deltaShift.y });
}; };
@ -37,8 +55,6 @@ const Map: react.FC<MapProperties> = (props: MapProperties) => {
setZoom(zoom * zoomFactor); setZoom(zoom * zoomFactor);
}; };
const [baseZoomLevel, setBaseZoomLevel] = useState(10);
console.log(`Rendering Map, zoom:${zoom}, shift:${JSON.stringify(shift)}`); console.log(`Rendering Map, zoom:${zoom}, shift:${JSON.stringify(shift)}`);
return ( return (
@ -88,8 +104,7 @@ const Map: react.FC<MapProperties> = (props: MapProperties) => {
tileSize={256} tileSize={256}
key='tiled-layers' key='tiled-layers'
numberOfZoomLevels={5} numberOfZoomLevels={5}
baseZoomLevel={baseZoomLevel} tiledLayerKeyState={[tiledLayerKey, setTiledLayerKey]}
setBaseZoomLevel={setBaseZoomLevel}
/> />
<circle key='circle' cx='50' cy='50' r='50' />, <circle key='circle' cx='50' cy='50' r='50' />,
</> </>

View File

@ -1,4 +1,5 @@
import react, { useEffect, useRef } from 'react'; import react, { useEffect, useRef } from 'react';
import { TiledLayerKey } from './Map';
interface TileProperties { interface TileProperties {
href?: string; href?: string;
@ -6,6 +7,7 @@ interface TileProperties {
y: number; y: number;
tileSize: number; tileSize: number;
delay?: number; delay?: number;
tileKey: TiledLayerKey;
} }
const Tile: react.FC<TileProperties> = (props: TileProperties) => { const Tile: react.FC<TileProperties> = (props: TileProperties) => {
@ -46,7 +48,7 @@ const Tile: react.FC<TileProperties> = (props: TileProperties) => {
}; };
loadImage(); loadImage();
} }
}, [props.href, props.delay, props.tileSize]); }, [props.href, props.delay, props.tileSize]);
// const children = useMemo( // const children = useMemo(
// () => ( // () => (

View File

@ -1,6 +1,7 @@
import react, { useEffect, useState } from 'react'; import react, { useEffect, useState } from 'react';
import Tile from './Tile'; import Tile from './Tile';
import fakeTile from './FakeTile.svg'; import fakeTile from './FakeTile.svg';
import { TiledLayerKey, tiledLayerKeyToString } from './Map';
interface Point { interface Point {
x: number; x: number;
@ -16,6 +17,7 @@ interface TiledLayerProperties {
tileSize: number; tileSize: number;
nbTiles: number; nbTiles: number;
active: boolean; active: boolean;
tiledLayerKey: TiledLayerKey;
} }
const TiledLayer: react.FC<TiledLayerProperties> = ( const TiledLayer: react.FC<TiledLayerProperties> = (
@ -25,7 +27,13 @@ const TiledLayer: react.FC<TiledLayerProperties> = (
for (let row = 0; row < props.nbTiles; row++) { for (let row = 0; row < props.nbTiles; row++) {
let tileRow = []; let tileRow = [];
for (let col = 0; col < props.nbTiles; col++) { for (let col = 0; col < props.nbTiles; col++) {
tileRow.push(<g key={`${row}/${col}`} />); const tileKey: TiledLayerKey = {
provider: props.tiledLayerKey.provider,
zoomLevel: props.tiledLayerKey.zoomLevel,
x: props.tiledLayerKey.x + col,
y: props.tiledLayerKey.y + row,
};
tileRow.push(<g key={tiledLayerKeyToString(tileKey)} />);
} }
initialTiles.push(tileRow); initialTiles.push(tileRow);
} }
@ -68,7 +76,12 @@ const TiledLayer: react.FC<TiledLayerProperties> = (
for (let row = 0; row < props.nbTiles; row++) { for (let row = 0; row < props.nbTiles; row++) {
let tileRow = []; let tileRow = [];
for (let col = 0; col < props.nbTiles; col++) { for (let col = 0; col < props.nbTiles; col++) {
const key = `${row}/${col}`; const tileKey: TiledLayerKey = {
provider: props.tiledLayerKey.provider,
zoomLevel: props.tiledLayerKey.zoomLevel,
x: props.tiledLayerKey.x + col,
y: props.tiledLayerKey.y + row,
};
if ( if (
tiles[row][col].type === 'g' && tiles[row][col].type === 'g' &&
row >= firstVisibleTiles.y && row >= firstVisibleTiles.y &&
@ -79,7 +92,8 @@ const TiledLayer: react.FC<TiledLayerProperties> = (
console.log(`Adding tile ${row}/${col}`); console.log(`Adding tile ${row}/${col}`);
tileRow.push( tileRow.push(
<Tile <Tile
key={key} key={tiledLayerKeyToString(tileKey)}
tileKey={tileKey}
href={fakeTile} href={fakeTile}
x={col * props.tileSize} x={col * props.tileSize}
y={row * props.tileSize} y={row * props.tileSize}

View File

@ -1,5 +1,6 @@
import react from 'react'; import react from 'react';
import TiledLayer from './TiledLayer'; import TiledLayer from './TiledLayer';
import { TiledLayerKey, tiledLayerKeyToString } from './Map';
interface Point { interface Point {
x: number; x: number;
@ -13,13 +14,16 @@ interface TiledLayersStackProperties {
zoom: number; zoom: number;
tileSize: number; tileSize: number;
numberOfZoomLevels?: number; numberOfZoomLevels?: number;
baseZoomLevel: number; tiledLayerKeyState: [TiledLayerKey, (tiledLayerKey: TiledLayerKey) => void];
setBaseZoomLevel: (baseZoomLevel: number) => void;
} }
const TiledLayersStack: react.FC<TiledLayersStackProperties> = ( const TiledLayersStack: react.FC<TiledLayersStackProperties> = (
props: TiledLayersStackProperties props: TiledLayersStackProperties
) => { ) => {
console.log(`Rendering TiledLayersStack`);
const [tiledLayerKey, setTiledLayerKey] = props.tiledLayerKeyState;
const numberOfZoomLevels = const numberOfZoomLevels =
props.numberOfZoomLevels === undefined props.numberOfZoomLevels === undefined
? 1 ? 1
@ -43,9 +47,16 @@ const TiledLayersStack: react.FC<TiledLayersStackProperties> = (
const getTiledLayer = (zoomLevel: number, isActive: boolean) => { const getTiledLayer = (zoomLevel: number, isActive: boolean) => {
const zoom = 2 ** (zoomLevel - safetyZoomLevels); const zoom = 2 ** (zoomLevel - safetyZoomLevels);
const currentTiledLayerKey = {
provider: tiledLayerKey.provider,
zoomLevel: zoomLevel + tiledLayerKey.zoomLevel,
x: tiledLayerKey.x * zoom,
y: tiledLayerKey.y * zoom,
};
return ( return (
<TiledLayer <TiledLayer
key={`layer${zoomLevel + props.baseZoomLevel}`} key={tiledLayerKeyToString(currentTiledLayerKey)}
tiledLayerKey={currentTiledLayerKey}
height={props.height * zoom} height={props.height * zoom}
width={props.width * zoom} width={props.width * zoom}
shift={{ shift={{