This commit is contained in:
2026-06-15 23:45:14 +02:00
parent 29fd832bcd
commit 22e3bb4a18
32 changed files with 2531 additions and 362 deletions
+19 -14
View File
@@ -121,13 +121,21 @@ export function MainMap({ fromGrid, toGrid, fromLabel, toLabel, beamAzimuths, be
// ── Antenna beam lobe(s) (drawn first, under the arc/markers) ──
if (from && beamAzimuths && beamAzimuths.length) {
const half = (beamWidth ?? 30) / 2;
const D = 5500; // lobe length (km) — short enough to rarely reach a pole
const radial = (b: number): [number, number][] =>
Array.from({ length: 14 }, (_, i) => {
const d = destinationPoint(from.lat, from.lon, b, (D * (i + 1)) / 14);
return [d.lat, d.lon] as [number, number];
});
const edge = { color: '#dc2626', weight: 1.5, opacity: 0.6 };
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.
const radial = (b: number): [number, number][] => {
const pts: [number, number][] = [];
const N = 64;
for (let i = 1; i <= N; i++) {
const d = destinationPoint(from.lat, from.lon, b, (D * i) / N);
pts.push([d.lat, d.lon]);
if (Math.abs(d.lat) > 86) break; // near a pole — stop before the snap
}
return pts;
};
for (const az of beamAzimuths) {
const arc: [number, number][] = [];
for (let b = az - half; b <= az + half + 0.001; b += 2) {
@@ -140,13 +148,10 @@ export function MainMap({ fromGrid, toGrid, fromLabel, toLabel, beamAzimuths, be
...arc,
...radial(az + half).reverse(),
]);
// A geodesic lobe that reaches near a pole can't be filled on a
// Mercator map without the polygon snapping across the whole world —
// draw just the two edges in that case; otherwise the translucent lobe.
if (ring.some(([la]) => Math.abs(la) > 82)) {
L.polyline(unwrapLon([[from.lat, from.lon], ...radial(az - half)]) as L.LatLngExpression[], edge).addTo(wo);
L.polyline(unwrapLon([[from.lat, from.lon], ...radial(az + half)]) as L.LatLngExpression[], edge).addTo(wo);
} else {
// 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);