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

View File

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

View File

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