Add Disney park outlines to map

- Polygons for Magic Kingdom, Epcot, Hollywood Studios, Animal Kingdom, Disney Springs
- Resort area outline (dashed) for Pop Century / Art of Animation
- Color-coded to match existing park badge colors
- Labels with park icons at polygon centers
- Toggle chip (🏰 Parks) in map controls to show/hide
- Outlines visible by default on map load
This commit is contained in:
2026-05-22 23:53:09 -04:00
parent a0e6f627f4
commit 5380bf7256
+124
View File
@@ -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 @@
<div id="tabMap" class="tab-panel">
<div class="map-controls">
<span class="map-chip" id="chipHeat" onclick="toggleHeatmap()">🔥 Heatmap</span>
<span class="map-chip park-on" id="chipParkOutlines" onclick="toggleParkOutlines()">🏰 Parks ON</span>
<span class="map-chip" id="chipGeoGPS" onclick="if(navigator.geolocation)navigator.geolocation.getCurrentPosition(p=>{map.setView([p.coords.latitude,p.coords.longitude],15)})">◎ My GPS</span>
</div>
<div id="mapContainer"></div>
@@ -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: '<div style="background:' + park.color + '22; color:' + park.color +
'; border:1px solid ' + park.color + '44; border-radius:6px; padding:2px 8px;' +
' font-size:11px; font-weight:600; white-space:nowrap; text-shadow:0 1px 2px rgba(0,0,0,0.8);">' +
park.icon + ' ' + park.name + '</div>',
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 };