Files
cmr-mini/miniprogram/engine/layer/trackLayer.ts

73 lines
2.1 KiB
TypeScript

import { type CameraState } from '../camera/camera'
import { calibratedLonLatToWorldTile } 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
}
function buildVectorCamera(scene: MapScene): CameraState {
return {
centerWorldX: scene.exactCenterWorldX,
centerWorldY: scene.exactCenterWorldY,
viewportWidth: scene.viewportWidth,
viewportHeight: scene.viewportHeight,
visibleColumns: scene.visibleColumns,
rotationRad: scene.rotationRad,
}
}
export class TrackLayer implements MapLayer {
projectPoints(scene: MapScene): ScreenPoint[] {
const camera = buildVectorCamera(scene)
return scene.track.map((point) => {
const worldPoint = calibratedLonLatToWorldTile(point, scene.zoom, scene.gpsCalibration, scene.gpsCalibrationOrigin)
return worldToScreen(camera, worldPoint, false)
})
}
draw(context: LayerRenderContext): void {
const { ctx, scene } = context
const points = this.projectPoints(scene)
if (!points.length) {
return
}
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()
}
}