diff --git a/assets/static/icons/cargo.svg b/assets/static/icons/cargo.svg
new file mode 100644
index 0000000..b3605b1
--- /dev/null
+++ b/assets/static/icons/cargo.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/assets/static/icons/commercial.svg b/assets/static/icons/commercial.svg
new file mode 100644
index 0000000..f1f1b28
--- /dev/null
+++ b/assets/static/icons/commercial.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/assets/static/icons/ga.svg b/assets/static/icons/ga.svg
new file mode 100644
index 0000000..cfba161
--- /dev/null
+++ b/assets/static/icons/ga.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/assets/static/icons/ground.svg b/assets/static/icons/ground.svg
new file mode 100644
index 0000000..ee5af8e
--- /dev/null
+++ b/assets/static/icons/ground.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/assets/static/icons/helicopter.svg b/assets/static/icons/helicopter.svg
new file mode 100644
index 0000000..5197bea
--- /dev/null
+++ b/assets/static/icons/helicopter.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/assets/static/icons/military.svg b/assets/static/icons/military.svg
new file mode 100644
index 0000000..c4e58a7
--- /dev/null
+++ b/assets/static/icons/military.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/assets/static/js/modules/aircraft-manager.js b/assets/static/js/modules/aircraft-manager.js
index c032cfc..781c339 100644
--- a/assets/static/js/modules/aircraft-manager.js
+++ b/assets/static/js/modules/aircraft-manager.js
@@ -12,9 +12,67 @@ export class AircraftManager {
this.markerUpdateCount = 0;
this.markerRemoveCount = 0;
+ // SVG icon cache
+ this.iconCache = new Map();
+ this.loadIcons();
+
// Map event listeners removed - let Leaflet handle positioning naturally
}
+ async loadIcons() {
+ const iconTypes = ['commercial', 'helicopter', 'military', 'cargo', 'ga', 'ground'];
+
+ for (const type of iconTypes) {
+ try {
+ const response = await fetch(`/static/icons/${type}.svg`);
+ const svgText = await response.text();
+ this.iconCache.set(type, svgText);
+ } catch (error) {
+ console.warn(`Failed to load icon for ${type}:`, error);
+ // Fallback to inline SVG if needed
+ this.iconCache.set(type, this.createFallbackIcon(type));
+ }
+ }
+ }
+
+ createFallbackIcon(type) {
+ // Fallback inline SVG if file loading fails
+ const color = 'currentColor';
+ let path = '';
+
+ switch (type) {
+ case 'helicopter':
+ path = `
+
+
+ `;
+ break;
+ case 'military':
+ path = ``;
+ break;
+ case 'cargo':
+ path = `
+ `;
+ break;
+ case 'ga':
+ path = ``;
+ break;
+ case 'ground':
+ path = `
+
+ `;
+ break;
+ default:
+ path = ``;
+ }
+
+ return `
+`;
+ }
updateAircraftData(data) {
if (data.aircraft) {
@@ -74,13 +132,21 @@ export class AircraftManager {
const oldPos = marker.getLatLng();
marker.setLatLng(pos);
- // Update icon if track has changed to apply new rotation
- if (aircraft.Track !== undefined) {
- const currentRotation = marker._currentRotation || 0;
- if (Math.abs(currentRotation - aircraft.Track) > 5) { // Update if rotation changed by more than 5 degrees
- marker.setIcon(this.createAircraftIcon(aircraft));
- marker._currentRotation = aircraft.Track;
- }
+ // Check if icon needs to be updated (track rotation, aircraft type, or ground status changes)
+ const currentRotation = marker._currentRotation || 0;
+ const currentType = marker._currentType || null;
+ const currentOnGround = marker._currentOnGround || false;
+
+ const newType = this.getAircraftIconType(aircraft);
+ const rotationChanged = aircraft.Track !== undefined && Math.abs(currentRotation - aircraft.Track) > 5;
+ const typeChanged = currentType !== newType;
+ const groundStatusChanged = currentOnGround !== aircraft.OnGround;
+
+ if (rotationChanged || typeChanged || groundStatusChanged) {
+ marker.setIcon(this.createAircraftIcon(aircraft));
+ marker._currentRotation = aircraft.Track || 0;
+ marker._currentType = newType;
+ marker._currentOnGround = aircraft.OnGround || false;
}
// Handle popup exactly like Leaflet expects
@@ -99,8 +165,10 @@ export class AircraftManager {
icon: icon
}).addTo(this.map);
- // Store current rotation for future updates
+ // Store current properties for future update comparisons
marker._currentRotation = aircraft.Track || 0;
+ marker._currentType = this.getAircraftIconType(aircraft);
+ marker._currentOnGround = aircraft.OnGround || false;
marker.bindPopup(this.createPopupContent(aircraft), {
maxWidth: 450,
@@ -133,60 +201,28 @@ export class AircraftManager {
const size = aircraft.OnGround ? 12 : 16;
const rotation = aircraft.Track || 0;
- // Create different SVG shapes based on aircraft type
- let aircraftPath;
+ // Get SVG template from cache
+ let svgTemplate = this.iconCache.get(iconType) || this.iconCache.get('commercial');
- switch (iconType) {
- case 'helicopter':
- // Helicopter shape with rotor disc
- aircraftPath = `
-
-
-
-
- `;
- break;
- case 'military':
- // Swept-wing fighter jet shape
- aircraftPath = `
-
- `;
- break;
- case 'cargo':
- // Wide-body cargo aircraft shape
- aircraftPath = `
-
-
- `;
- break;
- case 'ga':
- // Small general aviation aircraft
- aircraftPath = `
-
- `;
- break;
- case 'ground':
- // Ground vehicle - simplified truck/car shape
- aircraftPath = `
-
-
-
- `;
- break;
- default:
- // Default commercial aircraft shape
- aircraftPath = `
-
- `;
+ if (!svgTemplate) {
+ // Ultimate fallback - create a simple circle
+ svgTemplate = ``;
}
- const svg = `
-
- `;
+ // Apply color and rotation to the SVG
+ let svg = svgTemplate
+ .replace(/currentColor/g, color)
+ .replace(/width="32"/, `width="${size * 2}"`)
+ .replace(/height="32"/, `height="${size * 2}"`);
+
+ // Add rotation to the transform
+ if (rotation !== 0) {
+ svg = svg.replace(/transform="translate\(16,16\)"/, `transform="translate(16,16) rotate(${rotation})"`);
+ }
return L.divIcon({
html: svg,