Move documentation to docs/ directory and improve terminology

- Move ARCHITECTURE.md and CLAUDE.md to docs/ directory
- Replace "real-time" terminology with accurate "low-latency" and "high-performance"
- Update README to reflect correct performance characteristics
- Add comprehensive ICAO country database with SQLite backend
- Fix display options positioning and functionality
- Add map scale controls and improved range ring visibility
- Enhance aircraft marker orientation and trail management

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-08-24 16:24:46 +02:00
commit 20bdcf54ec
15 changed files with 746 additions and 67 deletions

View file

@ -16,6 +16,9 @@ export class AircraftManager {
this.iconCache = new Map();
this.loadIcons();
// Selected aircraft trail tracking
this.selectedAircraftCallback = null;
// Map event listeners removed - let Leaflet handle positioning naturally
}
@ -94,7 +97,22 @@ export class AircraftManager {
if (!currentICAOs.has(icao)) {
this.map.removeLayer(marker);
this.aircraftMarkers.delete(icao);
this.aircraftTrails.delete(icao);
// Remove trail if it exists
if (this.aircraftTrails.has(icao)) {
const trail = this.aircraftTrails.get(icao);
if (trail.polyline) {
this.map.removeLayer(trail.polyline);
}
this.aircraftTrails.delete(icao);
}
// Notify if this was the selected aircraft
if (this.selectedAircraftCallback && this.selectedAircraftCallback(icao)) {
// Aircraft was selected and disappeared - could notify main app
// For now, the callback will return false automatically since selectedAircraft will be cleared
}
this.markerRemoveCount++;
}
}
@ -189,8 +207,8 @@ export class AircraftManager {
}
}
// Update trails
if (this.showTrails) {
// Update trails - check both global trails and individual selected aircraft
if (this.showTrails || this.isSelectedAircraftTrailEnabled(icao)) {
this.updateAircraftTrail(icao, aircraft);
}
}
@ -318,8 +336,8 @@ export class AircraftManager {
createPopupContent(aircraft) {
const type = this.getAircraftType(aircraft);
const country = this.getCountryFromICAO(aircraft.ICAO24 || '');
const flag = this.getCountryFlag(country);
const country = aircraft.country || 'Unknown';
const flag = aircraft.flag || '🏳️';
const altitude = aircraft.Altitude || aircraft.BaroAltitude || 0;
const altitudeM = altitude ? Math.round(altitude * 0.3048) : 0;
@ -401,37 +419,6 @@ export class AircraftManager {
return minDistance === Infinity ? null : minDistance;
}
getCountryFromICAO(icao) {
if (!icao || icao.length < 6) return 'Unknown';
const prefix = icao[0];
const countryMap = {
'4': 'Europe',
'A': 'United States',
'C': 'Canada',
'D': 'Germany',
'F': 'France',
'G': 'United Kingdom',
'I': 'Italy',
'J': 'Japan'
};
return countryMap[prefix] || 'Unknown';
}
getCountryFlag(country) {
const flags = {
'United States': '🇺🇸',
'Canada': '🇨🇦',
'Germany': '🇩🇪',
'France': '🇫🇷',
'United Kingdom': '🇬🇧',
'Italy': '🇮🇹',
'Japan': '🇯🇵',
'Europe': '🇪🇺'
};
return flags[country] || '🏳️';
}
toggleTrails() {
this.showTrails = !this.showTrails;
@ -449,23 +436,56 @@ export class AircraftManager {
return this.showTrails;
}
centerMapOnAircraft() {
if (this.aircraftData.size === 0) return;
showAircraftTrail(icao) {
const aircraft = this.aircraftData.get(icao);
if (aircraft && aircraft.position_history && aircraft.position_history.length >= 2) {
this.updateAircraftTrail(icao, aircraft);
}
}
hideAircraftTrail(icao) {
if (this.aircraftTrails.has(icao)) {
const trail = this.aircraftTrails.get(icao);
if (trail.polyline) {
this.map.removeLayer(trail.polyline);
}
this.aircraftTrails.delete(icao);
}
}
setSelectedAircraftCallback(callback) {
this.selectedAircraftCallback = callback;
}
isSelectedAircraftTrailEnabled(icao) {
return this.selectedAircraftCallback && this.selectedAircraftCallback(icao);
}
centerMapOnAircraft(includeSourcesCallback = null) {
const validAircraft = Array.from(this.aircraftData.values())
.filter(a => a.Latitude && a.Longitude);
if (validAircraft.length === 0) return;
const allPoints = [];
if (validAircraft.length === 1) {
// Center on single aircraft
const aircraft = validAircraft[0];
this.map.setView([aircraft.Latitude, aircraft.Longitude], 12);
// Add aircraft positions
validAircraft.forEach(a => {
allPoints.push([a.Latitude, a.Longitude]);
});
// Add source positions if callback provided
if (includeSourcesCallback && typeof includeSourcesCallback === 'function') {
const sourcePositions = includeSourcesCallback();
allPoints.push(...sourcePositions);
}
if (allPoints.length === 0) return;
if (allPoints.length === 1) {
// Center on single point
this.map.setView(allPoints[0], 12);
} else {
// Fit bounds to all aircraft
const bounds = L.latLngBounds(
validAircraft.map(a => [a.Latitude, a.Longitude])
);
// Fit bounds to all points (aircraft + sources)
const bounds = L.latLngBounds(allPoints);
this.map.fitBounds(bounds.pad(0.1));
}
}