Refactoring to send a viewport property to slippy graphics (new, more generic, name for markers)

This commit is contained in:
Eric van der Vlist 2022-11-03 11:37:22 +01:00
parent 7f03b0bca4
commit c4094b28ae
6 changed files with 38 additions and 35 deletions

View File

@ -99,7 +99,7 @@ const App: React.FC = () => {
scope={scope}
setScope={debounce(setScope, 1000)}
numberOfTiledLayers={5}
markers={[<CurrentLocation key='currentLocation' />]}
slippyGraphics={[<CurrentLocation key='currentLocation' />]}
/>
</IonApp>
</IonContent>

View File

@ -28,8 +28,8 @@ export interface LayerStackProperties {
* The coordinates system
*/
coordinateSystem: CoordinateSystem;
/** Markers are non scalable SVG snippets tied to geo location */
markers?: ReactElement<any, string | JSXElementConstructor<any>>[];
/** Slippy graphics are non scalable SVG snippets defined by geo locations */
slippyGraphics?: ReactElement<any, string | JSXElementConstructor<any>>[];
}
/**
@ -53,7 +53,10 @@ export const LayerStack: react.FC<LayerStackProperties> = (
const activeTiledLayer = Math.floor(numberOfTiledLayers / 2);
const getTiledLayer = (i: number) => {
const getTiledLayer = (
i: number,
slippyGraphics?: typeof props.slippyGraphics
) => {
const relativeZoomLevel = i - activeTiledLayer;
const zoom = 2 ** relativeZoomLevel;
const origin = {
@ -82,6 +85,7 @@ export const LayerStack: react.FC<LayerStackProperties> = (
shift={shift}
zoom={256 / zoom}
coordinateSystem={props.coordinateSystem}
slippyGraphics={slippyGraphics}
/>
);
};
@ -96,36 +100,19 @@ export const LayerStack: react.FC<LayerStackProperties> = (
>
{
// Tiled layers with less detail
range(0, activeTiledLayer).map(getTiledLayer)
range(0, activeTiledLayer).map((index) => getTiledLayer(index))
}
{
// Tiled layers with more details
range(numberOfTiledLayers - 1, activeTiledLayer, -1).map(
getTiledLayer
range(numberOfTiledLayers - 1, activeTiledLayer, -1).map((index) =>
getTiledLayer(index)
)
}
{
// And the active one
getTiledLayer(activeTiledLayer)
getTiledLayer(activeTiledLayer, props.slippyGraphics)
}
</g>
{props.markers !== undefined ? (
<g
key='markers'
transform={`translate(${props.coordinateSystem.shift.x}, ${props.coordinateSystem.shift.y}) scale(${props.coordinateSystem.zoom})`}
>
<g
transform={`scale(256) translate(-${props.keyObject.x}, -${props.keyObject.y})`}
>
{props.markers.map((marker) =>
cloneElement(marker, {
keyObject: props.keyObject,
zoom: props.coordinateSystem.zoom,
})
)}
</g>
</g>
) : null}
</svg>
);
};

View File

@ -39,8 +39,8 @@ export interface LiveMapProperties {
numberOfTiledLayers?: number;
/** If provided, a function to call when the scope is updated. */
setScope?: (scope: MapScope) => void;
/** Markers are non scalable SVG snippets tied to geo location */
markers?: ReactElement<any, string | JSXElementConstructor<any>>[];
/** Slippy graphics are non scalable SVG snippets defined by geo locations */
slippyGraphics?: ReactElement<any, string | JSXElementConstructor<any>>[];
}
/**
@ -137,7 +137,7 @@ export const LiveMap: react.FC<LiveMapProperties> = (
<Map
scope={scope}
numberOfTiledLayers={props.numberOfTiledLayers}
markers={props.markers}
slippyGraphics={props.slippyGraphics}
/>
</div>
);

View File

@ -11,8 +11,8 @@ import { lon2tile, lat2tile } from '../../lib/geo';
export interface MapProperties {
scope: MapScope;
numberOfTiledLayers?: number;
/** Markers are non scalable SVG snippets tied to geo location */
markers?: ReactElement<any, string | JSXElementConstructor<any>>[];
/** Slippy graphics are non scalable SVG snippets defined by geo locations */
slippyGraphics?: ReactElement<any, string | JSXElementConstructor<any>>[];
}
/**
@ -62,7 +62,7 @@ export const Map: react.FC<MapProperties> = (props: MapProperties) => {
},
zoom: relativeScale,
}}
markers={props.markers}
slippyGraphics={props.slippyGraphics}
/>
</div>
);

View File

@ -1,14 +1,13 @@
import { KeyObject } from 'crypto';
import react, { ReactNode } from 'react';
import { lat2tile, lon2tile } from '../../lib/geo';
import { CoordinateSystem } from './LiveMap';
import { geoPoint, TileKeyObject } from './types';
import { geoPoint, Rectangle, TileKeyObject } from './types';
export interface MarkerProperties {
coordinates: geoPoint;
icon: ReactNode;
keyObject?: TileKeyObject;
zoom?: number;
viewPort?: Rectangle;
}
export const Marker: react.FC<MarkerProperties> = (props: MarkerProperties) => {

View File

@ -1,4 +1,9 @@
import react, { ReactNode, useRef } from 'react';
import react, {
cloneElement,
JSXElementConstructor,
ReactElement,
useRef,
} from 'react';
import TileSet from './TileSet';
import { Point, TileKeyObject } from './types';
import { CoordinateSystem } from './LiveMap';
@ -20,6 +25,8 @@ export interface TiledLayerProperties {
* The coordinate system
*/
coordinateSystem: CoordinateSystem;
/** Slippy graphics are non scalable SVG snippets defined by geo locations */
slippyGraphics?: ReactElement<any, string | JSXElementConstructor<any>>[];
}
/**
@ -89,6 +96,16 @@ export const TiledLayer: react.FC<TiledLayerProperties> = (
}}
viewPort={viewPort}
/>
{props.slippyGraphics !== undefined && viewPort !== undefined
? // Slippy graphics (if needed)
props.slippyGraphics.map((slippyGraphic) =>
cloneElement(slippyGraphic, {
keyObject: props.keyObject,
zoom: props.coordinateSystem.zoom,
viewPort: viewPort,
})
)
: null}
</g>
</>
);