import type { MapProjection } from "../geometry/mapProjection"; import type { MapPolygon } from "../model/mapTypes"; const SURVEY_COLORS: Record = { OPTICS: "#FFA040", RSA: "#40AFFF", COMBINED: "#C080FF" }; const DEFAULT_COLOR = "#FFA040"; type Pt = { x: number; y: number }; function unwrapX(points: Pt[], worldSize: number): Pt[] { if (points.length === 0) return []; const out: Pt[] = [points[0]]; let prevX = points[0].x; for (let i = 1; i < points.length; i++) { let x = points[i].x; while (x - prevX > worldSize / 2) x -= worldSize; while (prevX - x > worldSize / 2) x += worldSize; out.push({ x, y: points[i].y }); prevX = x; } return out; } export function drawRequests( ctx: CanvasRenderingContext2D, polygons: MapPolygon[], projection: MapProjection, viewport: { width: number; height: number } ) { ctx.save(); for (const polygon of polygons) { if (polygon.points.length < 3) continue; const raw = polygon.points.map((p) => projection.project(p)); const pts = unwrapX(raw, projection.worldSize); const color = SURVEY_COLORS[polygon.surveyType ?? ""] ?? DEFAULT_COLOR; ctx.fillStyle = hexToRgba(color, 0.18); ctx.strokeStyle = hexToRgba(color, 0.85); ctx.lineWidth = 1.5; ctx.setLineDash([4, 3]); for (const dx of [0, projection.worldSize, -projection.worldSize]) { const visible = pts.some((p) => { const x = p.x + dx; return x >= -64 && x <= viewport.width + 64 && p.y >= -64 && p.y <= viewport.height + 64; }); if (!visible) continue; ctx.beginPath(); for (let i = 0; i < pts.length; i++) { if (i === 0) ctx.moveTo(pts[i].x + dx, pts[i].y); else ctx.lineTo(pts[i].x + dx, pts[i].y); } ctx.closePath(); ctx.fill(); ctx.stroke(); } ctx.setLineDash([]); } ctx.restore(); } function hexToRgba(hex: string, alpha: number): string { const value = hex.replace("#", ""); const red = Number.parseInt(value.slice(0, 2), 16); const green = Number.parseInt(value.slice(2, 4), 16); const blue = Number.parseInt(value.slice(4, 6), 16); return `rgba(${red}, ${green}, ${blue}, ${alpha})`; }