Using useViewport in LayerStack rather than TiledLayer to share it with slippy graphics.

This commit is contained in:
Eric van der Vlist 2022-11-17 14:57:55 +01:00
parent fa049e36e5
commit 812849cdef
3 changed files with 22 additions and 17 deletions

View File

@ -4,9 +4,10 @@ import react, {
ReactComponentElement,
ReactElement,
ReactNode,
useRef,
} from 'react';
import { TileKeyObject } from './types';
import { Rectangle, TileKeyObject } from './types';
import { CoordinateSystem } from './LiveMap';
import { range } from 'lodash';
@ -14,6 +15,7 @@ import tileUri from './uris';
import TiledLayer from './TiledLayer';
import { ReactComponentOrElement } from '@ionic/react';
import { KeyObject } from 'crypto';
import useViewport from './use-viewport';
export interface LayerStackProperties {
/**
@ -53,13 +55,20 @@ export const LayerStack: react.FC<LayerStackProperties> = (
props.coordinateSystem
)}, slippyGraphics: ${props.slippyGraphics}`
);
const g = useRef<SVGGElement>(null);
const viewPort = useViewport({
coordinateSystem: props.coordinateSystem,
keyObject: props.keyObject,
svgElement: g,
});
const numberOfTiledLayers =
props.numberOfTiledLayers === undefined ? 1 : props.numberOfTiledLayers;
const activeTiledLayer = Math.floor(numberOfTiledLayers / 2);
const getTiledLayer = (i: number) => {
const getTiledLayer = (i: number, viewPort?: Rectangle) => {
const relativeZoomLevel = i - activeTiledLayer;
const zoom = 2 ** relativeZoomLevel;
const origin = {
@ -88,6 +97,7 @@ export const LayerStack: react.FC<LayerStackProperties> = (
shift={shift}
zoom={256 / zoom}
coordinateSystem={props.coordinateSystem}
viewPort={viewPort}
/>
);
};
@ -99,6 +109,7 @@ export const LayerStack: react.FC<LayerStackProperties> = (
<g
transform={`translate(${props.coordinateSystem.shift.x}, ${props.coordinateSystem.shift.y}) scale(${props.coordinateSystem.zoom})`}
key='tiles'
ref={g}
>
{
// Tiled layers with less detail
@ -112,7 +123,7 @@ export const LayerStack: react.FC<LayerStackProperties> = (
}
{
// And the active one
getTiledLayer(activeTiledLayer)
getTiledLayer(activeTiledLayer, viewPort)
}
{/* {props.slippyGraphics !== undefined ? (
// Slippy graphics (if needed)

View File

@ -28,6 +28,10 @@ export interface TiledLayerProperties {
* The coordinate system
*/
coordinateSystem: CoordinateSystem;
/**
*
*/
viewPort?: Rectangle;
}
/**
@ -40,20 +44,15 @@ export interface TiledLayerProperties {
export const TiledLayer: react.FC<TiledLayerProperties> = (
props: TiledLayerProperties
) => {
const g = useRef<SVGGElement>(null);
const viewPort = useViewport({ ...props, svgElement: g });
console.log(
`Rendering TiledLayer, zoom: ${props.zoom}, viewPort: ${JSON.stringify(
viewPort
props.viewPort
)}`
);
return (
<>
<g
transform={`scale(${props.zoom}) translate(${props.shift.x}, ${props.shift.y})`}
ref={g}
>
<TileSet
keyObject={{
@ -62,7 +61,7 @@ export const TiledLayer: react.FC<TiledLayerProperties> = (
x: 0,
y: 0,
}}
viewPort={viewPort}
viewPort={props.viewPort}
/>
</g>
</>

View File

@ -5,17 +5,12 @@ import { Rectangle, TileKeyObject } from './types';
const useViewport = (props: {
keyObject: TileKeyObject;
coordinateSystem: CoordinateSystem;
zoom: number;
svgElement: RefObject<SVGGElement>;
}) => {
const { keyObject, coordinateSystem, zoom, svgElement } = props;
const { keyObject, coordinateSystem, svgElement } = props;
const [viewPort, setViewPort] = useState<Rectangle>();
useEffect(() => {
console.log(
`TiledLayer zoom: ${zoom}, useEffect, g.current: ${svgElement.current}`
);
if (
zoom === 256 &&
svgElement.current !== null &&
svgElement.current.ownerSVGElement !== null &&
svgElement.current.ownerSVGElement.parentElement !== null
@ -50,7 +45,7 @@ const useViewport = (props: {
},
});
}
}, [props.keyObject, props.coordinateSystem, props.zoom]);
}, [props.keyObject, props.coordinateSystem]);
return viewPort;
};
export default useViewport;