fix(maps): fix _upgradeTiles race guard, interval leak, graticule events, ring labels

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
James Smith
2026-04-13 22:24:23 +01:00
parent 99edea33e3
commit 51f8a6f65b
+20 -7
View File
@@ -57,7 +57,7 @@ const MapUtils = {
if (typeof Settings === 'undefined') return; if (typeof Settings === 'undefined') return;
try { try {
await Settings.init(); await Settings.init();
if (!map || !map.getContainer || !map.getContainer()) return; if (!map || map._removed) return;
const layer = Settings.createTileLayer(); const layer = Settings.createTileLayer();
let loaded = false; let loaded = false;
layer.once('load', () => { layer.once('load', () => {
@@ -186,22 +186,35 @@ const MapUtils = {
}; };
if (options.graticule) { if (options.graticule) {
buildGraticule(); buildGraticule();
map.on('zoomend moveend', buildGraticule); map.on('zoomend', buildGraticule);
cleanupFns.push(() => { cleanupFns.push(() => {
map.off('zoomend moveend', buildGraticule); map.off('zoomend', buildGraticule);
removeGraticule(); removeGraticule();
}); });
} }
handles.showGraticule = () => { handles.showGraticule = () => {
buildGraticule(); buildGraticule();
map.on('zoomend moveend', buildGraticule); map.on('zoomend', buildGraticule);
}; };
handles.hideGraticule = () => { handles.hideGraticule = () => {
map.off('zoomend moveend', buildGraticule); map.off('zoomend', buildGraticule);
removeGraticule(); removeGraticule();
}; };
handles.removeAll = () => cleanupFns.forEach(fn => fn()); handles.removeAll = () => cleanupFns.forEach(fn => fn());
// Auto-cleanup when Leaflet map is removed
const autoCleanup = () => {
cleanupFns.forEach(fn => fn());
map.off('remove', autoCleanup);
};
map.on('remove', autoCleanup);
const originalRemoveAll = handles.removeAll;
handles.removeAll = () => {
map.off('remove', autoCleanup);
originalRemoveAll();
};
return handles; return handles;
}, },
@@ -227,8 +240,8 @@ const MapUtils = {
interactive: false, interactive: false,
}).addTo(layer); }).addTo(layer);
// Label at the top of each ring // Label at accurate north point of ring (Leaflet handles earth curvature)
const labelLat = center[0] + (dist * (unit === 'km' ? 0.009 : 0.0166)); const labelLat = L.circle(center, { radius: meters }).getBounds().getNorth();
L.marker([labelLat, center[1]], { L.marker([labelLat, center[1]], {
icon: L.divIcon({ icon: L.divIcon({
className: 'map-range-label', className: 'map-range-label',