mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
Merge branch 'upstream-shared-observer-location'
This commit is contained in:
@@ -17,10 +17,15 @@
|
||||
{% else %}
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/responsive.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/adsb_dashboard.css') }}">
|
||||
</head>
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/responsive.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/adsb_dashboard.css') }}">
|
||||
<script>
|
||||
window.INTERCEPT_SHARED_OBSERVER_LOCATION = {{ shared_observer_location | tojson }};
|
||||
window.INTERCEPT_ADSB_AUTO_START = {{ adsb_auto_start | tojson }};
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/core/observer-location.js') }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="radar-bg"></div>
|
||||
<div class="scanline"></div>
|
||||
@@ -517,16 +522,19 @@
|
||||
}
|
||||
|
||||
// Observer location and range rings (load from localStorage or default to London)
|
||||
let observerLocation = (function() {
|
||||
const saved = localStorage.getItem('observerLocation');
|
||||
if (saved) {
|
||||
try {
|
||||
const parsed = JSON.parse(saved);
|
||||
if (parsed.lat && parsed.lon) return parsed;
|
||||
} catch (e) {}
|
||||
}
|
||||
return { lat: 51.5074, lon: -0.1278 };
|
||||
})();
|
||||
let observerLocation = (function() {
|
||||
if (window.ObserverLocation && ObserverLocation.getForModule) {
|
||||
return ObserverLocation.getForModule('observerLocation');
|
||||
}
|
||||
const saved = localStorage.getItem('observerLocation');
|
||||
if (saved) {
|
||||
try {
|
||||
const parsed = JSON.parse(saved);
|
||||
if (parsed.lat && parsed.lon) return parsed;
|
||||
} catch (e) {}
|
||||
}
|
||||
return { lat: 51.5074, lon: -0.1278 };
|
||||
})();
|
||||
let rangeRingsLayer = null;
|
||||
let observerMarker = null;
|
||||
|
||||
@@ -1802,8 +1810,12 @@ ACARS: ${r.statistics.acarsMessages} messages`;
|
||||
observerLocation.lat = lat;
|
||||
observerLocation.lon = lon;
|
||||
|
||||
// Save to localStorage for persistence
|
||||
localStorage.setItem('observerLocation', JSON.stringify(observerLocation));
|
||||
// Save to localStorage for persistence
|
||||
if (window.ObserverLocation) {
|
||||
ObserverLocation.setForModule('observerLocation', observerLocation);
|
||||
} else {
|
||||
localStorage.setItem('observerLocation', JSON.stringify(observerLocation));
|
||||
}
|
||||
|
||||
if (radarMap) {
|
||||
radarMap.setView([lat, lon], radarMap.getZoom());
|
||||
@@ -1830,8 +1842,12 @@ ACARS: ${r.statistics.acarsMessages} messages`;
|
||||
observerLocation.lat = position.coords.latitude;
|
||||
observerLocation.lon = position.coords.longitude;
|
||||
|
||||
// Save to localStorage for persistence
|
||||
localStorage.setItem('observerLocation', JSON.stringify(observerLocation));
|
||||
// Save to localStorage for persistence
|
||||
if (window.ObserverLocation) {
|
||||
ObserverLocation.setForModule('observerLocation', observerLocation);
|
||||
} else {
|
||||
localStorage.setItem('observerLocation', JSON.stringify(observerLocation));
|
||||
}
|
||||
|
||||
document.getElementById('obsLat').value = observerLocation.lat.toFixed(4);
|
||||
document.getElementById('obsLon').value = observerLocation.lon.toFixed(4);
|
||||
@@ -1920,14 +1936,17 @@ ACARS: ${r.statistics.acarsMessages} messages`;
|
||||
}
|
||||
});
|
||||
|
||||
function updateLocationFromGps(position) {
|
||||
observerLocation.lat = position.latitude;
|
||||
observerLocation.lon = position.longitude;
|
||||
document.getElementById('obsLat').value = position.latitude.toFixed(4);
|
||||
document.getElementById('obsLon').value = position.longitude.toFixed(4);
|
||||
|
||||
// Center map on GPS location (on first fix)
|
||||
if (radarMap && !radarMap._gpsInitialized) {
|
||||
function updateLocationFromGps(position) {
|
||||
observerLocation.lat = position.latitude;
|
||||
observerLocation.lon = position.longitude;
|
||||
document.getElementById('obsLat').value = position.latitude.toFixed(4);
|
||||
document.getElementById('obsLon').value = position.longitude.toFixed(4);
|
||||
if (window.ObserverLocation && ObserverLocation.isSharedEnabled()) {
|
||||
ObserverLocation.setShared({ lat: position.latitude, lon: position.longitude });
|
||||
}
|
||||
|
||||
// Center map on GPS location (on first fix)
|
||||
if (radarMap && !radarMap._gpsInitialized) {
|
||||
radarMap.setView([position.latitude, position.longitude], radarMap.getZoom());
|
||||
radarMap._gpsInitialized = true;
|
||||
// Draw range rings immediately after centering
|
||||
@@ -2523,28 +2542,32 @@ sudo make install</code>
|
||||
}
|
||||
}
|
||||
|
||||
async function syncTrackingStatus() {
|
||||
// This function checks LOCAL tracking status on page load
|
||||
// For local mode: auto-start if session is already running OR SDR is available
|
||||
// For agent mode: don't auto-start (user controls agent tracking)
|
||||
|
||||
const useAgent = typeof adsbCurrentAgent !== 'undefined' && adsbCurrentAgent !== 'local';
|
||||
if (useAgent) {
|
||||
console.log('[ADS-B] Agent mode on page load - not auto-starting local');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/adsb/session');
|
||||
if (!response.ok) {
|
||||
// No session info - try to auto-start if SDR available
|
||||
console.log('[ADS-B] No session found, attempting auto-start...');
|
||||
await tryAutoStartLocal();
|
||||
return;
|
||||
}
|
||||
const data = await response.json();
|
||||
|
||||
if (data.tracking_active) {
|
||||
async function syncTrackingStatus() {
|
||||
// This function checks LOCAL tracking status on page load
|
||||
// For local mode: auto-start if session is already running OR SDR is available
|
||||
// For agent mode: don't auto-start (user controls agent tracking)
|
||||
|
||||
const useAgent = typeof adsbCurrentAgent !== 'undefined' && adsbCurrentAgent !== 'local';
|
||||
if (useAgent) {
|
||||
console.log('[ADS-B] Agent mode on page load - not auto-starting local');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/adsb/session');
|
||||
if (!response.ok) {
|
||||
// No session info - only auto-start if enabled
|
||||
if (window.INTERCEPT_ADSB_AUTO_START) {
|
||||
console.log('[ADS-B] No session found, attempting auto-start...');
|
||||
await tryAutoStartLocal();
|
||||
} else {
|
||||
console.log('[ADS-B] No session found; auto-start disabled');
|
||||
}
|
||||
return;
|
||||
}
|
||||
const data = await response.json();
|
||||
|
||||
if (data.tracking_active) {
|
||||
// Session is running - auto-connect to stream
|
||||
console.log('[ADS-B] Local session already active - auto-connecting to stream');
|
||||
|
||||
@@ -2580,18 +2603,24 @@ sudo make install</code>
|
||||
document.getElementById('trackingDot').classList.add('active');
|
||||
const statusEl = document.getElementById('trackingStatus');
|
||||
statusEl.textContent = 'TRACKING';
|
||||
} else {
|
||||
// Session not active - try to auto-start
|
||||
console.log('[ADS-B] No active session, attempting auto-start...');
|
||||
await tryAutoStartLocal();
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.warn('[ADS-B] Failed to sync tracking status:', err);
|
||||
// Try auto-start anyway
|
||||
await tryAutoStartLocal();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Session not active - only auto-start if enabled
|
||||
if (window.INTERCEPT_ADSB_AUTO_START) {
|
||||
console.log('[ADS-B] No active session, attempting auto-start...');
|
||||
await tryAutoStartLocal();
|
||||
} else {
|
||||
console.log('[ADS-B] No active session; auto-start disabled');
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.warn('[ADS-B] Failed to sync tracking status:', err);
|
||||
// Try auto-start only if enabled
|
||||
if (window.INTERCEPT_ADSB_AUTO_START) {
|
||||
await tryAutoStartLocal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function tryAutoStartLocal() {
|
||||
// Try to auto-start local ADS-B tracking if SDR is available
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/ais_dashboard.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/responsive.css') }}">
|
||||
<script>
|
||||
window.INTERCEPT_SHARED_OBSERVER_LOCATION = {{ shared_observer_location | tojson }};
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/core/observer-location.js') }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Radar background effects -->
|
||||
@@ -219,7 +223,12 @@
|
||||
const MAX_TRAIL_POINTS = 50;
|
||||
|
||||
// Observer location
|
||||
let observerLocation = { lat: 51.5074, lon: -0.1278 };
|
||||
let observerLocation = (function() {
|
||||
if (window.ObserverLocation && ObserverLocation.getForModule) {
|
||||
return ObserverLocation.getForModule('ais_observerLocation');
|
||||
}
|
||||
return { lat: 51.5074, lon: -0.1278 };
|
||||
})();
|
||||
let rangeRingsLayer = null;
|
||||
let observerMarker = null;
|
||||
|
||||
@@ -376,17 +385,9 @@
|
||||
|
||||
// Initialize map
|
||||
function initMap() {
|
||||
// Load saved observer location
|
||||
const saved = localStorage.getItem('ais_observerLocation');
|
||||
if (saved) {
|
||||
try {
|
||||
const parsed = JSON.parse(saved);
|
||||
if (parsed.lat && parsed.lon) {
|
||||
observerLocation = parsed;
|
||||
document.getElementById('obsLat').value = parsed.lat;
|
||||
document.getElementById('obsLon').value = parsed.lon;
|
||||
}
|
||||
} catch (e) {}
|
||||
if (observerLocation) {
|
||||
document.getElementById('obsLat').value = observerLocation.lat;
|
||||
document.getElementById('obsLon').value = observerLocation.lon;
|
||||
}
|
||||
|
||||
vesselMap = L.map('vesselMap', {
|
||||
@@ -470,7 +471,11 @@
|
||||
const lon = parseFloat(document.getElementById('obsLon').value);
|
||||
if (!isNaN(lat) && !isNaN(lon) && lat >= -90 && lat <= 90 && lon >= -180 && lon <= 180) {
|
||||
observerLocation = { lat, lon };
|
||||
localStorage.setItem('ais_observerLocation', JSON.stringify(observerLocation));
|
||||
if (window.ObserverLocation) {
|
||||
ObserverLocation.setForModule('ais_observerLocation', observerLocation);
|
||||
} else {
|
||||
localStorage.setItem('ais_observerLocation', JSON.stringify(observerLocation));
|
||||
}
|
||||
if (observerMarker) {
|
||||
observerMarker.setLatLng([lat, lon]);
|
||||
}
|
||||
@@ -1058,7 +1063,11 @@
|
||||
drawRangeRings();
|
||||
|
||||
// Save to localStorage
|
||||
localStorage.setItem('ais_observerLocation', JSON.stringify(observerLocation));
|
||||
if (window.ObserverLocation) {
|
||||
ObserverLocation.setForModule('ais_observerLocation', observerLocation);
|
||||
} else {
|
||||
localStorage.setItem('ais_observerLocation', JSON.stringify(observerLocation));
|
||||
}
|
||||
}
|
||||
|
||||
function showGpsIndicator(show) {
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
window._showDisclaimerOnLoad = true;
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
window.INTERCEPT_SHARED_OBSERVER_LOCATION = {{ shared_observer_location | tojson }};
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/core/observer-location.js') }}"></script>
|
||||
<!-- Fonts - Conditional CDN/Local loading -->
|
||||
{% if offline_settings.fonts_source == 'local' %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/fonts-local.css') }}">
|
||||
@@ -2252,6 +2256,9 @@
|
||||
|
||||
// Observer location for distance calculations (load from localStorage or default to London)
|
||||
let observerLocation = (function () {
|
||||
if (window.ObserverLocation && ObserverLocation.getForModule) {
|
||||
return ObserverLocation.getForModule('observerLocation');
|
||||
}
|
||||
const saved = localStorage.getItem('observerLocation');
|
||||
if (saved) {
|
||||
try {
|
||||
@@ -8375,8 +8382,15 @@
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
position => {
|
||||
document.getElementById('obsLat').value = position.coords.latitude.toFixed(4);
|
||||
document.getElementById('obsLon').value = position.coords.longitude.toFixed(4);
|
||||
const lat = position.coords.latitude;
|
||||
const lon = position.coords.longitude;
|
||||
document.getElementById('obsLat').value = lat.toFixed(4);
|
||||
document.getElementById('obsLon').value = lon.toFixed(4);
|
||||
observerLocation.lat = lat;
|
||||
observerLocation.lon = lon;
|
||||
if (window.ObserverLocation && ObserverLocation.isSharedEnabled()) {
|
||||
ObserverLocation.setShared({ lat, lon });
|
||||
}
|
||||
showInfo('Location updated!');
|
||||
},
|
||||
error => {
|
||||
@@ -8476,6 +8490,9 @@
|
||||
// Update observerLocation
|
||||
observerLocation.lat = position.latitude;
|
||||
observerLocation.lon = position.longitude;
|
||||
if (window.ObserverLocation && ObserverLocation.isSharedEnabled()) {
|
||||
ObserverLocation.setShared({ lat: position.latitude, lon: position.longitude });
|
||||
}
|
||||
|
||||
// Update APRS user location
|
||||
updateAprsUserLocation(position);
|
||||
|
||||
@@ -17,10 +17,14 @@
|
||||
{% else %}
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/responsive.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/satellite_dashboard.css') }}">
|
||||
</head>
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/responsive.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/satellite_dashboard.css') }}">
|
||||
<script>
|
||||
window.INTERCEPT_SHARED_OBSERVER_LOCATION = {{ shared_observer_location | tojson }};
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/core/observer-location.js') }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="grid-bg"></div>
|
||||
<div class="scanline"></div>
|
||||
@@ -313,16 +317,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
setupEmbeddedMode();
|
||||
initGroundMap();
|
||||
updateClock();
|
||||
setInterval(updateClock, 1000);
|
||||
setInterval(updateCountdown, 1000);
|
||||
setInterval(updateRealTimePositions, 5000);
|
||||
loadAgents();
|
||||
getLocation();
|
||||
});
|
||||
function applySharedObserverLocation() {
|
||||
if (window.ObserverLocation && ObserverLocation.isSharedEnabled()) {
|
||||
const shared = ObserverLocation.getShared();
|
||||
if (shared) {
|
||||
const latInput = document.getElementById('obsLat');
|
||||
const lonInput = document.getElementById('obsLon');
|
||||
if (latInput) latInput.value = shared.lat.toFixed(4);
|
||||
if (lonInput) lonInput.value = shared.lon.toFixed(4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
setupEmbeddedMode();
|
||||
const usedShared = applySharedObserverLocation();
|
||||
initGroundMap();
|
||||
updateClock();
|
||||
setInterval(updateClock, 1000);
|
||||
setInterval(updateCountdown, 1000);
|
||||
setInterval(updateRealTimePositions, 5000);
|
||||
loadAgents();
|
||||
if (!usedShared) {
|
||||
getLocation();
|
||||
}
|
||||
});
|
||||
|
||||
async function loadAgents() {
|
||||
try {
|
||||
@@ -376,10 +397,13 @@
|
||||
|
||||
if (data.status === 'success' && data.result) {
|
||||
const agentStatus = data.result;
|
||||
if (agentStatus.gps_position) {
|
||||
const gps = agentStatus.gps_position;
|
||||
document.getElementById('obsLat').value = gps.lat.toFixed(4);
|
||||
document.getElementById('obsLon').value = gps.lon.toFixed(4);
|
||||
if (agentStatus.gps_position) {
|
||||
const gps = agentStatus.gps_position;
|
||||
document.getElementById('obsLat').value = gps.lat.toFixed(4);
|
||||
document.getElementById('obsLon').value = gps.lon.toFixed(4);
|
||||
if (window.ObserverLocation && ObserverLocation.isSharedEnabled()) {
|
||||
ObserverLocation.setShared({ lat: gps.lat, lon: gps.lon });
|
||||
}
|
||||
|
||||
// Update observer marker label
|
||||
const agent = agents.find(a => a.id == agentId);
|
||||
@@ -407,39 +431,50 @@
|
||||
now.toISOString().substring(11, 19) + ' UTC';
|
||||
}
|
||||
|
||||
function initGroundMap() {
|
||||
groundMap = L.map('groundMap', {
|
||||
center: [20, 0],
|
||||
zoom: 2,
|
||||
minZoom: 1,
|
||||
maxZoom: 10,
|
||||
worldCopyJump: true
|
||||
});
|
||||
function initGroundMap() {
|
||||
groundMap = L.map('groundMap', {
|
||||
center: [20, 0],
|
||||
zoom: 2,
|
||||
minZoom: 1,
|
||||
maxZoom: 10,
|
||||
worldCopyJump: true
|
||||
});
|
||||
|
||||
// Use settings manager for tile layer (allows runtime changes)
|
||||
window.groundMap = groundMap;
|
||||
if (typeof Settings !== 'undefined' && Settings.createTileLayer) {
|
||||
Settings.createTileLayer().addTo(groundMap);
|
||||
Settings.registerMap(groundMap);
|
||||
} else {
|
||||
L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OSM</a> © <a href="https://carto.com/">CARTO</a>',
|
||||
maxZoom: 19,
|
||||
subdomains: 'abcd'
|
||||
}).addTo(groundMap);
|
||||
}
|
||||
}
|
||||
if (typeof Settings !== 'undefined' && Settings.createTileLayer) {
|
||||
Settings.createTileLayer().addTo(groundMap);
|
||||
Settings.registerMap(groundMap);
|
||||
} else {
|
||||
L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OSM</a> © <a href="https://carto.com/">CARTO</a>',
|
||||
maxZoom: 19,
|
||||
subdomains: 'abcd'
|
||||
}).addTo(groundMap);
|
||||
}
|
||||
|
||||
const lat = parseFloat(document.getElementById('obsLat')?.value);
|
||||
const lon = parseFloat(document.getElementById('obsLon')?.value);
|
||||
if (!Number.isNaN(lat) && !Number.isNaN(lon)) {
|
||||
groundMap.setView([lat, lon], 3);
|
||||
}
|
||||
}
|
||||
|
||||
function getLocation() {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(pos => {
|
||||
document.getElementById('obsLat').value = pos.coords.latitude.toFixed(4);
|
||||
document.getElementById('obsLon').value = pos.coords.longitude.toFixed(4);
|
||||
calculatePasses();
|
||||
}, () => {
|
||||
calculatePasses();
|
||||
});
|
||||
} else {
|
||||
function getLocation() {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(pos => {
|
||||
const lat = pos.coords.latitude;
|
||||
const lon = pos.coords.longitude;
|
||||
document.getElementById('obsLat').value = lat.toFixed(4);
|
||||
document.getElementById('obsLon').value = lon.toFixed(4);
|
||||
if (window.ObserverLocation && ObserverLocation.isSharedEnabled()) {
|
||||
ObserverLocation.setShared({ lat, lon });
|
||||
}
|
||||
calculatePasses();
|
||||
}, () => {
|
||||
calculatePasses();
|
||||
});
|
||||
} else {
|
||||
calculatePasses();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user