Correct algorithm for centering tiles.
This commit is contained in:
parent
9e8aec244e
commit
4e26d94843
|
@ -1,55 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
import { PigeonProps, Point } from 'pigeon-maps';
|
||||
import GPX from 'gpx-parser-builder';
|
||||
import { round } from 'lodash';
|
||||
|
||||
const GPXFigure: React.FC<PigeonProps> = (props: PigeonProps) => {
|
||||
const gpx = GPX.parse(localStorage.getItem('gpx'));
|
||||
|
||||
const dirtyLatLngToPixel = (point: Point) => {
|
||||
if (props.mapState === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const latRange = props.mapState.bounds.ne[0] - props.mapState.bounds.sw[0];
|
||||
const lonRange = props.mapState.bounds.ne[1] - props.mapState.bounds.sw[1];
|
||||
const x = round(
|
||||
((point[0] - props.mapState.bounds.sw[0]) * props.mapState.width) /
|
||||
lonRange
|
||||
);
|
||||
const y = round(
|
||||
((point[1] - props.mapState.bounds.sw[1]) * props.mapState.height) /
|
||||
latRange
|
||||
);
|
||||
return [x, props.mapState.height - y];
|
||||
};
|
||||
|
||||
const trkToPolyline = (gpxData: any) => {
|
||||
const latLongs: string[] = gpxData.trk[0].trkseg[0].trkpt.map(
|
||||
(trkpt: any) => {
|
||||
if (props.latLngToPixel === undefined) {
|
||||
return '';
|
||||
}
|
||||
const point: Point = [trkpt.$.lat, trkpt.$.lon];
|
||||
const pixelPoint = dirtyLatLngToPixel(point);
|
||||
if (pixelPoint === undefined) {
|
||||
return '';
|
||||
}
|
||||
return pixelPoint.join(' ');
|
||||
}
|
||||
);
|
||||
console.log('latLongs: ' + latLongs);
|
||||
return latLongs.join(' ');
|
||||
};
|
||||
|
||||
return (
|
||||
<polyline
|
||||
points={trkToPolyline(gpx)}
|
||||
stroke='black'
|
||||
strokeWidth='3'
|
||||
fill='none'
|
||||
></polyline>
|
||||
);
|
||||
};
|
||||
|
||||
export default GPXFigure;
|
|
@ -1,27 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Overlay, PigeonProps } from 'pigeon-maps';
|
||||
|
||||
import GPXFigure from './gpx-figure';
|
||||
|
||||
const GPXOverlay: React.FC<PigeonProps> = (props: PigeonProps) => {
|
||||
return (
|
||||
<Overlay >
|
||||
{props.mapState && props.mapState.width > 0 && (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox={'0 0 ' + props.mapState.width + ' ' + props.mapState.height}
|
||||
width={props.mapState.width}
|
||||
height={props.mapState.height}
|
||||
>
|
||||
<GPXFigure
|
||||
mapState={props.mapState}
|
||||
latLngToPixel={props.latLngToPixel}
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</Overlay>
|
||||
);
|
||||
};
|
||||
|
||||
export default GPXOverlay;
|
|
@ -1,7 +1,6 @@
|
|||
import _, { round } from 'lodash';
|
||||
import react, { useState, useEffect } from 'react';
|
||||
|
||||
import GPXOverlay from './gpx-overlay';
|
||||
import Tile from './tile';
|
||||
|
||||
import '../theme/map.css';
|
||||
|
@ -24,13 +23,13 @@ const lat2tile = (lat: number, zoom: number) => {
|
|||
Math.PI) /
|
||||
2) *
|
||||
Math.pow(2, zoom);
|
||||
const floor = Math.floor(real);
|
||||
return [floor, real - floor];
|
||||
};
|
||||
const floor = Math.floor(real);
|
||||
return [floor, real - floor];
|
||||
};
|
||||
|
||||
const Map: react.FC = () => {
|
||||
const initialCenter: [number, number] = [43.57029965, 3.94242897];
|
||||
const initialZoom: number = 15;
|
||||
const initialZoom: number = 17;
|
||||
const [center, setCenter] = useState(initialCenter);
|
||||
const [zoom, setZoom] = useState(initialZoom);
|
||||
|
||||
|
@ -51,12 +50,16 @@ const Map: react.FC = () => {
|
|||
|
||||
const nbTilesY = _.ceil(dimensions.height / tileSize) + 2;
|
||||
const nbTilesX = _.ceil(dimensions.width / tileSize) + 2;
|
||||
const [tileCenterY, deltaY] = lat2tile(center[0], zoom);
|
||||
const [tileCenterX, deltaX] = lon2tile(center[1], zoom);
|
||||
const [tileCenterY, reminderY] = lat2tile(center[0], zoom);
|
||||
const [tileCenterX, reminderX] = lon2tile(center[1], zoom);
|
||||
const firstTileY = tileCenterY - _.ceil(nbTilesY / 2);
|
||||
const firstTileX = tileCenterX - _.ceil(nbTilesX / 2);
|
||||
|
||||
|
||||
const locationY = ((tileCenterY + reminderY - firstTileY ) * tileSize) ;
|
||||
const locationX = ((tileCenterX + reminderX - firstTileX ) * tileSize) ;
|
||||
const targetLocationY = dimensions.height / 2;
|
||||
const targetLocationX = dimensions.width / 2;
|
||||
const deltaY = - targetLocationY + locationY;
|
||||
const deltaX = - targetLocationX + locationX;
|
||||
|
||||
return (
|
||||
<div className='tiles'>
|
||||
|
@ -69,8 +72,8 @@ const Map: react.FC = () => {
|
|||
ix={ix}
|
||||
x={firstTileX + ix}
|
||||
y={firstTileY + iy}
|
||||
deltaX ={deltaX}
|
||||
deltaY ={deltaY}
|
||||
deltaX={deltaX}
|
||||
deltaY={deltaY}
|
||||
zoom={zoom}
|
||||
/>
|
||||
))}
|
||||
|
|
|
@ -26,12 +26,18 @@ const Tile: React.FC<{
|
|||
height: tileSize + 'px',
|
||||
transform:
|
||||
'translate3d(' +
|
||||
(props.ix - props.deltaX -1) * tileSize +
|
||||
(props.ix * tileSize - props.deltaX) +
|
||||
'px, ' +
|
||||
(props.iy - props.deltaY -1) * tileSize +
|
||||
(props.iy * tileSize - props.deltaY) +
|
||||
'px, 0px)',
|
||||
};
|
||||
return <img src={tileProvider(props.zoom, props.x, props.y)} style={style} />;
|
||||
return (
|
||||
<img
|
||||
src={tileProvider(props.zoom, props.x, props.y)}
|
||||
style={style}
|
||||
alt=''
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tile;
|
||||
|
|
Loading…
Reference in New Issue