From 6d9c0d571af315facedd6c75ef8f615be7822639 Mon Sep 17 00:00:00 2001 From: OpenAI Codex Date: Thu, 6 Aug 2026 19:31:45 +0800 Subject: [PATCH] fix: restore Kyushu semantic beacon variants --- STEP_RECORD.md | 37 +++++++++++++++++++ navsea_build_kyushu_semantic_icon_test.py | 37 +++++++++++++++++-- .../sprite_icon_closure.json | 25 ++++++++++++- .../sprite_icon_closure.md | 4 +- ...vsea-delivery-kyushu-semantic-icon-v1.json | 20 +++++----- 5 files changed, 106 insertions(+), 17 deletions(-) diff --git a/STEP_RECORD.md b/STEP_RECORD.md index 7253500..8516768 100644 --- a/STEP_RECORD.md +++ b/STEP_RECORD.md @@ -54,6 +54,43 @@ - r2 sprite 中 `pattern_fill_fishery_or_fish_reef_area`、`fill-daytime-420`、`fill-daytime-427`、`fill-daytime-754` 均存在 - 备注:本机 headless Chrome 截图因 WebGL context 创建失败为空白,不能作为视觉确认依据;需在实际浏览器里刷新 r2 页面人工复核红框区域。 +### 2026-08-06 九州语义图标测试版 r2 修复灯标本体掉失 + +- 用户继续指出:`navigation_marks` 中一处灯标对象左侧原始版有黑色灯标本体,右侧语义版只剩黄色 flare,本体符号缺失。 +- 点击信息: + - `source-layer = navigation_marks` + - 右侧命中的 render layer 是 `nav-light-flare` + - 对象属性包含: + - `shape_class_code = 311` + - `display_code = 31135504` + - `canonical_object_type = light_beacon` + - `icon_id = lt_bcn` +- 根因分两层: + - `nav-marks-light-beacons` 对 `31135504` 使用的不是 `lt_bcn`,而是 style 里直接写死的旧 sprite key:`light_beacon_east_cardinal_variantt` + - r2 sprite 之前只保留了 `icon_id/arc_id` 驱动的 key,没有把 style 里直接写死的 `light_beacon_*` / `buoy_*` / `light_up_*` 等 variant key 一起带入 +- 进一步发现 builder 的 style transform 还把部分 `canonical_object_type` 过滤值误替换成了 sprite 短 key: + - `harbor_lighthouse -> lt_hbr` + - `breakwater_lighthouse -> lt_bkw` + - `light_beacon -> lt_bcn` + - 这会破坏无 `display_code` 分支和 `nav-marks` 排除条件 +- 已修复 `navsea_build_kyushu_semantic_icon_test.py`: + - sprite 构建改为按 `style` 实际引用的真实 sprite key 保留 literal icon/pattern 依赖,不再只保留 `icon_id/arc_id` + - `navigation_marks` 相关 layer 的 `canonical_object_type` 过滤值恢复为业务语义值: + - `harbor_lighthouse` + - `breakwater_lighthouse` + - `light_beacon` +- 修复后确认: + - `style.navsea-delivery-kyushu-semantic-icon-v1.json` 中 `31135504 -> light_beacon_east_cardinal_variantt` + - `/newpec/sprite-kyushu-semantic-icon-v1-20260806-r2/sprite.json` 中 `light_beacon_east_cardinal_variantt` 已存在 + - 闭合审计已刷新为: + - 扫描瓦片 `4707` + - 使用 key `83` + - sprite key `119` + - 缺失 key `0` + - 旧 `symbol-daytime-* / arc-daytime-*` key `0` + - 结论 `PASS` +- 备注:由于当前环境 headless Chrome 无法建立 WebGL context,未能在本机截图直接看到修复后的地图画面;需在真实浏览器里刷新 r2 页面确认该灯标本体已恢复。 + ### 2026-08-06 当前 Full PBF 与 style 显示消费关系调查 - 调查对象:`/home/wwwroot/pbf-delivery-full-20260418-rebuild`,共 `65148` 张 PBF;对照当前 Full extent-fix / semantic-extent-fix style。 diff --git a/navsea_build_kyushu_semantic_icon_test.py b/navsea_build_kyushu_semantic_icon_test.py index f857048..f8f6e5f 100644 --- a/navsea_build_kyushu_semantic_icon_test.py +++ b/navsea_build_kyushu_semantic_icon_test.py @@ -267,15 +267,43 @@ def transform_style(config: dict[str, Any]) -> dict[str, Any]: } style["sources"]["navsea_delivery"]["tiles"] = [TARGET_TILE_URL] + canonical_restore = { + "lt_hbr": "harbor_lighthouse", + "lt_bkw": "breakwater_lighthouse", + "lt_bcn": "light_beacon", + } + + def restore_canonical_values(value: Any) -> Any: + if isinstance(value, list): + if len(value) >= 3 and value[:2] == ["get", "canonical_object_type"]: + return value + return [restore_canonical_values(item) for item in value] + if isinstance(value, dict): + return {key: restore_canonical_values(item) for key, item in value.items()} + if isinstance(value, str): + return canonical_restore.get(value, value) + return value + for layer in style["layers"]: layer_id = layer.get("id") layout = layer.get("layout") or {} + layer_filter = layer.get("filter") if layer_id in SIMPLE_ICON_LAYERS: layout["icon-image"] = ["coalesce", ["get", "icon_id"], ""] layer["layout"] = layout elif layer_id == "nav-light-arc": layout["icon-image"] = ["coalesce", ["get", "arc_id"], ""] layer["layout"] = layout + elif layer_id in { + "nav-marks-harbor-lighthouses", + "nav-marks-breakwater-lighthouses", + "nav-marks-light-beacons", + "nav-marks", + }: + if layer_filter is not None: + layer["filter"] = restore_canonical_values(layer_filter) + if layer_id == "nav-marks": + layer["layout"] = restore_canonical_values(layout) return style @@ -296,7 +324,7 @@ def write_newpec_style() -> None: write_style(style, NEWPEC_STYLE_OUTPUT, NEWPEC_STYLE_DEPLOY) -def collect_literal_sprite_refs(style: dict[str, Any]) -> set[str]: +def collect_literal_sprite_refs(style: dict[str, Any], sprite_keys: set[str] | None = None) -> set[str]: refs: set[str] = set() def walk(value: Any) -> None: @@ -307,7 +335,9 @@ def collect_literal_sprite_refs(style: dict[str, Any]) -> set[str]: for child in value: walk(child) elif isinstance(value, str): - if ( + if sprite_keys is not None and value in sprite_keys: + refs.add(value) + elif ( value.startswith("pattern_fill_") or value.startswith("fill-daytime-") or value.startswith("fill_") @@ -335,11 +365,12 @@ def build_sprite(config: dict[str, Any], style: dict[str, Any]) -> dict[str, Any source_meta: dict[str, dict[str, dict[str, Any]]] = {} for filename in ("sprite.json", "sprite@2x.json"): source_meta[filename] = json.loads((SPRITE_SOURCE / filename).read_text(encoding="utf-8")) + source_sprite_keys = set().union(*(meta.keys() for meta in source_meta.values())) key_map = dict(config["sprite_key_map"]) key_map.update(STYLE_EXTRA_MAP) fallback_sources = {"lm_cus": "symbol-daytime-660"} - passthrough_keys = collect_literal_sprite_refs(style) + passthrough_keys = collect_literal_sprite_refs(style, source_sprite_keys) added: dict[str, str] = {} for filename, meta in source_meta.items(): # 测试包只改名图标/灯弧;fill/line pattern 等非图标纹理必须按 style 原名保留。 diff --git a/report/kyushu_semantic_icon_v1_2026-08-06/sprite_icon_closure.json b/report/kyushu_semantic_icon_v1_2026-08-06/sprite_icon_closure.json index 3352d0b..fa417e8 100644 --- a/report/kyushu_semantic_icon_v1_2026-08-06/sprite_icon_closure.json +++ b/report/kyushu_semantic_icon_v1_2026-08-06/sprite_icon_closure.json @@ -10,11 +10,21 @@ "arc_R", "arc_YW", "arc_open_YW", + "breakwater_lighthouse", "bu_can", "bu_gen", "bu_lat", "bu_lit", "bu_pil", + "buoy_east_cardinal", + "buoy_isolated_danger", + "buoy_north_cardinal", + "buoy_port_lateral_variantt_312350", + "buoy_safe_water", + "buoy_south_cardinal", + "buoy_special_mark", + "buoy_starboard_lateral_variantt_312351", + "buoy_west_cardinal", "fac_fisherina", "fac_fishport", "fac_marina", @@ -24,6 +34,7 @@ "fill-daytime-427", "fill-daytime-428", "fill-daytime-754", + "harbor_lighthouse", "hz_danger_clear", "hz_danger_iso", "hz_dolphin", @@ -43,6 +54,15 @@ "hz_wreck_hull", "hz_wreck_sub", "hz_wreck_survey", + "light_beacon_east_cardinal_variantt", + "light_beacon_isolated_danger_variantt_311359", + "light_beacon_north_cardinal_variantt", + "light_beacon_north_cardinal_variantt_311356", + "light_beacon_safe_water_variantt_311360", + "light_beacon_south_cardinal_variantt", + "light_beacon_west_cardinal_variantt_311358", + "light_up_green", + "light_up_red", "lm_chim", "lm_ctrl", "lm_cus", @@ -61,12 +81,13 @@ "mk_lead_c", "mk_lead_v", "mk_vais", + "mooring_buoy", "pattern_fill_fishery_or_fish_reef_area", "special_pattern_line_754", "tide_spot" ], - "used_key_count": 62, - "sprite_key_count": 98, + "used_key_count": 83, + "sprite_key_count": 119, "missing_keys": [], "legacy_sprite_keys": [], "verdict": "PASS" diff --git a/report/kyushu_semantic_icon_v1_2026-08-06/sprite_icon_closure.md b/report/kyushu_semantic_icon_v1_2026-08-06/sprite_icon_closure.md index d90f614..e14b2c8 100644 --- a/report/kyushu_semantic_icon_v1_2026-08-06/sprite_icon_closure.md +++ b/report/kyushu_semantic_icon_v1_2026-08-06/sprite_icon_closure.md @@ -2,8 +2,8 @@ - 资产版本:`kyushu-semantic-icon-v1-20260806-r2` - 扫描瓦片:`4707` -- 使用中的 icon_id/arc_id/纹理 key:`62` -- sprite 键数:`98` +- 使用中的 icon_id/arc_id/纹理 key:`83` +- sprite 键数:`119` - 缺失键:`0` - 旧前缀键:`0` - 结论:`PASS` diff --git a/src/pbf/style.navsea-delivery-kyushu-semantic-icon-v1.json b/src/pbf/style.navsea-delivery-kyushu-semantic-icon-v1.json index d9f04c3..e7a81e4 100644 --- a/src/pbf/style.navsea-delivery-kyushu-semantic-icon-v1.json +++ b/src/pbf/style.navsea-delivery-kyushu-semantic-icon-v1.json @@ -1515,7 +1515,7 @@ "get", "canonical_object_type" ], - "lt_hbr" + "harbor_lighthouse" ] ] ] @@ -1568,7 +1568,7 @@ "get", "canonical_object_type" ], - "lt_bkw" + "breakwater_lighthouse" ] ] ] @@ -1798,7 +1798,7 @@ "get", "canonical_object_type" ], - "lt_bcn" + "light_beacon" ] ] ] @@ -1927,18 +1927,18 @@ "get", "canonical_object_type" ], - "lt_hbr" + "harbor_lighthouse" ], - "lt_hbr", + "harbor_lighthouse", [ "==", [ "get", "canonical_object_type" ], - "lt_bkw" + "breakwater_lighthouse" ], - "lt_bkw", + "breakwater_lighthouse", [ "==", [ @@ -2034,7 +2034,7 @@ "get", "canonical_object_type" ], - "lt_hbr" + "harbor_lighthouse" ], [ "!=", @@ -2042,7 +2042,7 @@ "get", "canonical_object_type" ], - "lt_bkw" + "breakwater_lighthouse" ], [ "!=", @@ -2058,7 +2058,7 @@ "get", "canonical_object_type" ], - "lt_bcn" + "light_beacon" ] ] },