129 lines
2.7 KiB
TypeScript
129 lines
2.7 KiB
TypeScript
import React from 'react';
|
|
import { useSelector } from 'react-redux';
|
|
import { MapState } from '../../store/map';
|
|
|
|
export interface TileProvider {
|
|
name: string;
|
|
minZoom: number;
|
|
maxZoom: number;
|
|
getTileUrl: { (zoom: number, x: number, y: number): string };
|
|
}
|
|
|
|
const getRandomItem = (items: any[]) => {
|
|
const idx = Math.floor(Math.random() * items.length);
|
|
return items[idx];
|
|
};
|
|
|
|
const abc = ['a', 'b', 'c'];
|
|
|
|
export const tileProviders: any = {
|
|
osm: {
|
|
name: 'Open Street Map',
|
|
minZoom: 0,
|
|
maxZoom: 19,
|
|
getTileUrl: (zoom: number, x: number, y: number) =>
|
|
'https://tile.openstreetmap.org/' + zoom + '/' + x + '/' + y + '.png',
|
|
},
|
|
osmfr: {
|
|
name: 'Open Street Map France',
|
|
minZoom: 0,
|
|
maxZoom: 19,
|
|
getTileUrl: (zoom: number, x: number, y: number) =>
|
|
'https://' +
|
|
getRandomItem(abc) +
|
|
'.tile.openstreetmap.fr/osmfr/' +
|
|
zoom +
|
|
'/' +
|
|
x +
|
|
'/' +
|
|
y +
|
|
'.png',
|
|
},
|
|
otm: {
|
|
name: 'Open Topo Map',
|
|
minZoom: 0,
|
|
maxZoom: 19,
|
|
getTileUrl: (zoom: number, x: number, y: number) =>
|
|
'https://' +
|
|
getRandomItem(abc) +
|
|
'.tile.opentopomap.org/' +
|
|
zoom +
|
|
'/' +
|
|
x +
|
|
'/' +
|
|
y +
|
|
'.png',
|
|
},
|
|
cyclosm: {
|
|
name: 'CyclOSM',
|
|
minZoom: 0,
|
|
maxZoom: 19,
|
|
getTileUrl: (zoom: number, x: number, y: number) =>
|
|
'https://' +
|
|
getRandomItem(abc) +
|
|
'.tile-cyclosm.openstreetmap.fr/cyclosm/' +
|
|
zoom +
|
|
'/' +
|
|
x +
|
|
'/' +
|
|
y +
|
|
'.png',
|
|
},
|
|
// cyclosmlite: {
|
|
// name: 'CyclOSM lite',
|
|
// minZoom: 0,
|
|
// maxZoom: 19,
|
|
// getTileUrl: (zoom: number, x: number, y: number) =>
|
|
// 'https://' +
|
|
// getRandomItem(abc) +
|
|
// '.tile-cyclosm.openstreetmap.fr/cyclosm-lite/' +
|
|
// zoom +
|
|
// '/' +
|
|
// x +
|
|
// '/' +
|
|
// y +
|
|
// '.png',
|
|
// },
|
|
// esrisat: {
|
|
// name: 'ESRI Satellite',
|
|
// minZoom: 0,
|
|
// maxZoom: 19,
|
|
// getTileUrl: (zoom: number, x: number, y: number) =>
|
|
// 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/' +
|
|
// zoom +
|
|
// '/' +
|
|
// x +
|
|
// '/' +
|
|
// y +
|
|
// '.jpg',
|
|
// },
|
|
};
|
|
|
|
const Tile: React.FC<{
|
|
ix: number;
|
|
iy: number;
|
|
x: number;
|
|
y: number;
|
|
zoom: number;
|
|
}> = (props: {
|
|
ix: number;
|
|
iy: number;
|
|
x: number;
|
|
y: number;
|
|
zoom: number;
|
|
}) => {
|
|
const tileProvider = useSelector(
|
|
(state: { map: MapState }) => state.map.scope.tileProvider
|
|
) as keyof typeof tileProviders;
|
|
|
|
return (
|
|
<img
|
|
src={tileProviders[tileProvider].getTileUrl(props.zoom, props.x, props.y)}
|
|
className='tile'
|
|
alt=''
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default Tile;
|