From 5380bf725626301214fb96ff88943eda85e46cc0 Mon Sep 17 00:00:00 2001 From: Shawn Date: Fri, 22 May 2026 23:53:09 -0400 Subject: [PATCH] Add Disney park outlines to map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- static/index.html | 124 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) 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 };