diff --git a/kort7/app.js b/kort7/app.js
index 23ee16b..cad019c 100644
--- a/kort7/app.js
+++ b/kort7/app.js
@@ -18,6 +18,7 @@ L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
const statusEl = document.getElementById("status");
const alertsEl = document.getElementById("presenceAlerts");
+const offmapIndicatorsEl = document.getElementById("offmapIndicators");
const playBtn = document.getElementById("playBtn");
const pauseBtn = document.getElementById("pauseBtn");
const resetBtn = document.getElementById("resetBtn");
@@ -54,6 +55,34 @@ function fmtTs(ts) {
return `${ts}s`;
}
+function getDirectionInfo(lat, lon, bounds) {
+ const centerLat = (bounds.getSouth() + bounds.getNorth()) / 2;
+ const centerLon = (bounds.getWest() + bounds.getEast()) / 2;
+ const dLat = lat - centerLat;
+ const dLon = lon - centerLon;
+
+ const vertical = Math.abs(dLat) > 0.01 ? (dLat > 0 ? "N" : "S") : "";
+ const horizontal = Math.abs(dLon) > 0.01 ? (dLon > 0 ? "Ø" : "V") : "";
+ const label = `${vertical}${horizontal}` || "Nær kanten";
+
+ const arrowMap = {
+ "N": "↑",
+ "S": "↓",
+ "Ø": "→",
+ "V": "←",
+ "NØ": "↗",
+ "NV": "↖",
+ "SØ": "↘",
+ "SV": "↙",
+ "Nær kanten": "•"
+ };
+
+ return {
+ label,
+ arrow: arrowMap[label] || "•"
+ };
+}
+
function popupHtml(name, state) {
return `
@@ -396,6 +425,7 @@ function updateAlerts() {
if (alertVehicles.length === 0) {
alertsEl.innerHTML = "";
+ offmapIndicatorsEl.innerHTML = "";
return;
}
@@ -416,6 +446,24 @@ function updateAlerts() {
`;
}).join("");
+
+ const bounds = map.getBounds();
+ offmapIndicatorsEl.innerHTML = alertVehicles.map(v => {
+ const direction = getDirectionInfo(v.displayLat, v.displayLon, bounds);
+ const subtitle = v.presenceState === "covers"
+ ? "Usikkerheden dækker hele viewporten"
+ : `Mulig tilstedeværelse fra ${direction.label}`;
+
+ return `
+
+
${direction.arrow}
+
+ ${v.name}
+ ${subtitle}
+
+
+ `;
+ }).join("");
}
function updateStatus() {
diff --git a/kort7/kort7.html b/kort7/kort7.html
index a3b600a..585e24a 100644
--- a/kort7/kort7.html
+++ b/kort7/kort7.html
@@ -60,6 +60,58 @@
.alert-item strong { display:block; margin-bottom:2px; }
+ .offmap-indicators {
+ position: absolute;
+ right: 14px;
+ bottom: 14px;
+ z-index: 1000;
+ display: grid;
+ gap: 8px;
+ max-width: 260px;
+ pointer-events: none;
+ }
+
+ .offmap-indicator {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ gap: 10px;
+ align-items: center;
+ padding: 9px 11px;
+ border-radius: 12px;
+ background: rgba(18, 18, 18, 0.86);
+ color: #fff;
+ border: 1px solid rgba(255,255,255,0.12);
+ box-shadow: 0 6px 18px rgba(0,0,0,0.22);
+ font: 12px/1.3 system-ui, sans-serif;
+ }
+
+ .offmap-indicator.covers {
+ background: rgba(0, 72, 36, 0.9);
+ border-color: rgba(76, 175, 80, 0.55);
+ }
+
+ .offmap-arrow {
+ width: 26px;
+ height: 26px;
+ border-radius: 999px;
+ display: grid;
+ place-items: center;
+ font-size: 16px;
+ font-weight: 700;
+ color: #fff;
+ box-shadow: inset 0 0 0 2px rgba(255,255,255,0.18);
+ }
+
+ .offmap-meta strong {
+ display: block;
+ margin-bottom: 2px;
+ }
+
+ .offmap-meta span {
+ display: block;
+ opacity: 0.82;
+ }
+
.car {
width: 24px;
height: 24px;
@@ -88,6 +140,8 @@
+
+