import { type CameraState } from '../camera/camera' import { lonLatToWorldTile } from '../../utils/projection' import { worldToScreen } from '../camera/camera' import { type MapLayer, type LayerRenderContext } from './mapLayer' import { type MapScene } from '../renderer/mapRenderer' export interface ScreenPoint { x: number y: number } export class TrackLayer implements MapLayer { projectPoints(scene: MapScene, camera: CameraState): ScreenPoint[] { return scene.track.map((point) => { const worldPoint = lonLatToWorldTile(point, scene.zoom) const screenPoint = worldToScreen(camera, worldPoint, false) return { x: screenPoint.x + scene.translateX, y: screenPoint.y + scene.translateY, } }) } draw(context: LayerRenderContext): void { const { ctx, camera, scene } = context const points = this.projectPoints(scene, camera) ctx.save() ctx.lineCap = 'round' ctx.lineJoin = 'round' ctx.strokeStyle = 'rgba(23, 109, 93, 0.96)' ctx.lineWidth = 6 ctx.beginPath() points.forEach((screenPoint, index) => { if (index === 0) { ctx.moveTo(screenPoint.x, screenPoint.y) return } ctx.lineTo(screenPoint.x, screenPoint.y) }) ctx.stroke() ctx.fillStyle = '#f7fbf2' ctx.strokeStyle = '#176d5d' ctx.lineWidth = 4 points.forEach((screenPoint, index) => { ctx.beginPath() ctx.arc(screenPoint.x, screenPoint.y, 10, 0, Math.PI * 2) ctx.fill() ctx.stroke() ctx.fillStyle = '#176d5d' ctx.font = 'bold 14px sans-serif' ctx.textAlign = 'center' ctx.textBaseline = 'middle' ctx.fillText(String(index + 1), screenPoint.x, screenPoint.y) ctx.fillStyle = '#f7fbf2' }) ctx.restore() } }