Files
PolyWeather/web/static/index.html
T

199 lines
8.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PolyWeather — 天气衍生品智能地图</title>
<meta name="description" content="PolyWeather 天气衍生品智能地图。实时 METAR、MGM、DEB 融合预报与 AI 分析。">
<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<!-- Google Fonts: Inter -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap"
rel="stylesheet">
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<!-- ── Map ── -->
<div id="map"></div>
<!-- ── Header Overlay ── -->
<header id="header">
<div class="brand">
<h1>🌡️ PolyWeather</h1>
<span class="subtitle">天气衍生品智能分析</span>
</div>
<button class="info-btn" id="btnShowGuide" title="查看系统技术说明">️ 技术说明</button>
<div class="live-badge" id="liveBadge">
<span class="pulse-dot"></span>
<span>实时</span>
</div>
<button class="refresh-btn" id="refreshAllBtn" title="刷新所有数据"></button>
</div>
</header>
<!-- ── City List Sidebar (left) ── -->
<nav id="cityList" class="city-list">
<div class="city-list-header">
<span>🏙️ 监控城市</span>
<span class="city-count" id="cityCount">0</span>
</div>
<div id="cityListItems" class="city-list-items">
<!-- Dynamically populated -->
</div>
</nav>
<!-- ── Detail Panel (right) ── -->
<aside id="panel" class="detail-panel hidden">
<div class="panel-header">
<button class="panel-close" id="panelClose"></button>
<div class="panel-title-area">
<h2 id="panelCityName"></h2>
<div class="panel-meta">
<span id="panelRiskBadge" class="risk-badge"></span>
<span id="panelLocalTime" class="local-time"></span>
<button class="history-btn" id="btnShowHistory" title="查看历史记录与准确率">📊 历史对账</button>
</div>
</div>
</div>
<div id="panelContent" class="panel-body">
<!-- ── Temperature Hero ── -->
<section class="hero-section">
<div class="hero-weather" id="heroWeather"></div>
<div class="hero-temp">
<span class="hero-value" id="heroTemp"></span>
<span class="hero-unit" id="heroUnit">°C</span>
</div>
<div class="hero-max-time" id="heroMaxTime"></div>
<div class="hero-details">
<div class="hero-item">
<span class="label">📍 当前实测</span>
<span class="value" id="heroCurrent"></span>
</div>
<div class="hero-item">
<span class="label">🎯 WU 结算</span>
<span class="value highlight" id="heroWU"></span>
</div>
<div class="hero-item">
<span class="label">🧬 DEB 预测</span>
<span class="value" id="heroDEB"></span>
</div>
</div>
<div class="hero-sub" id="heroSub">
<!-- obs time, cloud, wind -->
</div>
</section>
<!-- ── Trend Sparkline ── -->
<section class="chart-section">
<h3>📊 今日温度走势</h3>
<div class="chart-wrapper">
<canvas id="tempChart"></canvas>
</div>
<div class="chart-legend" id="chartLegend"></div>
</section>
<!-- ── Probability Bars ── -->
<section class="prob-section">
<h3>🎲 结算概率分布</h3>
<div id="probBars" class="prob-bars">
<!-- Dynamically populated -->
</div>
</section>
<!-- ── Multi-Model Comparison ── -->
<section class="models-section">
<h3>🔬 多模型预报</h3>
<div id="modelBars" class="model-bars">
<!-- Dynamically populated -->
</div>
</section>
<!-- ── Forecast Table ── -->
<section class="forecast-section">
<h3>📅 多日预报</h3>
<div id="forecastTable" class="forecast-table"></div>
<div class="sun-info" id="sunInfo"></div>
</section>
<!-- ── AI Analysis ── -->
<section class="ai-section">
<h3>🤖 AI 深度分析</h3>
<div id="aiAnalysis" class="ai-box">
<span class="ai-placeholder">点击城市后加载...</span>
</div>
</section>
<!-- ── Risk Profile ── -->
<section class="risk-section">
<h3>⚠️ 数据偏差风险</h3>
<div id="riskInfo" class="risk-info"></div>
</section>
</div>
</aside>
</div>
<!-- ── Loading Overlay ── -->
<div id="loading" class="loading-overlay hidden">
<div class="loading-spinner"></div>
<span>正在获取气象数据,请稍候...</span>
</div>
<!-- ── Technical Guide Modal ── -->
<div id="guideModal" class="modal-overlay hidden">
<div class="modal-content large">
<div class="modal-header">
<h2>📚 PolyWeather 系统技术说明</h2>
<button class="modal-close" id="guideModalClose"></button>
</div>
<div class="modal-body">
<div class="guide-grid">
<div class="guide-card">
<h3>🧬 DEB 动态融合预测</h3>
<p><b>Dynamic Ensemble Blending</b> 是系统的核心算法。它不只是简单的平均值,而是根据各个模型(ECMWF, GFS, MGM等)在**过去 30
天**内的实际表现,动态分配权重。表现越稳的模型,在最终决策中占比越高。</p>
</div>
<div class="guide-card">
<h3>🎲 结算概率引擎 (μ)</h3>
<p>基于正态分布模型。我们提取所有预报模型的离散度作为**不确定性系数 ($\sigma$)**,结合 DEB 预测值作为**期望值 ($\mu$)**。这能告诉你某个温度区间(如 10°C
盘口)发生的真实概率,辅助对冲决策。</p>
</div>
<div class="guide-card">
<h3>📍 结算点 (Airport) 逻辑</h3>
<p>Polymarket 结算是以**机场 METAR
气象站**为准。在安卡拉等复杂城市,我们同时监控**市中心总站**(潜力热岛)和**机场站**(物理结算点)。当两者温差巨大时,往往预示着随后的补涨跳升机会。</p>
</div>
<div class="guide-card">
<h3>⚠️ 风险偏置档案</h3>
<p>系统记录了每个城市机场站与市区的距离、海拔差及季度性偏差。例如,首尔仁川机场因靠海,最高温通常比市区偏低;慕尼黑机场因海拔高,夜间降温极快。这些偏置已自动整合进 AI 分析逻辑中。
</p>
</div>
<div class="guide-card">
<h3>📈 未来日期概率分布</h3>
<p>当你切换到未来 3-5 天时,系统会基于各模型对该日期的预报分歧度重新计算概率。分歧越大,分布越扁平(风险高);共识越强,分布越尖锐(机会明朗)。</p>
</div>
</div>
<div class="guide-footer">
<p>※ 数据来源:NOAA METAR, Turkish MGM, Open-Meteo Ensemble, Meteoblue, NWS.</p>
</div>
</div>
</div>
</div>
<!-- Leaflet JS -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script>
<script src="/static/app.js"></script>
</body>
</html>