462 lines
23 KiB
Python
462 lines
23 KiB
Python
#!/usr/bin/env python3
|
||
"""生成 CM95 / NavSea Visual Object Reviewer 使用的中文名称补充表。
|
||
|
||
注意:
|
||
- 该文件只用于 UI 显示和人工理解;
|
||
- 不参与 Visual Object 匹配、聚类、Layer 判定;
|
||
- CM95 英文说明来自当前 CM95 仓库中的 S-52 metadata;
|
||
- 中文名称为工程显示译名,不冒充 IHO 官方中文译名。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
import re
|
||
from pathlib import Path
|
||
from typing import Any
|
||
|
||
ROOT = Path(__file__).resolve().parent
|
||
OUTPUT = ROOT / "output"
|
||
CM95_ROOT = Path("/root/sourceserver/cm95")
|
||
|
||
LAYER_ZH = {
|
||
"anchor_caution_hazard_outline": "锚泊注意/危险区轮廓",
|
||
"anchor_caution_hazard_point": "锚泊注意/危险点",
|
||
"anchorage_area": "锚地面",
|
||
"anchorage_outline": "锚地轮廓",
|
||
"anchorage_point": "锚地点",
|
||
"baseline_area": "基础区域",
|
||
"baseline_line": "基础线",
|
||
"baseline_outline": "基础区域轮廓",
|
||
"bathymetry_line": "海底地形线",
|
||
"bridge_structure": "桥梁结构",
|
||
"clearance_limit_line": "净空限制线",
|
||
"clearance_limit_point": "净空限制点",
|
||
"clip_outline_754": "特殊边界线",
|
||
"depth_contour": "等深线",
|
||
"depth_zone_739": "水深分区 739",
|
||
"depth_zone_741": "水深分区 741",
|
||
"facility_boundary_outline": "设施边界轮廓",
|
||
"facility_boundary_point": "港口/设施点",
|
||
"fixed_fishing_gear_area": "定置渔具区域",
|
||
"hazard_boundary_outline": "危险边界轮廓",
|
||
"hole_area": "孔洞/挖空区域",
|
||
"land_area": "陆地区域",
|
||
"navigation_hazard_outline": "航行危险轮廓",
|
||
"navigation_hazard_point": "航行危险点",
|
||
"navigation_marks": "航路标识",
|
||
"onshore_structure_area": "陆上结构物面",
|
||
"onshore_structure_line": "陆上结构物线",
|
||
"onshore_structure_point": "陆上结构物点",
|
||
"pilot_station_point": "引航站",
|
||
"place_label_land": "陆地地名",
|
||
"place_label_sea": "海域地名",
|
||
"seabed_line": "海底对象线",
|
||
"seabed_text_point": "海底文字点",
|
||
"submerged_reef_area": "水下礁区域",
|
||
"tide": "潮汐",
|
||
}
|
||
|
||
STD_KEY_ZH = {
|
||
"tidespot-daytime": "潮汐点",
|
||
"pattern_fill_fishery_or_fish_reef_area": "定置渔业/鱼礁填充",
|
||
"special_pattern_line_754": "特殊边界线",
|
||
"bollard_pile_stake": "系缆柱、桩、杭",
|
||
"cleared_danger_object": "扫海済危险物",
|
||
"dolphin_structure": "系泊墩",
|
||
"eddy_whirlpool": "涡流",
|
||
"fish_reef": "鱼礁",
|
||
"fish_reef_dangerous": "危险鱼礁",
|
||
"foul_ground": "碍锚海底",
|
||
"isolated_danger": "孤立危险物",
|
||
"obstruction": "障碍物",
|
||
"rock_exposed_drying_awash_group": "露出岩/干出岩/洗岩",
|
||
"sand_wave": "沙波",
|
||
"seaweed": "海草",
|
||
"subsea_installation_outfall_intake": "海底设施/放水口/取水口",
|
||
"sunken_rock": "暗岩",
|
||
"tide_rips_overfalls": "急潮/波纹",
|
||
"tower_yagura_observation_platform": "塔/架台/测台",
|
||
"wreck_fully_submerged_dangerous": "危险全沉船",
|
||
"wreck_hull_exposed": "船体或桅杆露出沉船",
|
||
"wreck_surveyed": "测定済沉船",
|
||
"anchorage_designated": "指定锚地",
|
||
"anchorage_quarantine": "检疫锚地",
|
||
"anchoring_prohibited": "禁止锚泊区",
|
||
"restriction_area_group": "限制区域",
|
||
"light_flare_green": "绿色灯光",
|
||
"light_flare_red": "红色灯光",
|
||
"light_flare_yellow_white": "黄色/白色灯光",
|
||
"harbor_lighthouse": "港湾灯塔",
|
||
"breakwater_lighthouse": "防波堤灯塔",
|
||
"coastal_lighthouse": "沿岸灯塔",
|
||
"light_minor": "小型灯标",
|
||
"light_beacon": "灯标",
|
||
"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": "西方位灯标",
|
||
"buoy_can": "罐形浮标",
|
||
"buoy_east_cardinal": "东方位浮标",
|
||
"buoy_isolated_danger": "孤立危险浮标",
|
||
"buoy_lattice": "架形浮标",
|
||
"buoy_north_cardinal": "北方位浮标",
|
||
"buoy_pillar": "柱形浮标",
|
||
"buoy_port_lateral_variantt_312350": "左舷浮标",
|
||
"buoy_safe_water": "安全水域浮标",
|
||
"buoy_south_cardinal": "南方位浮标",
|
||
"buoy_special_mark": "特殊标识浮标",
|
||
"buoy_starboard_lateral_variantt_312351": "右舷浮标",
|
||
"buoy_west_cardinal": "西方位浮标",
|
||
"mooring_buoy": "系泊浮标",
|
||
"fisherina": "渔港休闲设施",
|
||
"fishing_port": "渔港",
|
||
"marina": "游艇码头",
|
||
"port_general_small_harbor_group": "一般港湾/小港湾",
|
||
"sea_station_umi_no_eki": "海之驿",
|
||
"pilot_station": "引航站",
|
||
"symbol-daytime-401": "露出岩/干出岩/洗岩",
|
||
"symbol-daytime-404": "暗岩",
|
||
"symbol-daytime-405": "扫海済危险物",
|
||
"symbol-daytime-409": "孤立危险物",
|
||
"symbol-daytime-410": "船体或桅杆露出沉船",
|
||
"symbol-daytime-412": "危险全沉船",
|
||
"symbol-daytime-413": "测定済沉船",
|
||
"symbol-daytime-420": "碍锚海底",
|
||
"symbol-daytime-421": "沙波",
|
||
"symbol-daytime-422": "急潮/波纹",
|
||
"symbol-daytime-424": "涡流",
|
||
"symbol-daytime-425": "海草",
|
||
"symbol-daytime-427": "障碍物",
|
||
"symbol-daytime-428": "鱼礁",
|
||
"symbol-daytime-429": "危险鱼礁",
|
||
"symbol-daytime-431": "塔/架台/测台",
|
||
"symbol-daytime-432": "系缆柱、桩、杭",
|
||
"symbol-daytime-433": "系泊墩",
|
||
"symbol-daytime-434": "海底设施/放水口/取水口",
|
||
"symbol-daytime-640": "烟囱",
|
||
"symbol-daytime-650": "陆上显著结构物",
|
||
"symbol-daytime-660": "陆上显著结构物",
|
||
"symbol-daytime-661": "陆上显著结构物",
|
||
"symbol-daytime-681": "陆上显著结构物",
|
||
"symbol-daytime-698": "其他陆上结构物",
|
||
}
|
||
|
||
def color_zh(text: str) -> str:
|
||
replacements = [
|
||
("black/yellow/black", "黑/黄/黑"),
|
||
("yellow/black/yellow", "黄/黑/黄"),
|
||
("black/red/black", "黑/红/黑"),
|
||
("green/white", "绿/白"),
|
||
("red/white", "红/白"),
|
||
("black/yellow", "黑/黄"),
|
||
("yellow/black", "黄/黑"),
|
||
("white/black", "白/黑"),
|
||
("black/white", "黑/白"),
|
||
("white/red", "白/红"),
|
||
("red/green", "红/绿"),
|
||
("white or yellow", "白色或黄色"),
|
||
("yellow", "黄色"),
|
||
("green", "绿色"),
|
||
("red", "红色"),
|
||
("white", "白色"),
|
||
("black", "黑色"),
|
||
]
|
||
out = text
|
||
for en, zh in replacements:
|
||
out = out.replace(en, zh)
|
||
return out
|
||
|
||
def s52_zh(key: str, desc: str) -> tuple[str, str]:
|
||
"""返回 (中文显示名, 来源说明)。"""
|
||
d = desc.strip().lower()
|
||
if not d:
|
||
fallback = {
|
||
"STARPT01": "星形点标志",
|
||
"TOPMA115": "顶标",
|
||
"TOPMAR01": "浮标顶标",
|
||
}.get(key, "未提供说明")
|
||
return fallback, "工程显示译名"
|
||
|
||
exact = {
|
||
"anchorage area": "锚地",
|
||
"designated anchor berth for a single vessel": "指定单船锚泊位",
|
||
"symbol for opening bridge": "开启桥",
|
||
"berth number symbol": "泊位编号",
|
||
"built-up area": "建成区",
|
||
"coastguard station": "海岸警卫站",
|
||
"chimney": "烟囱",
|
||
"conspicuous chimney": "显著烟囱",
|
||
"ho information note": "海图机构信息注记",
|
||
"flare stack": "火炬塔",
|
||
"flagstaff, flagpole": "旗杆",
|
||
"fog signal": "雾号",
|
||
"fortified structure": "防御工事",
|
||
"fish haven": "鱼礁/鱼类栖息设施",
|
||
"fishing harbour": "渔港",
|
||
"light flare": "灯光标志",
|
||
"floodlight": "泛光灯",
|
||
"fish farm": "养殖场",
|
||
"mooring dolphin": "系泊墩",
|
||
"mast": "桅杆",
|
||
"offshore platform": "海上平台",
|
||
"pilot boarding place": "引航员登轮点",
|
||
"pile or bollard": "桩/系缆柱",
|
||
"traffic precautionary area": "通航注意区",
|
||
"radar reflector": "雷达反射器",
|
||
"radio station": "无线电台",
|
||
"radar transponder beacon": "雷达应答标",
|
||
"yacht harbour, marina": "游艇码头",
|
||
"sand waves": "沙波",
|
||
"traffic crossing area": "交通交叉区",
|
||
"traffic roundabout": "交通环岛",
|
||
"weed, kelp": "海草/海带",
|
||
"windmotor": "风车",
|
||
"submarine cable": "海底电缆",
|
||
"ferry route": "渡轮航线",
|
||
"fishing stakes": "定置渔桩",
|
||
"area with minor restrictions or information notices": "轻微限制/信息提示区域",
|
||
"beacon in general, black/yellow/back, full-chart": "一般立标(黑/黄/黑,完整显示)",
|
||
"beacon in general, yellow/back/yellow, full-chart": "一般立标(黄/黑/黄,完整显示)",
|
||
"beacon in general, black/red/back, full-chart": "一般立标(黑/红/黑,完整显示)",
|
||
"conical buoy,lateral-green,full-chart": "锥形侧面浮标(绿色,完整显示)",
|
||
"mooring buoy, can shape, paper-chart": "罐形系泊浮标(海图符号)",
|
||
"pillar buoy,cardianl-yby,full-chart": "柱形方位浮标(黄/黑/黄,完整显示)",
|
||
"topmark for buoys, cone point up, paper-chart": "浮标顶标:单锥尖向上",
|
||
"topmark for buoys, 2 cones point upward, paper-chart": "浮标顶标:双锥尖向上",
|
||
"topmark for buoys, 2 cones point downward, paper-chart": "浮标顶标:双锥尖向下",
|
||
"topmark for buoys, 2 cones base to base, paper-chart": "浮标顶标:双锥底相对",
|
||
"topmark for buoys, 2 cones point to point, paper-chart": "浮标顶标:双锥尖相对",
|
||
"topmark for buoys, sphere, paper-chart": "浮标顶标:球形",
|
||
"topmark for buoys, 2 spheres, paper-chart": "浮标顶标:双球",
|
||
"topmark for buoys, cylinder, paper-chart": "浮标顶标:圆柱形",
|
||
"beacon top mark, red boarded square board, vertical": "立标顶标:红边方形板(竖向)",
|
||
}
|
||
if d in exact:
|
||
return exact[d], "S-52 英文说明的中文显示译名"
|
||
|
||
if d.startswith("anchorage area as a point"):
|
||
return "锚地点", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("beacon in general"):
|
||
suffix = d.split(",", 1)[1].strip() if "," in d else ""
|
||
return "一般立标" + (f"({color_zh(suffix.replace('full-chart','完整显示').replace('paper-chart','海图符号'))})" if suffix else ""), "S-52 英文说明的中文显示译名"
|
||
if "spar beacon" in d:
|
||
return color_zh(d.replace("spar beacon", "杆形立标").replace("full-chart", "完整显示")), "S-52 英文说明的中文显示译名"
|
||
if "stake or pole beacon" in d:
|
||
return color_zh(d.replace("minor, ", "小型").replace("stake or pole beacon", "桩/杆形立标").replace("full-chart", "完整显示")), "S-52 英文说明的中文显示译名"
|
||
if d.startswith("beacon tower"):
|
||
return color_zh(d.replace("beacon tower", "塔形立标").replace("full-chart", "完整显示").replace("brb", "黑/红/黑")), "S-52 英文说明的中文显示译名"
|
||
if "buoy" in d:
|
||
out = d
|
||
out = out.replace("can buoy", "罐形浮标").replace("conical buoy", "锥形浮标")
|
||
out = out.replace("mooring buoy", "系泊浮标").replace("pillar buoy", "柱形浮标")
|
||
out = out.replace("spherical buoy", "球形浮标").replace("spar buoy", "杆形浮标")
|
||
out = out.replace("super-buoy", "特大型浮标").replace("super buoy", "特大型浮标")
|
||
out = out.replace("default symbol for buoy", "一般浮标")
|
||
out = out.replace("paper-chart", "海图符号").replace("full-chart", "完整显示")
|
||
out = out.replace("lateral-r", "侧面标识-红").replace("lateral-g", "侧面标识-绿")
|
||
out = out.replace("special purpose-y", "特殊用途-黄")
|
||
out = out.replace("cardinal-byb", "方位标-黑/黄/黑").replace("cardinal-yby", "方位标-黄/黑/黄")
|
||
out = out.replace("cardinal-by", "方位标-黑/黄").replace("cardinal-yb", "方位标-黄/黑")
|
||
out = out.replace("isol.danger-brb", "孤立危险标-黑/红/黑").replace("safe water-rw", "安全水域标-红/白")
|
||
out = color_zh(out)
|
||
return out, "S-52 英文说明的中文显示译名"
|
||
if d.startswith("caution area"):
|
||
return "注意区域", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("cautionary area"):
|
||
return "谨慎航行区域", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("foul area of seabed"):
|
||
return "碍锚海底(航行安全但不宜锚泊)", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("fish trap"):
|
||
return "渔具/鱼栅/金枪鱼网", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("navigable lock gate"):
|
||
return "可通航闸门", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("non-navigable lock gate"):
|
||
return "不可通航闸门", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("light flare"):
|
||
return color_zh(d.replace("light flare", "灯光标志")), "S-52 英文说明的中文显示译名"
|
||
if d.startswith("light float"):
|
||
return "灯浮体", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("light vessel"):
|
||
return color_zh(d.replace("light vessel", "灯船").replace("full-chart", "完整显示")), "S-52 英文说明的中文显示译名"
|
||
if d.startswith("cursor pick site for a magnetic anomaly"):
|
||
return "磁异常位置", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("point feature or area of low accuracy"):
|
||
return "低位置精度对象/区域", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("position of an elevation or control point"):
|
||
return "高程点/控制点", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("object which is not sufficiently described"):
|
||
return "未充分描述/无对应符号的对象", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("symbol indicating this object is radar conspicuous"):
|
||
return "雷达显著物标志", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("recommended route"):
|
||
return "推荐航路", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("topmark for buoys"):
|
||
tail = d.split(",", 1)[1].strip() if "," in d else ""
|
||
trans = tail.replace("2 cones point upward", "双锥尖向上").replace("2 cones point downward", "双锥尖向下")
|
||
trans = trans.replace("2 cones base to base", "双锥底相对").replace("2 cones point to point", "双锥尖相对")
|
||
trans = trans.replace("cone point up", "单锥尖向上").replace("2 spheres", "双球").replace("sphere", "球形").replace("cylinder", "圆柱形")
|
||
trans = trans.replace("paper-chart", "海图符号")
|
||
return f"浮标顶标:{trans}", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("topmark for beacons"):
|
||
tail = d.split(",", 1)[1].strip() if "," in d else ""
|
||
trans = tail.replace("2 cones point upward", "双锥尖向上").replace("2 cones point downward", "双锥尖向下")
|
||
trans = trans.replace("2 cones base to base", "双锥底相对").replace("2 cones point to point", "双锥尖相对")
|
||
trans = trans.replace("cone point up", "单锥尖向上").replace("2 spheres", "双球").replace("sphere", "球形").replace("cylinder", "圆柱形")
|
||
trans = trans.replace("paper-chart", "海图符号")
|
||
return f"立标顶标:{trans}", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("beacon top mark"):
|
||
return color_zh(d.replace("beacon top mark", "立标顶标").replace("square board", "方形板").replace("diagonal", "对角").replace("vertical", "竖向")), "S-52 英文说明的中文显示译名"
|
||
if d.startswith("tower"):
|
||
return color_zh(d.replace("tower", "塔").replace("full-chart and simplified", "完整/简化显示")), "S-52 英文说明的中文显示译名"
|
||
if d == "water tower":
|
||
return "水塔", "S-52 英文说明的中文显示译名"
|
||
if d == "conspicuous tower":
|
||
return "显著塔", "S-52 英文说明的中文显示译名"
|
||
if d == "radio, television tower":
|
||
return "无线电/电视塔", "S-52 英文说明的中文显示译名"
|
||
if d == "conspicuous radio, television tower":
|
||
return "显著无线电/电视塔", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("traffic direction"):
|
||
return "分道通航单向航道交通方向", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("overfalls, eddies and breakers"):
|
||
return "急流、涡流和碎波", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("pattern of symbols for a fish haven"):
|
||
return "鱼礁填充图案", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("pattern of symbols for a marine farm"):
|
||
return "养殖场填充图案", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("pattern of symbols for a marsh"):
|
||
return "沼泽填充图案", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("incompletely surveyed area"):
|
||
return "未完全测量区域", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("pattern of symbols for an area which is not sufficiently described"):
|
||
return "未充分描述区域填充图案", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("precautionary area or a traffic separation scheme"):
|
||
return "通航注意区/分道通航交叉或环岛", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("pattern of symbols for wooded areas"):
|
||
return "林地区域填充图案", "S-52 英文说明的中文显示译名"
|
||
if d == "essa or pssa boundary":
|
||
return "特别敏感海域/环境敏感海域边界", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("safety contour of low accuracy"):
|
||
return "低位置精度安全等深线", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("coastline or shoreline construction of low accuracy"):
|
||
return "低位置精度海岸线/岸线构筑物", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("oil, gas pipeline"):
|
||
return "油气管线(海底或陆上)", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("water pipeline"):
|
||
return "水管/下水管等", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("non-regulated recommended two-way track"):
|
||
return "非管制推荐双向航迹", "S-52 英文说明的中文显示译名"
|
||
if d.startswith("non-regulated recommended one-way track"):
|
||
return "非管制推荐单向航迹", "S-52 英文说明的中文显示译名"
|
||
|
||
# 兜底:避免伪造精确术语。仍展示英文原说明。
|
||
return "待人工确认中文名", "尚未建立可靠中文显示译名"
|
||
|
||
|
||
def build_cm95_names() -> dict[str, Any]:
|
||
cm = json.loads((OUTPUT / "cm95-anonymous" / "anonymous-catalog.json").read_text(encoding="utf-8"))
|
||
keys = sorted({o["resource_key"] for o in cm["visual_objects"] if o.get("resource_key")})
|
||
|
||
base = json.loads((CM95_ROOT / "build/s52_resources_v2/base/s52_symbol_metadata.json").read_text(encoding="utf-8"))
|
||
ap_raw = json.loads((CM95_ROOT / "build/s52_resources_v2/ap/s52-sprite-ap-pattern-metadata.json").read_text(encoding="utf-8"))
|
||
lc_raw = json.loads((CM95_ROOT / "build/s52_resources_v2/final/s52-sprite-full-line-metadata.json").read_text(encoding="utf-8"))
|
||
ap = {v.get("sprite_key"): v for v in ap_raw.values()}
|
||
lc = {v.get("sprite_key"): v for v in lc_raw.values()}
|
||
|
||
out: dict[str, Any] = {}
|
||
for key in keys:
|
||
rec = base.get(key) or ap.get(key) or lc.get(key)
|
||
source_type = "symbol" if key in base else ("fill-pattern" if key in ap else ("line-pattern" if key in lc else "unknown"))
|
||
desc = str((rec or {}).get("description") or "")
|
||
|
||
if not desc:
|
||
# 两个基础图标可从其同名 pattern metadata 得到安全的对象级概念。
|
||
if key == "FSHHAV02":
|
||
desc = "fish haven"
|
||
elif key == "MARSHES1":
|
||
desc = "marsh"
|
||
elif key == "CROSSX01":
|
||
desc = ""
|
||
|
||
zh, zh_source = s52_zh(key, desc)
|
||
if key == "MARSHES1":
|
||
zh, zh_source = "沼泽", "由同名 S-52 填充图案说明补充"
|
||
elif key == "FSHHAV02":
|
||
zh, zh_source = "鱼礁/鱼类栖息设施", "由同名 S-52 填充图案说明补充"
|
||
elif key == "CROSSX01":
|
||
zh, zh_source = "交叉标志(待确认)", "S-52 metadata 未找到说明,名称仅作 UI 提示"
|
||
|
||
out[key] = {
|
||
"code": key,
|
||
"resource_type": source_type,
|
||
"official_description_en": desc or None,
|
||
"display_name_zh": zh,
|
||
"display_name_source": zh_source,
|
||
}
|
||
return out
|
||
|
||
|
||
def std_name(key: str, layer: str) -> dict[str, Any]:
|
||
zh = STD_KEY_ZH.get(key)
|
||
source = "NavSea 标准资源语义键中文显示译名"
|
||
if not zh:
|
||
if key.startswith("leading_light"):
|
||
zh = "导灯"
|
||
elif key.startswith("leading_mark"):
|
||
zh = "导标"
|
||
elif key.startswith("arc-daytime"):
|
||
zh = "灯弧"
|
||
elif key.startswith("symbol-daytime"):
|
||
zh = LAYER_ZH.get(layer, "标准视觉对象")
|
||
source = "按标准 Layer 显示,具体对象名待补"
|
||
else:
|
||
zh = LAYER_ZH.get(layer, "标准视觉对象")
|
||
source = "按标准 Layer 显示,具体对象名待补"
|
||
return {
|
||
"resource_key": key,
|
||
"standard_layer": layer,
|
||
"standard_layer_zh": LAYER_ZH.get(layer, layer),
|
||
"display_name_zh": zh,
|
||
"display_name_source": source,
|
||
}
|
||
|
||
|
||
def build_std_names() -> dict[str, Any]:
|
||
std = json.loads((OUTPUT / "navsea-standard" / "standard-catalog.json").read_text(encoding="utf-8"))
|
||
out: dict[str, Any] = {}
|
||
for obj in std["visual_objects"]:
|
||
key = obj.get("resource_key")
|
||
layer = obj.get("standard_layer_name")
|
||
if not key or not layer:
|
||
continue
|
||
out[key] = std_name(key, layer)
|
||
return out
|
||
|
||
|
||
def main() -> None:
|
||
result = {
|
||
"schema": "visual-object-reference-names/v1",
|
||
"policy": {
|
||
"ui_only": True,
|
||
"used_for_matching": False,
|
||
"used_for_layer_assignment": False,
|
||
"chinese_names_are_display_translations": True,
|
||
},
|
||
"cm95": build_cm95_names(),
|
||
"navsea_standard": build_std_names(),
|
||
"standard_layer_zh": LAYER_ZH,
|
||
}
|
||
path = OUTPUT / "reference-name-enrichment-v1.json"
|
||
path.write_text(json.dumps(result, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||
print(path)
|
||
print("CM95", len(result["cm95"]))
|
||
print("NavSea Standard", len(result["navsea_standard"]))
|
||
print("CM95 待人工确认中文名", sum(x["display_name_zh"] == "待人工确认中文名" for x in result["cm95"].values()))
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|