diff --git a/CHANGELOG.md b/CHANGELOG.md index 08f1eddf..e12503a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,7 +54,7 @@ - 右侧详情面板识别稀疏 detail / 单日 forecast 中间态,并显示同步占位卡,避免用户把未补齐数据误认为完整结果 - 概率区改为“校准模型概率”:有 LGBM 时展示 LGBM 校准概率;模型共识与市场价格降级为辅助参考 - 模型层补齐 DWD ICON、ECMWF AIFS、ECCC GEM/GDPS/RDPS/HRDPS 等开放模型说明,并明确 AIFS 不称作“AI 预报” -- 新增 / 补齐 Manila、Karachi、Masroor Air Base 等城市说明;机场市场以 METAR / 机场主站为结算锚点,Wunderground 仅作为历史页面或参考入口 +- 新增 / 补齐 Manila、Karachi 等城市说明;机场市场以 METAR / 机场主站为结算锚点,Wunderground 仅作为历史页面或参考入口 - 历史对账、模型栈、LGBM、监控、前端 README 与网页 `/docs` 文档同步更新到当前产品口径 ## 1.5.3 - 2026-04-10 diff --git a/README.md b/README.md index 51cda871..3986d60f 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ flowchart LR - Europe / Middle East / Africa: Ankara, Istanbul, Moscow, London, Paris, Munich, Milan, Warsaw, Madrid, Tel Aviv, Amsterdam, Helsinki, Lagos, Cape Town, Jeddah - APAC: Seoul, Busan, Hong Kong, Lau Fau Shan, Taipei, Shanghai, Beijing, Qingdao, Wuhan, Chengdu, Chongqing, Shenzhen, Guangzhou, Singapore, Tokyo, Kuala Lumpur, Jakarta, Manila, Wellington - Americas: Toronto, New York, Los Angeles, San Francisco, Aurora, Austin, Houston, Chicago, Dallas, Miami, Atlanta, Seattle, Mexico City, Buenos Aires, Sao Paulo, Panama City -- South Asia: Lucknow, Karachi, Masroor Air Base +- South Asia: Lucknow, Karachi ## Quick Start diff --git a/README_ZH.md b/README_ZH.md index 3304afda..2567c149 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -100,7 +100,7 @@ flowchart LR - 欧洲/中东/非洲:Ankara、Istanbul、Moscow、London、Paris、Munich、Milan、Warsaw、Madrid、Tel Aviv、Amsterdam、Helsinki、Lagos、Cape Town、Jeddah - 亚太:Seoul、Busan、Hong Kong、Lau Fau Shan、Taipei、Shanghai、Beijing、Wuhan、Chengdu、Chongqing、Shenzhen、Guangzhou、Singapore、Tokyo、Kuala Lumpur、Jakarta、Manila、Wellington - 美洲:Toronto、New York、Los Angeles、San Francisco、Aurora、Austin、Houston、Chicago、Dallas、Miami、Atlanta、Seattle、Mexico City、Buenos Aires、Sao Paulo、Panama City -- 南亚:Lucknow、Karachi、Masroor Air Base +- 南亚:Lucknow、Karachi ## 快速启动 diff --git a/extension/README.md b/extension/README.md index cca67d5d..922870e7 100644 --- a/extension/README.md +++ b/extension/README.md @@ -50,7 +50,7 @@ - 当前版本仍是轻量产品,重点是“监控 + 基础判断 + 导流回站”,未接入支付链路。 - 若你的 API 做了严格鉴权,请先在设置页填写 token 再使用。 -- 插件城市列表来自主站 `/api/cities`,不是插件内置静态列表;本版已升级缓存版本,安装更新后会重新拉取 Manila、Karachi、Masroor Air Base 等最新城市。 +- 插件城市列表来自主站 `/api/cities`,不是插件内置静态列表;本版已升级缓存版本,安装更新后会重新拉取 Manila、Karachi 等最新城市。 - 插件走势图与主站保持一致:`Wunderground / weather.com` 是历史参考页,不是物理实测站;机场市场统一显示机场 `METAR` / 官方观测点位。 - 点击“打开网站查看更多”会回到主站继续查看完整分析。 - 插件不会承载完整分析;完整结构判断、历史对账和更多信号仍以主站为准。 diff --git a/frontend/content/docs/docs.ts b/frontend/content/docs/docs.ts index a23a0351..cea7adad 100644 --- a/frontend/content/docs/docs.ts +++ b/frontend/content/docs/docs.ts @@ -424,7 +424,7 @@ export const DOCS_PAGES: DocsPage[] = [ id: "city-rules", title: "当前主要口径", blocks: [ - { type: "bullets", items: ["多数机场市场:按机场 METAR 或机场主站实况结算。", "土耳其机场市场:机场主站仍以 METAR 为锚点,同时保留 Turkish MGM 作为领先结构参考。", "中国内地机场市场:机场主站仍以 METAR 为锚点,NMC 当前实况作为官方增强层,不直接替代机场结算站。", "日本 / 韩国机场市场:机场主站仍以 METAR 为锚点,同时可接入 JMA / KMA 官方增强层做领先结构参考。", "Manila、Karachi、Masroor Air Base 等新增机场城市按对应 METAR / 机场主站作为锚点;Masroor Air Base 是军事机场,OPMR 报文可能不连续,不能自动用 OPKC 替代结算口径。", "香港 / 流浮山 / 台湾等明确官方站点市场:按规则指定的官方结算站点结算,不能拿机场 TAF 或城区体感替代。"] }, + { type: "bullets", items: ["多数机场市场:按机场 METAR 或机场主站实况结算。", "土耳其机场市场:机场主站仍以 METAR 为锚点,同时保留 Turkish MGM 作为领先结构参考。", "中国内地机场市场:机场主站仍以 METAR 为锚点,NMC 当前实况作为官方增强层,不直接替代机场结算站。", "日本 / 韩国机场市场:机场主站仍以 METAR 为锚点,同时可接入 JMA / KMA 官方增强层做领先结构参考。", "Manila、Karachi 等新增机场城市按对应 METAR / 机场主站作为锚点。", "香港 / 流浮山 / 台湾等明确官方站点市场:按规则指定的官方结算站点结算,不能拿机场 TAF 或城区体感替代。"] }, ], }, { @@ -451,7 +451,7 @@ export const DOCS_PAGES: DocsPage[] = [ id: "city-rules", title: "Current primary rules", blocks: [ - { type: "bullets", items: ["Most airport-linked markets settle on airport METAR or the airport primary observing site.", "Turkish airport markets keep METAR as the airport anchor, with Turkish MGM retained as a leading-structure reference.", "Mainland China airport markets keep METAR as the airport anchor, while NMC current observations act as an official enhancement layer rather than a direct replacement anchor.", "Japanese and Korean airport markets can keep METAR as the anchor while using JMA / KMA nearby-network observations as an official enhancement layer.", "New airport cities such as Manila, Karachi, and Masroor Air Base are anchored to their corresponding METAR / airport-primary station. Masroor Air Base is a military airport; OPMR reports may be discontinuous, and OPKC should not automatically replace it as the settlement anchor.", "Markets with explicitly designated official sites, such as Hong Kong, Lau Fau Shan, and Taiwan station-driven contracts, should be anchored to those official settlement stations rather than generic airport logic."] }, + { type: "bullets", items: ["Most airport-linked markets settle on airport METAR or the airport primary observing site.", "Turkish airport markets keep METAR as the airport anchor, with Turkish MGM retained as a leading-structure reference.", "Mainland China airport markets keep METAR as the airport anchor, while NMC current observations act as an official enhancement layer rather than a direct replacement anchor.", "Japanese and Korean airport markets can keep METAR as the anchor while using JMA / KMA nearby-network observations as an official enhancement layer.", "New airport cities such as Manila and Karachi are anchored to their corresponding METAR / airport-primary station.", "Markets with explicitly designated official sites, such as Hong Kong, Lau Fau Shan, and Taiwan station-driven contracts, should be anchored to those official settlement stations rather than generic airport logic."] }, ], }, { diff --git a/frontend/lib/chart-utils.ts b/frontend/lib/chart-utils.ts index 5ffbf361..41df65fb 100644 --- a/frontend/lib/chart-utils.ts +++ b/frontend/lib/chart-utils.ts @@ -418,7 +418,7 @@ export function getTemperatureChartData( const minPlausibleObservationTemp = (() => { const name = String(detail.name || "").trim().toLowerCase(); const icao = String(detail.risk?.icao || "").trim().toUpperCase(); - if (name === "karachi" || name === "masroor air base" || icao === "OPKC" || icao === "OPMR") { + if (name === "karachi" || icao === "OPKC") { return detail.temp_symbol === "°F" ? 41 : 5; } return null; diff --git a/frontend/lib/dashboard-official-sources.ts b/frontend/lib/dashboard-official-sources.ts index 3e4701c2..a429266f 100644 --- a/frontend/lib/dashboard-official-sources.ts +++ b/frontend/lib/dashboard-official-sources.ts @@ -161,13 +161,6 @@ const CITY_SPECIFIC_SOURCES: Record = { kind: "metar", }, ], - "masroor air base": [ - { - label: "OPMR METAR", - href: "https://aviationweather.gov/data/metar/?id=OPMR&decoded=1&taf=1", - kind: "metar", - }, - ], istanbul: [ { label: "MGM", diff --git a/frontend/lib/scan-market-focus.ts b/frontend/lib/scan-market-focus.ts index 856d2ce3..f6af5bf2 100644 --- a/frontend/lib/scan-market-focus.ts +++ b/frontend/lib/scan-market-focus.ts @@ -99,7 +99,6 @@ const CITY_REGION_FALLBACK: Record = { jakarta: "asia_pacific", manila: "asia_pacific", karachi: "asia_pacific", - "masroor air base": "asia_pacific", tokyo: "asia_pacific", wellington: "asia_pacific", lucknow: "asia_pacific", diff --git a/src/data_collection/city_registry.py b/src/data_collection/city_registry.py index 4bbe1b5b..d2bbb2a3 100644 --- a/src/data_collection/city_registry.py +++ b/src/data_collection/city_registry.py @@ -271,23 +271,6 @@ CITY_REGISTRY = { "min_plausible_metar_temp_c": 5.0, "warning": "市场现按 Wunderground 真纳国际机场站整度°C口径结算;海风锋、干热输送与尘霾会影响峰值兑现时间。", }, - "masroor air base": { - "name": "Masroor Air Base", - "lat": 24.8936, - "lon": 66.9388, - "icao": "OPMR", - "settlement_station_code": "OPMR", - "settlement_station_label": "Masroor Air Base METAR", - "tz_offset": 18000, - "use_fahrenheit": False, - "is_major": False, - "risk_level": "medium", - "risk_emoji": "🟡", - "airport_name": "Masroor Air Base", - "distance_km": 0.0, - "min_plausible_metar_temp_c": 5.0, - "warning": "军事机场 METAR 锚点;公开报文可能不连续,若 OPMR 缺报则不要自动替换为 OPKC 结算口径。", - }, "tokyo": { "name": "Tokyo", "lat": 35.5523, @@ -858,7 +841,6 @@ ALIASES = { "jkt": "jakarta", "wihh": "jakarta", "halim": "jakarta", "mnl": "manila", "manila": "manila", "rpll": "manila", "khi": "karachi", "karachi": "karachi", "opkc": "karachi", "jinnah": "karachi", - "opmr": "masroor air base", "masroor": "masroor air base", "masroor airbase": "masroor air base", "hel": "helsinki", "efhk": "helsinki", "vantaa": "helsinki", "ams": "amsterdam", "eham": "amsterdam", "schiphol": "amsterdam", "pty": "panama city", "mpmg": "panama city", "panamacity": "panama city", @@ -905,10 +887,6 @@ ALIASES = { "马尼拉": "manila", "馬尼拉": "manila", "卡拉奇": "karachi", - "马斯鲁尔": "masroor air base", - "馬斯魯爾": "masroor air base", - "马斯鲁尔空军基地": "masroor air base", - "馬斯魯爾空軍基地": "masroor air base", "东京": "tokyo", "東京": "tokyo", "特拉维夫": "tel aviv", diff --git a/src/data_collection/city_time.py b/src/data_collection/city_time.py index b41d82e7..0cbb04f5 100644 --- a/src/data_collection/city_time.py +++ b/src/data_collection/city_time.py @@ -41,7 +41,6 @@ CITY_TIME_ZONES = { "lucknow": "Asia/Kolkata", "madrid": "Europe/Madrid", "manila": "Asia/Manila", - "masroor air base": "Asia/Karachi", "mexico city": "America/Mexico_City", "miami": "America/New_York", "milan": "Europe/Rome", diff --git a/src/data_collection/weather_sources.py b/src/data_collection/weather_sources.py index 81341e7a..4c884aca 100644 --- a/src/data_collection/weather_sources.py +++ b/src/data_collection/weather_sources.py @@ -66,8 +66,7 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour "kuala lumpur": ["WMKK", "WMSA"], "jakarta": ["WIHH", "WIII"], "manila": ["RPLL"], - "karachi": ["OPKC", "OPMR"], - "masroor air base": ["OPMR", "OPKC"], + "karachi": ["OPKC"], "tokyo": ["RJTT", "RJAA", "RJAH", "RJTJ"], "tel aviv": ["LLBG"], "milan": ["LIMC", "LIML", "LIME", "LIPO"], @@ -623,11 +622,6 @@ class WeatherDataCollector(OpenMeteoCacheMixin, SettlementSourceMixin, MetarSour "karachi": "Karachi", "opkc": "Karachi", "卡拉奇": "Karachi", - "masroor": "Masroor Air Base", - "masroor air base": "Masroor Air Base", - "opmr": "Masroor Air Base", - "马斯鲁尔": "Masroor Air Base", - "馬斯魯爾": "Masroor Air Base", "helsinki": "Helsinki", "vantaa": "Helsinki", "赫尔辛基": "Helsinki", diff --git a/tests/test_country_networks.py b/tests/test_country_networks.py index d255efc8..5eab4155 100644 --- a/tests/test_country_networks.py +++ b/tests/test_country_networks.py @@ -24,15 +24,12 @@ def test_new_city_registry_entries_are_wired(): assert CITY_REGISTRY["karachi"]["settlement_station_code"] == "OPKC" assert CITY_REGISTRY["qingdao"]["settlement_source"] == "wunderground" assert CITY_REGISTRY["qingdao"]["settlement_station_code"] == "ZSQD" - assert CITY_REGISTRY["masroor air base"]["icao"] == "OPMR" assert ALIASES["rpll"] == "manila" assert ALIASES["opkc"] == "karachi" assert ALIASES["zsqd"] == "qingdao" - assert ALIASES["opmr"] == "masroor air base" assert CITIES["manila"]["lat"] == CITY_REGISTRY["manila"]["lat"] assert CITIES["karachi"]["lon"] == CITY_REGISTRY["karachi"]["lon"] assert CITIES["qingdao"]["lat"] == CITY_REGISTRY["qingdao"]["lat"] - assert CITIES["masroor air base"]["settlement_source"] == "metar" def test_city_time_zone_mapping_covers_every_city_and_dst_offsets():