skydesportensdag/wwwroot/participant-map.js
2026-10-02 22:07:03 +02:00

60 lines
2.6 KiB
JavaScript

const mapStatus = document.querySelector("#map-status");
const postalLocations = fetch("/postnummer-positioner.json")
.then((response) => {
if (!response.ok) throw new Error("Postnummerpositioner mangler.");
return response.json();
}).catch(() => null);
let participantMap;
let participantMarkers;
let mapRevision = 0;
let tileError = false;
async function updateParticipantMap(visitors) {
const revision = ++mapRevision;
const locations = await postalLocations;
if (revision !== mapRevision) return;
if (!locations || typeof L === "undefined") {
mapStatus.textContent = "Kortet kunne ikke indlæses. Deltagerlisten kan stadig bruges.";
return;
}
if (!participantMap) {
participantMap = L.map("participant-map").setView([56.1, 10.5], 6);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 18,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> | Postbyer: <a href="https://www.geonames.org/">GeoNames</a>'
}).on("tileerror", () => {
if (!tileError) {
tileError = true;
mapStatus.textContent += " Baggrundskortet kunne ikke hentes; kontrollér internetforbindelsen.";
}
}).addTo(participantMap);
participantMarkers = L.layerGroup().addTo(participantMap);
}
participantMarkers.clearLayers();
const groups = new Map();
let missing = 0;
for (const visitor of visitors) {
const code = String(visitor.postalCode ?? "").trim();
if (!locations[code]) { missing++; continue; }
groups.set(code, (groups.get(code) ?? 0) + 1);
}
const bounds = [];
for (const [code, total] of groups) {
const location = locations[code];
const point = [location.lat, location.lng];
bounds.push(point);
const popup = document.createElement("div");
popup.textContent = `${code} ${location.city}: ${total} ${total === 1 ? "deltager" : "deltagere"}`;
L.circleMarker(point, {
radius: Math.min(32, 7 + Math.sqrt(total) * 3),
color: "#16472d", fillColor: "#1d5b39", fillOpacity: 0.65, weight: 2
}).bindPopup(popup).bindTooltip(`${code}: ${total}`).addTo(participantMarkers);
}
if (bounds.length) participantMap.fitBounds(bounds, { padding: [35, 35], maxZoom: 11 });
else participantMap.setView([56.1, 10.5], 6);
mapStatus.textContent = visitors.length === 0 ? "Ingen deltagere registreret endnu." :
`${visitors.length - missing} deltagere fra ${groups.size} postnumre vist.${missing ? ` ${missing} deltagere har et ukendt postnummer og vises ikke på kortet.` : ""}`;
if (tileError) mapStatus.textContent += " Baggrundskortet kunne ikke hentes; kontrollér internetforbindelsen.";
}