fix: proper beam heading on the map

This commit is contained in:
2026-06-16 20:24:49 +02:00
parent e5c6bddb29
commit 3d15f20c7f
+12 -23
View File
@@ -122,10 +122,8 @@ export function MainMap({ fromGrid, toGrid, fromLabel, toLabel, beamAzimuths, be
if (from && beamAzimuths && beamAzimuths.length) {
const half = (beamWidth ?? 30) / 2;
const D = 5500; // lobe length (km)
// A great circle pointing poleward runs to lat ±90, where Mercator is
// infinite — the line then snaps across the top of the map. Generate the
// radial with plenty of points (smooth curve) and STOP it just before the
// pole, so a north/south beam draws a clean line toward the edge instead.
// Great-circle radial out to distance D, stopping just short of the pole so
// a poleward line doesn't snap across the top of the Mercator map.
const radial = (b: number): [number, number][] => {
const pts: [number, number][] = [];
const N = 64;
@@ -137,26 +135,17 @@ export function MainMap({ fromGrid, toGrid, fromLabel, toLabel, beamAzimuths, be
return pts;
};
for (const az of beamAzimuths) {
const arc: [number, number][] = [];
for (let b = az - half; b <= az + half + 0.001; b += 2) {
const d = destinationPoint(from.lat, from.lon, b, D);
arc.push([d.lat, d.lon]);
// Draw the lobe as a FAN of translucent great-circle radials, not a
// filled polygon: a polygon breaks badly near the poles on Mercator (its
// edges run off toward ±90° and the fill smears across the map), while
// each radial LINE stays clean. The overlapping lines read as a lobe —
// solid near the antenna, fanning out toward the front. Works for any
// azimuth, north/south included.
for (let b = az - half; b <= az + half + 0.001; b += 1.5) {
const line = unwrapLon([[from.lat, from.lon], ...radial(b)]);
L.polyline(line as L.LatLngExpression[], { color: '#dc2626', weight: 6, opacity: 0.07 }).addTo(wo);
}
const ring = unwrapLon([
[from.lat, from.lon],
...radial(az - half),
...arc,
...radial(az + half).reverse(),
]);
// Near a pole the lobe's two edges diverge wildly (one runs NW, the
// other NE) and look broken on a Mercator map — so for a poleward beam
// show ONLY the clean boresight (below). Otherwise draw the filled lobe.
if (!ring.some(([la]) => Math.abs(la) > 78)) {
L.polygon(ring as L.LatLngExpression[], {
color: '#dc2626', weight: 1, opacity: 0.5, fillColor: '#dc2626', fillOpacity: 0.14,
}).addTo(wo);
}
// Boresight (dashed centre line) — always; great-circle polyline is safe.
// Boresight (dashed centre line).
const cl = unwrapLon([[from.lat, from.lon], ...radial(az)]);
L.polyline(cl as L.LatLngExpression[], { color: '#dc2626', weight: 1.5, opacity: 0.7, dashArray: '5 4' })
.bindTooltip(`Beam ${Math.round(az)}°`, { permanent: false, direction: 'top' }).addTo(wo);