diff --git a/static/index.html b/static/index.html
index 508558d..2eb760e 100644
--- a/static/index.html
+++ b/static/index.html
@@ -798,6 +798,8 @@
}
.map-chip.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.map-chip.heat-on { background: var(--amber); border-color: var(--amber); color: #000; }
+ .map-chip.park-on { background: var(--accent); border-color: var(--accent); color: #fff; }
+ .park-label-icon { pointer-events: none !important; background: transparent !important; border: none !important; }
.leaflet-popup-content-wrapper {
background: var(--card) !important;
color: var(--text) !important;
@@ -1318,6 +1320,7 @@
🔥 Heatmap
+ 🏰 Parks ON
◎ My GPS
@@ -1855,6 +1858,8 @@
document.dispatchEvent(new CustomEvent('geofenceDrawn', { detail: { layer: e.layerType, coords: e.layer.toGeoJSON() } }));
});
}
+ // Draw Disney park outlines on first map init
+ if (parkOutlinesVisible) drawParkOutlines();
// Restore heatmap layer if it was active
if (heatVisible) setTimeout(() => loadHeatmapData(), 300);
}
@@ -3142,6 +3147,125 @@
function parkIcon(key) { return PARK_ICONS[key] || '📍'; }
function parkName(key) { return PARK_NAMES[key] || key; }
+ // ── Disney Park Outline Polygons ───────────────────────────────────────
+ const DISNEY_PARK_OUTLINES = {
+ 'magic-kingdom': {
+ name: 'Magic Kingdom',
+ color: '#8b5cf6',
+ icon: '🏰',
+ coords: [
+ [28.4250, -81.5840], [28.4240, -81.5775], [28.4200, -81.5765],
+ [28.4175, -81.5765], [28.4160, -81.5775], [28.4140, -81.5795],
+ [28.4130, -81.5835], [28.4160, -81.5855], [28.4200, -81.5860],
+ [28.4250, -81.5840]
+ ]
+ },
+ 'epcot': {
+ name: 'Epcot',
+ color: '#06b6d4',
+ icon: '🌍',
+ coords: [
+ [28.3785, -81.5525], [28.3790, -81.5460], [28.3750, -81.5450],
+ [28.3710, -81.5460], [28.3695, -81.5490], [28.3705, -81.5525],
+ [28.3740, -81.5535], [28.3785, -81.5525]
+ ]
+ },
+ 'hollywood-studios': {
+ name: 'Hollywood Studios',
+ color: '#f59e0b',
+ icon: '🎬',
+ coords: [
+ [28.3605, -81.5620], [28.3610, -81.5560], [28.3580, -81.5550],
+ [28.3545, -81.5555], [28.3535, -81.5585], [28.3550, -81.5615],
+ [28.3580, -81.5625], [28.3605, -81.5620]
+ ]
+ },
+ 'animal-kingdom': {
+ name: 'Animal Kingdom',
+ color: '#22c55e',
+ icon: '🌿',
+ coords: [
+ [28.3620, -81.5945], [28.3625, -81.5870], [28.3590, -81.5860],
+ [28.3550, -81.5865], [28.3530, -81.5890], [28.3540, -81.5930],
+ [28.3570, -81.5945], [28.3620, -81.5945]
+ ]
+ },
+ 'disney-springs': {
+ name: 'Disney Springs',
+ color: '#ec4899',
+ icon: '🛍️',
+ coords: [
+ [28.3730, -81.5240], [28.3730, -81.5180], [28.3695, -81.5170],
+ [28.3670, -81.5180], [28.3665, -81.5215], [28.3680, -81.5240],
+ [28.3730, -81.5240]
+ ]
+ },
+ 'resort': {
+ name: 'Resort Area',
+ color: '#3b82f6',
+ icon: '🏨',
+ coords: [
+ // Pop Century / Art of Animation area
+ [28.3520, -81.5450], [28.3520, -81.5400], [28.3480, -81.5400],
+ [28.3480, -81.5450], [28.3520, -81.5450]
+ ]
+ }
+ };
+
+ // Park outline state
+ let parkOutlinesVisible = true;
+ let parkOutlineGroup = null;
+
+ function drawParkOutlines() {
+ if (!map) return;
+ if (parkOutlineGroup) map.removeLayer(parkOutlineGroup);
+ parkOutlineGroup = L.featureGroup();
+
+ Object.entries(DISNEY_PARK_OUTLINES).forEach(([key, park]) => {
+ const polygon = L.polygon(park.coords, {
+ color: park.color,
+ weight: 2,
+ opacity: 0.8,
+ fillColor: park.color,
+ fillOpacity: 0.12,
+ dashArray: key === 'resort' ? '6, 4' : null, // dashed for resort areas
+ }).addTo(parkOutlineGroup);
+
+ // Add a label at the polygon center
+ const bounds = polygon.getBounds();
+ const center = bounds.getCenter();
+ const label = L.marker(center, {
+ icon: L.divIcon({
+ className: 'park-label-icon',
+ html: '
' +
+ park.icon + ' ' + park.name + '
',
+ iconSize: [0, 0],
+ iconAnchor: [0, 0],
+ }),
+ interactive: false,
+ }).addTo(parkOutlineGroup);
+ });
+
+ parkOutlineGroup.addTo(map);
+ }
+
+ function toggleParkOutlines() {
+ parkOutlinesVisible = !parkOutlinesVisible;
+ const chip = document.getElementById('chipParkOutlines');
+ if (parkOutlinesVisible) {
+ chip.classList.add('park-on');
+ chip.textContent = '🏰 Parks ON';
+ drawParkOutlines();
+ } else {
+ chip.classList.remove('park-on');
+ chip.textContent = '🏰 Parks';
+ if (parkOutlineGroup) map.removeLayer(parkOutlineGroup);
+ parkOutlineGroup = null;
+ }
+ }
+
// ── Filter state ──────────────────────────────────────────────────────
let assetFilters = { category: null, status: null, make: null, disney_park: null, disney_filter: null, q: '',
customer_id: null, location_id: null, assigned_to: null };