Add 20nm object preservation audit and final hazard icon fix

This commit is contained in:
OpenAI Codex
2026-04-01 15:28:20 +08:00
parent 609d9716bf
commit 5c4c91e462
12 changed files with 1839 additions and 30 deletions

View File

@@ -46,6 +46,13 @@ Current official order:
Do not treat a visual match as a pass if objects have already been dropped or wrongly merged.
Preferred current 20nm object-preservation entry point:
- [`navsea_object_preservation_audit.py`](/root/sourceserver/pbf/navsea_object_preservation_audit.py)
- current reports:
- [`report/object_preservation_20nm/object_preservation_delivery_20nm.md`](/root/sourceserver/pbf/report/object_preservation_20nm/object_preservation_delivery_20nm.md)
- [`report/object_preservation_20nm/object_preservation_final_20nm.md`](/root/sourceserver/pbf/report/object_preservation_20nm/object_preservation_final_20nm.md)
## Current Visual Regression Baseline
The current working visual baseline is:

View File

@@ -135,6 +135,22 @@ Last Updated: 2026-04-01
- `fid=13025299` 这种具体对象为什么消失
### D. Current 20nm Object-Preservation Entry Point
当前已经补上一条专门的对象保真审计:
- [`navsea_object_preservation_audit.py`](/root/sourceserver/pbf/navsea_object_preservation_audit.py)
当前最重要的结论是:
-`delivery_20nm` 的危险物对象虽然几何还在,但原始 `分類番号` 全部丢失
- 当前 `final_20nm` 的危险物对象和原始 `分類番号` 已经完整保留下来
代表报告:
- [`report/object_preservation_20nm/object_preservation_delivery_20nm.md`](/root/sourceserver/pbf/report/object_preservation_20nm/object_preservation_delivery_20nm.md)
- [`report/object_preservation_20nm/object_preservation_final_20nm.md`](/root/sourceserver/pbf/report/object_preservation_20nm/object_preservation_final_20nm.md)
## Audit Evolution
下面是审计方法升级到现在的过程。
@@ -403,4 +419,3 @@ Last Updated: 2026-04-01
当前项目的正式审计规则可以压成一句话:
- 先审“对象有没有丢”,再审“渲染有没有错”,最后才审“视觉像不像”。

View File

@@ -12,12 +12,12 @@ Remote: `ssh://git@nas:2222/tei/pbf.git`
当前页面版本体系:
- `HTML: compare-r13-20260401-1105`
- `HTML: compare-r14-20260401-1523`
当前页面支持 2 个 profile但仍是同一张 HTML
1. 唐津 20 海里
- `Style: karatsu-final-style-r3-20260401-1105 (style.navsea-delivery-karatsu-20nm-final.json)`
- `Style: karatsu-final-style-r4-20260401-1523 (style.navsea-delivery-karatsu-20nm-final.json)`
- `PBF: karatsu-final-pbf-20nm-20260401-0248 (pbf-delivery-karatsu-20nm-final)`
2. 九州
@@ -55,16 +55,19 @@ Remote: `ssh://git@nas:2222/tei/pbf.git`
- `20nm pbf` 本身最近没有被重建改坏
- 鱼礁、灯塔、灯台等对象在 `20nm pbf` 里仍然存在
- 当前 compare 页右侧使用的是 `20nm final PBF`,不是旧的 `20nm delivery`
- 当前“看起来又丢了”的主因优先判断为:
- style 表达式 / icon 选择问题
- 图层叠放和 icon-size 导致的近距离互相遮挡
- 不是 compare HTML 切错
- 也不是 20nm pbf 最近重建
- 也不是 20nm pbf 最近重建坏了对象
当前新增结论:
- 紫色大 `X` 对应的不是 `428`
- 它实际对应 `symbol-daytime-429`
- 在当前 sprite 体系里:
- `409 -> symbol-daytime-409`
- `429 -> symbol-daytime-429`
- `428` 更像鱼礁/椭圆眼形符号
- 第二类“X 丢了”的问题,已经确认有一部分是危险物点与红绿小灯在近坐标重叠:
- 例如同一热点存在:
@@ -72,25 +75,48 @@ Remote: `ssh://git@nas:2222/tei/pbf.git`
- red light `30600002` at `[3013,524]`
- green light `30600001` at `[3029,505]`
- 这类问题更像图层叠放和当前 icon-size 过大,不是 PBF 缺对象
- `fid=13025299` 这类对象不是重叠问题
- 左侧原始版是 `p航行危険障害物 / 分類番号 409`
- 当前右侧 `20nm final` 在同坐标附近没有等价保留下这个 `409`
- 这是 `builder / mapping` 问题,不是单纯 style 问题
- 当前审计没把它快速暴露出来的原因有两层:
- `20nm` backend render audit 只能在层级总量上报:
- `icon_missing_in_engineering | p航行危険障害物 | 664`
- `extra_icon_in_engineering | navigation_hazard_point | 664`
- 它提示“这一层有问题”,但不会自然收敛到 `fid=13025299`
- AOI 小范围图像审计当前热点没有覆盖这块 `荒曽根/大曽根` 区域
- 当前 builder 风险点:
- `p航行危険障害物 / p投錨注意障害物` 的 hazard 语义推断太粗
- 很多对象会被归并进 `hazard_mark / obstruction / fish_reef / wreck` 这些大桶
- 原始 `分類番号 409` 这类细分对象没有独立保真规则
- `fid=13025299` 这类对象的最新结论已经纠正
- 左侧原始版是 `p航行危険障害物 / 分類番号 409 / 孤立危険物`
- 当前 `20nm final` 后台对象保真审计显示这类 `409` 在 final 里是完整保留下来的
- 当前问题已经收敛成:
-`20nm delivery` 没保留 `class_code`
- `20nm final style` 之前没有对 `navigation_hazard_point``class_code` 选 icon
- 也就是说,这批点现在的主问题是 `final style`,不是 `final PBF` 丢对象
一句话判断:
- 当前 `20nm final` 这条线,危险物对象保真已经过关
- 当前主矛盾是 `style`
- 不是 `PBF 不见了`
## Object Preservation Audit
当前已经新增一条专门的对象保真审计:
- 脚本:
- [`navsea_object_preservation_audit.py`](/root/sourceserver/pbf/navsea_object_preservation_audit.py)
- 报告:
- [`report/object_preservation_20nm/object_preservation_delivery_20nm.md`](/root/sourceserver/pbf/report/object_preservation_20nm/object_preservation_delivery_20nm.md)
- [`report/object_preservation_20nm/object_preservation_final_20nm.md`](/root/sourceserver/pbf/report/object_preservation_20nm/object_preservation_final_20nm.md)
当前结论非常明确:
- `delivery_20nm`
- raw objects: `2090`
- preserved: `0`
- raw class lost: `2090`
- `final_20nm`
- raw objects: `2090`
- preserved: `2090`
- missing object: `0`
- raw class lost: `0`
重点含义:
-`20nm delivery` 的危险物细分类全部丢失
- 当前 `20nm final` 的危险物细分类已经完整保留下来
- `p航行危険障害物:409` 在 final 中是:
- raw=`25`
- preserved=`25`
## Final Release Candidate
@@ -152,7 +178,9 @@ Remote: `ssh://git@nas:2222/tei/pbf.git`
- 为了恢复危险物和灯标/浮标细节,重新带回了:
- `class_code`
- `display_code`
- `r3`把危险物和航标 icon-size 收回旧版默认尺度,优先减轻危险物与灯标互相遮挡
- `r4`补上:
- `navigation_hazard_point``class_code` 选 icon
- 之前 `r3` 已把危险物和航标 icon-size 收回旧版默认尺度,优先减轻危险物与灯标互相遮挡
- 但当前 AOI 图像审计仍显示大差异
- 所以它目前只能算 `final release candidate`
- 还不能直接认定为稳定最终版
@@ -189,24 +217,31 @@ Remote: `ssh://git@nas:2222/tei/pbf.git`
-`object preservation audit`
-`render audit`
- 最后 `AOI / visual audit`
- 其中 `20nm` 的危险物对象保真,当前已经有专门脚本和报告,不再只靠 render audit 猜
## Current Audit Status
### 20nm Visual Pilot
当前新版 `r14 / style-r4` strict audit
- [`report/strict_audit_final_20nm_r4/strict_audit_summary.md`](/root/sourceserver/pbf/report/strict_audit_final_20nm_r4/strict_audit_summary.md)
- changed ratio: `0.916883`
当前 3 个热点:
1. `takashima_main_harbor_marks`
- changed ratio: `0.783759`
- changed ratio: `0.800170`
2. `takashima_inner_nearshore_hazards`
- changed ratio: `0.744246`
- changed ratio: `0.711509`
3. `east_breakwater_marks`
- changed ratio: `0.617833`
- changed ratio: `0.999713`
这说明:
- 视觉仍然没有收敛到“可推广”状态
- 主港航标区仍是第一优先级观察点
- 近岸碍航与鱼礁区有一点改善,但离稳定还远
### 10nm Object-Level Backend Audit

View File

@@ -0,0 +1,329 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
from collections import Counter, defaultdict
from dataclasses import dataclass
from pathlib import Path
from typing import Any
import mapbox_vector_tile
DEFAULT_RAW_ROOT = Path(
"/home/wwwroot/newpec/exported_auto/"
"tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles"
)
DEFAULT_DELIVERY_ROOT = Path("/home/wwwroot/pbf-delivery-karatsu-20nm")
DEFAULT_FINAL_ROOT = Path("/home/wwwroot/pbf-delivery-karatsu-20nm-final")
DEFAULT_REPORT_ROOT = Path("/root/sourceserver/pbf/report/object_preservation_20nm")
HAZARD_LAYER_RULES = (
{
"raw_layer": "p航行危険障害物",
"delivery_layer": "navigation_hazard_point",
"raw_class_field": "分類番号",
"delivery_class_field": "class_code",
"label": "navigation hazards",
},
{
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class_field": "分類番号",
"delivery_class_field": "class_code",
"label": "anchor hazards",
},
)
MAX_EXAMPLES = 20
@dataclass(frozen=True)
class TileCoord:
z: int
x: int
y: int
def canonical_json(value: Any) -> str:
return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
def parse_at_name(at_raw: Any) -> str | None:
if not at_raw:
return None
try:
parsed = json.loads(at_raw)
except Exception:
return None
for item in parsed:
if not isinstance(item, list) or len(item) != 2:
continue
if item[0] in {"名称", "船名"}:
text = str(item[1]).strip()
if text:
return text
return None
def geometry_signature(feature: dict[str, Any]) -> str:
geometry = feature.get("geometry") or {}
return canonical_json(geometry)
def build_tile_index(tile_path: Path, rules: tuple[dict[str, str], ...]) -> dict[str, list[dict[str, Any]]]:
decoded = mapbox_vector_tile.decode(tile_path.read_bytes())
indexed: dict[str, list[dict[str, Any]]] = {}
for rule in rules:
indexed[rule["delivery_layer"]] = decoded.get(rule["delivery_layer"], {}).get("features", [])
indexed[rule["raw_layer"]] = decoded.get(rule["raw_layer"], {}).get("features", [])
return indexed
def audit_one_target(
*,
target_name: str,
raw_root: Path,
target_root: Path,
report_root: Path,
) -> tuple[Path, Path]:
report_root.mkdir(parents=True, exist_ok=True)
report_json = report_root / f"object_preservation_{target_name}.json"
report_md = report_root / f"object_preservation_{target_name}.md"
target_tiles = sorted(target_root.glob("*/*/*.pbf"))
totals = Counter()
rule_stats: dict[str, Counter[str]] = defaultdict(Counter)
class_stats: dict[str, Counter[str]] = defaultdict(Counter)
issue_examples: dict[str, list[dict[str, Any]]] = defaultdict(list)
for target_tile in target_tiles:
rel = target_tile.relative_to(target_root)
raw_tile = raw_root / rel
if not raw_tile.exists():
continue
totals["tiles_compared"] += 1
z = int(rel.parts[0])
x = int(rel.parts[1])
y = int(Path(rel.parts[2]).stem)
tile = TileCoord(z=z, x=x, y=y)
raw_index = build_tile_index(raw_tile, HAZARD_LAYER_RULES)
target_index = build_tile_index(target_tile, HAZARD_LAYER_RULES)
all_target_geoms: dict[str, list[tuple[str, dict[str, Any]]]] = defaultdict(list)
for rule in HAZARD_LAYER_RULES:
for feat in target_index[rule["delivery_layer"]]:
all_target_geoms[geometry_signature(feat)].append((rule["delivery_layer"], feat))
for rule in HAZARD_LAYER_RULES:
raw_layer = rule["raw_layer"]
delivery_layer = rule["delivery_layer"]
raw_class_field = rule["raw_class_field"]
delivery_class_field = rule["delivery_class_field"]
key = f"{raw_layer}->{delivery_layer}"
target_by_geom: dict[str, list[dict[str, Any]]] = defaultdict(list)
for feat in target_index[delivery_layer]:
target_by_geom[geometry_signature(feat)].append(feat)
for raw_feat in raw_index[raw_layer]:
totals["raw_objects"] += 1
rule_stats[key]["raw_objects"] += 1
raw_props = raw_feat.get("properties", {})
raw_class = raw_props.get(raw_class_field)
class_key = f"{raw_layer}:{raw_class}"
geom_sig = geometry_signature(raw_feat)
name = raw_props.get("名称") or parse_at_name(raw_props.get("at"))
candidates = target_by_geom.get(geom_sig, [])
matched_class = False
if not candidates:
other_layer_hits = all_target_geoms.get(geom_sig, [])
issue = "missing_object"
if other_layer_hits:
issue = "wrong_relayer"
totals[issue] += 1
rule_stats[key][issue] += 1
class_stats[class_key][issue] += 1
if len(issue_examples[issue]) < MAX_EXAMPLES:
issue_examples[issue].append(
{
"tile": [tile.z, tile.x, tile.y],
"fid": raw_props.get("fid"),
"name": name,
"raw_layer": raw_layer,
"delivery_layer": delivery_layer,
"raw_class": raw_class,
"other_layer_hits": [
{
"delivery_layer": layer_name,
"delivery_class": feat.get("properties", {}).get(delivery_class_field),
"canonical_object_type": feat.get("properties", {}).get("canonical_object_type"),
}
for layer_name, feat in other_layer_hits[:5]
],
}
)
continue
for candidate in candidates:
target_props = candidate.get("properties", {})
if target_props.get(delivery_class_field) == raw_class:
matched_class = True
break
if matched_class:
totals["preserved"] += 1
rule_stats[key]["preserved"] += 1
class_stats[class_key]["preserved"] += 1
continue
if all(candidate.get("properties", {}).get(delivery_class_field) is None for candidate in candidates):
issue = "raw_class_lost"
else:
issue = "class_mismatch"
totals[issue] += 1
rule_stats[key][issue] += 1
class_stats[class_key][issue] += 1
if len(issue_examples[issue]) < MAX_EXAMPLES:
issue_examples[issue].append(
{
"tile": [tile.z, tile.x, tile.y],
"fid": raw_props.get("fid"),
"name": name,
"raw_layer": raw_layer,
"delivery_layer": delivery_layer,
"raw_class": raw_class,
"candidates": [
{
"delivery_class": candidate.get("properties", {}).get(delivery_class_field),
"canonical_object_type": candidate.get("properties", {}).get("canonical_object_type"),
"chart_symbol_code": candidate.get("properties", {}).get("chart_symbol_code"),
"chart_icon_image": candidate.get("properties", {}).get("chart_icon_image"),
}
for candidate in candidates[:5]
],
}
)
top_class_issues = []
for class_key, stats in class_stats.items():
top_class_issues.append(
{
"class_key": class_key,
"raw_objects": sum(stats.values()),
"preserved": stats.get("preserved", 0),
"missing_object": stats.get("missing_object", 0),
"wrong_relayer": stats.get("wrong_relayer", 0),
"raw_class_lost": stats.get("raw_class_lost", 0),
"class_mismatch": stats.get("class_mismatch", 0),
}
)
top_class_issues.sort(
key=lambda item: (
item["missing_object"] + item["wrong_relayer"] + item["raw_class_lost"] + item["class_mismatch"],
item["raw_objects"],
),
reverse=True,
)
payload = {
"target_name": target_name,
"raw_root": str(raw_root),
"target_root": str(target_root),
"totals": dict(totals),
"rule_stats": {key: dict(stats) for key, stats in sorted(rule_stats.items())},
"top_class_issues": top_class_issues[:20],
"issue_examples": issue_examples,
}
report_json.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
lines = [
f"# Object Preservation Audit: {target_name}",
"",
f"- raw root: `{raw_root}`",
f"- target root: `{target_root}`",
"",
"## Totals",
"",
f"- tiles compared: `{totals.get('tiles_compared', 0)}`",
f"- raw objects: `{totals.get('raw_objects', 0)}`",
f"- preserved: `{totals.get('preserved', 0)}`",
f"- missing object: `{totals.get('missing_object', 0)}`",
f"- wrong relayer: `{totals.get('wrong_relayer', 0)}`",
f"- raw class lost: `{totals.get('raw_class_lost', 0)}`",
f"- class mismatch: `{totals.get('class_mismatch', 0)}`",
"",
"## Per Rule",
"",
]
for key, stats in sorted(rule_stats.items()):
lines.extend(
[
f"### `{key}`",
"",
f"- raw objects: `{stats.get('raw_objects', 0)}`",
f"- preserved: `{stats.get('preserved', 0)}`",
f"- missing object: `{stats.get('missing_object', 0)}`",
f"- wrong relayer: `{stats.get('wrong_relayer', 0)}`",
f"- raw class lost: `{stats.get('raw_class_lost', 0)}`",
f"- class mismatch: `{stats.get('class_mismatch', 0)}`",
"",
]
)
lines.extend(["## Top Class Issues", ""])
for item in top_class_issues[:12]:
lines.append(
"- `{class_key}` raw=`{raw_objects}` preserved=`{preserved}` missing=`{missing_object}` "
"wrong_relayer=`{wrong_relayer}` class_lost=`{raw_class_lost}` class_mismatch=`{class_mismatch}`".format(
**item
)
)
lines.append("")
for issue_name, examples in issue_examples.items():
if not examples:
continue
lines.extend([f"## Examples: `{issue_name}`", ""])
for example in examples:
lines.append(f"- {canonical_json(example)}")
lines.append("")
report_md.write_text("\n".join(lines), encoding="utf-8")
return report_md, report_json
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Audit raw-object preservation for hazard layers between original and delivery/final PBFs."
)
parser.add_argument("--raw-root", type=Path, default=DEFAULT_RAW_ROOT)
parser.add_argument("--delivery-root", type=Path, default=DEFAULT_DELIVERY_ROOT)
parser.add_argument("--final-root", type=Path, default=DEFAULT_FINAL_ROOT)
parser.add_argument("--report-root", type=Path, default=DEFAULT_REPORT_ROOT)
return parser.parse_args()
def main() -> None:
args = parse_args()
targets = (
("delivery_20nm", args.delivery_root),
("final_20nm", args.final_root),
)
for target_name, target_root in targets:
report_md, report_json = audit_one_target(
target_name=target_name,
raw_root=args.raw_root,
target_root=target_root,
report_root=args.report_root,
)
print(f"wrote {report_md}")
print(f"wrote {report_json}")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,606 @@
{
"target_name": "delivery_20nm",
"raw_root": "/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles",
"target_root": "/home/wwwroot/pbf-delivery-karatsu-20nm",
"totals": {
"tiles_compared": 154,
"raw_objects": 2090,
"raw_class_lost": 2090
},
"rule_stats": {
"p投錨注意障害物->anchor_caution_hazard_point": {
"raw_objects": 1426,
"raw_class_lost": 1426
},
"p航行危険障害物->navigation_hazard_point": {
"raw_objects": 664,
"raw_class_lost": 664
}
},
"top_class_issues": [
{
"class_key": "p投錨注意障害物:428",
"raw_objects": 702,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 702,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:404",
"raw_objects": 413,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 413,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:420",
"raw_objects": 355,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 355,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:425",
"raw_objects": 255,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 255,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:403",
"raw_objects": 128,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 128,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:432",
"raw_objects": 40,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 40,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:421",
"raw_objects": 32,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 32,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:415",
"raw_objects": 25,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 25,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:413",
"raw_objects": 25,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 25,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:409",
"raw_objects": 25,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 25,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:431",
"raw_objects": 22,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 22,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:434",
"raw_objects": 18,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 18,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:433",
"raw_objects": 15,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 15,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:427",
"raw_objects": 9,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 9,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:405",
"raw_objects": 5,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 5,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:412",
"raw_objects": 5,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 5,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:422",
"raw_objects": 4,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 4,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:424",
"raw_objects": 3,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 3,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:402",
"raw_objects": 3,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 3,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:410",
"raw_objects": 3,
"preserved": 0,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 3,
"class_mismatch": 0
}
],
"issue_examples": {
"raw_class_lost": [
{
"tile": [
11,
1761,
819
],
"fid": 13018869,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018870,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018918,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13020459,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13020673,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13020674,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13020675,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13020697,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13020698,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13020699,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 428,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "魚礁",
"chart_symbol_code": "fish_reef",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018650,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018651,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018652,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018653,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018654,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018655,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018656,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018657,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018658,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
},
{
"tile": [
11,
1761,
819
],
"fid": 13018659,
"name": null,
"raw_layer": "p投錨注意障害物",
"delivery_layer": "anchor_caution_hazard_point",
"raw_class": 425,
"candidates": [
{
"delivery_class": null,
"canonical_object_type": "海草",
"chart_symbol_code": "hazard_mark",
"chart_icon_image": "symbol-daytime-428"
}
]
}
]
}
}

View File

@@ -0,0 +1,72 @@
# Object Preservation Audit: delivery_20nm
- raw root: `/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles`
- target root: `/home/wwwroot/pbf-delivery-karatsu-20nm`
## Totals
- tiles compared: `154`
- raw objects: `2090`
- preserved: `0`
- missing object: `0`
- wrong relayer: `0`
- raw class lost: `2090`
- class mismatch: `0`
## Per Rule
### `p投錨注意障害物->anchor_caution_hazard_point`
- raw objects: `1426`
- preserved: `0`
- missing object: `0`
- wrong relayer: `0`
- raw class lost: `1426`
- class mismatch: `0`
### `p航行危険障害物->navigation_hazard_point`
- raw objects: `664`
- preserved: `0`
- missing object: `0`
- wrong relayer: `0`
- raw class lost: `664`
- class mismatch: `0`
## Top Class Issues
- `p投錨注意障害物:428` raw=`702` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`702` class_mismatch=`0`
- `p航行危険障害物:404` raw=`413` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`413` class_mismatch=`0`
- `p投錨注意障害物:420` raw=`355` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`355` class_mismatch=`0`
- `p投錨注意障害物:425` raw=`255` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`255` class_mismatch=`0`
- `p航行危険障害物:403` raw=`128` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`128` class_mismatch=`0`
- `p航行危険障害物:432` raw=`40` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`40` class_mismatch=`0`
- `p投錨注意障害物:421` raw=`32` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`32` class_mismatch=`0`
- `p投錨注意障害物:415` raw=`25` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`25` class_mismatch=`0`
- `p投錨注意障害物:413` raw=`25` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`25` class_mismatch=`0`
- `p航行危険障害物:409` raw=`25` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`25` class_mismatch=`0`
- `p航行危険障害物:431` raw=`22` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`22` class_mismatch=`0`
- `p投錨注意障害物:434` raw=`18` preserved=`0` missing=`0` wrong_relayer=`0` class_lost=`18` class_mismatch=`0`
## Examples: `raw_class_lost`
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018869,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018870,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018918,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13020459,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13020673,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13020674,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13020675,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13020697,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13020698,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"魚礁","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"fish_reef","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13020699,"name":null,"raw_class":428,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018650,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018651,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018652,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018653,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018654,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018655,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018656,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018657,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018658,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}
- {"candidates":[{"canonical_object_type":"海草","chart_icon_image":"symbol-daytime-428","chart_symbol_code":"hazard_mark","delivery_class":null}],"delivery_layer":"anchor_caution_hazard_point","fid":13018659,"name":null,"raw_class":425,"raw_layer":"p投錨注意障害物","tile":[11,1761,819]}

View File

@@ -0,0 +1,203 @@
{
"target_name": "final_20nm",
"raw_root": "/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles",
"target_root": "/home/wwwroot/pbf-delivery-karatsu-20nm-final",
"totals": {
"tiles_compared": 154,
"raw_objects": 2090,
"preserved": 2090
},
"rule_stats": {
"p投錨注意障害物->anchor_caution_hazard_point": {
"raw_objects": 1426,
"preserved": 1426
},
"p航行危険障害物->navigation_hazard_point": {
"raw_objects": 664,
"preserved": 664
}
},
"top_class_issues": [
{
"class_key": "p投錨注意障害物:428",
"raw_objects": 702,
"preserved": 702,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:404",
"raw_objects": 413,
"preserved": 413,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:420",
"raw_objects": 355,
"preserved": 355,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:425",
"raw_objects": 255,
"preserved": 255,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:403",
"raw_objects": 128,
"preserved": 128,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:432",
"raw_objects": 40,
"preserved": 40,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:421",
"raw_objects": 32,
"preserved": 32,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:415",
"raw_objects": 25,
"preserved": 25,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:413",
"raw_objects": 25,
"preserved": 25,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:409",
"raw_objects": 25,
"preserved": 25,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:431",
"raw_objects": 22,
"preserved": 22,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:434",
"raw_objects": 18,
"preserved": 18,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:433",
"raw_objects": 15,
"preserved": 15,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:427",
"raw_objects": 9,
"preserved": 9,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:405",
"raw_objects": 5,
"preserved": 5,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:412",
"raw_objects": 5,
"preserved": 5,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:422",
"raw_objects": 4,
"preserved": 4,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p投錨注意障害物:424",
"raw_objects": 3,
"preserved": 3,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:402",
"raw_objects": 3,
"preserved": 3,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
},
{
"class_key": "p航行危険障害物:410",
"raw_objects": 3,
"preserved": 3,
"missing_object": 0,
"wrong_relayer": 0,
"raw_class_lost": 0,
"class_mismatch": 0
}
],
"issue_examples": {}
}

View File

@@ -0,0 +1,49 @@
# Object Preservation Audit: final_20nm
- raw root: `/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles`
- target root: `/home/wwwroot/pbf-delivery-karatsu-20nm-final`
## Totals
- tiles compared: `154`
- raw objects: `2090`
- preserved: `2090`
- missing object: `0`
- wrong relayer: `0`
- raw class lost: `0`
- class mismatch: `0`
## Per Rule
### `p投錨注意障害物->anchor_caution_hazard_point`
- raw objects: `1426`
- preserved: `1426`
- missing object: `0`
- wrong relayer: `0`
- raw class lost: `0`
- class mismatch: `0`
### `p航行危険障害物->navigation_hazard_point`
- raw objects: `664`
- preserved: `664`
- missing object: `0`
- wrong relayer: `0`
- raw class lost: `0`
- class mismatch: `0`
## Top Class Issues
- `p投錨注意障害物:428` raw=`702` preserved=`702` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p航行危険障害物:404` raw=`413` preserved=`413` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p投錨注意障害物:420` raw=`355` preserved=`355` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p投錨注意障害物:425` raw=`255` preserved=`255` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p航行危険障害物:403` raw=`128` preserved=`128` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p航行危険障害物:432` raw=`40` preserved=`40` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p投錨注意障害物:421` raw=`32` preserved=`32` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p投錨注意障害物:415` raw=`25` preserved=`25` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p投錨注意障害物:413` raw=`25` preserved=`25` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p航行危険障害物:409` raw=`25` preserved=`25` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p航行危険障害物:431` raw=`22` preserved=`22` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`
- `p投錨注意障害物:434` raw=`18` preserved=`18` missing=`0` wrong_relayer=`0` class_lost=`0` class_mismatch=`0`

View File

@@ -0,0 +1,323 @@
{
"compare_url": "http://192.168.200.184/newpec/navsea-compare-karatsu-20nm.html",
"compare_version": "compare-r14-20260401-1523",
"backend_audit_json": "/root/sourceserver/pbf/NavSea_Original_vs_Delivery_Render_Audit_Karatsu_20nm_2026-03-31.r7.json",
"visual_metrics": {
"image_width": 640,
"image_height": 400,
"total_pixels": 256000,
"changed_pixels": 234722,
"changed_ratio": 0.916883,
"mean_abs_rgb": [
32.4853,
31.6172,
51.0769
],
"rms_rgb": [
56.1542,
51.3272,
69.6673
],
"diff_bbox": [
0,
0,
640,
400
],
"full_crop_left": [
0,
150,
640,
550
],
"full_crop_right": [
640,
150,
1280,
550
],
"hotspots": [
{
"image_width": 109,
"image_height": 64,
"total_pixels": 6976,
"changed_pixels": 6974,
"changed_ratio": 0.999713,
"mean_abs_rgb": [
111.1264,
94.1901,
85.8125
],
"rms_rgb": [
148.771,
125.2909,
112.8771
],
"diff_bbox": [
0,
0,
109,
64
],
"id": "east_breakwater_marks",
"label": "东侧防波堤灯台区",
"notes": "防波堤灯台和港口标记区。优先验证远一点的灯台/航标是否也能稳定打出来。",
"backend_focus": [
"p航路標識群",
"safety_icon_missing"
],
"pane_box_norm": [
0.83,
0.0,
1.0,
0.16
],
"pane_box_pixels": [
531,
0,
640,
64
],
"left_image": "report/strict_audit_final_20nm_r4/hotspots/east_breakwater_marks_left.png",
"right_image": "report/strict_audit_final_20nm_r4/hotspots/east_breakwater_marks_right.png",
"diff_image": "report/strict_audit_final_20nm_r4/hotspots/east_breakwater_marks_diff.png"
},
{
"image_width": 147,
"image_height": 80,
"total_pixels": 11760,
"changed_pixels": 9410,
"changed_ratio": 0.80017,
"mean_abs_rgb": [
23.2099,
21.248,
26.5393
],
"rms_rgb": [
47.0367,
43.8919,
48.7282
],
"diff_bbox": [
0,
0,
147,
80
],
"id": "takashima_main_harbor_marks",
"label": "高岛主港航标区",
"notes": "主港口灯塔、红绿标识、近岸障碍标记。优先验证灯塔、小灯、红绿标识是否真正恢复。",
"backend_focus": [
"p航路標識群",
"safety_icon_missing",
"text_missing_in_engineering"
],
"pane_box_norm": [
0.34,
0.05,
0.57,
0.25
],
"pane_box_pixels": [
218,
20,
365,
100
],
"left_image": "report/strict_audit_final_20nm_r4/hotspots/takashima_main_harbor_marks_left.png",
"right_image": "report/strict_audit_final_20nm_r4/hotspots/takashima_main_harbor_marks_right.png",
"diff_image": "report/strict_audit_final_20nm_r4/hotspots/takashima_main_harbor_marks_diff.png"
},
{
"image_width": 115,
"image_height": 68,
"total_pixels": 7820,
"changed_pixels": 5564,
"changed_ratio": 0.711509,
"mean_abs_rgb": [
20.363,
20.8864,
23.9097
],
"rms_rgb": [
34.4925,
37.2038,
41.2721
],
"diff_bbox": [
0,
0,
115,
68
],
"id": "takashima_inner_nearshore_hazards",
"label": "高岛近岸碍航与鱼礁区",
"notes": "近岸鱼礁、碍航点、灯塔与小灯混合区。优先验证鱼礁和碍航物是否还在。",
"backend_focus": [
"p投錨注意障害物",
"p航行危険障害物",
"p航路標識群"
],
"pane_box_norm": [
0.44,
0.14,
0.62,
0.31
],
"pane_box_pixels": [
282,
56,
397,
124
],
"left_image": "report/strict_audit_final_20nm_r4/hotspots/takashima_inner_nearshore_hazards_left.png",
"right_image": "report/strict_audit_final_20nm_r4/hotspots/takashima_inner_nearshore_hazards_right.png",
"diff_image": "report/strict_audit_final_20nm_r4/hotspots/takashima_inner_nearshore_hazards_diff.png"
}
]
},
"backend_summary": {
"original_feature_instances": 258317,
"engineering_feature_instances": 258317,
"result_count": 516634,
"status_counts": {
"extra_in_engineering": 258317,
"missing_in_engineering": 258317
},
"top_annotation_issues": [
{
"issue": "extra_text_in_engineering",
"source_layer": "bathymetry_line",
"count": 24168
},
{
"issue": "text_missing_in_engineering",
"source_layer": "L海底地形",
"count": 24168
},
{
"issue": "extra_text_in_engineering",
"source_layer": "depth_contour",
"count": 11929
},
{
"issue": "text_missing_in_engineering",
"source_layer": "L等深線",
"count": 11929
},
{
"issue": "extra_text_in_engineering",
"source_layer": "seabed_text_point",
"count": 4499
},
{
"issue": "text_missing_in_engineering",
"source_layer": "p底質",
"count": 4499
},
{
"issue": "extra_text_in_engineering",
"source_layer": "navigation_marks",
"count": 1516
},
{
"issue": "text_missing_in_engineering",
"source_layer": "p航路標識群",
"count": 1516
},
{
"issue": "text_missing_in_engineering",
"source_layer": "p地名",
"count": 1444
},
{
"issue": "extra_text_in_engineering",
"source_layer": "place_label_sea",
"count": 1444
}
],
"top_style_semantic_issues": [
{
"issue": "depth_numeric_missing",
"source_layer": "L海底地形",
"count": 24168
},
{
"issue": "depth_numeric_missing",
"source_layer": "L等深線",
"count": 11929
},
{
"issue": "safety_icon_missing",
"source_layer": "p航路標識群",
"count": 1885
},
{
"issue": "depth_numeric_missing",
"source_layer": "L概略等深線",
"count": 350
},
{
"issue": "clearance_numeric_missing",
"source_layer": "p高さ制限",
"count": 33
}
],
"top_source_layer_issues": [
{
"status": "extra_in_engineering",
"source_layer": "baseline_outline",
"count": 87709
},
{
"status": "missing_in_engineering",
"source_layer": "P基本線ククリ",
"count": 87709
},
{
"status": "extra_in_engineering",
"source_layer": "baseline_area",
"count": 50421
},
{
"status": "missing_in_engineering",
"source_layer": "P基本線",
"count": 50421
},
{
"status": "extra_in_engineering",
"source_layer": "depth_contour",
"count": 36460
},
{
"status": "missing_in_engineering",
"source_layer": "L等深線",
"count": 36460
},
{
"status": "extra_in_engineering",
"source_layer": "bathymetry_line",
"count": 35940
},
{
"status": "missing_in_engineering",
"source_layer": "L海底地形",
"count": 35940
},
{
"status": "extra_in_engineering",
"source_layer": "onshore_structure_line",
"count": 10544
},
{
"status": "missing_in_engineering",
"source_layer": "L陸上構造物陸",
"count": 10544
}
]
},
"notes": [
"Visual metrics are browser-rendered screenshot diff metrics from the fixed compare page.",
"Backend metrics are current render-audit summary metrics and may remain blind to sprite-load failures."
]
}

View File

@@ -0,0 +1,104 @@
# NavSea Strict Audit Summary
## Scope
- Compare page: `http://192.168.200.184/newpec/navsea-compare-karatsu-20nm.html`
- Compare version: `compare-r14-20260401-1523`
- Backend render audit: `/root/sourceserver/pbf/NavSea_Original_vs_Delivery_Render_Audit_Karatsu_20nm_2026-03-31.r7.json`
## Visual Audit
- changed pixels: `234722` / `256000`
- changed ratio: `0.916883`
- mean abs rgb: `[32.4853, 31.6172, 51.0769]`
- rms rgb: `[56.1542, 51.3272, 69.6673]`
- left crop: `[0, 150, 640, 550]`
- right crop: `[640, 150, 1280, 550]`
Artifacts:
- `report/strict_audit_final_20nm_r4/compare_full.png`
- `report/strict_audit_final_20nm_r4/compare_left.png`
- `report/strict_audit_final_20nm_r4/compare_right.png`
- `report/strict_audit_final_20nm_r4/compare_diff.png`
## Hotspot AOI Audit
### 东侧防波堤灯台区
- id: `east_breakwater_marks`
- notes: `防波堤灯台和港口标记区。优先验证远一点的灯台/航标是否也能稳定打出来。`
- backend focus: `['p航路標識群', 'safety_icon_missing']`
- changed pixels: `6974` / `6976`
- changed ratio: `0.999713`
- mean abs rgb: `[111.1264, 94.1901, 85.8125]`
- pane box norm: `[0.83, 0.0, 1.0, 0.16]`
- pane box pixels: `[531, 0, 640, 64]`
- left image: `report/strict_audit_final_20nm_r4/hotspots/east_breakwater_marks_left.png`
- right image: `report/strict_audit_final_20nm_r4/hotspots/east_breakwater_marks_right.png`
- diff image: `report/strict_audit_final_20nm_r4/hotspots/east_breakwater_marks_diff.png`
### 高岛主港航标区
- id: `takashima_main_harbor_marks`
- notes: `主港口灯塔、红绿标识、近岸障碍标记。优先验证灯塔、小灯、红绿标识是否真正恢复。`
- backend focus: `['p航路標識群', 'safety_icon_missing', 'text_missing_in_engineering']`
- changed pixels: `9410` / `11760`
- changed ratio: `0.80017`
- mean abs rgb: `[23.2099, 21.248, 26.5393]`
- pane box norm: `[0.34, 0.05, 0.57, 0.25]`
- pane box pixels: `[218, 20, 365, 100]`
- left image: `report/strict_audit_final_20nm_r4/hotspots/takashima_main_harbor_marks_left.png`
- right image: `report/strict_audit_final_20nm_r4/hotspots/takashima_main_harbor_marks_right.png`
- diff image: `report/strict_audit_final_20nm_r4/hotspots/takashima_main_harbor_marks_diff.png`
### 高岛近岸碍航与鱼礁区
- id: `takashima_inner_nearshore_hazards`
- notes: `近岸鱼礁、碍航点、灯塔与小灯混合区。优先验证鱼礁和碍航物是否还在。`
- backend focus: `['p投錨注意障害物', 'p航行危険障害物', 'p航路標識群']`
- changed pixels: `5564` / `7820`
- changed ratio: `0.711509`
- mean abs rgb: `[20.363, 20.8864, 23.9097]`
- pane box norm: `[0.44, 0.14, 0.62, 0.31]`
- pane box pixels: `[282, 56, 397, 124]`
- left image: `report/strict_audit_final_20nm_r4/hotspots/takashima_inner_nearshore_hazards_left.png`
- right image: `report/strict_audit_final_20nm_r4/hotspots/takashima_inner_nearshore_hazards_right.png`
- diff image: `report/strict_audit_final_20nm_r4/hotspots/takashima_inner_nearshore_hazards_diff.png`
## Backend Render Audit
- original feature instances: `258317`
- delivery feature instances: `258317`
- result count: `516634`
Status counts:
- `extra_in_engineering`: `258317`
- `missing_in_engineering`: `258317`
Top annotation issues:
- `extra_text_in_engineering` | `bathymetry_line` | `24168`
- `text_missing_in_engineering` | `L海底地形` | `24168`
- `extra_text_in_engineering` | `depth_contour` | `11929`
- `text_missing_in_engineering` | `L等深線` | `11929`
- `extra_text_in_engineering` | `seabed_text_point` | `4499`
- `text_missing_in_engineering` | `p底質` | `4499`
- `extra_text_in_engineering` | `navigation_marks` | `1516`
- `text_missing_in_engineering` | `p航路標識群` | `1516`
- `text_missing_in_engineering` | `p地名` | `1444`
- `extra_text_in_engineering` | `place_label_sea` | `1444`
Top style semantic issues:
- `depth_numeric_missing` | `L海底地形` | `24168`
- `depth_numeric_missing` | `L等深線` | `11929`
- `safety_icon_missing` | `p航路標識群` | `1885`
- `depth_numeric_missing` | `L概略等深線` | `350`
- `clearance_numeric_missing` | `p高さ制限` | `33`
## Interpretation
- This report intentionally puts browser-rendered visual output and backend render-audit summary in one place.
- If the browser screenshot improves but backend counts do not, the current backend audit is likely blind to a browser/runtime issue such as sprite resolution.

View File

@@ -314,7 +314,7 @@
<script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
<script>
const HTML_VERSION = "compare-r13-20260401-1105";
const HTML_VERSION = "compare-r14-20260401-1523";
const ORIGINAL_STYLE_URL = "./style.json";
const ORIGINAL_TILE_URL = "http://192.168.200.184/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles/{z}/{x}/{y}.pbf";
const PROFILES = {
@@ -325,7 +325,7 @@
deliveryPaneLabel: "最终 release style + 唐津 20 海里 final PBF",
deliveryStyleUrl: "./domain/style.navsea-delivery-karatsu-20nm-final.json",
deliveryTileUrl: "http://192.168.200.184/pbf-delivery-karatsu-20nm-final/{z}/{x}/{y}.pbf",
deliveryStyleVersion: "karatsu-final-style-r3-20260401-1105",
deliveryStyleVersion: "karatsu-final-style-r4-20260401-1523",
deliveryPbfVersion: "karatsu-final-pbf-20nm-20260401-0248",
deliveryStyleFile: "style.navsea-delivery-karatsu-20nm-final.json",
deliveryPbfName: "pbf-delivery-karatsu-20nm-final",

View File

@@ -1220,12 +1220,78 @@
"icon-allow-overlap": true,
"icon-ignore-placement": true,
"icon-image": [
"coalesce",
"case",
[
"get",
"chart_icon_image"
"has",
"class_code"
],
""
[
"match",
[
"get",
"class_code"
],
401,
"symbol-daytime-401",
402,
"symbol-daytime-401",
403,
"symbol-daytime-401",
404,
"symbol-daytime-404",
405,
"symbol-daytime-405",
409,
"symbol-daytime-409",
410,
"symbol-daytime-410",
412,
"symbol-daytime-412",
413,
"symbol-daytime-413",
415,
"symbol-daytime-413",
420,
"symbol-daytime-420",
421,
"symbol-daytime-421",
422,
"symbol-daytime-422",
424,
"symbol-daytime-424",
425,
"symbol-daytime-425",
427,
"symbol-daytime-427",
428,
"symbol-daytime-428",
429,
"symbol-daytime-429",
431,
"symbol-daytime-431",
432,
"symbol-daytime-432",
433,
"symbol-daytime-433",
434,
"symbol-daytime-434",
[
"coalesce",
[
"get",
"chart_icon_image"
],
""
]
],
[
"coalesce",
[
"get",
"chart_icon_image"
],
""
]
]
}
},