feat(grids): one world, a zoom that holds it, and the modes to filter it

The grid-square map drew the world two or three times across a wide window, each
copy carrying the same squares — worldCopyJump earns its keep on the great-circle
map, where a path reads better crossing a second Asia, and costs only confusion
on a map of where you have been heard. It is off here, the tiles no longer wrap,
and addBasemap takes the option so the other map is untouched.

Zooming out far enough to hold Greenland and Antarctica together was impossible:
the floor was zoom 1, and one step further out was already too far. Zoom 0 is
the whole planet, and the view now opens on a fitWorld computed from the
container rather than a guessed zoom level — repeated once when the container
first has a real size, because the tab is mounted hidden.

That exposed the next thing: Esri answers a request outside the world with a grey
"Map data not yet available" tile, and zoomed out that was most of the screen.
The tile layers carry a bounds, so those tiles are never asked for, and what is
left beside the planet is the panel's own background instead of a white slab.

Finally the mode filter offers All, Phone and CW beside Digital and FTx. The
backend already accepted all of them — GridSquares understands "ALL" and the
ModeClass names — only the interface was offering two.
This commit is contained in:
2026-08-21 14:35:54 +02:00
parent c31ab05c80
commit d01c288454
3 changed files with 67 additions and 17 deletions
+17 -3
View File
@@ -85,13 +85,27 @@ export function addBasemap(
key: BasemapKey,
base: React.MutableRefObject<L.TileLayer | null>,
labels: React.MutableRefObject<L.TileLayer | null>,
// noWrap draws the world ONCE instead of repeating it east and west.
//
// The great-circle map wants the repeats: a path from France to Japan reads
// better crossing a second copy of Asia than wrapping round the back. A map of
// where you have been heard does not — three North Americas is three times the
// same answer, and it makes the picture harder to read, not wider.
// bounds stops Leaflet asking for tiles outside the world at all: Esri answers
// those with a grey "Map data not yet available" image, and zoomed out on a
// wide window that is most of the screen.
opts?: { noWrap?: boolean; bounds?: L.LatLngBoundsExpression },
) {
if (base.current) { m.removeLayer(base.current); base.current = null; }
if (labels.current) { m.removeLayer(labels.current); labels.current = null; }
const bm = BASEMAPS[key];
const opts: L.TileLayerOptions = { maxZoom: 19, updateWhenIdle: true, updateWhenZooming: false, keepBuffer: 1 };
base.current = L.tileLayer(bm.url, { ...opts, attribution: bm.attr, subdomains: bm.subdomains ?? 'abc' }).addTo(m);
if (bm.labelsUrl) labels.current = L.tileLayer(bm.labelsUrl, opts).addTo(m);
const tileOpts: L.TileLayerOptions = {
maxZoom: 19, updateWhenIdle: true, updateWhenZooming: false, keepBuffer: 1,
noWrap: !!opts?.noWrap,
...(opts?.bounds ? { bounds: opts.bounds } : {}),
};
base.current = L.tileLayer(bm.url, { ...tileOpts, attribution: bm.attr, subdomains: bm.subdomains ?? 'abc' }).addTo(m);
if (bm.labelsUrl) labels.current = L.tileLayer(bm.labelsUrl, tileOpts).addTo(m);
}
function dot(color: string): L.DivIcon {