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} scope={scope}
setScope={debounce(setScope, 1000)} setScope={debounce(setScope, 1000)}
numberOfTiledLayers={5} numberOfTiledLayers={5}
markers={[<CurrentLocation key='currentLocation' />]} slippyGraphics={[<CurrentLocation key='currentLocation' />]}
/> />
</IonApp> </IonApp>
</IonContent> </IonContent>

View File

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

View File

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

View File

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

View File

@ -1,14 +1,13 @@
import { KeyObject } from 'crypto';
import react, { ReactNode } from 'react'; import react, { ReactNode } from 'react';
import { lat2tile, lon2tile } from '../../lib/geo'; import { lat2tile, lon2tile } from '../../lib/geo';
import { CoordinateSystem } from './LiveMap'; import { geoPoint, Rectangle, TileKeyObject } from './types';
import { geoPoint, TileKeyObject } from './types';
export interface MarkerProperties { export interface MarkerProperties {
coordinates: geoPoint; coordinates: geoPoint;
icon: ReactNode; icon: ReactNode;
keyObject?: TileKeyObject; keyObject?: TileKeyObject;
zoom?: number; zoom?: number;
viewPort?: Rectangle;
} }
export const Marker: react.FC<MarkerProperties> = (props: MarkerProperties) => { 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 TileSet from './TileSet';
import { Point, TileKeyObject } from './types'; import { Point, TileKeyObject } from './types';
import { CoordinateSystem } from './LiveMap'; import { CoordinateSystem } from './LiveMap';
@ -20,6 +25,8 @@ export interface TiledLayerProperties {
* The coordinate system * The coordinate system
*/ */
coordinateSystem: CoordinateSystem; 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} 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> </g>
</> </>
); );