新增 AMOS 跑道级实时气象数据源(韩国仁川/釜山)

- src/data_collection/amos_station_sources.py:新增 AmosStationSourceMixin
- 从 global.amo.go.kr 爬取跑道级观测:温度/露点/气压/风向风速/能见度/RVR/云层
- 解析 METAR + TAF 报文,提取温/湿/压/风数值
- 解析跑道级表格数据(每跑道独立风分量、侧风、视程)
- 覆盖首尔/仁川 (RKSI) 和釜山/金海 (RKPK)

- weather_sources.py:集成 AmosStationSourceMixin
- fetch_all_sources 中为 seoul/busan 自动追加 AMOS 数据
- 结果存入 results["amos"],包含原始 METAR/TAF 和解析后的跑道数据

Tested: python -m ruff check ., npx tsc --noEmit
This commit is contained in:
2569718930@qq.com
2026-05-10 17:55:39 +08:00
parent fe681503ae
commit 058ab7a619
2 changed files with 290 additions and 5 deletions
+26 -5
View File
@@ -15,17 +15,21 @@ from src.data_collection.jma_amedas_sources import JmaAmedasSourceMixin
from src.data_collection.russia_station_sources import RussiaStationSourceMixin
from src.data_collection.nmc_sources import NmcSourceMixin
from src.data_collection.nws_open_meteo_sources import NwsOpenMeteoSourceMixin
from src.data_collection.amos_station_sources import AmosStationSourceMixin
class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSourceMixin, MgmSourceMixin, KmaStationSourceMixin, JmaAmedasSourceMixin, RussiaStationSourceMixin, NmcSourceMixin, NwsOpenMeteoSourceMixin):
class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSourceMixin, MgmSourceMixin, KmaStationSourceMixin, JmaAmedasSourceMixin, RussiaStationSourceMixin, NmcSourceMixin, NwsOpenMeteoSourceMixin, AmosStationSourceMixin):
"""
Multi-source weather data collector
Supports:
- OpenWeatherMap (free, fast updates)
- Weather Underground (Polymarket settlement source)
- Visual Crossing (rich historical data)
- NOAA Aviation Weather (METAR - airport observations)
- Open-Meteo (global forecast + multi-model ensemble)
- METAR/TAF (aviation weather observations)
- AMOS (Korean runway-level airport sensors — RKSI, RKPK)
- NWS (US National Weather Service)
- MGM (Turkish Meteorological Service)
- KMA / JMA / NMC / HKO / CWA (country official networks)
- Polymarket (weather derivative markets)
"""
from src.data_collection.city_registry import CITY_REGISTRY
@@ -891,6 +895,21 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour
results["mgm_nearby"] = official_rows
results["nearby_source"] = "kma"
def _attach_korean_amos_data(
self, results: Dict, city_lower: str, use_fahrenheit: bool
) -> None:
"""Fetch AMOS runway-level observations for Seoul and Busan."""
if city_lower not in ("seoul", "busan"):
return
try:
amos_data = self.fetch_amos_official_current(
city_lower, use_fahrenheit=use_fahrenheit
)
if amos_data:
results["amos"] = amos_data
except Exception as exc:
logger.debug("AMOS attach failed city={}: {}", city_lower, exc)
def _attach_russia_official_nearby(
self, results: Dict, city_lower: str, use_fahrenheit: bool
) -> None:
@@ -1019,6 +1038,7 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour
self._attach_china_official_nearby(results, city_lower, use_fahrenheit)
self._attach_japan_official_nearby(results, city_lower, use_fahrenheit)
self._attach_korea_official_nearby(results, city_lower, use_fahrenheit)
self._attach_korean_amos_data(results, city_lower, use_fahrenheit)
self._attach_russia_official_nearby(results, city_lower, use_fahrenheit)
if city_lower == "warsaw":
self._attach_warsaw_official_nearby(results, use_fahrenheit)
@@ -1061,6 +1081,7 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour
self._attach_china_official_nearby(results, city_lower, use_fahrenheit)
self._attach_japan_official_nearby(results, city_lower, use_fahrenheit)
self._attach_korea_official_nearby(results, city_lower, use_fahrenheit)
self._attach_korean_amos_data(results, city_lower, use_fahrenheit)
self._attach_russia_official_nearby(results, city_lower, use_fahrenheit)
if city_lower == "warsaw":
self._attach_warsaw_official_nearby(results, use_fahrenheit)