fix: preserve Kyushu semantic fill patterns

This commit is contained in:
OpenAI Codex
2026-08-06 18:35:04 +08:00
parent e52328b3f5
commit 69b4f961a6
8 changed files with 600 additions and 23 deletions

View File

@@ -27,10 +27,11 @@ TARGET_ROOT = Path("/home/wwwroot/pbf-delivery-kyushu-semantic-icon-v1-20260806"
TARGET_TILE_URL = "http://192.168.200.184/pbf-delivery-kyushu-semantic-icon-v1-20260806/{z}/{x}/{y}.pbf"
KYUSHU_BBOX = (128.0, 30.0, 132.5, 34.9)
ZOOMS = tuple(range(5, 13))
ASSET_VERSION = "kyushu-semantic-icon-v1-20260806-r2"
SPRITE_SOURCE = Path("/mnt/sda1/www/newpec/sprite-semantic")
SPRITE_TARGET = Path("/mnt/sda1/www/newpec/sprite-kyushu-semantic-icon-v1-20260806")
SPRITE_URL = "http://192.168.200.184/newpec/sprite-kyushu-semantic-icon-v1-20260806/sprite"
SPRITE_TARGET = Path(f"/mnt/sda1/www/newpec/sprite-{ASSET_VERSION}")
SPRITE_URL = f"http://192.168.200.184/newpec/sprite-{ASSET_VERSION}/sprite"
STYLE_SOURCE = REPO_ROOT / "src/pbf/style.navsea-delivery-full-semantic-extentfix.json"
STYLE_OUTPUT = REPO_ROOT / "src/pbf/style.navsea-delivery-kyushu-semantic-icon-v1.json"
@@ -142,6 +143,21 @@ def arc_icon(properties: dict[str, Any], config: dict[str, Any]) -> str | None:
return config["arc_rules"].get(color, config["arc_rules"]["other"])
def normalize_pattern_properties(layer_name: str, properties: dict[str, Any]) -> None:
if (
layer_name == "anchor_caution_hazard_area"
and str(properties.get("class_code")) == "420"
and properties.get("chart_fill_pattern") == "fill-daytime-405"
):
properties["chart_fill_pattern"] = "fill-daytime-420"
if (
layer_name == "navigation_hazard_area"
and str(properties.get("class_code")) == "427"
and properties.get("chart_fill_pattern") == "fill-daytime-405"
):
properties["chart_fill_pattern"] = "fill-daytime-427"
def rewrite_tile(
source: Path,
target: Path,
@@ -162,6 +178,7 @@ def rewrite_tile(
for feature in layer["features"]:
properties = dict(feature.get("properties") or {})
before = dict(properties)
normalize_pattern_properties(layer_name, properties)
legacy = properties.get("chart_icon_image")
if isinstance(legacy, str) and (
legacy.startswith("symbol-daytime-") or legacy.startswith("arc-daytime-")
@@ -279,9 +296,41 @@ def write_newpec_style() -> None:
write_style(style, NEWPEC_STYLE_OUTPUT, NEWPEC_STYLE_DEPLOY)
def build_sprite(config: dict[str, Any]) -> dict[str, Any]:
def collect_literal_sprite_refs(style: dict[str, Any]) -> set[str]:
refs: set[str] = set()
def walk(value: Any) -> None:
if isinstance(value, dict):
for child in value.values():
walk(child)
elif isinstance(value, list):
for child in value:
walk(child)
elif isinstance(value, str):
if (
value.startswith("pattern_fill_")
or value.startswith("fill-daytime-")
or value.startswith("fill_")
or value.startswith("special_pattern_")
or value in {"tide_spot"}
):
refs.add(value)
for layer in style.get("layers", []):
layout = layer.get("layout") or {}
paint = layer.get("paint") or {}
for field in ("icon-image",):
if field in layout:
walk(layout[field])
for field in ("fill-pattern", "line-pattern"):
if field in paint:
walk(paint[field])
return refs
def build_sprite(config: dict[str, Any], style: dict[str, Any]) -> dict[str, Any]:
if SPRITE_TARGET.exists():
raise RuntimeError(f"refusing to overwrite existing sprite target: {SPRITE_TARGET}")
shutil.rmtree(SPRITE_TARGET)
SPRITE_TARGET.mkdir(parents=True)
source_meta: dict[str, dict[str, dict[str, Any]]] = {}
for filename in ("sprite.json", "sprite@2x.json"):
@@ -290,11 +339,25 @@ def build_sprite(config: dict[str, Any]) -> dict[str, Any]:
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)
added: dict[str, str] = {}
removed = set(key_map)
for filename, meta in source_meta.items():
# 测试包只保留新的短语键,避免把未使用的旧 symbol/arc 键继续带入 sprite
# 测试包只改名图标/灯弧fill/line pattern 等非图标纹理必须按 style 原名保留
output: dict[str, dict[str, Any]] = {}
data_driven_pattern_keys = {
key
for key in meta
if (
key.startswith("pattern_fill_")
or key.startswith("fill-daytime-")
or key.startswith("fill_")
or key.startswith("special_pattern_")
)
}
for key in sorted(passthrough_keys | data_driven_pattern_keys):
if key in meta:
output[key] = dict(meta[key])
added[key] = key
for old_key, new_key in key_map.items():
source_key = old_key if old_key in meta else None
if source_key is None:
@@ -313,7 +376,11 @@ def build_sprite(config: dict[str, Any]) -> dict[str, Any]:
for filename in ("sprite.png", "sprite@2x.png"):
shutil.copy2(SPRITE_SOURCE / filename, SPRITE_TARGET / filename)
return {"added": added, "fallbacks": {"lm_cus": fallback_sources["lm_cus"]}}
return {
"added": added,
"passthrough_keys": sorted(passthrough_keys),
"fallbacks": {"lm_cus": fallback_sources["lm_cus"]},
}
def main() -> None:
@@ -364,8 +431,10 @@ def main() -> None:
icon_counts.update(result["icon_counts"])
arc_counts.update(result["arc_counts"])
sprite = build_sprite(config)
style = transform_style(config)
style["metadata"]["navsea_test_version"] = ASSET_VERSION
style["sprite"] = SPRITE_URL
sprite = build_sprite(config, style)
write_style(style, STYLE_OUTPUT, STYLE_DEPLOY)
write_newpec_style()