Compare commits

...

7 Commits

Author SHA1 Message Date
OpenAI Codex
ed5de0752f 完善 Full PBF 跨机器重建配置 2026-08-06 15:42:15 +08:00
OpenAI Codex
d0ef394eac 补充 Full 重建代码节点追溯 2026-08-06 15:39:08 +08:00
OpenAI Codex
8dcdd134dc 固化全国 Full semantic extentfix 重建基线 2026-08-06 15:25:15 +08:00
OpenAI Codex
4386f293f0 record full rebuild staging audits 2026-08-06 15:25:11 +08:00
OpenAI Codex
8d2c43f43d rebuild hotspot tiles for full semantic audit 2026-08-06 15:25:08 +08:00
OpenAI Codex
449d76a463 audit full semantic extent and AOI visuals 2026-08-06 15:25:08 +08:00
OpenAI Codex
5cb0eead7c guard high-extent tile reencoding 2026-08-06 15:25:08 +08:00
33 changed files with 11656 additions and 7 deletions

View File

@@ -0,0 +1,490 @@
# NavSea 全国 Full PBF 重建流水线说明
最后确认:`2026-06-11`
## 1. 文档目的
本文固化当前全国 Full PBF 基线的可重复重建节点:
- 当前基线目录:`/home/wwwroot/pbf-delivery-full-20260418-rebuild`
- 原始海图来源:全国 `newpec` PBF
- 语义来源MySQL `pbf_analysis`
- 固定规则包:`navsea-core`
- 历史固定代码节点Git commit `6d72340`
- 当前专用分支对应节点Git commit `5cb0eea`
本文用于以后重新生成与 `pbf-delivery-full-20260418-rebuild` 业务内容等价的全国 Full PBF。
这里的“业务内容等价”是指:
- 瓦片范围一致
- source layer、对象和属性语义一致
- 几何与 extent 一致
- 样式消费结果和人工视觉判断一致
不强制要求每个 PBF 文件的二进制 SHA256 完全一致。编码库版本、属性顺序或 feature 编码顺序变化,都可能造成字节不同。
## 2. 当前确认条件
### 2.1 数据库
当前已确认数据库内容没有被修改。
数据库配置由 `navsea_tile_builder.py``DbConfig` 提供:
- database`pbf_analysis`
- unix socket`/tmp/mysql.sock`
当前关键表数量:
| 表 | 行数 |
| --- | ---: |
| `features` | `6685117` |
| `properties` | `23659423` |
| `pbf_relayer_candidates` | `6685117` |
规则包:
- `bundle_id = navsea-core`
- 当前状态:`v1-draft`
### 2.2 原始 PBF
原始几何与原始属性来源:
```text
/home/wwwroot/newpec/exported_auto/
tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles
```
本文后续命令将其写成单行路径。
### 2.3 Reference Footprint
全国瓦片生成范围使用:
```text
/home/wwwroot/pbf-delivery-full-20260415
```
`--reference-tile-root` 只决定需要生成哪些 `z/x/y` 瓦片。
实际瓦片几何仍读取原始 `newpec` PBF语义数据仍读取 MySQL。不要把 `20260415` 理解成新包的内容来源。
### 2.4 固定代码版本
当前可重建分支已经包含全国 Full 生成器、规则包、semantic 后处理和审计代码。当前分支节点为:
```text
full-semantic-extentfix-baseline @ d0ef394
```
历史上用于 2026-04-18 重建的源节点仍记录为 `6d72340`。如果需要严格复现历史代码,可额外 fetch 该节点;如果目标是重建当前 Full 基线,直接使用当前分支即可。当前分支固定包含:
- `navsea_tile_builder.py`
- `navsea_mapping_registry.py`
- `tasks/pbf/mappings/` 下的规则文件
## 3. 流水线总览
```text
原始 newpec 全国 PBF
+
MySQL pbf_analysis 语义表
+
navsea-core 映射规则
当前 `full-semantic-extentfix-baseline` 代码节点
按 z0-8 / z9-10 / z11 / z12 分片重建
合并全国候选根目录
瓦片数量与 mapping audit
对象保真与 geometry / extent audit
全国固定 AOI 视觉审计
人工确认后切换 style 和正式目录
```
## 4. 重建前准备
### 4.1 禁止直接覆盖当前基线
不要直接写入:
```text
/home/wwwroot/pbf-delivery-full-20260418-rebuild
```
先生成候选目录,审计通过后再切换。本文示例候选目录:
```text
/home/wwwroot/pbf-delivery-full-rebuild-candidate
```
### 4.2 使用当前分支代码
```bash
cd /root/sourceserver/pbf
git switch --detach full-semantic-extentfix-baseline
```
检查固定版本:
```bash
git rev-parse HEAD
```
期望为 `d0ef394` 或该分支后续更新后的提交。
### 4.3 设置路径变量
```bash
export REPO=/root/sourceserver/pbf
export CODE=$REPO
export PY=$REPO/.venv/bin/python
# 按目标机器实际情况设置NAVSEA_DB_SOCKET 为空时使用 TCP。
export NAVSEA_DB_HOST=127.0.0.1
export NAVSEA_DB_PORT=3306
export NAVSEA_DB_USER=root
export NAVSEA_DB_PASSWORD='请填入数据库密码'
export NAVSEA_DB_NAME=pbf_analysis
export NAVSEA_DB_SOCKET=/tmp/mysql.sock
export SOURCE=/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles
export REFERENCE=/home/wwwroot/pbf-delivery-full-20260415
export PARTS=/home/wwwroot/pbf-delivery-full-rebuild-candidate.parts
export CANDIDATE=/home/wwwroot/pbf-delivery-full-rebuild-candidate
```
### 4.4 输入预检
```bash
test -d "$SOURCE"
test -d "$REFERENCE"
test -x "$PY"
test -f "$CODE/navsea_tile_builder.py"
```
检查 reference 瓦片总数:
```bash
find "$REFERENCE" -type f -name '*.pbf' | wc -l
```
当前期望:
```text
65148
```
检查数据库连接和关键表:
```bash
cd "$REPO"
$PY - <<'PY'
import pymysql
from navsea_tile_builder import DbConfig
config = DbConfig()
connection = pymysql.connect(
host=config.host,
port=config.port,
user=config.user,
password=config.password,
database=config.database,
unix_socket=config.unix_socket,
)
with connection:
with connection.cursor() as cursor:
for table in ("features", "properties", "pbf_relayer_candidates"):
cursor.execute(f"SELECT COUNT(*) FROM `{table}`")
print(table, cursor.fetchone()[0])
PY
```
## 5. 全国分片重建
### 5.1 清理候选输出
候选目录只能在确认它不是正式目录后删除:
```bash
rm -rf "$PARTS" "$CANDIDATE"
mkdir -p "$PARTS"
```
### 5.2 通用构建参数
四个分片必须使用相同业务参数:
```text
--strip-legacy-japanese-delivery
--release-minimal
--fid-key 'thisMyWorld@2026'
--bundle-id navsea-core
```
机器实际只有 4 核。建议四个分片各使用 `workers=1` 并行执行,避免沿用历史上的过度并发参数。
### 5.3 z0 至 z8
```bash
$PY "$CODE/navsea_tile_builder.py" \
--source-root "$SOURCE" \
--reference-tile-root "$REFERENCE" \
--output "$PARTS/z0_8" \
--zmin 0 \
--zmax 8 \
--workers 1 \
--strip-legacy-japanese-delivery \
--release-minimal \
--fid-key 'thisMyWorld@2026' \
--bundle-id navsea-core
```
### 5.4 z9 至 z10
```bash
$PY "$CODE/navsea_tile_builder.py" \
--source-root "$SOURCE" \
--reference-tile-root "$REFERENCE" \
--output "$PARTS/z9_10" \
--zmin 9 \
--zmax 10 \
--workers 1 \
--strip-legacy-japanese-delivery \
--release-minimal \
--fid-key 'thisMyWorld@2026' \
--bundle-id navsea-core
```
### 5.5 z11
```bash
$PY "$CODE/navsea_tile_builder.py" \
--source-root "$SOURCE" \
--reference-tile-root "$REFERENCE" \
--output "$PARTS/z11" \
--zmin 11 \
--zmax 11 \
--workers 1 \
--strip-legacy-japanese-delivery \
--release-minimal \
--fid-key 'thisMyWorld@2026' \
--bundle-id navsea-core
```
### 5.6 z12
```bash
$PY "$CODE/navsea_tile_builder.py" \
--source-root "$SOURCE" \
--reference-tile-root "$REFERENCE" \
--output "$PARTS/z12" \
--zmin 12 \
--zmax 12 \
--workers 1 \
--strip-legacy-japanese-delivery \
--release-minimal \
--fid-key 'thisMyWorld@2026' \
--bundle-id navsea-core
```
如需四段并行,应分别保存日志并检查每个命令的退出状态。不能仅根据目录里已经出现 PBF 就判断任务完成。
## 6. 分片验收与合并
### 6.1 检查 mapping audit
每个分片会在其父目录生成对应的 mapping audit 文件。必须检查:
- 构建进程正常退出
- `written` 数量符合对应 zoom 范围
- 没有影响交付字段的 unresolved mapping
- 没有异常大批量 skipped tile
### 6.2 合并候选根目录
```bash
mkdir -p "$CANDIDATE"
cp -a "$PARTS/z0_8/." "$CANDIDATE/"
cp -a "$PARTS/z9_10/." "$CANDIDATE/"
cp -a "$PARTS/z11/." "$CANDIDATE/"
cp -a "$PARTS/z12/." "$CANDIDATE/"
```
这些分片的 zoom 范围互不重叠,合并时不应出现同路径覆盖冲突。
### 6.3 检查瓦片数量
```bash
find "$CANDIDATE" -type f -name '*.pbf' -printf '%P\n' |
awk -F/ '{count[$1]++} END {for (z in count) print "z" z "=" count[z]}' |
sort -V
```
当前基线期望:
| Zoom | 瓦片数 |
| ---: | ---: |
| `0` | `1` |
| `5` | `10` |
| `6` | `27` |
| `7` | `76` |
| `8` | `230` |
| `9` | `813` |
| `10` | `3156` |
| `11` | `12279` |
| `12` | `48556` |
| 合计 | `65148` |
当前数据库没有 `z1-z4` 对应的受支持输出,因此最终目录中没有这些 zoom 的 PBF。
## 7. 交付审计
审计顺序必须保持:
1. 对象保真审计
2. 渲染与 geometry / extent 审计
3. AOI / 人工视觉审计
不能因为画面看起来接近,就跳过对象和几何门禁。
### 7.1 Geometry / Extent 审计
```bash
cd "$REPO"
$PY navsea_geometry_native_audit.py \
--target-root "$CANDIDATE" \
--label full-rebuild-candidate \
--output-dir report/full_rebuild_candidate_geometry
```
重点检查:
- `source_extent_mismatch_tiles = 0`
- 不出现历史上的 `extent=4096` 错退
- 高精度 tile 继续保持原始 source 的 `extent=1048576`
- 不出现旧坏片式的大范围几何错移
坐标超 extent 本身不一定是错误。必须结合 source extent 和原始 tile 对照判断。
### 7.2 与当前基线做结构比较
不要只比较 SHA256。推荐逐瓦片解码后比较
- layer 集合
- layer extent
- feature 数量
- feature geometry
- 标准化后的 properties
- NavSea FID
对结构差异必须输出具体 `z/x/y`、layer 和 feature 锚点,不能只给一个全局差异数量。
### 7.3 全国 AOI 视觉审计
候选目录需要可通过 HTTP 访问,例如:
```text
http://192.168.200.184/pbf-delivery-full-rebuild-candidate/{z}/{x}/{y}.pbf
```
通过 compare 页的临时覆盖参数审计候选包:
```bash
$PY navsea_full_aoi_visual_audit.py \
--compare-url 'http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-rebuild-candidate%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf' \
--variant full \
--output-dir report/full_rebuild_candidate_visual
```
人工复核至少覆盖:
- 博多港
- 唐津
- 东京湾
- 大阪湾
- 冲绳
- `z10`
- `z12`
重点确认:
- 没有大片空白
- 岛屿、岸线和危险物没有错位
- 安全图标和关键文字没有缺失
- 点击拾取仍能定位到正确对象
## 8. 发布切换
所有审计通过前,不修改正式 style不覆盖当前基线。
推荐发布方式:
1. 保留当前 `/home/wwwroot/pbf-delivery-full-20260418-rebuild`
2. 将候选目录部署为带新日期或版本号的正式目录
3. 更新 extentfix style 的 tile URL
4. 更新全国 compare 页可见版本字符串
5. 部署 style 和 compare 页
6. 清缓存后再次完成固定 AOI 人工确认
7.`STEP_RECORD.md` 记录新目录、版本、审计报告和切换时间
只有明确要求原路径替换时,才对 `pbf-delivery-full-20260418-rebuild` 做原子目录切换。切换前必须保留可快速回退的旧目录。
## 9. 历史脚本的职责边界
### `navsea_tile_builder.py`
全国 Full PBF 的核心生成器。
负责:
- 从原始 PBF 读取几何与原始 feature
- 从 MySQL 读取语义投影
- 应用 NavSea mapping registry
- 输出 delivery layer、标准字段和 NavSea FID
### `navsea_rebuild_hotspot_tiles.py`
只用于固定 AOI 热点重建和问题定位。
它不是全国 Full PBF 的正式生成 pipeline不能用它代替本文的全国分片重建。
### `navsea_geometry_native_audit.py`
负责 geometry、extent 和 native 风险审计。
### `navsea_full_aoi_visual_audit.py`
负责全国固定 AOI 的浏览器截图和视觉 diff。
## 10. 节点结论
以后需要重新生成全国 Full PBF 时,以本文作为入口节点。
固定重建要素为:
```text
历史代码节点6d72340
当前分支节点5cb0eea
数据库pbf_analysis 当前确认未修改的数据
规则包navsea-core
原始 PBFnewpec-mvt-20260106
reference footprintpbf-delivery-full-20260415
生成方式:四段分片重建后合并
审计顺序:对象保真 → 渲染/几何 → AOI 视觉
```
如果上述任一输入发生变化,生成结果应视为新的全国版本,不能继续沿用 `20260418-rebuild` 的版本含义。

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,354 @@
from __future__ import annotations
import csv
import json
import os
import re
import shutil
import subprocess
from concurrent.futures import ProcessPoolExecutor
from dataclasses import dataclass
from pathlib import Path
import mapbox_vector_tile
from PIL import Image
from navsea_tile_reencode_guard import (
assert_reencoded_tile_safe,
decode_tile_with_extents,
encode_layers_preserving_extents,
)
REPO_ROOT = Path(__file__).resolve().parent
BASE_AUDIT_CSV = REPO_ROOT / "tasks/pbf/NavSea_Sprite_Audit_newpec_style_with_pbf_2026-04-16.csv"
T_OVERRIDE_CSV = REPO_ROOT / "tasks/pbf/NavSea_Sprite_Basis_T_建议修正表_2026-04-16.csv"
MAPPING_JSON = REPO_ROOT / "src/pbf/semantic_sprite_key_map_2026-04-16.json"
SOURCE_SPRITE_JSON_2X = Path("/mnt/sda1/www/newpec/sprite/sprite@2x.json")
SOURCE_SPRITE_PNG_2X = Path("/mnt/sda1/www/newpec/sprite/sprite@2x.png")
OUTPUT_SPRITE_DIR = Path("/mnt/sda1/www/newpec/sprite-semantic")
SOURCE_STYLE = REPO_ROOT / "src/pbf/style.navsea-delivery-full.json"
OUTPUT_STYLE = REPO_ROOT / "src/pbf/style.navsea-delivery-full-semantic.json"
DEPLOYED_STYLE = Path("/mnt/sda1/www/newpec/domain/style.navsea-delivery-full-semantic.json")
SOURCE_PBF_ROOT = Path("/home/wwwroot/pbf-delivery-full-20260415")
OUTPUT_PBF_ROOT = Path("/home/wwwroot/pbf-delivery-full-semantic-20260416")
SEMANTIC_SPRITE_BASE_URL = "http://192.168.200.184/newpec/sprite-semantic/sprite"
SEMANTIC_PBF_TILE_URL = "http://192.168.200.184/pbf-delivery-full-semantic-20260416/{z}/{x}/{y}.pbf"
STYLE_VERSION = "full-semantic-style-r1-20260416-1628"
PBF_VERSION = "full-semantic-pbf-r1-20260416-1628"
SPRITE_VERSION = "full-semantic-sprite-r1-20260416-1628"
PBF_PROPERTY_FIELDS = ("chart_icon_image", "chart_fill_pattern")
@dataclass(frozen=True)
class AuditRow:
old_sprite_key: str
used_in_newpec_style: int
used_in_pbf: int
new_sprite_key: str
def normalize_key(value: str) -> str:
value = re.sub(r"\s*\[[^\]]+\]\s*", "", value.strip())
value = value.replace("-", "_").replace(" ", "_").lower()
value = (
value.replace("easte", "east")
.replace("sourth", "south")
.replace("varian", "variant")
.replace("cardianal", "cardinal")
)
value = re.sub(r"_+", "_", value).strip("_")
return value
def load_audit_rows() -> list[AuditRow]:
overrides: dict[str, str] = {}
with T_OVERRIDE_CSV.open(encoding="utf-8-sig") as handle:
for row in csv.DictReader(handle):
overrides[row["old_sprite_key"].strip()] = row["suggested_new_sprite_key"].strip()
rows: list[AuditRow] = []
with BASE_AUDIT_CSV.open(encoding="utf-8-sig") as handle:
for row in csv.DictReader(handle):
old_key = row["old_sprite_key"].strip()
new_key = overrides.get(old_key) or row["new_sprite_key"].strip()
rows.append(
AuditRow(
old_sprite_key=old_key,
used_in_newpec_style=int(row["used_in_newpec_style"] or 0),
used_in_pbf=int(row["used_in_pbf"] or 0),
new_sprite_key=normalize_key(new_key) if new_key else "",
)
)
return rows
def build_mapping(rows: list[AuditRow]) -> dict[str, str]:
mapping: dict[str, str] = {}
for row in rows:
if row.new_sprite_key:
mapping[row.old_sprite_key] = row.new_sprite_key
return mapping
def build_used_sprite_entries(rows: list[AuditRow], mapping: dict[str, str]) -> list[tuple[str, str]]:
used: list[tuple[str, str]] = []
for row in rows:
if row.used_in_newpec_style <= 0 and row.used_in_pbf <= 0:
continue
used.append((row.old_sprite_key, mapping.get(row.old_sprite_key, row.old_sprite_key)))
return used
def write_mapping_json(mapping: dict[str, str]) -> None:
MAPPING_JSON.write_text(
json.dumps(dict(sorted(mapping.items())), ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
def pack_entries(
entries: list[tuple[str, str]],
source_meta: dict[str, dict],
scale: float,
max_width: int,
) -> tuple[Image.Image, dict[str, dict]]:
positions: dict[str, dict] = {}
cursor_x = 0
cursor_y = 0
row_height = 0
packed: list[tuple[str, tuple[int, int, int, int]]] = []
for old_key, new_key in entries:
meta = source_meta[old_key]
width = max(1, round(meta["width"] * scale))
height = max(1, round(meta["height"] * scale))
if cursor_x and cursor_x + width > max_width:
cursor_x = 0
cursor_y += row_height
row_height = 0
packed.append((old_key, (cursor_x, cursor_y, width, height)))
record = {
"x": cursor_x,
"y": cursor_y,
"width": width,
"height": height,
"pixelRatio": 1 if scale == 0.5 else 2,
}
positions[new_key] = record
if old_key != new_key:
positions[old_key] = dict(record)
cursor_x += width
row_height = max(row_height, height)
atlas_height = cursor_y + row_height
image = Image.new("RGBA", (max_width, atlas_height), (0, 0, 0, 0))
source_image = Image.open(SOURCE_SPRITE_PNG_2X).convert("RGBA")
for old_key, (x, y, width, height) in packed:
meta = source_meta[old_key]
crop = source_image.crop(
(
meta["x"],
meta["y"],
meta["x"] + meta["width"],
meta["y"] + meta["height"],
)
)
if scale != 1.0:
crop = crop.resize((width, height), Image.LANCZOS)
image.paste(crop, (x, y))
return image, positions
def build_semantic_sprite(entries: list[tuple[str, str]]) -> None:
OUTPUT_SPRITE_DIR.mkdir(parents=True, exist_ok=True)
source_meta = json.loads(SOURCE_SPRITE_JSON_2X.read_text(encoding="utf-8"))
atlas_2x, meta_2x = pack_entries(entries, source_meta, scale=1.0, max_width=2048)
atlas_1x, meta_1x = pack_entries(entries, source_meta, scale=0.5, max_width=1024)
atlas_2x.save(OUTPUT_SPRITE_DIR / "sprite@2x.png")
atlas_1x.save(OUTPUT_SPRITE_DIR / "sprite.png")
(OUTPUT_SPRITE_DIR / "sprite@2x.json").write_text(
json.dumps(meta_2x, ensure_ascii=False, indent=2) + "\n", encoding="utf-8"
)
(OUTPUT_SPRITE_DIR / "sprite.json").write_text(
json.dumps(meta_1x, ensure_ascii=False, indent=2) + "\n", encoding="utf-8"
)
def replace_sprite_keys(value, mapping: dict[str, str]):
if isinstance(value, dict):
return {k: replace_sprite_keys(v, mapping) for k, v in value.items()}
if isinstance(value, list):
return [replace_sprite_keys(item, mapping) for item in value]
if isinstance(value, str):
return mapping.get(value, value)
return value
def build_semantic_style(mapping: dict[str, str]) -> None:
style = json.loads(SOURCE_STYLE.read_text(encoding="utf-8"))
style = replace_sprite_keys(style, mapping)
style["name"] = "NavSea Delivery Full Semantic"
style["sprite"] = SEMANTIC_SPRITE_BASE_URL
if style.get("sources", {}).get("navsea_delivery"):
style["sources"]["navsea_delivery"]["tiles"] = [SEMANTIC_PBF_TILE_URL]
OUTPUT_STYLE.write_text(json.dumps(style, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
DEPLOYED_STYLE.write_text(json.dumps(style, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
def hardlink_or_copy(src: Path, dst: Path) -> None:
dst.parent.mkdir(parents=True, exist_ok=True)
if dst.exists():
dst.unlink()
try:
os.link(src, dst)
except OSError:
dst.write_bytes(src.read_bytes())
def remap_tile(src: Path, dst: Path, value_map: dict[str, str], needles: list[bytes]) -> tuple[bool, int]:
raw = src.read_bytes()
if not any(needle in raw for needle in needles):
hardlink_or_copy(src, dst)
return False, 0
decoded, source_extents = decode_tile_with_extents(raw)
changed_features = 0
changed = False
layers = []
for layer_name, layer in decoded.items():
features = []
for feature in layer["features"]:
props = feature.get("properties", {})
feature_changed = False
for field in PBF_PROPERTY_FIELDS:
value = props.get(field)
if isinstance(value, str) and value in value_map:
props[field] = value_map[value]
feature_changed = True
if feature_changed:
changed_features += 1
changed = True
output_feature = {
"geometry": feature["geometry"],
"properties": props,
}
if feature.get("id") is not None:
output_feature["id"] = feature["id"]
features.append(output_feature)
layers.append({"name": layer_name, "features": features})
if changed:
dst.parent.mkdir(parents=True, exist_ok=True)
if dst.exists():
dst.unlink()
dst.write_bytes(encode_layers_preserving_extents(layers, source_extents))
assert_reencoded_tile_safe(src, dst)
else:
hardlink_or_copy(src, dst)
return changed, changed_features
def remap_tile_job(args: tuple[str, str, dict[str, str], list[bytes]]) -> tuple[bool, int]:
src_str, dst_str, value_map, needles = args
return remap_tile(Path(src_str), Path(dst_str), value_map, needles)
def backfill_missing_tiles(src_root: Path, dst_root: Path) -> int:
missing = 0
for src in src_root.rglob("*.pbf"):
dst = dst_root / src.relative_to(src_root)
if dst.exists():
continue
hardlink_or_copy(src, dst)
missing += 1
return missing
def build_semantic_pbf(rows: list[AuditRow], mapping: dict[str, str]) -> dict[str, int]:
value_map = {
row.old_sprite_key: mapping[row.old_sprite_key]
for row in rows
if row.used_in_pbf > 0 and row.old_sprite_key in mapping
}
needles = [old.encode("utf-8") for old in value_map]
if OUTPUT_PBF_ROOT.exists():
shutil.rmtree(OUTPUT_PBF_ROOT)
OUTPUT_PBF_ROOT.parent.mkdir(parents=True, exist_ok=True)
subprocess.run(
["cp", "-al", f"{SOURCE_PBF_ROOT}/.", str(OUTPUT_PBF_ROOT)],
check=True,
)
rg_cmd = ["rg", "-a", "-l", "-F"]
for old_key in value_map:
rg_cmd.extend(["-e", old_key])
rg_cmd.append(str(SOURCE_PBF_ROOT))
result = subprocess.run(rg_cmd, check=True, capture_output=True, text=True)
tile_paths = [Path(line) for line in result.stdout.splitlines() if line.strip()]
stats = {
"tiles_total": len(list(SOURCE_PBF_ROOT.rglob("*.pbf"))),
"tiles_changed": 0,
"features_changed": 0,
"tiles_scanned_for_rewrite": len(tile_paths),
}
jobs = [
(
str(src),
str(OUTPUT_PBF_ROOT / src.relative_to(SOURCE_PBF_ROOT)),
value_map,
needles,
)
for src in tile_paths
]
with ProcessPoolExecutor(max_workers=min(os.cpu_count() or 4, 12)) as executor:
for changed, feature_count in executor.map(remap_tile_job, jobs, chunksize=128):
if changed:
stats["tiles_changed"] += 1
stats["features_changed"] += feature_count
stats["tiles_backfilled"] = backfill_missing_tiles(SOURCE_PBF_ROOT, OUTPUT_PBF_ROOT)
stats["tiles_total_after_backfill"] = len(list(OUTPUT_PBF_ROOT.rglob("*.pbf")))
return stats
def main() -> None:
rows = load_audit_rows()
mapping = build_mapping(rows)
used_entries = build_used_sprite_entries(rows, mapping)
write_mapping_json(mapping)
build_semantic_sprite(used_entries)
build_semantic_style(mapping)
pbf_stats = build_semantic_pbf(rows, mapping)
summary = {
"mapping_count": len(mapping),
"used_sprite_entries": len(used_entries),
"style_output": str(OUTPUT_STYLE),
"deployed_style": str(DEPLOYED_STYLE),
"sprite_output_dir": str(OUTPUT_SPRITE_DIR),
"pbf_output_dir": str(OUTPUT_PBF_ROOT),
**pbf_stats,
"style_version": STYLE_VERSION,
"pbf_version": PBF_VERSION,
"sprite_version": SPRITE_VERSION,
}
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
from pathlib import Path
from typing import Any
from navsea_tile_reencode_guard import validate_reencoded_tile
DEFAULT_SOURCE_ROOT = Path(
"/home/wwwroot/newpec/exported_auto/"
"tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles"
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="审计 PBF 是否存在高 extent 被 4096 口径重编码的几何错移。")
parser.add_argument("--target-root", type=Path, required=True)
parser.add_argument("--source-root", type=Path, default=DEFAULT_SOURCE_ROOT)
parser.add_argument("--output-json", type=Path)
parser.add_argument("--zoom", action="append", type=int)
parser.add_argument("--sample-limit", type=int, default=50)
return parser.parse_args()
def should_include(rel: Path, zoom_filter: set[int] | None) -> bool:
if not zoom_filter:
return True
try:
return int(rel.parts[0]) in zoom_filter
except Exception:
return False
def main() -> None:
args = parse_args()
zoom_filter = set(args.zoom or [])
suspicious_tiles: list[dict[str, Any]] = []
checked = 0
for tile_path in sorted(args.target_root.glob("*/*/*.pbf")):
rel = tile_path.relative_to(args.target_root)
if not should_include(rel, zoom_filter or None):
continue
source_tile = args.source_root / rel
if not source_tile.exists():
continue
checked += 1
verdict = validate_reencoded_tile(source_tile, tile_path)
if verdict["suspicious"]:
suspicious_tiles.append(
{
"tile": str(rel),
**verdict,
}
)
suspicious_tiles.sort(
key=lambda item: (
item["output_max_overflow"] - item["source_max_overflow"],
item["tile"],
),
reverse=True,
)
summary = {
"target_root": str(args.target_root),
"source_root": str(args.source_root),
"zoom_filter": sorted(zoom_filter),
"tiles_checked": checked,
"suspicious_tile_count": len(suspicious_tiles),
"samples": suspicious_tiles[: args.sample_limit],
}
if args.output_json:
args.output_json.parent.mkdir(parents=True, exist_ok=True)
args.output_json.write_text(json.dumps(summary, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,227 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import subprocess
from pathlib import Path
from typing import Any
from urllib.parse import urlencode
from PIL import Image, ImageChops, ImageStat
DEFAULT_COMPARE_URL = "http://192.168.200.184/newpec/navsea-compare-full-audit.html"
DEFAULT_AOI_JSON = Path("/root/sourceserver/pbf/tasks/pbf/NavSea_Full_AOI_Visual_Audit_2026-04-18.json")
DEFAULT_OUTPUT_DIR = Path("/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="对全国 full / semantic 做 AOI 截图 + 图像 diff 审计。")
parser.add_argument("--compare-url", default=DEFAULT_COMPARE_URL)
parser.add_argument("--aoi-json", type=Path, default=DEFAULT_AOI_JSON)
parser.add_argument("--output-dir", type=Path, default=DEFAULT_OUTPUT_DIR)
parser.add_argument("--width", type=int, default=1280)
parser.add_argument("--height", type=int, default=720)
parser.add_argument("--toolbar-height", type=int, default=120)
parser.add_argument("--bottom-trim", type=int, default=30)
parser.add_argument("--timeout-sec", type=int, default=120)
parser.add_argument("--virtual-time-budget-ms", type=int, default=30000)
parser.add_argument("--variant", action="append", choices=("full", "semantic"), help="只跑指定 variant可重复传入")
return parser.parse_args()
def run_browser_screenshot(
compare_url: str,
output_png: Path,
width: int,
height: int,
timeout_sec: int,
virtual_time_budget_ms: int,
) -> None:
cmd = [
"timeout",
f"{timeout_sec}s",
"google-chrome",
"--headless=new",
"--disable-gpu",
"--enable-unsafe-swiftshader",
"--no-sandbox",
f"--virtual-time-budget={virtual_time_budget_ms}",
f"--window-size={width},{height}",
f"--screenshot={output_png}",
compare_url,
]
subprocess.run(cmd, check=True, capture_output=True, text=True)
def compute_visual_metrics(left_img: Image.Image, right_img: Image.Image) -> dict[str, Any]:
diff = ImageChops.difference(left_img, right_img)
diff_rgb = diff.convert("RGB")
diff_gray = diff.convert("L")
stat = ImageStat.Stat(diff_rgb)
mean_abs = [round(v, 4) for v in stat.mean]
rms = [round(v, 4) for v in stat.rms]
bbox = diff_gray.getbbox()
nonzero_pixels = 0
if bbox:
mask = diff_gray.point(lambda value: 255 if value else 0)
histogram = mask.histogram()
nonzero_pixels = histogram[255] if len(histogram) > 255 else 0
total_pixels = left_img.size[0] * left_img.size[1]
changed_ratio = round(nonzero_pixels / total_pixels, 6) if total_pixels else 0.0
return {
"changed_pixels": nonzero_pixels,
"total_pixels": total_pixels,
"changed_ratio": changed_ratio,
"mean_abs_rgb": mean_abs,
"rms_rgb": rms,
"diff_bbox": list(bbox) if bbox else None,
"diff_image": diff,
}
def crop_compare_panes(full_png: Path, left_png: Path, right_png: Path, diff_png: Path, toolbar_height: int, bottom_trim: int) -> dict[str, Any]:
image = Image.open(full_png).convert("RGBA")
usable_top = toolbar_height
usable_bottom = max(usable_top + 1, image.height - bottom_trim)
mid_x = image.width // 2
left = image.crop((0, usable_top, mid_x, usable_bottom))
right = image.crop((mid_x, usable_top, image.width, usable_bottom))
left.save(left_png)
right.save(right_png)
metrics = compute_visual_metrics(left, right)
diff_image = metrics.pop("diff_image")
diff_image.convert("RGB").point(lambda value: min(255, value * 4)).save(diff_png)
metrics["left_crop"] = [0, usable_top, mid_x, usable_bottom]
metrics["right_crop"] = [mid_x, usable_top, image.width, usable_bottom]
return metrics
def build_case_url(compare_url: str, variant: str, center: list[float], zoom: int | float) -> str:
query = urlencode(
{
"variant": variant,
"audit": "1",
"center": f"{center[0]},{center[1]}",
"zoom": zoom,
}
)
separator = "&" if "?" in compare_url else "?"
return f"{compare_url}{separator}{query}"
def write_report(output_dir: Path, summary: dict[str, Any]) -> tuple[Path, Path]:
report_json = output_dir / "full_aoi_visual_audit.json"
report_md = output_dir / "full_aoi_visual_audit.md"
report_json.write_text(json.dumps(summary, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
lines = [
"# 全国 AOI 截图对比审计",
"",
"## 总览",
"",
f"- compare page: `{summary['compare_url']}`",
f"- cases: `{len(summary['cases'])}`",
"",
"## 差异排序",
"",
]
for case in summary["cases"]:
lines.extend(
[
f"### {case['label']} · {case['variant']} · z{case['zoom']}",
"",
f"- changed ratio: `{case['changed_ratio']}`",
f"- changed pixels: `{case['changed_pixels']}` / `{case['total_pixels']}`",
f"- mean abs rgb: `{case['mean_abs_rgb']}`",
f"- compare url: `{case['compare_url']}`",
f"- left image: `{case['left_image']}`",
f"- right image: `{case['right_image']}`",
f"- diff image: `{case['diff_image']}`",
"",
]
)
report_md.write_text("\n".join(lines) + "\n", encoding="utf-8")
return report_md, report_json
def main() -> None:
args = parse_args()
output_dir = args.output_dir
output_dir.mkdir(parents=True, exist_ok=True)
aois = json.loads(args.aoi_json.read_text(encoding="utf-8"))
cases: list[dict[str, Any]] = []
variants = args.variant or ["full", "semantic"]
for variant in variants:
for aoi in aois:
for zoom in aoi["zoom_levels"]:
case_id = f"{aoi['id']}_{variant}_z{zoom}"
case_dir = output_dir / case_id
case_dir.mkdir(parents=True, exist_ok=True)
compare_url = build_case_url(args.compare_url, variant, aoi["center"], zoom)
full_png = case_dir / "compare_full.png"
left_png = case_dir / "compare_left.png"
right_png = case_dir / "compare_right.png"
diff_png = case_dir / "compare_diff.png"
run_browser_screenshot(
compare_url=compare_url,
output_png=full_png,
width=args.width,
height=args.height,
timeout_sec=args.timeout_sec,
virtual_time_budget_ms=args.virtual_time_budget_ms,
)
metrics = crop_compare_panes(
full_png=full_png,
left_png=left_png,
right_png=right_png,
diff_png=diff_png,
toolbar_height=args.toolbar_height,
bottom_trim=args.bottom_trim,
)
cases.append(
{
"id": case_id,
"label": aoi["label"],
"variant": variant,
"zoom": zoom,
"center": aoi["center"],
"radius_nm": aoi["radius_nm"],
"compare_url": compare_url,
"changed_pixels": metrics["changed_pixels"],
"total_pixels": metrics["total_pixels"],
"changed_ratio": metrics["changed_ratio"],
"mean_abs_rgb": metrics["mean_abs_rgb"],
"rms_rgb": metrics["rms_rgb"],
"diff_bbox": metrics["diff_bbox"],
"left_image": str(left_png),
"right_image": str(right_png),
"diff_image": str(diff_png),
}
)
cases.sort(key=lambda item: item["changed_ratio"], reverse=True)
summary = {
"compare_url": args.compare_url,
"cases": cases,
}
report_md, report_json = write_report(output_dir, summary)
print(
json.dumps(
{
"report_md": str(report_md),
"report_json": str(report_json),
"top_cases": cases[:5],
},
ensure_ascii=False,
indent=2,
)
)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,368 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import os
from collections import Counter, defaultdict
from dataclasses import dataclass
from pathlib import Path
from typing import Any
from mapbox_vector_tile.Mapbox import vector_tile_pb2
DEFAULT_SOURCE_ROOT = Path(
"/home/wwwroot/newpec/exported_auto/"
"tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles"
)
@dataclass
class LayerGeometryStats:
point_count: int = 0
min_x: int = 0
max_x: int = 0
min_y: int = 0
max_y: int = 0
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="审计并按需修复 NavSea PBF 的几何 / extent / native 风险。")
parser.add_argument("--target-root", type=Path, required=True)
parser.add_argument("--label", required=True)
parser.add_argument("--output-dir", type=Path, required=True)
parser.add_argument("--source-root", type=Path, default=DEFAULT_SOURCE_ROOT)
parser.add_argument("--apply-fix", action="store_true", help="若检测到 extent 与源瓦片不一致,则按源瓦片 extent 原地修复。")
parser.add_argument("--sample-limit", type=int, default=30)
parser.add_argument("--zoom", action="append", type=int, help="只审指定 zoom可重复传入多次。")
return parser.parse_args()
def zigzag_decode(value: int) -> int:
return (value >> 1) ^ (-(value & 1))
def decode_feature_geometry(geometry: list[int]) -> LayerGeometryStats:
stats = LayerGeometryStats()
cursor_x = 0
cursor_y = 0
initialized = False
idx = 0
while idx < len(geometry):
command = geometry[idx]
idx += 1
command_id = command & 0x7
command_count = command >> 3
if command_id in (1, 2): # MoveTo, LineTo
for _ in range(command_count):
if idx + 1 >= len(geometry):
raise ValueError("geometry command truncated")
cursor_x += zigzag_decode(geometry[idx])
cursor_y += zigzag_decode(geometry[idx + 1])
idx += 2
if not initialized:
stats.min_x = stats.max_x = cursor_x
stats.min_y = stats.max_y = cursor_y
initialized = True
else:
stats.min_x = min(stats.min_x, cursor_x)
stats.max_x = max(stats.max_x, cursor_x)
stats.min_y = min(stats.min_y, cursor_y)
stats.max_y = max(stats.max_y, cursor_y)
stats.point_count += 1
elif command_id == 7: # ClosePath
continue
else:
raise ValueError(f"unsupported geometry command id={command_id}")
return stats
def merge_layer_stats(existing: LayerGeometryStats | None, incoming: LayerGeometryStats) -> LayerGeometryStats:
if existing is None or existing.point_count == 0:
return incoming
if incoming.point_count == 0:
return existing
return LayerGeometryStats(
point_count=existing.point_count + incoming.point_count,
min_x=min(existing.min_x, incoming.min_x),
max_x=max(existing.max_x, incoming.max_x),
min_y=min(existing.min_y, incoming.min_y),
max_y=max(existing.max_y, incoming.max_y),
)
def analyze_tile(tile_path: Path) -> dict[str, Any]:
tile = vector_tile_pb2.tile()
tile.ParseFromString(tile_path.read_bytes())
layer_summaries: list[dict[str, Any]] = []
extent_values: set[int] = set()
tile_outside_extent = False
tile_max_overflow = 0
for layer in tile.layers:
extent = int(layer.extent or 4096)
extent_values.add(extent)
aggregate: LayerGeometryStats | None = None
for feature in layer.features:
geom_stats = decode_feature_geometry(list(feature.geometry))
aggregate = merge_layer_stats(aggregate, geom_stats)
if aggregate is None:
aggregate = LayerGeometryStats()
outside_extent = False
overflow = 0
if aggregate.point_count:
overflow = max(
0,
-aggregate.min_x,
-aggregate.min_y,
aggregate.max_x - extent,
aggregate.max_y - extent,
)
outside_extent = overflow > 0
tile_outside_extent = tile_outside_extent or outside_extent
tile_max_overflow = max(tile_max_overflow, overflow)
layer_summaries.append(
{
"name": layer.name,
"extent": extent,
"point_count": aggregate.point_count,
"min_x": aggregate.min_x,
"max_x": aggregate.max_x,
"min_y": aggregate.min_y,
"max_y": aggregate.max_y,
"outside_extent": outside_extent,
"overflow": overflow,
}
)
return {
"extent_values": sorted(extent_values),
"outside_extent": tile_outside_extent,
"max_overflow": tile_max_overflow,
"layers": layer_summaries,
}
def desired_extent_from_source(source_path: Path) -> int | None:
if not source_path.exists():
return None
tile = vector_tile_pb2.tile()
tile.ParseFromString(source_path.read_bytes())
extents = sorted({int(layer.extent or 4096) for layer in tile.layers})
if not extents:
return None
if len(extents) == 1:
return extents[0]
return max(extents)
def repair_tile_extents(tile_path: Path, desired_extent: int) -> bool:
tile = vector_tile_pb2.tile()
raw = tile_path.read_bytes()
tile.ParseFromString(raw)
changed = False
for layer in tile.layers:
current = int(layer.extent or 4096)
if current != desired_extent:
layer.extent = desired_extent
changed = True
if changed:
tile_path.write_bytes(tile.SerializeToString())
return changed
def hardlink_copy_tree(src_root: Path, dst_root: Path) -> None:
if dst_root.exists():
raise SystemExit(f"backup root already exists: {dst_root}")
dst_root.mkdir(parents=True, exist_ok=True)
os.system(f"cp -al {src_root}/. {dst_root}/")
def write_report(
output_dir: Path,
label: str,
target_root: Path,
source_root: Path,
summary: dict[str, Any],
) -> tuple[Path, Path]:
output_dir.mkdir(parents=True, exist_ok=True)
report_json = output_dir / "geometry_native_audit.json"
report_md = output_dir / "geometry_native_audit.md"
report_json.write_text(json.dumps(summary, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
lines = [
f"# {label} 几何 / Extent / Native 风险审计",
"",
"## 范围",
"",
f"- target root: `{target_root}`",
f"- source root: `{source_root}`",
f"- tiles: `{summary['tile_count']}`",
f"- repaired tiles: `{summary['repaired_tiles']}`",
"",
"## 总体结论",
"",
f"- 坐标超当前 extent 的瓦片数:`{summary['outside_extent_tiles']}`",
f"- 与源瓦片 extent 不一致的瓦片数:`{summary['source_extent_mismatch_tiles']}`",
f"- 可直接按源 extent 修复的瓦片数:`{summary['fixable_from_source_tiles']}`",
"",
"## Zoom 汇总",
"",
]
for zoom in sorted(summary["zoom_summary"], key=int):
item = summary["zoom_summary"][zoom]
lines.extend(
[
f"### z{zoom}",
"",
f"- tiles: `{item['tile_count']}`",
f"- outside extent: `{item['outside_extent_tiles']}`",
f"- source mismatch: `{item['source_extent_mismatch_tiles']}`",
f"- extent counts: `{item['extent_counts']}`",
"",
]
)
lines.extend(["## 代表问题样本", ""])
for item in summary["sample_tiles"]:
lines.extend(
[
f"### `{item['tile']}`",
"",
f"- extent values: `{item['extent_values']}`",
f"- source extent: `{item['source_extent']}`",
f"- outside extent: `{item['outside_extent']}`",
f"- max overflow: `{item['max_overflow']}`",
f"- fixable from source: `{item['fixable_from_source']}`",
"",
]
)
report_md.write_text("\n".join(lines) + "\n", encoding="utf-8")
return report_md, report_json
def main() -> None:
args = parse_args()
target_root = args.target_root
source_root = args.source_root
output_dir = args.output_dir
if not target_root.exists():
raise SystemExit(f"target root not found: {target_root}")
if not source_root.exists():
raise SystemExit(f"source root not found: {source_root}")
zoom_summary: dict[str, dict[str, Any]] = defaultdict(
lambda: {
"tile_count": 0,
"outside_extent_tiles": 0,
"source_extent_mismatch_tiles": 0,
"extent_counts": Counter(),
}
)
sample_tiles: list[dict[str, Any]] = []
repaired_tiles = 0
outside_extent_tiles = 0
source_extent_mismatch_tiles = 0
fixable_from_source_tiles = 0
tile_paths = sorted(target_root.glob("*/*/*.pbf"))
if args.zoom:
zoom_filter = {str(item) for item in args.zoom}
tile_paths = [path for path in tile_paths if path.parent.parent.name in zoom_filter]
for tile_path in tile_paths:
rel = tile_path.relative_to(target_root)
zoom = rel.parts[0]
analysis = analyze_tile(tile_path)
source_extent = desired_extent_from_source(source_root / rel)
current_extent = max(analysis["extent_values"]) if analysis["extent_values"] else None
mismatch = source_extent is not None and current_extent is not None and source_extent != current_extent
fixable = bool(
mismatch
and source_extent is not None
and analysis["outside_extent"]
and analysis["max_overflow"] <= max(0, source_extent - (current_extent or 0))
)
zoom_item = zoom_summary[zoom]
zoom_item["tile_count"] += 1
for extent in analysis["extent_values"]:
zoom_item["extent_counts"][extent] += 1
if analysis["outside_extent"]:
outside_extent_tiles += 1
zoom_item["outside_extent_tiles"] += 1
if mismatch:
source_extent_mismatch_tiles += 1
zoom_item["source_extent_mismatch_tiles"] += 1
if fixable:
fixable_from_source_tiles += 1
if args.apply_fix and fixable and source_extent is not None:
if repair_tile_extents(tile_path, source_extent):
repaired_tiles += 1
analysis = analyze_tile(tile_path)
if len(sample_tiles) < args.sample_limit and (analysis["outside_extent"] or mismatch):
sample_tiles.append(
{
"tile": str(rel),
"extent_values": analysis["extent_values"],
"source_extent": source_extent,
"outside_extent": analysis["outside_extent"],
"max_overflow": analysis["max_overflow"],
"fixable_from_source": fixable,
}
)
normalized_zoom_summary = {
zoom: {
"tile_count": item["tile_count"],
"outside_extent_tiles": item["outside_extent_tiles"],
"source_extent_mismatch_tiles": item["source_extent_mismatch_tiles"],
"extent_counts": dict(sorted(item["extent_counts"].items())),
}
for zoom, item in sorted(zoom_summary.items(), key=lambda kv: int(kv[0]))
}
summary = {
"label": args.label,
"target_root": str(target_root),
"source_root": str(source_root),
"tile_count": len(tile_paths),
"outside_extent_tiles": outside_extent_tiles,
"source_extent_mismatch_tiles": source_extent_mismatch_tiles,
"fixable_from_source_tiles": fixable_from_source_tiles,
"repaired_tiles": repaired_tiles,
"zoom_summary": normalized_zoom_summary,
"sample_tiles": sample_tiles,
}
report_md, report_json = write_report(output_dir, args.label, target_root, source_root, summary)
print(
json.dumps(
{
"report_md": str(report_md),
"report_json": str(report_json),
"outside_extent_tiles": outside_extent_tiles,
"source_extent_mismatch_tiles": source_extent_mismatch_tiles,
"fixable_from_source_tiles": fixable_from_source_tiles,
"repaired_tiles": repaired_tiles,
},
ensure_ascii=False,
indent=2,
)
)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,277 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import math
import shutil
import subprocess
from pathlib import Path
import mercantile
from build_semantic_delivery_assets import build_mapping, load_audit_rows, remap_tile
REPO_ROOT = Path(__file__).resolve().parent
SOURCE_TILE_ROOT = Path(
"/home/wwwroot/newpec/exported_auto/"
"tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles"
)
FULL_ROOT = Path("/home/wwwroot/pbf-delivery-full-20260415")
SEMANTIC_ROOT = Path("/home/wwwroot/pbf-delivery-full-semantic-20260416")
DEFAULT_AOI_JSON = REPO_ROOT / "tasks/pbf/NavSea_Full_AOI_Visual_Audit_2026-04-18.json"
DEFAULT_OUTPUT_DIR = REPO_ROOT / "report/full_hotspot_rebuild_2026-04-18"
DEFAULT_TMP_ROOT = Path("/tmp/navsea_hotspot_rebuild")
FID_KEY = "thisMyWorld@2026"
BUNDLE_ID = "navsea-core"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="重建全国固定 AOI 热点 tile修复旧坏几何。")
parser.add_argument("--aoi-json", type=Path, default=DEFAULT_AOI_JSON)
parser.add_argument("--output-dir", type=Path, default=DEFAULT_OUTPUT_DIR)
parser.add_argument("--tmp-root", type=Path, default=DEFAULT_TMP_ROOT)
parser.add_argument("--zoom", action="append", type=int, help="只修指定 zoom可重复传入")
return parser.parse_args()
def aoi_bbox(center: list[float], radius_nm: float) -> tuple[float, float, float, float]:
lng, lat = center
radius_km = radius_nm * 1.852
lat_delta = radius_km / 111.32
lon_delta = radius_km / (111.32 * math.cos(math.radians(lat)))
return (
lng - lon_delta,
lat - lat_delta,
lng + lon_delta,
lat + lat_delta,
)
def hardlink_or_copy(src: Path, dst: Path) -> None:
dst.parent.mkdir(parents=True, exist_ok=True)
if dst.exists():
dst.unlink()
try:
dst.hardlink_to(src)
except OSError:
shutil.copy2(src, dst)
def collect_tiles(aoi_json: Path, zoom_filter: set[int] | None) -> tuple[list[dict], list[str]]:
aois = json.loads(aoi_json.read_text(encoding="utf-8"))
tile_map: dict[str, dict] = {}
labels: list[str] = []
for aoi in aois:
labels.append(aoi["label"])
west, south, east, north = aoi_bbox(aoi["center"], aoi["radius_nm"])
for zoom in aoi["zoom_levels"]:
if zoom_filter and zoom not in zoom_filter:
continue
for tile in mercantile.tiles(west, south, east, north, [zoom]):
rel = Path(str(tile.z)) / str(tile.x) / f"{tile.y}.pbf"
tile_map[str(rel)] = {
"z": tile.z,
"x": tile.x,
"y": tile.y,
"relative_path": str(rel),
}
tiles = sorted(tile_map.values(), key=lambda item: (item["z"], item["x"], item["y"]))
return tiles, labels
def prepare_reference_root(reference_root: Path, tiles: list[dict]) -> int:
if reference_root.exists():
shutil.rmtree(reference_root)
prepared = 0
for tile in tiles:
rel = Path(tile["relative_path"])
src = SOURCE_TILE_ROOT / rel
if not src.exists():
continue
dst = reference_root / rel
hardlink_or_copy(src, dst)
prepared += 1
return prepared
def backup_existing_tiles(backup_root: Path, target_root: Path, tiles: list[dict]) -> int:
if backup_root.exists():
shutil.rmtree(backup_root)
backed_up = 0
for tile in tiles:
rel = Path(tile["relative_path"])
src = target_root / rel
if not src.exists():
continue
dst = backup_root / rel
hardlink_or_copy(src, dst)
backed_up += 1
return backed_up
def run_full_rebuild(reference_root: Path, rebuild_root: Path, zoom_filter: set[int] | None) -> None:
if rebuild_root.exists():
shutil.rmtree(rebuild_root)
cmd = [
str(REPO_ROOT / ".venv/bin/python"),
str(REPO_ROOT / "navsea_tile_builder.py"),
"--reference-tile-root",
str(reference_root),
"--output",
str(rebuild_root),
"--workers",
"1",
"--strip-legacy-japanese-delivery",
"--release-minimal",
"--fid-key",
FID_KEY,
"--bundle-id",
BUNDLE_ID,
]
if zoom_filter:
cmd.extend(["--zmin", str(min(zoom_filter)), "--zmax", str(max(zoom_filter))])
subprocess.run(cmd, check=True, cwd=REPO_ROOT)
def deploy_full_tiles(rebuild_root: Path, target_root: Path, tiles: list[dict]) -> int:
deployed = 0
for tile in tiles:
rel = Path(tile["relative_path"])
src = rebuild_root / rel
if not src.exists():
continue
hardlink_or_copy(src, target_root / rel)
deployed += 1
return deployed
def deploy_semantic_tiles(rebuild_root: Path, target_root: Path, tiles: list[dict]) -> dict[str, int]:
rows = load_audit_rows()
mapping = build_mapping(rows)
value_map = {
row.old_sprite_key: mapping[row.old_sprite_key]
for row in rows
if row.used_in_pbf > 0 and row.old_sprite_key in mapping
}
needles = [old.encode("utf-8") for old in value_map]
stats = {
"tiles_total": 0,
"tiles_written": 0,
"tiles_semantic_rewritten": 0,
"features_semantic_changed": 0,
}
for tile in tiles:
rel = Path(tile["relative_path"])
src = rebuild_root / rel
if not src.exists():
continue
dst = target_root / rel
changed, feature_count = remap_tile(src, dst, value_map, needles)
stats["tiles_total"] += 1
stats["tiles_written"] += 1
if changed:
stats["tiles_semantic_rewritten"] += 1
stats["features_semantic_changed"] += feature_count
return stats
def write_report(output_dir: Path, summary: dict) -> tuple[Path, Path]:
output_dir.mkdir(parents=True, exist_ok=True)
report_json = output_dir / "full_hotspot_rebuild.json"
report_md = output_dir / "full_hotspot_rebuild.md"
report_json.write_text(json.dumps(summary, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
lines = [
"# 全国热点 AOI 旧坏 Tile 重建修复",
"",
"## 范围",
"",
f"- AOI 配置:`{summary['aoi_json']}`",
f"- AOI 标签:`{', '.join(summary['aoi_labels'])}`",
f"- zoom`{summary['zoom_filter'] or '按 AOI 原配置'}`",
f"- 参考源:`{summary['source_root']}`",
f"- full 目标:`{summary['full_root']}`",
f"- semantic 目标:`{summary['semantic_root']}`",
"",
"## 数量",
"",
f"- 热点 tile 数:`{summary['tile_count']}`",
f"- 参考 tile 准备:`{summary['prepared_reference_tiles']}`",
f"- full 备份:`{summary['full_backup_tiles']}`",
f"- semantic 备份:`{summary['semantic_backup_tiles']}`",
f"- full 部署:`{summary['full_deployed_tiles']}`",
f"- semantic 部署:`{summary['semantic_stats']['tiles_written']}`",
f"- semantic 重写:`{summary['semantic_stats']['tiles_semantic_rewritten']}`",
f"- semantic 改动 feature`{summary['semantic_stats']['features_semantic_changed']}`",
"",
"## 备份目录",
"",
f"- full backup: `{summary['full_backup_root']}`",
f"- semantic backup: `{summary['semantic_backup_root']}`",
"",
"## 说明",
"",
"- 这轮不是单纯回写 extent而是用当前 builder 对固定热点 tile 重新生成 full 包。",
"- semantic 包再以重建后的 full tile 为底稿,按当前语义 sprite 映射规则重写相关属性。",
"- 目标是先消除全国审计热点里的旧坏几何与大片空白问题。",
"",
]
report_md.write_text("\n".join(lines) + "\n", encoding="utf-8")
return report_md, report_json
def main() -> None:
args = parse_args()
zoom_filter = set(args.zoom or [])
tiles, aoi_labels = collect_tiles(args.aoi_json, zoom_filter or None)
tmp_root = args.tmp_root
reference_root = tmp_root / "reference_tiles"
rebuild_root = tmp_root / "rebuild_full"
full_backup_root = tmp_root / "backup_full"
semantic_backup_root = tmp_root / "backup_semantic"
prepared_reference_tiles = prepare_reference_root(reference_root, tiles)
full_backup_tiles = backup_existing_tiles(full_backup_root, FULL_ROOT, tiles)
semantic_backup_tiles = backup_existing_tiles(semantic_backup_root, SEMANTIC_ROOT, tiles)
run_full_rebuild(reference_root, rebuild_root, zoom_filter or None)
full_deployed_tiles = deploy_full_tiles(rebuild_root, FULL_ROOT, tiles)
semantic_stats = deploy_semantic_tiles(rebuild_root, SEMANTIC_ROOT, tiles)
summary = {
"aoi_json": str(args.aoi_json),
"aoi_labels": aoi_labels,
"zoom_filter": sorted(zoom_filter),
"source_root": str(SOURCE_TILE_ROOT),
"full_root": str(FULL_ROOT),
"semantic_root": str(SEMANTIC_ROOT),
"tile_count": len(tiles),
"prepared_reference_tiles": prepared_reference_tiles,
"full_backup_root": str(full_backup_root),
"semantic_backup_root": str(semantic_backup_root),
"full_backup_tiles": full_backup_tiles,
"semantic_backup_tiles": semantic_backup_tiles,
"full_deployed_tiles": full_deployed_tiles,
"semantic_stats": semantic_stats,
}
report_md, report_json = write_report(args.output_dir, summary)
print(
json.dumps(
{
"report_md": str(report_md),
"report_json": str(report_json),
"tile_count": len(tiles),
"full_deployed_tiles": full_deployed_tiles,
"semantic_stats": semantic_stats,
},
ensure_ascii=False,
indent=2,
)
)
if __name__ == "__main__":
main()

View File

@@ -4,6 +4,7 @@ import argparse
import hashlib import hashlib
import json import json
import math import math
import os
import re import re
import struct import struct
from collections import defaultdict from collections import defaultdict
@@ -221,12 +222,12 @@ def normalize_release_canonical_object_type(source_layer: str, canonical_object_
@dataclass(frozen=True) @dataclass(frozen=True)
class DbConfig: class DbConfig:
host: str = "localhost" host: str = os.getenv("NAVSEA_DB_HOST", "localhost")
port: int = 3306 port: int = int(os.getenv("NAVSEA_DB_PORT", "3306"))
user: str = "root" user: str = os.getenv("NAVSEA_DB_USER", "root")
password: str = "2chi9ks2" password: str = os.getenv("NAVSEA_DB_PASSWORD", "")
database: str = "pbf_analysis" database: str = os.getenv("NAVSEA_DB_NAME", "pbf_analysis")
unix_socket: str | None = "/tmp/mysql.sock" unix_socket: str | None = os.getenv("NAVSEA_DB_SOCKET", "/tmp/mysql.sock") or None
@dataclass(frozen=True) @dataclass(frozen=True)

View File

@@ -0,0 +1,77 @@
#!/usr/bin/env python3
from __future__ import annotations
from pathlib import Path
from typing import Any
import mapbox_vector_tile
from navsea_geometry_native_audit import analyze_tile
def decode_tile_with_extents(raw: bytes) -> tuple[dict[str, Any], dict[str, int]]:
decoded = mapbox_vector_tile.decode(raw)
extents = {
layer_name: int(layer.get("extent") or 4096)
for layer_name, layer in decoded.items()
}
return decoded, extents
def encode_layers_preserving_extents(
encoded_layers: list[dict[str, Any]],
layer_extents: dict[str, int],
) -> bytes:
per_layer_options = {
layer["name"]: {"extents": int(layer_extents[layer["name"]])}
for layer in encoded_layers
}
return mapbox_vector_tile.encode(encoded_layers, per_layer_options=per_layer_options)
def validate_reencoded_tile(
source_tile_path: Path,
output_tile_path: Path,
*,
tolerance: int = 4096,
) -> dict[str, Any]:
source_analysis = analyze_tile(source_tile_path)
output_analysis = analyze_tile(output_tile_path)
source_extent = max(source_analysis["extent_values"]) if source_analysis["extent_values"] else 4096
output_extent = max(output_analysis["extent_values"]) if output_analysis["extent_values"] else 4096
source_overflow = int(source_analysis["max_overflow"])
output_overflow = int(output_analysis["max_overflow"])
suspicious_extent_shift = (
output_extent > 4096
and output_overflow >= source_overflow + (output_extent - 4096) - tolerance
)
suspicious = output_overflow > source_overflow + tolerance or suspicious_extent_shift
return {
"source_extent_values": source_analysis["extent_values"],
"output_extent_values": output_analysis["extent_values"],
"source_max_overflow": source_overflow,
"output_max_overflow": output_overflow,
"suspicious_extent_shift": suspicious_extent_shift,
"suspicious": suspicious,
}
def assert_reencoded_tile_safe(
source_tile_path: Path,
output_tile_path: Path,
*,
tolerance: int = 4096,
) -> None:
verdict = validate_reencoded_tile(source_tile_path, output_tile_path, tolerance=tolerance)
if verdict["suspicious"]:
raise RuntimeError(
"reencoded tile geometry drift detected: "
f"source={source_tile_path} output={output_tile_path} "
f"source_extent={verdict['source_extent_values']} "
f"output_extent={verdict['output_extent_values']} "
f"source_overflow={verdict['source_max_overflow']} "
f"output_overflow={verdict['output_max_overflow']} "
f"suspicious_extent_shift={verdict['suspicious_extent_shift']}"
)

View File

@@ -0,0 +1,685 @@
{
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html",
"cases": [
{
"id": "okinawa_10nm_full_z12",
"label": "冲绳 10 海里",
"variant": "full",
"zoom": 12,
"center": [
127.67,
26.21
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=127.67%2C26.21&zoom=12",
"changed_pixels": 314441,
"total_pixels": 364800,
"changed_ratio": 0.861954,
"mean_abs_rgb": [
40.364,
41.3728,
55.3433
],
"rms_rgb": [
67.4457,
66.8189,
83.1026
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z12/compare_diff.png"
},
{
"id": "karatsu_5nm_full_z12",
"label": "唐津 5 海里",
"variant": "full",
"zoom": 12,
"center": [
129.9697,
33.4425
],
"radius_nm": 5,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=129.9697%2C33.4425&zoom=12",
"changed_pixels": 313371,
"total_pixels": 364800,
"changed_ratio": 0.859021,
"mean_abs_rgb": [
32.3459,
33.3448,
50.9619
],
"rms_rgb": [
53.1806,
51.4741,
72.4363
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z12/compare_diff.png"
},
{
"id": "okinawa_10nm_semantic_z12",
"label": "冲绳 10 海里",
"variant": "semantic",
"zoom": 12,
"center": [
127.67,
26.21
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=127.67%2C26.21&zoom=12",
"changed_pixels": 310142,
"total_pixels": 364800,
"changed_ratio": 0.85017,
"mean_abs_rgb": [
40.3146,
41.3705,
55.2069
],
"rms_rgb": [
67.4717,
66.8981,
83.0146
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z12/compare_diff.png"
},
{
"id": "karatsu_5nm_semantic_z12",
"label": "唐津 5 海里",
"variant": "semantic",
"zoom": 12,
"center": [
129.9697,
33.4425
],
"radius_nm": 5,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=129.9697%2C33.4425&zoom=12",
"changed_pixels": 309067,
"total_pixels": 364800,
"changed_ratio": 0.847223,
"mean_abs_rgb": [
32.2753,
33.2837,
50.6801
],
"rms_rgb": [
53.1618,
51.4769,
72.184
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z12/compare_diff.png"
},
{
"id": "karatsu_5nm_full_z10",
"label": "唐津 5 海里",
"variant": "full",
"zoom": 10,
"center": [
129.9697,
33.4425
],
"radius_nm": 5,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=129.9697%2C33.4425&zoom=10",
"changed_pixels": 267772,
"total_pixels": 364800,
"changed_ratio": 0.734024,
"mean_abs_rgb": [
25.3191,
24.6696,
50.8948
],
"rms_rgb": [
43.688,
39.9594,
68.802
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z10/compare_diff.png"
},
{
"id": "karatsu_5nm_semantic_z10",
"label": "唐津 5 海里",
"variant": "semantic",
"zoom": 10,
"center": [
129.9697,
33.4425
],
"radius_nm": 5,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=129.9697%2C33.4425&zoom=10",
"changed_pixels": 263392,
"total_pixels": 364800,
"changed_ratio": 0.722018,
"mean_abs_rgb": [
24.5744,
23.762,
48.4161
],
"rms_rgb": [
42.989,
38.9809,
66.1666
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z10/compare_diff.png"
},
{
"id": "tokyo_bay_10nm_full_z12",
"label": "东京湾 10 海里",
"variant": "full",
"zoom": 12,
"center": [
139.85,
35.42
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=139.85%2C35.42&zoom=12",
"changed_pixels": 242549,
"total_pixels": 364800,
"changed_ratio": 0.664882,
"mean_abs_rgb": [
21.7351,
25.7701,
23.1903
],
"rms_rgb": [
44.1671,
46.1494,
50.8333
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z12/compare_diff.png"
},
{
"id": "tokyo_bay_10nm_semantic_z12",
"label": "东京湾 10 海里",
"variant": "semantic",
"zoom": 12,
"center": [
139.85,
35.42
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=139.85%2C35.42&zoom=12",
"changed_pixels": 235968,
"total_pixels": 364800,
"changed_ratio": 0.646842,
"mean_abs_rgb": [
21.5178,
25.5206,
22.6922
],
"rms_rgb": [
43.901,
45.7039,
50.198
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z12/compare_diff.png"
},
{
"id": "hakata_10nm_full_z10",
"label": "博多港中心 10 海里",
"variant": "full",
"zoom": 10,
"center": [
130.335,
33.6385
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=130.335%2C33.6385&zoom=10",
"changed_pixels": 233090,
"total_pixels": 364800,
"changed_ratio": 0.638953,
"mean_abs_rgb": [
22.602,
21.9769,
43.8265
],
"rms_rgb": [
43.1938,
39.2381,
64.4699
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z10/compare_diff.png"
},
{
"id": "hakata_10nm_semantic_z10",
"label": "博多港中心 10 海里",
"variant": "semantic",
"zoom": 10,
"center": [
130.335,
33.6385
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=130.335%2C33.6385&zoom=10",
"changed_pixels": 226222,
"total_pixels": 364800,
"changed_ratio": 0.620126,
"mean_abs_rgb": [
22.2492,
21.4661,
42.4354
],
"rms_rgb": [
42.9444,
38.7677,
62.857
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z10/compare_diff.png"
},
{
"id": "tokyo_bay_10nm_full_z10",
"label": "东京湾 10 海里",
"variant": "full",
"zoom": 10,
"center": [
139.85,
35.42
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=139.85%2C35.42&zoom=10",
"changed_pixels": 208628,
"total_pixels": 364800,
"changed_ratio": 0.571897,
"mean_abs_rgb": [
21.5068,
21.8381,
37.6819
],
"rms_rgb": [
43.9016,
42.4239,
60.7869
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z10/compare_diff.png"
},
{
"id": "tokyo_bay_10nm_semantic_z10",
"label": "东京湾 10 海里",
"variant": "semantic",
"zoom": 10,
"center": [
139.85,
35.42
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=139.85%2C35.42&zoom=10",
"changed_pixels": 208306,
"total_pixels": 364800,
"changed_ratio": 0.571014,
"mean_abs_rgb": [
21.3378,
21.3679,
37.1671
],
"rms_rgb": [
43.6894,
41.6284,
60.1436
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z10/compare_diff.png"
},
{
"id": "hakata_10nm_full_z12",
"label": "博多港中心 10 海里",
"variant": "full",
"zoom": 12,
"center": [
130.335,
33.6385
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=130.335%2C33.6385&zoom=12",
"changed_pixels": 194689,
"total_pixels": 364800,
"changed_ratio": 0.533687,
"mean_abs_rgb": [
20.7021,
21.5285,
26.4928
],
"rms_rgb": [
45.2912,
45.6054,
50.3669
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z12/compare_diff.png"
},
{
"id": "osaka_bay_10nm_full_z10",
"label": "大阪 10 海里",
"variant": "full",
"zoom": 10,
"center": [
135.35,
34.61
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=135.35%2C34.61&zoom=10",
"changed_pixels": 194451,
"total_pixels": 364800,
"changed_ratio": 0.533035,
"mean_abs_rgb": [
21.0579,
20.6348,
35.3722
],
"rms_rgb": [
44.3815,
41.2946,
58.6624
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z10/compare_diff.png"
},
{
"id": "osaka_bay_10nm_full_z12",
"label": "大阪 10 海里",
"variant": "full",
"zoom": 12,
"center": [
135.35,
34.61
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=135.35%2C34.61&zoom=12",
"changed_pixels": 194138,
"total_pixels": 364800,
"changed_ratio": 0.532177,
"mean_abs_rgb": [
23.4548,
25.0792,
21.5488
],
"rms_rgb": [
49.0486,
49.6832,
54.94
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z12/compare_diff.png"
},
{
"id": "hakata_10nm_semantic_z12",
"label": "博多港中心 10 海里",
"variant": "semantic",
"zoom": 12,
"center": [
130.335,
33.6385
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=130.335%2C33.6385&zoom=12",
"changed_pixels": 193860,
"total_pixels": 364800,
"changed_ratio": 0.531414,
"mean_abs_rgb": [
20.125,
20.7366,
25.1796
],
"rms_rgb": [
44.4182,
44.2282,
48.4008
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z12/compare_diff.png"
},
{
"id": "okinawa_10nm_full_z10",
"label": "冲绳 10 海里",
"variant": "full",
"zoom": 10,
"center": [
127.67,
26.21
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=127.67%2C26.21&zoom=10",
"changed_pixels": 192396,
"total_pixels": 364800,
"changed_ratio": 0.527401,
"mean_abs_rgb": [
19.8231,
18.7544,
25.9994
],
"rms_rgb": [
43.3599,
39.8588,
51.1734
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z10/compare_diff.png"
},
{
"id": "osaka_bay_10nm_semantic_z10",
"label": "大阪 10 海里",
"variant": "semantic",
"zoom": 10,
"center": [
135.35,
34.61
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=135.35%2C34.61&zoom=10",
"changed_pixels": 191439,
"total_pixels": 364800,
"changed_ratio": 0.524778,
"mean_abs_rgb": [
20.8376,
20.016,
34.5041
],
"rms_rgb": [
44.2009,
40.5148,
57.712
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z10/compare_diff.png"
},
{
"id": "osaka_bay_10nm_semantic_z12",
"label": "大阪 10 海里",
"variant": "semantic",
"zoom": 12,
"center": [
135.35,
34.61
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=135.35%2C34.61&zoom=12",
"changed_pixels": 187180,
"total_pixels": 364800,
"changed_ratio": 0.513103,
"mean_abs_rgb": [
23.438,
24.8296,
21.3988
],
"rms_rgb": [
49.1511,
49.5348,
54.9121
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z12/compare_diff.png"
},
{
"id": "okinawa_10nm_semantic_z10",
"label": "冲绳 10 海里",
"variant": "semantic",
"zoom": 10,
"center": [
127.67,
26.21
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=127.67%2C26.21&zoom=10",
"changed_pixels": 186366,
"total_pixels": 364800,
"changed_ratio": 0.510872,
"mean_abs_rgb": [
19.3335,
17.9048,
24.0201
],
"rms_rgb": [
42.9399,
38.9411,
48.1207
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z10/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z10/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z10/compare_diff.png"
}
]
}

View File

@@ -0,0 +1,209 @@
# 全国 AOI 截图对比审计
## 总览
- compare page: `http://192.168.200.184/newpec/navsea-compare-full-audit.html`
- cases: `20`
## 差异排序
### 冲绳 10 海里 · full · z12
- changed ratio: `0.861954`
- changed pixels: `314441` / `364800`
- mean abs rgb: `[40.364, 41.3728, 55.3433]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=127.67%2C26.21&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z12/compare_diff.png`
### 唐津 5 海里 · full · z12
- changed ratio: `0.859021`
- changed pixels: `313371` / `364800`
- mean abs rgb: `[32.3459, 33.3448, 50.9619]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=129.9697%2C33.4425&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z12/compare_diff.png`
### 冲绳 10 海里 · semantic · z12
- changed ratio: `0.85017`
- changed pixels: `310142` / `364800`
- mean abs rgb: `[40.3146, 41.3705, 55.2069]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=127.67%2C26.21&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z12/compare_diff.png`
### 唐津 5 海里 · semantic · z12
- changed ratio: `0.847223`
- changed pixels: `309067` / `364800`
- mean abs rgb: `[32.2753, 33.2837, 50.6801]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=129.9697%2C33.4425&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z12/compare_diff.png`
### 唐津 5 海里 · full · z10
- changed ratio: `0.734024`
- changed pixels: `267772` / `364800`
- mean abs rgb: `[25.3191, 24.6696, 50.8948]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=129.9697%2C33.4425&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_full_z10/compare_diff.png`
### 唐津 5 海里 · semantic · z10
- changed ratio: `0.722018`
- changed pixels: `263392` / `364800`
- mean abs rgb: `[24.5744, 23.762, 48.4161]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=129.9697%2C33.4425&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/karatsu_5nm_semantic_z10/compare_diff.png`
### 东京湾 10 海里 · full · z12
- changed ratio: `0.664882`
- changed pixels: `242549` / `364800`
- mean abs rgb: `[21.7351, 25.7701, 23.1903]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=139.85%2C35.42&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z12/compare_diff.png`
### 东京湾 10 海里 · semantic · z12
- changed ratio: `0.646842`
- changed pixels: `235968` / `364800`
- mean abs rgb: `[21.5178, 25.5206, 22.6922]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=139.85%2C35.42&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z12/compare_diff.png`
### 博多港中心 10 海里 · full · z10
- changed ratio: `0.638953`
- changed pixels: `233090` / `364800`
- mean abs rgb: `[22.602, 21.9769, 43.8265]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=130.335%2C33.6385&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z10/compare_diff.png`
### 博多港中心 10 海里 · semantic · z10
- changed ratio: `0.620126`
- changed pixels: `226222` / `364800`
- mean abs rgb: `[22.2492, 21.4661, 42.4354]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=130.335%2C33.6385&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z10/compare_diff.png`
### 东京湾 10 海里 · full · z10
- changed ratio: `0.571897`
- changed pixels: `208628` / `364800`
- mean abs rgb: `[21.5068, 21.8381, 37.6819]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=139.85%2C35.42&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_full_z10/compare_diff.png`
### 东京湾 10 海里 · semantic · z10
- changed ratio: `0.571014`
- changed pixels: `208306` / `364800`
- mean abs rgb: `[21.3378, 21.3679, 37.1671]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=139.85%2C35.42&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/tokyo_bay_10nm_semantic_z10/compare_diff.png`
### 博多港中心 10 海里 · full · z12
- changed ratio: `0.533687`
- changed pixels: `194689` / `364800`
- mean abs rgb: `[20.7021, 21.5285, 26.4928]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=130.335%2C33.6385&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_full_z12/compare_diff.png`
### 大阪 10 海里 · full · z10
- changed ratio: `0.533035`
- changed pixels: `194451` / `364800`
- mean abs rgb: `[21.0579, 20.6348, 35.3722]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=135.35%2C34.61&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z10/compare_diff.png`
### 大阪 10 海里 · full · z12
- changed ratio: `0.532177`
- changed pixels: `194138` / `364800`
- mean abs rgb: `[23.4548, 25.0792, 21.5488]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=135.35%2C34.61&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_full_z12/compare_diff.png`
### 博多港中心 10 海里 · semantic · z12
- changed ratio: `0.531414`
- changed pixels: `193860` / `364800`
- mean abs rgb: `[20.125, 20.7366, 25.1796]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=130.335%2C33.6385&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/hakata_10nm_semantic_z12/compare_diff.png`
### 冲绳 10 海里 · full · z10
- changed ratio: `0.527401`
- changed pixels: `192396` / `364800`
- mean abs rgb: `[19.8231, 18.7544, 25.9994]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=127.67%2C26.21&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_full_z10/compare_diff.png`
### 大阪 10 海里 · semantic · z10
- changed ratio: `0.524778`
- changed pixels: `191439` / `364800`
- mean abs rgb: `[20.8376, 20.016, 34.5041]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=135.35%2C34.61&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z10/compare_diff.png`
### 大阪 10 海里 · semantic · z12
- changed ratio: `0.513103`
- changed pixels: `187180` / `364800`
- mean abs rgb: `[23.438, 24.8296, 21.3988]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=135.35%2C34.61&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/osaka_bay_10nm_semantic_z12/compare_diff.png`
### 冲绳 10 海里 · semantic · z10
- changed ratio: `0.510872`
- changed pixels: `186366` / `364800`
- mean abs rgb: `[19.3335, 17.9048, 24.0201]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=127.67%2C26.21&zoom=10`
- left image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z10/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z10/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_aoi_visual_audit_2026-04-18_r1/okinawa_10nm_semantic_z10/compare_diff.png`

View File

@@ -0,0 +1,109 @@
# 全国 full / semantic 高 extent 几何错移根因报告
## 1. 结论
- 当前全国 `full / semantic` 中反复出现的“大块空白 / 岛礁附近整块打穿 / 右侧大片缺失”问题
- 根因不是 `style` 改图标本身
- 真正根因是:
- 某条会重写 `PBF` 的生产链路
- 在处理原始 `extent = 1048576` 的高精度 tile 时
- 用了 `4096` 口径重编码几何
- 结果会把 tile 的几何整体错移,尤其是 `Y` 坐标整张 tile 下移一个:
- `1048576 - 4096 = 1044480`
量级的偏移
## 2. 证据
### 2.1 生产坏 tile 的数值签名
- 代表坏 tile
- `/tmp/navsea_hotspot_rebuild/backup_full/12/3526/1643.pbf`
- `/tmp/navsea_hotspot_rebuild/backup_semantic/12/3526/1643.pbf`
- 对比 source tile
- `/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles/12/3526/1643.pbf`
- source 正常 overflow
- `20480`
- 坏 tile overflow
- `1064960`
### 2.2 复现实验
- 已直接拿 source tile 做重编码实验
- 当把原始 `extent = 1048576` tile 重新编码时,故意把 layer `extent` 改成 `4096`
- 可以稳定复现出与生产坏 tile 一模一样的几何签名:
- `overflow = 1064960`
- 这说明:
- 当前线上坏 tile 不是随机损坏
- 而是非常明确的“高 extent tile 被按 4096 口径重编码”的产物
### 2.3 热点备份审计结果
- 对修前热点 full 备份:
- [`hotspot_backup_full_shift_audit_2026-04-18.json`](/root/sourceserver/pbf/report/hotspot_backup_full_shift_audit_2026-04-18.json)
- 对修前热点 semantic 备份:
- [`hotspot_backup_semantic_shift_audit_2026-04-18.json`](/root/sourceserver/pbf/report/hotspot_backup_semantic_shift_audit_2026-04-18.json)
- 结果:
- `backup_full``154` 张里有 `42` 张命中该签名
- `backup_semantic``154` 张里有 `43` 张命中该签名
## 3. 为什么会让人误以为是“改图标导致的”
- 图标 / style 变更本身不会把海底等深线、海岸线、陆域几何整块打空
- 但“图标改名 / 属性改写”这类需求往往会触发:
- `decode pbf`
- `改属性`
- `encode pbf`
这条重写链
- 一旦这条链在高 extent tile 上没有保回原始 extent
- 几何就会被整体写坏
- 所以用户看到“像是改 style 图标之后坏了”
- 现象上是对的
- 但根因不是 style
- 而是“被图标/属性变更触发的 PBF 重编码链”出了错
## 4. 本轮代码修复
### 4.1 已新增重编码守卫
- [`navsea_tile_reencode_guard.py`](/root/sourceserver/pbf/navsea_tile_reencode_guard.py)
用途:
- 统一保存原 layer `extent`
- 重编码后立即和 source tile 做几何签名比对
- 一旦出现:
- overflow 异常增大
- 或命中 `1048576 -> 4096` 错重编码签名
直接报错,不允许静默产出坏 tile
### 4.2 已新增根因审计脚本
- [`navsea_extent_shift_audit.py`](/root/sourceserver/pbf/navsea_extent_shift_audit.py)
用途:
- 审计目标目录里是否存在:
- 高 extent tile 被按 4096 口径错重编码
的几何签名
### 4.3 已加固语义版 PBF 重写链
- 已修改:
- [`build_semantic_delivery_assets.py`](/root/sourceserver/pbf/build_semantic_delivery_assets.py)
当前要求:
- decode 时显式带出原始 layer extent
- encode 时必须按原 layer extent 写回
- 每张被重写的 tile 写完后立即做几何守卫校验
## 5. 当前对线上问题的影响
- 热点 AOI 中已修过的 tile
- 已通过重建替换为当前正确几何
- 但全国目录里仍可能存在更多尚未重建的历史坏 tile
- 因此要“彻底解决”全国问题,最终仍需要:
- 用当前受保护的生产链路重建全国 `full`
- 再基于新的 full 重建 `semantic`
- 并在部署前跑一轮 `extent shift audit`

View File

@@ -0,0 +1,45 @@
{
"scope": {
"zoom": 12,
"full_root": "/home/wwwroot/pbf-delivery-full-20260415",
"semantic_root": "/home/wwwroot/pbf-delivery-full-semantic-20260416"
},
"pre_fix": {
"full": {
"tile_count": 48556,
"extent_counts": {
"1048576": 47366,
"4096": 1190
}
},
"semantic": {
"tile_count": 48556,
"extent_counts": {
"1048576": 47296,
"4096": 1260
}
}
},
"backup_roots": [
"/home/wwwroot/pbf-delivery-full-20260415-backup-20260418-preextentfix",
"/home/wwwroot/pbf-delivery-full-semantic-20260416-backup-20260418-preextentfix"
],
"repaired_tiles": {
"full": 1183,
"semantic": 1215
},
"post_fix": {
"full": {
"tile_count": 48556,
"extent_counts": {
"1048576": 48556
}
},
"semantic": {
"tile_count": 48556,
"extent_counts": {
"1048576": 48556
}
}
}
}

View File

@@ -0,0 +1,50 @@
# 全国 full / semantic z12 extent 逻辑审计与修复
## 范围
- `/home/wwwroot/pbf-delivery-full-20260415`
- `/home/wwwroot/pbf-delivery-full-semantic-20260416`
- 聚焦 zoom `12`
## 修前统计
- `full z12`
- 总瓦片:`48556`
- `extent = 1048576``47366`
- `extent = 4096``1190`
- `semantic z12`
- 总瓦片:`48556`
- `extent = 1048576``47296`
- `extent = 4096``1260`
## 修复动作
- 已先做硬链接备份:
- `/home/wwwroot/pbf-delivery-full-20260415-backup-20260418-preextentfix`
- `/home/wwwroot/pbf-delivery-full-semantic-20260416-backup-20260418-preextentfix`
- 对当前 `extent = 4096` 的 z12 错片:
- 逐张读取原始 `newpec` 同路径 source tile
- 若 source extent 为 `1048576`
- 则把当前 delivery / semantic tile 的全部 layer extent 回写为 `1048576`
## 修复结果
- `full repaired = 1183`
- `semantic repaired = 1215`
## 修后复核
- `full z12`
- `48556 / 48556` 全部为 `1048576`
- `semantic z12`
- `48556 / 48556` 全部为 `1048576`
## 当前结论
- 这轮已确认全国 `full / semantic``z12` 中确实存在一批 extent 错退片
- 当前这批错片已经按 source tile 口径修回
- 这一步解决的是:
- 几何 / extent / native 风险中的明确 metadata 错片问题
- 这不等于:
- 全国视觉等价性已经通过

View File

@@ -0,0 +1,27 @@
{
"aoi_json": "/root/sourceserver/pbf/tasks/pbf/NavSea_Full_AOI_Visual_Audit_2026-04-18.json",
"aoi_labels": [
"博多港中心 10 海里",
"东京湾 10 海里",
"大阪 10 海里",
"冲绳 10 海里",
"唐津 5 海里"
],
"zoom_filter": [],
"source_root": "/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles",
"full_root": "/home/wwwroot/pbf-delivery-full-20260415",
"semantic_root": "/home/wwwroot/pbf-delivery-full-semantic-20260416",
"tile_count": 154,
"prepared_reference_tiles": 154,
"full_backup_root": "/tmp/navsea_hotspot_rebuild/backup_full",
"semantic_backup_root": "/tmp/navsea_hotspot_rebuild/backup_semantic",
"full_backup_tiles": 154,
"semantic_backup_tiles": 154,
"full_deployed_tiles": 154,
"semantic_stats": {
"tiles_total": 154,
"tiles_written": 154,
"tiles_semantic_rewritten": 0,
"features_semantic_changed": 0
}
}

View File

@@ -0,0 +1,33 @@
# 全国热点 AOI 旧坏 Tile 重建修复
## 范围
- AOI 配置:`/root/sourceserver/pbf/tasks/pbf/NavSea_Full_AOI_Visual_Audit_2026-04-18.json`
- AOI 标签:`博多港中心 10 海里, 东京湾 10 海里, 大阪 10 海里, 冲绳 10 海里, 唐津 5 海里`
- zoom`按 AOI 原配置`
- 参考源:`/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles`
- full 目标:`/home/wwwroot/pbf-delivery-full-20260415`
- semantic 目标:`/home/wwwroot/pbf-delivery-full-semantic-20260416`
## 数量
- 热点 tile 数:`154`
- 参考 tile 准备:`154`
- full 备份:`154`
- semantic 备份:`154`
- full 部署:`154`
- semantic 部署:`154`
- semantic 重写:`0`
- semantic 改动 feature`0`
## 备份目录
- full backup: `/tmp/navsea_hotspot_rebuild/backup_full`
- semantic backup: `/tmp/navsea_hotspot_rebuild/backup_semantic`
## 说明
- 这轮不是单纯回写 extent而是用当前 builder 对固定热点 tile 重新生成 full 包。
- semantic 包再以重建后的 full tile 为底稿,按当前语义 sprite 映射规则重写相关属性。
- 目标是先消除全国审计热点里的旧坏几何与大片空白问题。

View File

@@ -0,0 +1,73 @@
{
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf",
"cases": [
{
"id": "karatsu_5nm_full_z12",
"label": "唐津 5 海里",
"variant": "full",
"zoom": 12,
"center": [
129.9697,
33.4425
],
"radius_nm": 5,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf&variant=full&audit=1&center=129.9697%2C33.4425&zoom=12",
"changed_pixels": 276326,
"total_pixels": 364800,
"changed_ratio": 0.757473,
"mean_abs_rgb": [
28.6339,
29.7368,
58.0848
],
"rms_rgb": [
48.2024,
47.0653,
75.8149
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/karatsu_5nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/karatsu_5nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/karatsu_5nm_full_z12/compare_diff.png"
},
{
"id": "hakata_10nm_full_z12",
"label": "博多港中心 10 海里",
"variant": "full",
"zoom": 12,
"center": [
130.335,
33.6385
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf&variant=full&audit=1&center=130.335%2C33.6385&zoom=12",
"changed_pixels": 193301,
"total_pixels": 364800,
"changed_ratio": 0.529882,
"mean_abs_rgb": [
20.6516,
21.4763,
26.4402
],
"rms_rgb": [
45.2293,
45.5602,
50.335
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/hakata_10nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/hakata_10nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/hakata_10nm_full_z12/compare_diff.png"
}
]
}

View File

@@ -0,0 +1,29 @@
# 全国 AOI 截图对比审计
## 总览
- compare page: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf`
- cases: `2`
## 差异排序
### 唐津 5 海里 · full · z12
- changed ratio: `0.757473`
- changed pixels: `276326` / `364800`
- mean abs rgb: `[28.6339, 29.7368, 58.0848]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf&variant=full&audit=1&center=129.9697%2C33.4425&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/karatsu_5nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/karatsu_5nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/karatsu_5nm_full_z12/compare_diff.png`
### 博多港中心 10 海里 · full · z12
- changed ratio: `0.529882`
- changed pixels: `193301` / `364800`
- mean abs rgb: `[20.6516, 21.4763, 26.4402]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf&variant=full&audit=1&center=130.335%2C33.6385&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/hakata_10nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/hakata_10nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_rebuild_staging_hakata_karatsu_z12_2026-04-18/hakata_10nm_full_z12/compare_diff.png`

View File

@@ -0,0 +1,39 @@
{
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf",
"cases": [
{
"id": "okinawa_10nm_full_z12",
"label": "冲绳 10 海里",
"variant": "full",
"zoom": 12,
"center": [
127.67,
26.21
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf&variant=full&audit=1&center=127.67%2C26.21&zoom=12",
"changed_pixels": 286800,
"total_pixels": 364800,
"changed_ratio": 0.786184,
"mean_abs_rgb": [
35.1541,
37.5348,
57.2885
],
"rms_rgb": [
57.997,
59.3287,
80.8913
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_2026-04-18/okinawa_10nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_2026-04-18/okinawa_10nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_2026-04-18/okinawa_10nm_full_z12/compare_diff.png"
}
]
}

View File

@@ -0,0 +1,19 @@
# 全国 AOI 截图对比审计
## 总览
- compare page: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf`
- cases: `1`
## 差异排序
### 冲绳 10 海里 · full · z12
- changed ratio: `0.786184`
- changed pixels: `286800` / `364800`
- mean abs rgb: `[35.1541, 37.5348, 57.2885]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf&variant=full&audit=1&center=127.67%2C26.21&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_2026-04-18/okinawa_10nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_2026-04-18/okinawa_10nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_2026-04-18/okinawa_10nm_full_z12/compare_diff.png`

View File

@@ -0,0 +1,39 @@
{
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf",
"cases": [
{
"id": "okinawa_10nm_full_z12",
"label": "冲绳 10 海里",
"variant": "full",
"zoom": 12,
"center": [
127.67,
26.21
],
"radius_nm": 10,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf&variant=full&audit=1&center=127.67%2C26.21&zoom=12",
"changed_pixels": 286800,
"total_pixels": 364800,
"changed_ratio": 0.786184,
"mean_abs_rgb": [
35.1541,
37.5348,
57.2885
],
"rms_rgb": [
57.997,
59.3287,
80.8913
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_r2_2026-04-18/okinawa_10nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_r2_2026-04-18/okinawa_10nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_r2_2026-04-18/okinawa_10nm_full_z12/compare_diff.png"
}
]
}

View File

@@ -0,0 +1,19 @@
# 全国 AOI 截图对比审计
## 总览
- compare page: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf`
- cases: `1`
## 差异排序
### 冲绳 10 海里 · full · z12
- changed ratio: `0.786184`
- changed pixels: `286800` / `364800`
- mean abs rgb: `[35.1541, 37.5348, 57.2885]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?deliveryTileUrl=http%3A%2F%2F192.168.200.184%2Fpbf-delivery-full-20260418-staging-z12%2F%7Bz%7D%2F%7Bx%7D%2F%7By%7D.pbf&variant=full&audit=1&center=127.67%2C26.21&zoom=12`
- left image: `/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_r2_2026-04-18/okinawa_10nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_r2_2026-04-18/okinawa_10nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/full_rebuild_staging_okinawa_z12_r2_2026-04-18/okinawa_10nm_full_z12/compare_diff.png`

View File

@@ -0,0 +1,555 @@
{
"target_root": "/tmp/navsea_hotspot_rebuild/backup_full",
"source_root": "/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles",
"zoom_filter": [],
"tiles_checked": 154,
"suspicious_tile_count": 42,
"samples": [
{
"tile": "12/3641/1615.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3641/1614.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3640/1616.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3640/1615.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3640/1614.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1618.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1617.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1616.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1615.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1614.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3588/1629.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3588/1628.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3588/1627.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3588/1626.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1630.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1629.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1628.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1627.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1626.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3585/1630.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3585/1629.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3585/1628.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3585/1627.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3527/1643.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3527/1642.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3526/1643.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3526/1642.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3525/1644.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3525/1643.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3525/1642.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1740.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1739.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1738.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1737.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1736.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1740.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1739.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1738.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1737.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1736.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3499/1739.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3499/1738.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
}
]
}

View File

@@ -0,0 +1,568 @@
{
"target_root": "/tmp/navsea_hotspot_rebuild/backup_semantic",
"source_root": "/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles",
"zoom_filter": [],
"tiles_checked": 154,
"suspicious_tile_count": 43,
"samples": [
{
"tile": "12/3641/1615.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3641/1614.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3640/1616.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3640/1615.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3640/1614.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1618.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1617.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1616.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1615.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3639/1614.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3588/1629.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3588/1628.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3588/1627.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3588/1626.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1630.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1629.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1628.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1627.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3586/1626.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3585/1630.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3585/1629.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3585/1628.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3585/1627.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3527/1643.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3527/1642.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3526/1643.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3526/1642.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3525/1644.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3525/1643.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3525/1642.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1740.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1739.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1738.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1737.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3501/1736.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1740.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1739.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1738.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1737.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3500/1736.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3499/1740.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3499/1739.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
},
{
"tile": "12/3499/1738.pbf",
"source_extent_values": [
1048576
],
"output_extent_values": [
1048576
],
"source_max_overflow": 20480,
"output_max_overflow": 1064960,
"suspicious_extent_shift": true,
"suspicious": true
}
]
}

View File

@@ -0,0 +1,73 @@
{
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html",
"cases": [
{
"id": "karatsu_5nm_full_z12",
"label": "唐津 5 海里",
"variant": "full",
"zoom": 12,
"center": [
129.9697,
33.4425
],
"radius_nm": 5,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=129.9697%2C33.4425&zoom=12",
"changed_pixels": 277714,
"total_pixels": 364800,
"changed_ratio": 0.761277,
"mean_abs_rgb": [
28.6843,
29.789,
58.1373
],
"rms_rgb": [
48.2605,
47.109,
75.836
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_full_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_full_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_full_z12/compare_diff.png"
},
{
"id": "karatsu_5nm_semantic_z12",
"label": "唐津 5 海里",
"variant": "semantic",
"zoom": 12,
"center": [
129.9697,
33.4425
],
"radius_nm": 5,
"compare_url": "http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=129.9697%2C33.4425&zoom=12",
"changed_pixels": 274149,
"total_pixels": 364800,
"changed_ratio": 0.751505,
"mean_abs_rgb": [
28.5041,
29.6077,
57.8853
],
"rms_rgb": [
48.0973,
46.9345,
75.7303
],
"diff_bbox": [
0,
0,
640,
513
],
"left_image": "/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_semantic_z12/compare_left.png",
"right_image": "/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_semantic_z12/compare_right.png",
"diff_image": "/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_semantic_z12/compare_diff.png"
}
]
}

View File

@@ -0,0 +1,29 @@
# 全国 AOI 截图对比审计
## 总览
- compare page: `http://192.168.200.184/newpec/navsea-compare-full-audit.html`
- cases: `2`
## 差异排序
### 唐津 5 海里 · full · z12
- changed ratio: `0.761277`
- changed pixels: `277714` / `364800`
- mean abs rgb: `[28.6843, 29.789, 58.1373]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=full&audit=1&center=129.9697%2C33.4425&zoom=12`
- left image: `/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_full_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_full_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_full_z12/compare_diff.png`
### 唐津 5 海里 · semantic · z12
- changed ratio: `0.751505`
- changed pixels: `274149` / `364800`
- mean abs rgb: `[28.5041, 29.6077, 57.8853]`
- compare url: `http://192.168.200.184/newpec/navsea-compare-full-audit.html?variant=semantic&audit=1&center=129.9697%2C33.4425&zoom=12`
- left image: `/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_semantic_z12/compare_left.png`
- right image: `/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_semantic_z12/compare_right.png`
- diff image: `/root/sourceserver/pbf/report/karatsu_hotspot_verify_2026-04-18/karatsu_5nm_semantic_z12/compare_diff.png`

View File

@@ -6,3 +6,5 @@ eccodes>=1.7
mercantile>=1.2 mercantile>=1.2
mapbox-vector-tile>=2.1 mapbox-vector-tile>=2.1
PyMySQL>=1.1 PyMySQL>=1.1
Pillow>=10.0
cryptography>=42.0

View File

@@ -0,0 +1,645 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>NavSea Full Audit Compare</title>
<link href="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css" rel="stylesheet" />
<style>
:root {
--bg: #eef2ed;
--panel: rgba(250, 248, 242, 0.94);
--ink: #17232b;
--muted: #667780;
--line: rgba(23, 35, 43, 0.12);
--shadow: 0 14px 28px rgba(23, 35, 43, 0.14);
--left: #305f72;
--right: #8b5e34;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
height: 100%;
background:
radial-gradient(circle at top left, rgba(48, 95, 114, 0.12), transparent 28%),
radial-gradient(circle at bottom right, rgba(139, 94, 52, 0.1), transparent 24%),
var(--bg);
color: var(--ink);
font-family: "Avenir Next", "Segoe UI", "PingFang SC", "Noto Sans SC", sans-serif;
}
body {
display: grid;
grid-template-rows: auto 1fr;
}
.toolbar {
display: flex;
justify-content: space-between;
gap: 18px;
align-items: flex-start;
padding: 14px 18px 12px;
background: linear-gradient(180deg, rgba(250, 248, 242, 0.98), rgba(250, 248, 242, 0.9));
border-bottom: 1px solid var(--line);
box-shadow: var(--shadow);
z-index: 20;
flex-wrap: wrap;
}
.title {
font-size: 18px;
font-weight: 700;
letter-spacing: 0.02em;
}
.subtitle {
margin-top: 4px;
max-width: 920px;
font-size: 13px;
line-height: 1.5;
color: var(--muted);
}
.toolbar-actions {
display: flex;
gap: 10px;
flex-wrap: wrap;
align-items: center;
}
.version-chip {
display: inline-flex;
align-items: center;
min-height: 40px;
padding: 0 14px;
border-radius: 999px;
border: 1px solid rgba(23, 35, 43, 0.16);
background: rgba(250, 248, 242, 0.9);
color: var(--ink);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.01em;
white-space: nowrap;
box-shadow: 0 10px 22px rgba(23, 35, 43, 0.08);
}
button {
height: 40px;
padding: 0 14px;
border-radius: 12px;
border: 1px solid rgba(23, 35, 43, 0.16);
background: linear-gradient(180deg, #234a59, #17333f);
color: #fff;
font: inherit;
font-weight: 700;
cursor: pointer;
box-shadow: 0 10px 22px rgba(23, 35, 43, 0.18);
}
.layout {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
min-height: 0;
position: relative;
}
.pane {
position: relative;
min-width: 0;
border-right: 1px solid var(--line);
}
.pane:last-child {
border-right: none;
}
.map {
position: absolute;
inset: 0;
}
.pane-tag {
position: absolute;
top: 12px;
left: 12px;
z-index: 5;
padding: 10px 12px;
border-radius: 12px;
background: var(--panel);
border: 1px solid rgba(23, 35, 43, 0.08);
box-shadow: 0 12px 24px rgba(23, 35, 43, 0.12);
backdrop-filter: blur(6px);
}
.pane-tag strong {
display: block;
margin-bottom: 3px;
font-size: 13px;
}
.pane-tag span {
display: block;
font-size: 12px;
color: var(--muted);
}
.inspect-panel {
position: fixed;
right: 14px;
bottom: 14px;
z-index: 30;
width: min(380px, calc(100vw - 28px));
max-height: 42vh;
overflow: auto;
padding: 11px 12px;
border-radius: 14px;
background: rgba(250, 248, 242, 0.95);
border: 1px solid rgba(23, 35, 43, 0.12);
box-shadow: var(--shadow);
backdrop-filter: blur(10px);
}
.inspect-panel h3 {
margin: 0 0 6px;
font-size: 13px;
}
.inspect-hint {
margin: 0 0 8px;
color: var(--muted);
font-size: 11px;
line-height: 1.45;
}
.inspect-meta {
display: grid;
grid-template-columns: 96px 1fr;
gap: 4px 8px;
margin-bottom: 8px;
font-size: 11px;
line-height: 1.35;
}
.inspect-meta dt {
color: var(--muted);
font-weight: 700;
}
.inspect-meta dd {
margin: 0;
word-break: break-word;
}
.inspect-json {
margin: 0;
padding: 9px 10px;
border-radius: 10px;
background: rgba(23, 35, 43, 0.93);
color: #eef4f7;
font-size: 11px;
line-height: 1.4;
white-space: pre-wrap;
word-break: break-word;
overflow: auto;
}
.status {
position: fixed;
left: 50%;
bottom: 14px;
transform: translateX(-50%);
z-index: 30;
max-width: calc(100% - 420px);
padding: 8px 12px;
border-radius: 999px;
background: rgba(23, 35, 43, 0.84);
color: #f7f9fb;
font-size: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
body.audit-mode .pane-tag,
body.audit-mode .inspect-panel,
body.audit-mode .status,
body.audit-mode .maplibregl-ctrl-top-right,
body.audit-mode .maplibregl-ctrl-bottom-right,
body.audit-mode .maplibregl-ctrl-bottom-left {
display: none !important;
}
@media (max-width: 980px) {
.layout {
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
}
.pane {
border-right: none;
border-bottom: 1px solid var(--line);
}
.pane:last-child {
border-bottom: none;
}
.inspect-panel {
width: min(360px, calc(100vw - 24px));
max-height: 30vh;
right: 12px;
bottom: 54px;
}
.status {
max-width: calc(100% - 24px);
}
}
</style>
</head>
<body>
<div class="toolbar">
<div>
<div id="page-title" class="title">全国人工审计对比页</div>
<div id="page-subtitle" class="subtitle">左侧固定加载原始 <code>style.json</code> + 原始 newpec 瓦片;右侧固定加载全国 delivery 的 <code>style.navsea-delivery-full.json</code> + 全国 delivery PBF + 当前 sprite。两边联动同步适合直接审 style / pbf / sprite 的整体视觉差异。</div>
</div>
<div class="toolbar-actions">
<div id="html-chip" class="version-chip">HTML: 加载中</div>
<div id="style-chip" class="version-chip">Style: 加载中</div>
<div id="pbf-chip" class="version-chip">PBF: 加载中</div>
<div id="sprite-chip" class="version-chip">Sprite: 加载中</div>
<button id="reload-btn" type="button">重新加载</button>
<button id="home-btn" type="button">回到全国</button>
</div>
</div>
<div class="layout">
<section class="pane">
<div class="pane-tag">
<strong style="color: var(--left);">左侧 · 原始版</strong>
<span>style.json + 原始 newpec 瓦片</span>
</div>
<div id="map-original" class="map"></div>
</section>
<section class="pane">
<div class="pane-tag">
<strong style="color: var(--right);">右侧 · Delivery</strong>
<span id="delivery-pane-label">全国 delivery style + 全国 delivery PBF + 当前 sprite</span>
</div>
<div id="map-delivery" class="map"></div>
</section>
</div>
<aside class="inspect-panel">
<h3>点击对比</h3>
<p id="inspect-hint" class="inspect-hint">点击左右任一地图对象,查看当前命中的 source、source-layer、render layer 和属性。</p>
<dl class="inspect-meta">
<dt>面板</dt>
<dd id="inspect-side">-</dd>
<dt>点击坐标</dt>
<dd id="inspect-lnglat">-</dd>
<dt>source</dt>
<dd id="inspect-source">-</dd>
<dt>source-layer</dt>
<dd id="inspect-layer">-</dd>
<dt>geometry</dt>
<dd id="inspect-geometry">-</dd>
<dt>render layer</dt>
<dd id="inspect-render-layer">-</dd>
</dl>
<pre id="inspect-json" class="inspect-json">{
"message": "等待点击对象"
}</pre>
</aside>
<div id="status" class="status">等待加载对比样式…</div>
<script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
<script>
const HTML_VERSION = "full-audit-r3-20260418-1546";
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 searchParams = new URLSearchParams(window.location.search);
const auditMode = searchParams.get("audit") === "1";
const variantParam = (searchParams.get("variant") || "semantic").trim().toLowerCase();
const deliveryTileUrlOverride = (searchParams.get("deliveryTileUrl") || "").trim();
const PROFILES = {
full: {
label: "全国",
pageTitle: "全国人工审计对比页",
subtitle: "左侧固定加载原始 <code>style.json</code> + 原始 newpec 瓦片;右侧固定加载全国 delivery 版 <code>style.navsea-delivery-full.json</code> + 全国 delivery PBF。两边联动同步适合直接做原始版与全国 delivery 的截图对比审计。",
deliveryPaneLabel: "全国 delivery style + 全国 delivery PBF",
deliveryStyleUrl: "./domain/style.navsea-delivery-full.json",
deliveryTileUrl: "http://192.168.200.184/pbf-delivery-full-20260415/{z}/{x}/{y}.pbf",
deliveryStyleVersion: "full-delivery-style-current",
deliveryPbfVersion: "full-delivery-pbf-20260415",
deliverySpriteVersion: "newpec-sprite-current",
deliveryStyleFile: "style.navsea-delivery-full.json",
deliveryPbfName: "pbf-delivery-full-20260415",
deliverySpriteName: "newpec/sprite/sprite",
initialView: {
center: [136.5, 35.8],
zoom: 4.8,
bearing: 0,
pitch: 0
},
homeLabel: "回到全国"
},
semantic: {
label: "全国",
pageTitle: "全国人工审计对比页",
subtitle: "左侧固定加载原始 <code>style.json</code> + 原始 newpec 瓦片;右侧固定加载全国 delivery 的语义版 <code>style.navsea-delivery-full-semantic.json</code> + 语义版全国 delivery PBF + 语义版 sprite atlas。两边联动同步适合直接做原始版与全国语义版的截图对比审计。",
deliveryPaneLabel: "全国语义版 delivery style + 语义版全国 delivery PBF + 语义版 sprite",
deliveryStyleUrl: "./domain/style.navsea-delivery-full-semantic.json",
deliveryTileUrl: "http://192.168.200.184/pbf-delivery-full-semantic-20260416/{z}/{x}/{y}.pbf",
deliveryStyleVersion: "full-semantic-style-r3-20260416-2210",
deliveryPbfVersion: "full-semantic-pbf-r2-20260416-2248-hazardfix",
deliverySpriteVersion: "full-semantic-sprite-r1-20260416-1628",
deliveryStyleFile: "style.navsea-delivery-full-semantic.json",
deliveryPbfName: "pbf-delivery-full-semantic-20260416",
deliverySpriteName: "newpec/sprite-semantic/sprite",
initialView: {
center: [136.5, 35.8],
zoom: 4.8,
bearing: 0,
pitch: 0
},
homeLabel: "回到全国"
}
};
const PROFILE = PROFILES[variantParam] || PROFILES.semantic;
const reloadBtn = document.getElementById("reload-btn");
const homeBtn = document.getElementById("home-btn");
const pageTitleEl = document.getElementById("page-title");
const pageSubtitleEl = document.getElementById("page-subtitle");
const deliveryPaneLabelEl = document.getElementById("delivery-pane-label");
const htmlChip = document.getElementById("html-chip");
const styleChip = document.getElementById("style-chip");
const pbfChip = document.getElementById("pbf-chip");
const spriteChip = document.getElementById("sprite-chip");
const statusEl = document.getElementById("status");
const inspectHintEl = document.getElementById("inspect-hint");
const inspectSideEl = document.getElementById("inspect-side");
const inspectLngLatEl = document.getElementById("inspect-lnglat");
const inspectSourceEl = document.getElementById("inspect-source");
const inspectLayerEl = document.getElementById("inspect-layer");
const inspectGeometryEl = document.getElementById("inspect-geometry");
const inspectRenderLayerEl = document.getElementById("inspect-render-layer");
const inspectJsonEl = document.getElementById("inspect-json");
let originalMap;
let deliveryMap;
let syncLock = false;
let styleVersion = `${HTML_VERSION}-${Date.now()}`;
htmlChip.textContent = `HTML: ${HTML_VERSION}`;
if (auditMode) document.body.classList.add("audit-mode");
function parseNumberParam(value) {
if (value === null || value === undefined || value === "") return null;
const parsed = Number(value);
return Number.isFinite(parsed) ? parsed : null;
}
function getRequestedCamera() {
const centerValue = searchParams.get("center");
const zoomValue = parseNumberParam(searchParams.get("zoom"));
const bearingValue = parseNumberParam(searchParams.get("bearing"));
const pitchValue = parseNumberParam(searchParams.get("pitch"));
if (!centerValue && zoomValue === null && bearingValue === null && pitchValue === null) {
return {
center: PROFILE.initialView.center,
zoom: PROFILE.initialView.zoom,
bearing: PROFILE.initialView.bearing,
pitch: PROFILE.initialView.pitch
};
}
let center = PROFILE.initialView.center;
if (centerValue) {
const parts = centerValue.split(",").map((item) => Number(item.trim()));
if (parts.length === 2 && parts.every(Number.isFinite)) {
center = [parts[0], parts[1]];
}
}
return {
center,
zoom: zoomValue ?? PROFILE.initialView.zoom,
bearing: bearingValue ?? PROFILE.initialView.bearing,
pitch: pitchValue ?? PROFILE.initialView.pitch
};
}
function applyProfileUi() {
pageTitleEl.textContent = PROFILE.pageTitle;
pageSubtitleEl.innerHTML = PROFILE.subtitle;
deliveryPaneLabelEl.textContent = PROFILE.deliveryPaneLabel;
homeBtn.textContent = PROFILE.homeLabel;
styleChip.textContent = `Style: ${PROFILE.deliveryStyleVersion} (${PROFILE.deliveryStyleFile})`;
if (deliveryTileUrlOverride) {
pbfChip.textContent = `PBF: override (${deliveryTileUrlOverride})`;
} else {
pbfChip.textContent = `PBF: ${PROFILE.deliveryPbfVersion} (${PROFILE.deliveryPbfName})`;
}
spriteChip.textContent = `Sprite: ${PROFILE.deliverySpriteVersion} (${PROFILE.deliverySpriteName})`;
document.title = `NavSea Compare · ${PROFILE.label}`;
}
function setStatus(text) {
statusEl.textContent = text;
}
function withCacheBuster(url, version) {
const separator = url.includes("?") ? "&" : "?";
return `${url}${separator}v=${version}`;
}
async function fetchStyle(url) {
const response = await fetch(withCacheBuster(url, styleVersion), { cache: "no-store" });
if (!response.ok) {
throw new Error(`加载样式失败: ${url}`);
}
return response.json();
}
function touchStyleAssets(style) {
if (style.sprite) style.sprite = withCacheBuster(style.sprite, styleVersion);
if (style.glyphs) style.glyphs = withCacheBuster(style.glyphs, styleVersion);
Object.values(style.sources || {}).forEach((source) => {
if (Array.isArray(source.tiles)) {
source.tiles = source.tiles.map((tileUrl) => withCacheBuster(tileUrl, styleVersion));
}
if (typeof source.url === "string") {
source.url = withCacheBuster(source.url, styleVersion);
}
});
return style;
}
function buildOriginalStyle(style) {
const next = structuredClone(style);
if (next.sources?.newpec) {
next.sources.newpec.tiles = [withCacheBuster(ORIGINAL_TILE_URL, styleVersion)];
}
return touchStyleAssets(next);
}
function buildDeliveryStyle(style) {
const next = structuredClone(style);
if (next.sources?.navsea_delivery) {
const tileUrl = deliveryTileUrlOverride || PROFILE.deliveryTileUrl;
next.sources.navsea_delivery.tiles = [withCacheBuster(tileUrl, styleVersion)];
}
return touchStyleAssets(next);
}
function resetInspectPanel(message) {
inspectHintEl.textContent = message;
inspectSideEl.textContent = "-";
inspectLngLatEl.textContent = "-";
inspectSourceEl.textContent = "-";
inspectLayerEl.textContent = "-";
inspectGeometryEl.textContent = "-";
inspectRenderLayerEl.textContent = "-";
inspectJsonEl.textContent = JSON.stringify({ message }, null, 2);
}
function formatLngLat(lngLat) {
return `${lngLat.lng.toFixed(6)}, ${lngLat.lat.toFixed(6)}`;
}
function updateInspectPanel(side, event, feature) {
inspectHintEl.textContent = "已选中对象。继续点击可对照两侧差异。";
inspectSideEl.textContent = side;
inspectLngLatEl.textContent = formatLngLat(event.lngLat);
inspectSourceEl.textContent = feature.source || "-";
inspectLayerEl.textContent = feature.sourceLayer || feature.layer?.["source-layer"] || "-";
inspectGeometryEl.textContent = feature.geometry?.type || "-";
inspectRenderLayerEl.textContent = feature.layer?.id || "-";
inspectJsonEl.textContent = JSON.stringify(feature.properties || {}, null, 2);
}
function bindInspect(map, sideLabel) {
map.on("click", (event) => {
const features = map.queryRenderedFeatures(event.point);
if (!features.length) {
resetInspectPanel(`${sideLabel}点击位置没有命中对象。点击坐标: ${formatLngLat(event.lngLat)}`);
return;
}
updateInspectPanel(sideLabel, event, features[0]);
});
}
function syncMaps(primary, secondary) {
primary.on("move", () => {
if (syncLock) return;
syncLock = true;
secondary.jumpTo({
center: primary.getCenter(),
zoom: primary.getZoom(),
bearing: primary.getBearing(),
pitch: primary.getPitch()
});
syncLock = false;
});
}
async function loadMaps() {
const requestedCamera = getRequestedCamera();
styleVersion = `${HTML_VERSION}-${Date.now()}`;
reloadBtn.disabled = true;
homeBtn.disabled = true;
setStatus(`正在加载全国原始版和 delivery 版样式… HTML ${HTML_VERSION}`);
try {
const [originalStyleRaw, deliveryStyleRaw] = await Promise.all([
fetchStyle(ORIGINAL_STYLE_URL),
fetchStyle(PROFILE.deliveryStyleUrl)
]);
const originalStyle = buildOriginalStyle(originalStyleRaw);
const deliveryStyle = buildDeliveryStyle(deliveryStyleRaw);
if (!originalMap && !deliveryMap) {
originalMap = new maplibregl.Map({
container: "map-original",
style: originalStyle,
center: requestedCamera.center,
zoom: requestedCamera.zoom,
bearing: requestedCamera.bearing,
pitch: requestedCamera.pitch
});
deliveryMap = new maplibregl.Map({
container: "map-delivery",
style: deliveryStyle,
center: requestedCamera.center,
zoom: requestedCamera.zoom,
bearing: requestedCamera.bearing,
pitch: requestedCamera.pitch
});
originalMap.addControl(new maplibregl.NavigationControl(), "top-right");
deliveryMap.addControl(new maplibregl.NavigationControl(), "top-right");
bindInspect(originalMap, "左侧原始版");
bindInspect(deliveryMap, "右侧Delivery");
syncMaps(originalMap, deliveryMap);
syncMaps(deliveryMap, originalMap);
let loaded = 0;
function markLoaded() {
loaded += 1;
if (loaded >= 2) {
setStatus(`全国双屏已加载可直接拖动、缩放、点击对比。HTML ${HTML_VERSION}`);
}
}
originalMap.on("load", markLoaded);
deliveryMap.on("load", markLoaded);
} else {
const camera = requestedCamera;
let loaded = 0;
function markLoaded() {
loaded += 1;
if (loaded >= 2) {
originalMap.jumpTo(camera);
deliveryMap.jumpTo(camera);
setStatus(`全国双屏样式已重新加载。HTML ${HTML_VERSION}`);
}
}
originalMap.once("style.load", markLoaded);
deliveryMap.once("style.load", markLoaded);
originalMap.setStyle(originalStyle, { diff: false });
deliveryMap.setStyle(deliveryStyle, { diff: false });
}
} catch (error) {
console.error(error);
setStatus(error.message || "加载失败");
} finally {
reloadBtn.disabled = false;
homeBtn.disabled = false;
}
}
reloadBtn.addEventListener("click", loadMaps);
homeBtn.addEventListener("click", () => {
if (!originalMap || !deliveryMap) return;
const camera = {
center: PROFILE.initialView.center,
zoom: PROFILE.initialView.zoom,
bearing: PROFILE.initialView.bearing,
pitch: PROFILE.initialView.pitch
};
window.history.replaceState({}, "", window.location.pathname);
originalMap.jumpTo(camera);
deliveryMap.jumpTo(camera);
setStatus("已回到全国初始视角。");
});
applyProfileUi();
resetInspectPanel("点击左右任一地图对象,查看当前命中的 source、source-layer、render layer 和属性。");
loadMaps();
</script>
</body>
</html>

View File

@@ -0,0 +1,101 @@
{
"fill-daytime-175": "fill_x",
"fill-daytime-420": "fill_nasi",
"fill-daytime-427": "fill_net_red",
"fill-daytime-428": "pattern_fill_obstruction_or_fish_reef",
"fill-daytime-745": "fill_mark_r",
"fill-daytime-746": "fill_mark_y",
"fill-daytime-747": "fill_mark",
"fill-daytime-750": "fill_point",
"fill-daytime-753": "fill_y",
"fill-daytime-754": "pattern_fill_facility_area",
"fill-daytime-755": "fill_a",
"fill-daytime-900": "fill_box",
"fill-daytime-910": "pattern_fill_fishery_or_fish_reef_area",
"light-daytime-1": "light_flare_green",
"light-daytime-2": "light_flare_red",
"light-daytime-3": "light_flare_yellow_white",
"line-daytime-712": "line_a",
"line-daytime-721": "line_b",
"line-daytime-730": "line_c",
"line-daytime-748": "line_d",
"line-daytime-754": "special_pattern_line_754",
"symbol-daytime-300": "coastal_lighthouse",
"symbol-daytime-301": "harbor_lighthouse",
"symbol-daytime-302": "breakwater_lighthouse",
"symbol-daytime-303": "light_minor",
"symbol-daytime-30500001": "leading_light_variantt_30500001",
"symbol-daytime-30500002": "leading_light_variantt_30500002",
"symbol-daytime-30500003": "leading_light_variantt_30500003",
"symbol-daytime-30700001": "light_up_green",
"symbol-daytime-30700002": "light_up_red",
"symbol-daytime-30700003": "leading_mark_variantt_30700003",
"symbol-daytime-308": "leading_mark_variantt_308",
"symbol-daytime-310": "light_beacon",
"symbol-daytime-311350": "port_hand_mark_topmark",
"symbol-daytime-311351": "starboard_hand_mark_topmark",
"symbol-daytime-311354": "light_beacon_north_cardinal_variantt",
"symbol-daytime-311355": "light_beacon_east_cardinal_variantt",
"symbol-daytime-311356": "light_beacon_north_cardinal_variantt_311356",
"symbol-daytime-311357": "light_beacon_south_cardinal_variantt",
"symbol-daytime-311358": "light_beacon_west_cardinal_variantt_311358",
"symbol-daytime-311359": "light_beacon_isolated_danger_variantt_311359",
"symbol-daytime-311360": "light_beacon_safe_water_variantt_311360",
"symbol-daytime-312350": "buoy_port_lateral_variantt_312350",
"symbol-daytime-312351": "buoy_starboard_lateral_variantt_312351",
"symbol-daytime-312354": "buoy_north_cardinal",
"symbol-daytime-312355": "buoy_east_cardinal",
"symbol-daytime-312356": "buoy_west_cardinal",
"symbol-daytime-312357": "buoy_south_cardinal",
"symbol-daytime-312358": "buoy_isolated_danger",
"symbol-daytime-312359": "buoy_safe_water",
"symbol-daytime-312360": "buoy_special_mark",
"symbol-daytime-313362": "mooring_buoy",
"symbol-daytime-314362": "safe_water_mark",
"symbol-daytime-316": "mark_box_box",
"symbol-daytime-317": "mark_with_topmark",
"symbol-daytime-320": "buoy_light",
"symbol-daytime-321": "buoy_generic",
"symbol-daytime-323": "buoy_pillar",
"symbol-daytime-324350": "port_hand_mark",
"symbol-daytime-324351": "starboard_hand_mark",
"symbol-daytime-324360": "special_mark",
"symbol-daytime-325": "buoy_can",
"symbol-daytime-327": "buoy_lattice",
"symbol-daytime-335359": "nav_mark_vais",
"symbol-daytime-401": "rock_exposed_drying_awash_group",
"symbol-daytime-404": "sunken_rock",
"symbol-daytime-405": "cleared_danger_object",
"symbol-daytime-407": "coral_red",
"symbol-daytime-408": "coral_black",
"symbol-daytime-409": "isolated_danger",
"symbol-daytime-410": "wreck_hull_exposed",
"symbol-daytime-412": "wreck_fully_submerged_dangerous",
"symbol-daytime-413": "wreck_surveyed",
"symbol-daytime-414": "unknown_tu_b",
"symbol-daytime-420": "foul_ground",
"symbol-daytime-421": "sand_wave",
"symbol-daytime-422": "tide_rips_overfalls",
"symbol-daytime-424": "eddy_whirlpool",
"symbol-daytime-425": "seaweed",
"symbol-daytime-426": "unknown_t_object",
"symbol-daytime-427": "obstruction",
"symbol-daytime-428": "fish_reef",
"symbol-daytime-429": "fish_reef_dangerous",
"symbol-daytime-430": "fill_box_point",
"symbol-daytime-431": "tower_yagura_observation_platform",
"symbol-daytime-432": "bollard_pile_stake",
"symbol-daytime-433": "dolphin_structure",
"symbol-daytime-434": "subsea_installation_outfall_intake",
"symbol-daytime-498": "fill_box_black",
"symbol-daytime-500": "pilot_station",
"symbol-daytime-505": "port_general_small_harbor_group",
"symbol-daytime-520": "fishing_port",
"symbol-daytime-530": "marina",
"symbol-daytime-540": "fisherina",
"symbol-daytime-550": "sea_station_umi_no_eki",
"symbol-daytime-719": "anchorage_quarantine",
"symbol-daytime-720": "anchorage_designated",
"symbol-daytime-721": "restriction_area_group",
"symbol-daytime-724": "anchoring_prohibited"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
[
{
"id": "hakata_10nm",
"label": "博多港中心 10 海里",
"center": [130.335, 33.6385],
"radius_nm": 10,
"zoom_levels": [10, 12]
},
{
"id": "tokyo_bay_10nm",
"label": "东京湾 10 海里",
"center": [139.85, 35.42],
"radius_nm": 10,
"zoom_levels": [10, 12]
},
{
"id": "osaka_bay_10nm",
"label": "大阪 10 海里",
"center": [135.35, 34.61],
"radius_nm": 10,
"zoom_levels": [10, 12]
},
{
"id": "okinawa_10nm",
"label": "冲绳 10 海里",
"center": [127.67, 26.21],
"radius_nm": 10,
"zoom_levels": [10, 12]
},
{
"id": "karatsu_5nm",
"label": "唐津 5 海里",
"center": [129.9697, 33.4425],
"radius_nm": 5,
"zoom_levels": [10, 12]
}
]

View File

@@ -0,0 +1,477 @@
old_sprite_key,used_in_newpec_style,used_in_pbf,usage_note,manual_label_ja,new_sprite_key,basis,source_page
symbol-daytime-428,2,3322,style_and_pbf,魚礁,fish_reef [manual],manual,guide115_08
symbol-daytime-301,11,2830,style_and_pbf,港湾灯台,harbor_lighthouse,manual,guide115_02
symbol-daytime-303,9,1581,style_and_pbf,,light_minor,,
symbol-daytime-405,2,1286,style_and_pbf,掃海済みの危険物,cleared_danger_object [manual],manual,guide115_07_20260120
symbol-daytime-310,18,927,style_and_pbf,,light_beacon,,
fill-daytime-428,2,899,style_and_pbf,,pattern_fill_obstruction_or_fish_reef,,
symbol-daytime-320,12,810,style_and_pbf,,buoy_light,,
symbol-daytime-327,18,573,style_and_pbf,,buoy_lattice,,
symbol-daytime-429,2,554,style_and_pbf,魚礁(危険なもの),fish_reef_dangerous [manual],manual,guide115_08
fill-daytime-754,1,446,style_and_pbf,,pattern_fill_facility_area,,
symbol-daytime-30500003,7,328,style_and_pbf,,leading_light_variant_30500003,,
symbol-daytime-413,4,319,style_and_pbf,測定済みの沈船,wreck_surveyed [manual],manual,guide115_08
symbol-daytime-321,5,311,style_and_pbf,,buoy_generic,,
symbol-daytime-323,8,238,style_and_pbf,,buoy_pillar,,
symbol-daytime-719,1,150,style_and_pbf,検疫錨地,anchorage_quarantine [manual],manual,guide115_01
symbol-daytime-412,2,111,style_and_pbf,危険全沈没船,wreck_fully_submerged_dangerous [manual],manual,guide115_08
symbol-daytime-308,1,110,style_and_pbf,,leading_mark_variant_308,,
symbol-daytime-30700003,4,87,style_and_pbf,,leading_mark_variant_30700003,,
symbol-daytime-325,7,76,style_and_pbf,,buoy_can,,
symbol-daytime-30500001,1,50,style_and_pbf,,leading_light_variant_30500001,,
symbol-daytime-30500002,2,42,style_and_pbf,,leading_light_variant_30500002,,
symbol-daytime-335359,2,40,style_and_pbf,,nav_mark_vais,,
symbol-daytime-410,4,34,style_and_pbf,船体露出沈船,wreck_hull_exposed,manual,guide115_08
symbol-daytime-300,13,0,style_only,沿岸灯台,coastal_lighthouse,manual,guide115_02
fill-daytime-421,12,0,style_only,,,,
symbol-daytime-302,11,0,style_only,防波堤灯台,breakwater_lighthouse,manual,guide115_02
symbol-daytime-314,8,0,style_only,,,,
symbol-daytime-401,6,0,style_only,水上岩・干出岩・洗岩(共通),rock_exposed_drying_awash_group [manual],manual,guide115_07_20260120
fill-daytime-407,4,0,style_only,,,,
symbol-daytime-333,4,0,style_only,,,,
fill-daytime-401,3,0,style_only,,,,
fill-daytime-756,3,0,style_only,,,,
symbol-daytime-312356,3,0,style_only,西方位浮標,buoy_west_cardinal [manual],manual,guide115_04
symbol-daytime-312357,3,0,style_only,南方位浮標,buoy_south_cardinal [manual],manual,guide115_04
symbol-daytime-312360,3,0,style_only,特殊標識浮標,buoy_special_mark [manual],manual,guide115_04
symbol-daytime-313362,3,0,style_only,係船浮標,mooring_buoy [manual],manual,guide115_04
symbol-daytime-314362,3,0,style_only,,,,
symbol-daytime-317,3,0,style_only,,,,
symbol-daytime-721,3,0,style_only,制限区域・航路横断等禁止区域・航泊禁止区域(共通),restriction_area_group [manual],manual,guide115_02
fill-daytime-420,2,0,style_only,,,,
fill-daytime-427,2,0,style_only,,,,
fill-daytime-429,2,0,style_only,,,,
line-daytime-710,2,0,style_only,,,,
line-daytime-713,2,0,style_only,,,,
symbol-daytime-311354,2,0,style_only,左舷標識灯標(推定),light_beacon_port_lateral_variant_311354 [manual?],manual?,guide115_03
symbol-daytime-311355,2,0,style_only,右舷標識灯標(推定),light_beacon_starboard_lateral_variant_311355 [manual?],manual?,guide115_03
symbol-daytime-311357,2,0,style_only,東方位標識灯標(推定),light_beacon_east_cardinal_variant_311357 [manual?],manual?,guide115_03
symbol-daytime-311358,2,0,style_only,西方位標識灯標(推定),light_beacon_west_cardinal_variant_311358 [manual?],manual?,guide115_03
symbol-daytime-311359,2,0,style_only,孤立障害標識灯標(推定),light_beacon_isolated_danger_variant_311359 [manual?],manual?,guide115_03
symbol-daytime-311360,2,0,style_only,安全水域標識灯標(推定),light_beacon_safe_water_variant_311360 [manual?],manual?,guide115_03
symbol-daytime-312350,2,0,style_only,左舷浮標(推定),buoy_port_lateral_variant_312350 [manual?],manual?,guide115_04
symbol-daytime-312354,2,0,style_only,北方位浮標,buoy_north_cardinal [manual],manual,guide115_04
symbol-daytime-312358,2,0,style_only,孤立障害浮標,buoy_isolated_danger [manual],manual,guide115_04
symbol-daytime-316,2,0,style_only,,,,
symbol-daytime-324360,2,0,style_only,,,,
symbol-daytime-404,2,0,style_only,暗岩,sunken_rock [manual],manual,guide115_07_20260120
symbol-daytime-406,2,0,style_only,,,,
symbol-daytime-407,2,0,style_only,,,,
symbol-daytime-408,2,0,style_only,,,,
symbol-daytime-409,2,0,style_only,孤立危険物,isolated_danger [manual],manual,guide115_08
symbol-daytime-414,2,0,style_only,,,,
symbol-daytime-420,2,0,style_only,険悪物,foul_ground [manual],manual,guide115_08
symbol-daytime-421,2,0,style_only,サンドウェーブ,sand_wave [manual],manual,guide115_08
symbol-daytime-422,2,0,style_only,急潮・波紋・激潮,tide_rips_overfalls [manual],manual,guide115_08
symbol-daytime-424,2,0,style_only,渦流,eddy_whirlpool [manual],manual,guide115_08
symbol-daytime-425,2,0,style_only,海草,seaweed [manual],manual,guide115_08
symbol-daytime-426,2,0,style_only,,,,
symbol-daytime-427,2,0,style_only,障害物,obstruction [manual],manual,guide115_08
symbol-daytime-430,2,0,style_only,,,,
symbol-daytime-431,2,0,style_only,塔、やぐら、測台,tower_yagura_observation_platform [manual],manual,guide115_08
symbol-daytime-432,2,0,style_only,ボッシーン、パイル、杭,bollard_pile_stake [manual],manual,guide115_08
symbol-daytime-433,2,0,style_only,ドルフィン,dolphin_structure [manual],manual,guide115_08
symbol-daytime-434,2,0,style_only,海底設置物、放水口、取水口,subsea_installation_outfall_intake [manual],manual,guide115_08
symbol-daytime-498,2,0,style_only,,,,
symbol-daytime-505,2,0,style_only,一般港湾・小港湾(共通),port_general_small_harbor_group [manual],manual,guide115_01
arrow-daytime-0,1,0,style_only,,,,
arrow-daytime-1,1,0,style_only,,,,
arrow-daytime-2,1,0,style_only,,,,
arrow-daytime-3,1,0,style_only,,,,
arrow-daytime-4,1,0,style_only,,,,
fill-daytime-175,1,0,style_only,,,,
fill-daytime-745,1,0,style_only,,,,
fill-daytime-746,1,0,style_only,,,,
fill-daytime-747,1,0,style_only,,,,
fill-daytime-750,1,0,style_only,,,,
fill-daytime-753,1,0,style_only,,,,
fill-daytime-755,1,0,style_only,,,,
fill-daytime-900,1,0,style_only,,,,
fill-daytime-910,1,0,style_only,漁業区・魚礁エリア塗り,pattern_fill_fishery_or_fish_reef_area [style],style,style.navsea-delivery-full.json
light-daytime-1,1,0,style_only,灯光(緑),light_flare_green [manual],manual,guide115_02
light-daytime-2,1,0,style_only,灯光(赤),light_flare_red [manual],manual,guide115_02
light-daytime-3,1,0,style_only,灯光(黄・白),light_flare_yellow_white [manual],manual,guide115_02
line-daytime-712,1,0,style_only,,,,
line-daytime-721,1,0,style_only,,,,
line-daytime-730,1,0,style_only,,,,
line-daytime-748,1,0,style_only,,,,
line-daytime-754,1,0,style_only,特殊パターン線 754,special_pattern_line_754 [style],style,style.navsea-delivery-full.json
symbol-daytime-30700001,1,0,style_only,,,,
symbol-daytime-30700002,1,0,style_only,,,,
symbol-daytime-311350,1,0,style_only,,,,
symbol-daytime-311351,1,0,style_only,,,,
symbol-daytime-311356,1,0,style_only,北方位標識灯標(推定),light_beacon_north_cardinal_variant_311356 [manual?],manual?,guide115_03
symbol-daytime-312351,1,0,style_only,右舷浮標(推定),buoy_starboard_lateral_variant_312351 [manual?],manual?,guide115_04
symbol-daytime-312355,1,0,style_only,東方位浮標,buoy_east_cardinal [manual],manual,guide115_04
symbol-daytime-312359,1,0,style_only,安全水域浮標,buoy_safe_water [manual],manual,guide115_04
symbol-daytime-324350,1,0,style_only,,,,
symbol-daytime-324351,1,0,style_only,,,,
symbol-daytime-335350,1,0,style_only,,,,
symbol-daytime-335351,1,0,style_only,,,,
symbol-daytime-500,1,0,style_only,パイロットステーション,pilot_station [manual],manual,guide115_01
symbol-daytime-520,1,0,style_only,漁港,fishing_port [manual],manual,guide115_01
symbol-daytime-530,1,0,style_only,マリーナ,marina [manual],manual,guide115_01
symbol-daytime-540,1,0,style_only,フィッシャリーナ,fisherina [manual],manual,guide115_01
symbol-daytime-550,1,0,style_only,海の駅,sea_station_umi_no_eki [manual],manual,guide115_01
symbol-daytime-720,1,0,style_only,錨泊(指定)地,anchorage_designated [manual],manual,guide115_01
symbol-daytime-724,1,0,style_only,錨泊禁止区域,anchoring_prohibited [manual],manual,guide115_02
symbol-daytime-759,1,0,style_only,,,,
symbol-daytime-760,1,0,style_only,,,,
symbol-daytime-761,1,0,style_only,,,,
tidespot-daytime,1,0,style_only,,,,
arc-daytime-0105306901192310,0,0,unused_in_current_full,,,,
arc-daytime-01180035,0,0,unused_in_current_full,,,,
arc-daytime-01293219,0,0,unused_in_current_full,,,,
arc-daytime-0200103104031001,0,0,unused_in_current_full,,,,
arc-daytime-02002252,0,0,unused_in_current_full,,,,
arc-daytime-0201102104021011,0,0,unused_in_current_full,,,,
arc-daytime-02048301,0,0,unused_in_current_full,,,,
arc-daytime-0206408002180297,0,0,unused_in_current_full,,,,
arc-daytime-02113325,0,0,unused_in_current_full,,,,
arc-daytime-0222231004310222,0,0,unused_in_current_full,,,,
arc-daytime-0223726704267237,0,0,unused_in_current_full,,,,
arc-daytime-0225529904299089,0,0,unused_in_current_full,,,,
arc-daytime-02257145,0,0,unused_in_current_full,,,,
arc-daytime-02300210,0,0,unused_in_current_full,,,,
arc-daytime-02317310,0,0,unused_in_current_full,,,,
arc-daytime-04002244,0,0,unused_in_current_full,,,,
arc-daytime-04004246,0,0,unused_in_current_full,,,,
arc-daytime-04006315,0,0,unused_in_current_full,,,,
arc-daytime-04007277,0,0,unused_in_current_full,,,,
arc-daytime-04008243,0,0,unused_in_current_full,,,,
arc-daytime-04010293,0,0,unused_in_current_full,,,,
arc-daytime-04014213,0,0,unused_in_current_full,,,,
arc-daytime-04016181,0,0,unused_in_current_full,,,,
arc-daytime-04016291,0,0,unused_in_current_full,,,,
arc-daytime-04018198,0,0,unused_in_current_full,,,,
arc-daytime-04018258,0,0,unused_in_current_full,,,,
arc-daytime-04020236,0,0,unused_in_current_full,,,,
arc-daytime-04020243,0,0,unused_in_current_full,,,,
arc-daytime-04021213,0,0,unused_in_current_full,,,,
arc-daytime-04021253,0,0,unused_in_current_full,,,,
arc-daytime-04022202,0,0,unused_in_current_full,,,,
arc-daytime-04022307,0,0,unused_in_current_full,,,,
arc-daytime-04024258,0,0,unused_in_current_full,,,,
arc-daytime-04025273,0,0,unused_in_current_full,,,,
arc-daytime-04027289,0,0,unused_in_current_full,灯弧(黄・白系),,,
arc-daytime-04028287,0,0,unused_in_current_full,,,,
arc-daytime-04029268,0,0,unused_in_current_full,,,,
arc-daytime-04029280,0,0,unused_in_current_full,,,,
arc-daytime-04030275,0,0,unused_in_current_full,,,,
arc-daytime-04031330,0,0,unused_in_current_full,,,,
arc-daytime-04033249,0,0,unused_in_current_full,,,,
arc-daytime-04035209,0,0,unused_in_current_full,,,,
arc-daytime-04035221042430270202703502221243,0,0,unused_in_current_full,,,,
arc-daytime-04035283,0,0,unused_in_current_full,,,,
arc-daytime-04036216,0,0,unused_in_current_full,,,,
arc-daytime-04040253,0,0,unused_in_current_full,,,,
arc-daytime-04043223,0,0,unused_in_current_full,,,,
arc-daytime-04045135,0,0,unused_in_current_full,,,,
arc-daytime-04048213,0,0,unused_in_current_full,,,,
arc-daytime-04051314,0,0,unused_in_current_full,,,,
arc-daytime-040522800208109201052073,0,0,unused_in_current_full,,,,
arc-daytime-04052305,0,0,unused_in_current_full,,,,
arc-daytime-04053279,0,0,unused_in_current_full,,,,
arc-daytime-04054226,0,0,unused_in_current_full,,,,
arc-daytime-04057308,0,0,unused_in_current_full,,,,
arc-daytime-04060257,0,0,unused_in_current_full,,,,
arc-daytime-04060319,0,0,unused_in_current_full,,,,
arc-daytime-0406126602079097,0,0,unused_in_current_full,,,,
arc-daytime-04063251042640410204106302251264,0,0,unused_in_current_full,,,,
arc-daytime-04068298,0,0,unused_in_current_full,,,,
arc-daytime-04070270,0,0,unused_in_current_full,,,,
arc-daytime-04070314,0,0,unused_in_current_full,,,,
arc-daytime-04070336,0,0,unused_in_current_full,,,,
arc-daytime-04073309,0,0,unused_in_current_full,,,,
arc-daytime-04077286,0,0,unused_in_current_full,,,,
arc-daytime-04079310,0,0,unused_in_current_full,,,,
arc-daytime-04079335,0,0,unused_in_current_full,,,,
arc-daytime-04081293,0,0,unused_in_current_full,,,,
arc-daytime-04082332,0,0,unused_in_current_full,,,,
arc-daytime-0408402102021084,0,0,unused_in_current_full,,,,
arc-daytime-0408626602266086,0,0,unused_in_current_full,,,,
arc-daytime-04091357,0,0,unused_in_current_full,,,,
arc-daytime-04092292,0,0,unused_in_current_full,,,,
arc-daytime-04093033,0,0,unused_in_current_full,,,,
arc-daytime-04093340,0,0,unused_in_current_full,,,,
arc-daytime-04094000,0,0,unused_in_current_full,,,,
arc-daytime-040951040203509502104170,0,0,unused_in_current_full,,,,
arc-daytime-04095312,0,0,unused_in_current_full,,,,
arc-daytime-04097050,0,0,unused_in_current_full,,,,
arc-daytime-04097335,0,0,unused_in_current_full,,,,
arc-daytime-04098000,0,0,unused_in_current_full,,,,
arc-daytime-04099318,0,0,unused_in_current_full,,,,
arc-daytime-04102142,0,0,unused_in_current_full,,,,
arc-daytime-04102355,0,0,unused_in_current_full,,,,
arc-daytime-04104012,0,0,unused_in_current_full,,,,
arc-daytime-04105013,0,0,unused_in_current_full,,,,
arc-daytime-04105020,0,0,unused_in_current_full,,,,
arc-daytime-0410533902339015,0,0,unused_in_current_full,,,,
arc-daytime-04106344,0,0,unused_in_current_full,,,,
arc-daytime-04107043,0,0,unused_in_current_full,,,,
arc-daytime-04108347,0,0,unused_in_current_full,,,,
arc-daytime-04109033,0,0,unused_in_current_full,,,,
arc-daytime-04109316,0,0,unused_in_current_full,,,,
arc-daytime-04115052,0,0,unused_in_current_full,,,,
arc-daytime-04116064,0,0,unused_in_current_full,,,,
arc-daytime-0411609202092116,0,0,unused_in_current_full,,,,
arc-daytime-04118329,0,0,unused_in_current_full,,,,
arc-daytime-041201250413031202125130,0,0,unused_in_current_full,,,,
arc-daytime-04121318,0,0,unused_in_current_full,,,,
arc-daytime-04124324,0,0,unused_in_current_full,,,,
arc-daytime-04125351,0,0,unused_in_current_full,,,,
arc-daytime-04132318,0,0,unused_in_current_full,,,,
arc-daytime-04133030,0,0,unused_in_current_full,,,,
arc-daytime-04135320,0,0,unused_in_current_full,,,,
arc-daytime-04138018,0,0,unused_in_current_full,,,,
arc-daytime-0413935602106139,0,0,unused_in_current_full,,,,
arc-daytime-04140012,0,0,unused_in_current_full,,,,
arc-daytime-04140341,0,0,unused_in_current_full,,,,
arc-daytime-04152017,0,0,unused_in_current_full,,,,
arc-daytime-04155005,0,0,unused_in_current_full,,,,
arc-daytime-04156008,0,0,unused_in_current_full,,,,
arc-daytime-04156335,0,0,unused_in_current_full,,,,
arc-daytime-04159010,0,0,unused_in_current_full,,,,
arc-daytime-04160006,0,0,unused_in_current_full,,,,
arc-daytime-04160329,0,0,unused_in_current_full,,,,
arc-daytime-04162032,0,0,unused_in_current_full,,,,
arc-daytime-04166358,0,0,unused_in_current_full,,,,
arc-daytime-04168018,0,0,unused_in_current_full,,,,
arc-daytime-04169065,0,0,unused_in_current_full,,,,
arc-daytime-041702050421505102205215,0,0,unused_in_current_full,,,,
arc-daytime-04172080,0,0,unused_in_current_full,,,,
arc-daytime-04173082,0,0,unused_in_current_full,,,,
arc-daytime-04175017,0,0,unused_in_current_full,,,,
arc-daytime-04177071,0,0,unused_in_current_full,,,,
arc-daytime-04178066,0,0,unused_in_current_full,,,,
arc-daytime-04180008,0,0,unused_in_current_full,,,,
arc-daytime-04180060,0,0,unused_in_current_full,,,,
arc-daytime-04180062,0,0,unused_in_current_full,,,,
arc-daytime-0418112902129181,0,0,unused_in_current_full,,,,
arc-daytime-04182090,0,0,unused_in_current_full,,,,
arc-daytime-04185055,0,0,unused_in_current_full,,,,
arc-daytime-04185095,0,0,unused_in_current_full,,,,
arc-daytime-04187142,0,0,unused_in_current_full,,,,
arc-daytime-04190057,0,0,unused_in_current_full,,,,
arc-daytime-04190085,0,0,unused_in_current_full,,,,
arc-daytime-04194029,0,0,unused_in_current_full,,,,
arc-daytime-04195021,0,0,unused_in_current_full,,,,
arc-daytime-04197017,0,0,unused_in_current_full,,,,
arc-daytime-04198097,0,0,unused_in_current_full,,,,
arc-daytime-04198358,0,0,unused_in_current_full,,,,
arc-daytime-04199019,0,0,unused_in_current_full,,,,
arc-daytime-0419907902043079,0,0,unused_in_current_full,,,,
arc-daytime-04199343,0,0,unused_in_current_full,,,,
arc-daytime-04201091,0,0,unused_in_current_full,,,,
arc-daytime-04203099,0,0,unused_in_current_full,,,,
arc-daytime-04204043,0,0,unused_in_current_full,,,,
arc-daytime-04204099,0,0,unused_in_current_full,,,,
arc-daytime-04205045,0,0,unused_in_current_full,,,,
arc-daytime-04205097,0,0,unused_in_current_full,,,,
arc-daytime-04207038,0,0,unused_in_current_full,,,,
arc-daytime-0420704802048070,0,0,unused_in_current_full,,,,
arc-daytime-04209116,0,0,unused_in_current_full,,,,
arc-daytime-04210091,0,0,unused_in_current_full,,,,
arc-daytime-04213013,0,0,unused_in_current_full,,,,
arc-daytime-04215162,0,0,unused_in_current_full,,,,
arc-daytime-04216098,0,0,unused_in_current_full,,,,
arc-daytime-04217119,0,0,unused_in_current_full,,,,
arc-daytime-04221052,0,0,unused_in_current_full,,,,
arc-daytime-04221104,0,0,unused_in_current_full,,,,
arc-daytime-04222055,0,0,unused_in_current_full,,,,
arc-daytime-04222063,0,0,unused_in_current_full,,,,
arc-daytime-04223137,0,0,unused_in_current_full,,,,
arc-daytime-04229073,0,0,unused_in_current_full,,,,
arc-daytime-04230050,0,0,unused_in_current_full,,,,
arc-daytime-04230076,0,0,unused_in_current_full,,,,
arc-daytime-042310350405610002035056,0,0,unused_in_current_full,,,,
arc-daytime-0423116704125167,0,0,unused_in_current_full,,,,
arc-daytime-04232050,0,0,unused_in_current_full,,,,
arc-daytime-0423222602226232,0,0,unused_in_current_full,,,,
arc-daytime-04233110,0,0,unused_in_current_full,,,,
arc-daytime-042352850429530504320170,0,0,unused_in_current_full,,,,
arc-daytime-04237100,0,0,unused_in_current_full,,,,
arc-daytime-04240170,0,0,unused_in_current_full,,,,
arc-daytime-0424122702227241,0,0,unused_in_current_full,,,,
arc-daytime-04242150,0,0,unused_in_current_full,,,,
arc-daytime-04245092,0,0,unused_in_current_full,,,,
arc-daytime-0424628604296140,0,0,unused_in_current_full,,,,
arc-daytime-04251115,0,0,unused_in_current_full,,,,
arc-daytime-0425408002080101,0,0,unused_in_current_full,,,,
arc-daytime-04254169,0,0,unused_in_current_full,,,,
arc-daytime-04255075,0,0,unused_in_current_full,,,,
arc-daytime-04257132,0,0,unused_in_current_full,,,,
arc-daytime-04257134,0,0,unused_in_current_full,,,,
arc-daytime-042572820429532304010148022172570228229502323010,0,0,unused_in_current_full,,,,
arc-daytime-04259113,0,0,unused_in_current_full,,,,
arc-daytime-04261114,0,0,unused_in_current_full,,,,
arc-daytime-04263083,0,0,unused_in_current_full,,,,
arc-daytime-04265214,0,0,unused_in_current_full,,,,
arc-daytime-0426524202242265,0,0,unused_in_current_full,,,,
arc-daytime-04266162,0,0,unused_in_current_full,,,,
arc-daytime-04269146,0,0,unused_in_current_full,,,,
arc-daytime-04270080,0,0,unused_in_current_full,,,,
arc-daytime-0427021502215270,0,0,unused_in_current_full,,,,
arc-daytime-04271113,0,0,unused_in_current_full,,,,
arc-daytime-04271115,0,0,unused_in_current_full,,,,
arc-daytime-04272211,0,0,unused_in_current_full,,,,
arc-daytime-0427410502250274,0,0,unused_in_current_full,,,,
arc-daytime-04274157,0,0,unused_in_current_full,,,,
arc-daytime-04275131,0,0,unused_in_current_full,,,,
arc-daytime-04278130,0,0,unused_in_current_full,,,,
arc-daytime-04279098,0,0,unused_in_current_full,,,,
arc-daytime-04285147,0,0,unused_in_current_full,,,,
arc-daytime-042900770207709004090189,0,0,unused_in_current_full,,,,
arc-daytime-04295180,0,0,unused_in_current_full,,,,
arc-daytime-04297154,0,0,unused_in_current_full,,,,
arc-daytime-04297190,0,0,unused_in_current_full,,,,
arc-daytime-04297254,0,0,unused_in_current_full,,,,
arc-daytime-04300156,0,0,unused_in_current_full,,,,
arc-daytime-04301172,0,0,unused_in_current_full,,,,
arc-daytime-04301175,0,0,unused_in_current_full,,,,
arc-daytime-04306184,0,0,unused_in_current_full,,,,
arc-daytime-04307120,0,0,unused_in_current_full,,,,
arc-daytime-04311219,0,0,unused_in_current_full,,,,
arc-daytime-04313145,0,0,unused_in_current_full,,,,
arc-daytime-04314107,0,0,unused_in_current_full,,,,
arc-daytime-04314201,0,0,unused_in_current_full,,,,
arc-daytime-04318146,0,0,unused_in_current_full,,,,
arc-daytime-04323171,0,0,unused_in_current_full,,,,
arc-daytime-04323233,0,0,unused_in_current_full,,,,
arc-daytime-04325262,0,0,unused_in_current_full,,,,
arc-daytime-04326162,0,0,unused_in_current_full,,,,
arc-daytime-04326164,0,0,unused_in_current_full,,,,
arc-daytime-04327228,0,0,unused_in_current_full,,,,
arc-daytime-04331151,0,0,unused_in_current_full,,,,
arc-daytime-04334203,0,0,unused_in_current_full,,,,
arc-daytime-04336243,0,0,unused_in_current_full,,,,
arc-daytime-04343296,0,0,unused_in_current_full,,,,
arc-daytime-04346177,0,0,unused_in_current_full,,,,
arc-daytime-04350210,0,0,unused_in_current_full,,,,
arc-daytime-04352232,0,0,unused_in_current_full,,,,
arc-daytime-04356186,0,0,unused_in_current_full,,,,
arc-daytime-04358167,0,0,unused_in_current_full,,,,
arc-daytime-05177027,0,0,unused_in_current_full,,,,
arc-daytime-06172050,0,0,unused_in_current_full,,,,
arc-daytime-06191091,0,0,unused_in_current_full,,,,
arc-daytime-07207029,0,0,unused_in_current_full,,,,
arc-daytime-07207075,0,0,unused_in_current_full,,,,
arc-daytime-07357229,0,0,unused_in_current_full,,,,
arc-daytime-08007250,0,0,unused_in_current_full,,,,
arc-daytime-08024245,0,0,unused_in_current_full,,,,
arc-daytime-08034279,0,0,unused_in_current_full,,,,
arc-daytime-08057336,0,0,unused_in_current_full,,,,
arc-daytime-08068287,0,0,unused_in_current_full,,,,
arc-daytime-08189045,0,0,unused_in_current_full,,,,
arc-daytime-08208134,0,0,unused_in_current_full,,,,
arc-daytime-08241098,0,0,unused_in_current_full,,,,
arc-daytime-08255101,0,0,unused_in_current_full,,,,
arc-daytime-08350232,0,0,unused_in_current_full,,,,
arc-daytime-l3,0,0,unused_in_current_full,,,,
arc-daytime-m1,0,0,unused_in_current_full,灯弧(緑),,,
arc-daytime-m2,0,0,unused_in_current_full,灯弧(赤),,,
arc-daytime-m3,0,0,unused_in_current_full,灯弧(黄・白),,,
arc-daytime-s1,0,0,unused_in_current_full,,,,
arc-daytime-s2,0,0,unused_in_current_full,,,,
arc-daytime-s3,0,0,unused_in_current_full,,,,
shipfinder-hull-blue,0,0,unused_in_current_full,,,,
shipfinder-hull-gray,0,0,unused_in_current_full,,,,
shipfinder-hull-green,0,0,unused_in_current_full,,,,
shipfinder-hull-orange,0,0,unused_in_current_full,,,,
shipfinder-hull-red,0,0,unused_in_current_full,,,,
shipfinder-hull-yellow,0,0,unused_in_current_full,,,,
shipfinder-left,0,0,unused_in_current_full,,,,
shipfinder-lost,0,0,unused_in_current_full,,,,
shipfinder-right,0,0,unused_in_current_full,,,,
shipfinder-sog1,0,0,unused_in_current_full,,,,
shipfinder-sog2,0,0,unused_in_current_full,,,,
shipfinder-sog3,0,0,unused_in_current_full,,,,
shipfinder-sog4,0,0,unused_in_current_full,,,,
shipfinder-sog5,0,0,unused_in_current_full,,,,
shipfinder-sog6,0,0,unused_in_current_full,,,,
shipfinder-straight,0,0,unused_in_current_full,,,,
symbol-daytime-311362,0,0,unused_in_current_full,,,,
symbol-daytime-314350,0,0,unused_in_current_full,,,,
symbol-daytime-314351,0,0,unused_in_current_full,,,,
symbol-daytime-314354,0,0,unused_in_current_full,,,,
symbol-daytime-314355,0,0,unused_in_current_full,,,,
symbol-daytime-314356,0,0,unused_in_current_full,,,,
symbol-daytime-314357,0,0,unused_in_current_full,,,,
symbol-daytime-314358,0,0,unused_in_current_full,,,,
symbol-daytime-314359,0,0,unused_in_current_full,,,,
symbol-daytime-314360,0,0,unused_in_current_full,,,,
symbol-daytime-316350,0,0,unused_in_current_full,,,,
symbol-daytime-316351,0,0,unused_in_current_full,,,,
symbol-daytime-316354,0,0,unused_in_current_full,,,,
symbol-daytime-316355,0,0,unused_in_current_full,,,,
symbol-daytime-316356,0,0,unused_in_current_full,,,,
symbol-daytime-316357,0,0,unused_in_current_full,,,,
symbol-daytime-316358,0,0,unused_in_current_full,,,,
symbol-daytime-316359,0,0,unused_in_current_full,,,,
symbol-daytime-316360,0,0,unused_in_current_full,,,,
symbol-daytime-316362,0,0,unused_in_current_full,,,,
symbol-daytime-318350,0,0,unused_in_current_full,,,,
symbol-daytime-318351,0,0,unused_in_current_full,,,,
symbol-daytime-318354,0,0,unused_in_current_full,,,,
symbol-daytime-318355,0,0,unused_in_current_full,,,,
symbol-daytime-318356,0,0,unused_in_current_full,,,,
symbol-daytime-318357,0,0,unused_in_current_full,,,,
symbol-daytime-318358,0,0,unused_in_current_full,,,,
symbol-daytime-318359,0,0,unused_in_current_full,,,,
symbol-daytime-318360,0,0,unused_in_current_full,,,,
symbol-daytime-318362,0,0,unused_in_current_full,,,,
symbol-daytime-321350,0,0,unused_in_current_full,,,,
symbol-daytime-321351,0,0,unused_in_current_full,,,,
symbol-daytime-321354,0,0,unused_in_current_full,,,,
symbol-daytime-321355,0,0,unused_in_current_full,,,,
symbol-daytime-321356,0,0,unused_in_current_full,,,,
symbol-daytime-321357,0,0,unused_in_current_full,,,,
symbol-daytime-321358,0,0,unused_in_current_full,,,,
symbol-daytime-321359,0,0,unused_in_current_full,,,,
symbol-daytime-321360,0,0,unused_in_current_full,,,,
symbol-daytime-321362,0,0,unused_in_current_full,,,,
symbol-daytime-324354,0,0,unused_in_current_full,,,,
symbol-daytime-324355,0,0,unused_in_current_full,,,,
symbol-daytime-324356,0,0,unused_in_current_full,,,,
symbol-daytime-324357,0,0,unused_in_current_full,,,,
symbol-daytime-324358,0,0,unused_in_current_full,,,,
symbol-daytime-324359,0,0,unused_in_current_full,,,,
symbol-daytime-324362,0,0,unused_in_current_full,,,,
symbol-daytime-331,0,0,unused_in_current_full,,,,
symbol-daytime-332350,0,0,unused_in_current_full,,,,
symbol-daytime-332351,0,0,unused_in_current_full,,,,
symbol-daytime-332354,0,0,unused_in_current_full,,,,
symbol-daytime-332355,0,0,unused_in_current_full,,,,
symbol-daytime-332356,0,0,unused_in_current_full,,,,
symbol-daytime-332357,0,0,unused_in_current_full,,,,
symbol-daytime-332358,0,0,unused_in_current_full,,,,
symbol-daytime-332359,0,0,unused_in_current_full,,,,
symbol-daytime-332360,0,0,unused_in_current_full,,,,
symbol-daytime-332362,0,0,unused_in_current_full,,,,
symbol-daytime-333350,0,0,unused_in_current_full,,,,
symbol-daytime-333351,0,0,unused_in_current_full,,,,
symbol-daytime-333354,0,0,unused_in_current_full,,,,
symbol-daytime-333355,0,0,unused_in_current_full,,,,
symbol-daytime-333356,0,0,unused_in_current_full,,,,
symbol-daytime-333357,0,0,unused_in_current_full,,,,
symbol-daytime-333358,0,0,unused_in_current_full,,,,
symbol-daytime-333359,0,0,unused_in_current_full,,,,
symbol-daytime-333360,0,0,unused_in_current_full,,,,
symbol-daytime-333362,0,0,unused_in_current_full,,,,
symbol-daytime-335354,0,0,unused_in_current_full,,,,
symbol-daytime-335355,0,0,unused_in_current_full,,,,
symbol-daytime-335356,0,0,unused_in_current_full,,,,
symbol-daytime-335357,0,0,unused_in_current_full,,,,
symbol-daytime-335358,0,0,unused_in_current_full,,,,
symbol-daytime-335360,0,0,unused_in_current_full,,,,
symbol-daytime-335374,0,0,unused_in_current_full,,,,
symbol-daytime-590,0,0,unused_in_current_full,,,,
symbol-daytime-640,0,0,unused_in_current_full,煙突,,,
symbol-daytime-650,0,0,unused_in_current_full,塔、やぐら、風車,,,
symbol-daytime-660,0,0,unused_in_current_full,海事関係署,,,
symbol-daytime-661,0,0,unused_in_current_full,漁業協同組合,,,
symbol-daytime-670,0,0,unused_in_current_full,,,,
symbol-daytime-680,0,0,unused_in_current_full,,,,
symbol-daytime-681,0,0,unused_in_current_full,山頂,,,
symbol-daytime-682,0,0,unused_in_current_full,,,,
symbol-daytime-698,0,0,unused_in_current_full,その他(記念碑等),,,
1 old_sprite_key used_in_newpec_style used_in_pbf usage_note manual_label_ja new_sprite_key basis source_page
2 symbol-daytime-428 2 3322 style_and_pbf 魚礁 fish_reef [manual] manual guide115_08
3 symbol-daytime-301 11 2830 style_and_pbf 港湾灯台 harbor_lighthouse manual guide115_02
4 symbol-daytime-303 9 1581 style_and_pbf light_minor
5 symbol-daytime-405 2 1286 style_and_pbf 掃海済みの危険物 cleared_danger_object [manual] manual guide115_07_20260120
6 symbol-daytime-310 18 927 style_and_pbf light_beacon
7 fill-daytime-428 2 899 style_and_pbf pattern_fill_obstruction_or_fish_reef
8 symbol-daytime-320 12 810 style_and_pbf buoy_light
9 symbol-daytime-327 18 573 style_and_pbf buoy_lattice
10 symbol-daytime-429 2 554 style_and_pbf 魚礁(危険なもの) fish_reef_dangerous [manual] manual guide115_08
11 fill-daytime-754 1 446 style_and_pbf pattern_fill_facility_area
12 symbol-daytime-30500003 7 328 style_and_pbf leading_light_variant_30500003
13 symbol-daytime-413 4 319 style_and_pbf 測定済みの沈船 wreck_surveyed [manual] manual guide115_08
14 symbol-daytime-321 5 311 style_and_pbf buoy_generic
15 symbol-daytime-323 8 238 style_and_pbf buoy_pillar
16 symbol-daytime-719 1 150 style_and_pbf 検疫錨地 anchorage_quarantine [manual] manual guide115_01
17 symbol-daytime-412 2 111 style_and_pbf 危険全沈没船 wreck_fully_submerged_dangerous [manual] manual guide115_08
18 symbol-daytime-308 1 110 style_and_pbf leading_mark_variant_308
19 symbol-daytime-30700003 4 87 style_and_pbf leading_mark_variant_30700003
20 symbol-daytime-325 7 76 style_and_pbf buoy_can
21 symbol-daytime-30500001 1 50 style_and_pbf leading_light_variant_30500001
22 symbol-daytime-30500002 2 42 style_and_pbf leading_light_variant_30500002
23 symbol-daytime-335359 2 40 style_and_pbf nav_mark_vais
24 symbol-daytime-410 4 34 style_and_pbf 船体露出沈船 wreck_hull_exposed manual guide115_08
25 symbol-daytime-300 13 0 style_only 沿岸灯台 coastal_lighthouse manual guide115_02
26 fill-daytime-421 12 0 style_only
27 symbol-daytime-302 11 0 style_only 防波堤灯台 breakwater_lighthouse manual guide115_02
28 symbol-daytime-314 8 0 style_only
29 symbol-daytime-401 6 0 style_only 水上岩・干出岩・洗岩(共通) rock_exposed_drying_awash_group [manual] manual guide115_07_20260120
30 fill-daytime-407 4 0 style_only
31 symbol-daytime-333 4 0 style_only
32 fill-daytime-401 3 0 style_only
33 fill-daytime-756 3 0 style_only
34 symbol-daytime-312356 3 0 style_only 西方位浮標 buoy_west_cardinal [manual] manual guide115_04
35 symbol-daytime-312357 3 0 style_only 南方位浮標 buoy_south_cardinal [manual] manual guide115_04
36 symbol-daytime-312360 3 0 style_only 特殊標識浮標 buoy_special_mark [manual] manual guide115_04
37 symbol-daytime-313362 3 0 style_only 係船浮標 mooring_buoy [manual] manual guide115_04
38 symbol-daytime-314362 3 0 style_only
39 symbol-daytime-317 3 0 style_only
40 symbol-daytime-721 3 0 style_only 制限区域・航路横断等禁止区域・航泊禁止区域(共通) restriction_area_group [manual] manual guide115_02
41 fill-daytime-420 2 0 style_only
42 fill-daytime-427 2 0 style_only
43 fill-daytime-429 2 0 style_only
44 line-daytime-710 2 0 style_only
45 line-daytime-713 2 0 style_only
46 symbol-daytime-311354 2 0 style_only 左舷標識灯標(推定) light_beacon_port_lateral_variant_311354 [manual?] manual? guide115_03
47 symbol-daytime-311355 2 0 style_only 右舷標識灯標(推定) light_beacon_starboard_lateral_variant_311355 [manual?] manual? guide115_03
48 symbol-daytime-311357 2 0 style_only 東方位標識灯標(推定) light_beacon_east_cardinal_variant_311357 [manual?] manual? guide115_03
49 symbol-daytime-311358 2 0 style_only 西方位標識灯標(推定) light_beacon_west_cardinal_variant_311358 [manual?] manual? guide115_03
50 symbol-daytime-311359 2 0 style_only 孤立障害標識灯標(推定) light_beacon_isolated_danger_variant_311359 [manual?] manual? guide115_03
51 symbol-daytime-311360 2 0 style_only 安全水域標識灯標(推定) light_beacon_safe_water_variant_311360 [manual?] manual? guide115_03
52 symbol-daytime-312350 2 0 style_only 左舷浮標(推定) buoy_port_lateral_variant_312350 [manual?] manual? guide115_04
53 symbol-daytime-312354 2 0 style_only 北方位浮標 buoy_north_cardinal [manual] manual guide115_04
54 symbol-daytime-312358 2 0 style_only 孤立障害浮標 buoy_isolated_danger [manual] manual guide115_04
55 symbol-daytime-316 2 0 style_only
56 symbol-daytime-324360 2 0 style_only
57 symbol-daytime-404 2 0 style_only 暗岩 sunken_rock [manual] manual guide115_07_20260120
58 symbol-daytime-406 2 0 style_only
59 symbol-daytime-407 2 0 style_only
60 symbol-daytime-408 2 0 style_only
61 symbol-daytime-409 2 0 style_only 孤立危険物 isolated_danger [manual] manual guide115_08
62 symbol-daytime-414 2 0 style_only
63 symbol-daytime-420 2 0 style_only 険悪物 foul_ground [manual] manual guide115_08
64 symbol-daytime-421 2 0 style_only サンドウェーブ sand_wave [manual] manual guide115_08
65 symbol-daytime-422 2 0 style_only 急潮・波紋・激潮 tide_rips_overfalls [manual] manual guide115_08
66 symbol-daytime-424 2 0 style_only 渦流 eddy_whirlpool [manual] manual guide115_08
67 symbol-daytime-425 2 0 style_only 海草 seaweed [manual] manual guide115_08
68 symbol-daytime-426 2 0 style_only
69 symbol-daytime-427 2 0 style_only 障害物 obstruction [manual] manual guide115_08
70 symbol-daytime-430 2 0 style_only
71 symbol-daytime-431 2 0 style_only 塔、やぐら、測台 tower_yagura_observation_platform [manual] manual guide115_08
72 symbol-daytime-432 2 0 style_only ボッシーン、パイル、杭 bollard_pile_stake [manual] manual guide115_08
73 symbol-daytime-433 2 0 style_only ドルフィン dolphin_structure [manual] manual guide115_08
74 symbol-daytime-434 2 0 style_only 海底設置物、放水口、取水口 subsea_installation_outfall_intake [manual] manual guide115_08
75 symbol-daytime-498 2 0 style_only
76 symbol-daytime-505 2 0 style_only 一般港湾・小港湾(共通) port_general_small_harbor_group [manual] manual guide115_01
77 arrow-daytime-0 1 0 style_only
78 arrow-daytime-1 1 0 style_only
79 arrow-daytime-2 1 0 style_only
80 arrow-daytime-3 1 0 style_only
81 arrow-daytime-4 1 0 style_only
82 fill-daytime-175 1 0 style_only
83 fill-daytime-745 1 0 style_only
84 fill-daytime-746 1 0 style_only
85 fill-daytime-747 1 0 style_only
86 fill-daytime-750 1 0 style_only
87 fill-daytime-753 1 0 style_only
88 fill-daytime-755 1 0 style_only
89 fill-daytime-900 1 0 style_only
90 fill-daytime-910 1 0 style_only 漁業区・魚礁エリア塗り pattern_fill_fishery_or_fish_reef_area [style] style style.navsea-delivery-full.json
91 light-daytime-1 1 0 style_only 灯光(緑) light_flare_green [manual] manual guide115_02
92 light-daytime-2 1 0 style_only 灯光(赤) light_flare_red [manual] manual guide115_02
93 light-daytime-3 1 0 style_only 灯光(黄・白) light_flare_yellow_white [manual] manual guide115_02
94 line-daytime-712 1 0 style_only
95 line-daytime-721 1 0 style_only
96 line-daytime-730 1 0 style_only
97 line-daytime-748 1 0 style_only
98 line-daytime-754 1 0 style_only 特殊パターン線 754 special_pattern_line_754 [style] style style.navsea-delivery-full.json
99 symbol-daytime-30700001 1 0 style_only
100 symbol-daytime-30700002 1 0 style_only
101 symbol-daytime-311350 1 0 style_only
102 symbol-daytime-311351 1 0 style_only
103 symbol-daytime-311356 1 0 style_only 北方位標識灯標(推定) light_beacon_north_cardinal_variant_311356 [manual?] manual? guide115_03
104 symbol-daytime-312351 1 0 style_only 右舷浮標(推定) buoy_starboard_lateral_variant_312351 [manual?] manual? guide115_04
105 symbol-daytime-312355 1 0 style_only 東方位浮標 buoy_east_cardinal [manual] manual guide115_04
106 symbol-daytime-312359 1 0 style_only 安全水域浮標 buoy_safe_water [manual] manual guide115_04
107 symbol-daytime-324350 1 0 style_only
108 symbol-daytime-324351 1 0 style_only
109 symbol-daytime-335350 1 0 style_only
110 symbol-daytime-335351 1 0 style_only
111 symbol-daytime-500 1 0 style_only パイロットステーション pilot_station [manual] manual guide115_01
112 symbol-daytime-520 1 0 style_only 漁港 fishing_port [manual] manual guide115_01
113 symbol-daytime-530 1 0 style_only マリーナ marina [manual] manual guide115_01
114 symbol-daytime-540 1 0 style_only フィッシャリーナ fisherina [manual] manual guide115_01
115 symbol-daytime-550 1 0 style_only 海の駅 sea_station_umi_no_eki [manual] manual guide115_01
116 symbol-daytime-720 1 0 style_only 錨泊(指定)地 anchorage_designated [manual] manual guide115_01
117 symbol-daytime-724 1 0 style_only 錨泊禁止区域 anchoring_prohibited [manual] manual guide115_02
118 symbol-daytime-759 1 0 style_only
119 symbol-daytime-760 1 0 style_only
120 symbol-daytime-761 1 0 style_only
121 tidespot-daytime 1 0 style_only
122 arc-daytime-0105306901192310 0 0 unused_in_current_full
123 arc-daytime-01180035 0 0 unused_in_current_full
124 arc-daytime-01293219 0 0 unused_in_current_full
125 arc-daytime-0200103104031001 0 0 unused_in_current_full
126 arc-daytime-02002252 0 0 unused_in_current_full
127 arc-daytime-0201102104021011 0 0 unused_in_current_full
128 arc-daytime-02048301 0 0 unused_in_current_full
129 arc-daytime-0206408002180297 0 0 unused_in_current_full
130 arc-daytime-02113325 0 0 unused_in_current_full
131 arc-daytime-0222231004310222 0 0 unused_in_current_full
132 arc-daytime-0223726704267237 0 0 unused_in_current_full
133 arc-daytime-0225529904299089 0 0 unused_in_current_full
134 arc-daytime-02257145 0 0 unused_in_current_full
135 arc-daytime-02300210 0 0 unused_in_current_full
136 arc-daytime-02317310 0 0 unused_in_current_full
137 arc-daytime-04002244 0 0 unused_in_current_full
138 arc-daytime-04004246 0 0 unused_in_current_full
139 arc-daytime-04006315 0 0 unused_in_current_full
140 arc-daytime-04007277 0 0 unused_in_current_full
141 arc-daytime-04008243 0 0 unused_in_current_full
142 arc-daytime-04010293 0 0 unused_in_current_full
143 arc-daytime-04014213 0 0 unused_in_current_full
144 arc-daytime-04016181 0 0 unused_in_current_full
145 arc-daytime-04016291 0 0 unused_in_current_full
146 arc-daytime-04018198 0 0 unused_in_current_full
147 arc-daytime-04018258 0 0 unused_in_current_full
148 arc-daytime-04020236 0 0 unused_in_current_full
149 arc-daytime-04020243 0 0 unused_in_current_full
150 arc-daytime-04021213 0 0 unused_in_current_full
151 arc-daytime-04021253 0 0 unused_in_current_full
152 arc-daytime-04022202 0 0 unused_in_current_full
153 arc-daytime-04022307 0 0 unused_in_current_full
154 arc-daytime-04024258 0 0 unused_in_current_full
155 arc-daytime-04025273 0 0 unused_in_current_full
156 arc-daytime-04027289 0 0 unused_in_current_full 灯弧(黄・白系)
157 arc-daytime-04028287 0 0 unused_in_current_full
158 arc-daytime-04029268 0 0 unused_in_current_full
159 arc-daytime-04029280 0 0 unused_in_current_full
160 arc-daytime-04030275 0 0 unused_in_current_full
161 arc-daytime-04031330 0 0 unused_in_current_full
162 arc-daytime-04033249 0 0 unused_in_current_full
163 arc-daytime-04035209 0 0 unused_in_current_full
164 arc-daytime-04035221042430270202703502221243 0 0 unused_in_current_full
165 arc-daytime-04035283 0 0 unused_in_current_full
166 arc-daytime-04036216 0 0 unused_in_current_full
167 arc-daytime-04040253 0 0 unused_in_current_full
168 arc-daytime-04043223 0 0 unused_in_current_full
169 arc-daytime-04045135 0 0 unused_in_current_full
170 arc-daytime-04048213 0 0 unused_in_current_full
171 arc-daytime-04051314 0 0 unused_in_current_full
172 arc-daytime-040522800208109201052073 0 0 unused_in_current_full
173 arc-daytime-04052305 0 0 unused_in_current_full
174 arc-daytime-04053279 0 0 unused_in_current_full
175 arc-daytime-04054226 0 0 unused_in_current_full
176 arc-daytime-04057308 0 0 unused_in_current_full
177 arc-daytime-04060257 0 0 unused_in_current_full
178 arc-daytime-04060319 0 0 unused_in_current_full
179 arc-daytime-0406126602079097 0 0 unused_in_current_full
180 arc-daytime-04063251042640410204106302251264 0 0 unused_in_current_full
181 arc-daytime-04068298 0 0 unused_in_current_full
182 arc-daytime-04070270 0 0 unused_in_current_full
183 arc-daytime-04070314 0 0 unused_in_current_full
184 arc-daytime-04070336 0 0 unused_in_current_full
185 arc-daytime-04073309 0 0 unused_in_current_full
186 arc-daytime-04077286 0 0 unused_in_current_full
187 arc-daytime-04079310 0 0 unused_in_current_full
188 arc-daytime-04079335 0 0 unused_in_current_full
189 arc-daytime-04081293 0 0 unused_in_current_full
190 arc-daytime-04082332 0 0 unused_in_current_full
191 arc-daytime-0408402102021084 0 0 unused_in_current_full
192 arc-daytime-0408626602266086 0 0 unused_in_current_full
193 arc-daytime-04091357 0 0 unused_in_current_full
194 arc-daytime-04092292 0 0 unused_in_current_full
195 arc-daytime-04093033 0 0 unused_in_current_full
196 arc-daytime-04093340 0 0 unused_in_current_full
197 arc-daytime-04094000 0 0 unused_in_current_full
198 arc-daytime-040951040203509502104170 0 0 unused_in_current_full
199 arc-daytime-04095312 0 0 unused_in_current_full
200 arc-daytime-04097050 0 0 unused_in_current_full
201 arc-daytime-04097335 0 0 unused_in_current_full
202 arc-daytime-04098000 0 0 unused_in_current_full
203 arc-daytime-04099318 0 0 unused_in_current_full
204 arc-daytime-04102142 0 0 unused_in_current_full
205 arc-daytime-04102355 0 0 unused_in_current_full
206 arc-daytime-04104012 0 0 unused_in_current_full
207 arc-daytime-04105013 0 0 unused_in_current_full
208 arc-daytime-04105020 0 0 unused_in_current_full
209 arc-daytime-0410533902339015 0 0 unused_in_current_full
210 arc-daytime-04106344 0 0 unused_in_current_full
211 arc-daytime-04107043 0 0 unused_in_current_full
212 arc-daytime-04108347 0 0 unused_in_current_full
213 arc-daytime-04109033 0 0 unused_in_current_full
214 arc-daytime-04109316 0 0 unused_in_current_full
215 arc-daytime-04115052 0 0 unused_in_current_full
216 arc-daytime-04116064 0 0 unused_in_current_full
217 arc-daytime-0411609202092116 0 0 unused_in_current_full
218 arc-daytime-04118329 0 0 unused_in_current_full
219 arc-daytime-041201250413031202125130 0 0 unused_in_current_full
220 arc-daytime-04121318 0 0 unused_in_current_full
221 arc-daytime-04124324 0 0 unused_in_current_full
222 arc-daytime-04125351 0 0 unused_in_current_full
223 arc-daytime-04132318 0 0 unused_in_current_full
224 arc-daytime-04133030 0 0 unused_in_current_full
225 arc-daytime-04135320 0 0 unused_in_current_full
226 arc-daytime-04138018 0 0 unused_in_current_full
227 arc-daytime-0413935602106139 0 0 unused_in_current_full
228 arc-daytime-04140012 0 0 unused_in_current_full
229 arc-daytime-04140341 0 0 unused_in_current_full
230 arc-daytime-04152017 0 0 unused_in_current_full
231 arc-daytime-04155005 0 0 unused_in_current_full
232 arc-daytime-04156008 0 0 unused_in_current_full
233 arc-daytime-04156335 0 0 unused_in_current_full
234 arc-daytime-04159010 0 0 unused_in_current_full
235 arc-daytime-04160006 0 0 unused_in_current_full
236 arc-daytime-04160329 0 0 unused_in_current_full
237 arc-daytime-04162032 0 0 unused_in_current_full
238 arc-daytime-04166358 0 0 unused_in_current_full
239 arc-daytime-04168018 0 0 unused_in_current_full
240 arc-daytime-04169065 0 0 unused_in_current_full
241 arc-daytime-041702050421505102205215 0 0 unused_in_current_full
242 arc-daytime-04172080 0 0 unused_in_current_full
243 arc-daytime-04173082 0 0 unused_in_current_full
244 arc-daytime-04175017 0 0 unused_in_current_full
245 arc-daytime-04177071 0 0 unused_in_current_full
246 arc-daytime-04178066 0 0 unused_in_current_full
247 arc-daytime-04180008 0 0 unused_in_current_full
248 arc-daytime-04180060 0 0 unused_in_current_full
249 arc-daytime-04180062 0 0 unused_in_current_full
250 arc-daytime-0418112902129181 0 0 unused_in_current_full
251 arc-daytime-04182090 0 0 unused_in_current_full
252 arc-daytime-04185055 0 0 unused_in_current_full
253 arc-daytime-04185095 0 0 unused_in_current_full
254 arc-daytime-04187142 0 0 unused_in_current_full
255 arc-daytime-04190057 0 0 unused_in_current_full
256 arc-daytime-04190085 0 0 unused_in_current_full
257 arc-daytime-04194029 0 0 unused_in_current_full
258 arc-daytime-04195021 0 0 unused_in_current_full
259 arc-daytime-04197017 0 0 unused_in_current_full
260 arc-daytime-04198097 0 0 unused_in_current_full
261 arc-daytime-04198358 0 0 unused_in_current_full
262 arc-daytime-04199019 0 0 unused_in_current_full
263 arc-daytime-0419907902043079 0 0 unused_in_current_full
264 arc-daytime-04199343 0 0 unused_in_current_full
265 arc-daytime-04201091 0 0 unused_in_current_full
266 arc-daytime-04203099 0 0 unused_in_current_full
267 arc-daytime-04204043 0 0 unused_in_current_full
268 arc-daytime-04204099 0 0 unused_in_current_full
269 arc-daytime-04205045 0 0 unused_in_current_full
270 arc-daytime-04205097 0 0 unused_in_current_full
271 arc-daytime-04207038 0 0 unused_in_current_full
272 arc-daytime-0420704802048070 0 0 unused_in_current_full
273 arc-daytime-04209116 0 0 unused_in_current_full
274 arc-daytime-04210091 0 0 unused_in_current_full
275 arc-daytime-04213013 0 0 unused_in_current_full
276 arc-daytime-04215162 0 0 unused_in_current_full
277 arc-daytime-04216098 0 0 unused_in_current_full
278 arc-daytime-04217119 0 0 unused_in_current_full
279 arc-daytime-04221052 0 0 unused_in_current_full
280 arc-daytime-04221104 0 0 unused_in_current_full
281 arc-daytime-04222055 0 0 unused_in_current_full
282 arc-daytime-04222063 0 0 unused_in_current_full
283 arc-daytime-04223137 0 0 unused_in_current_full
284 arc-daytime-04229073 0 0 unused_in_current_full
285 arc-daytime-04230050 0 0 unused_in_current_full
286 arc-daytime-04230076 0 0 unused_in_current_full
287 arc-daytime-042310350405610002035056 0 0 unused_in_current_full
288 arc-daytime-0423116704125167 0 0 unused_in_current_full
289 arc-daytime-04232050 0 0 unused_in_current_full
290 arc-daytime-0423222602226232 0 0 unused_in_current_full
291 arc-daytime-04233110 0 0 unused_in_current_full
292 arc-daytime-042352850429530504320170 0 0 unused_in_current_full
293 arc-daytime-04237100 0 0 unused_in_current_full
294 arc-daytime-04240170 0 0 unused_in_current_full
295 arc-daytime-0424122702227241 0 0 unused_in_current_full
296 arc-daytime-04242150 0 0 unused_in_current_full
297 arc-daytime-04245092 0 0 unused_in_current_full
298 arc-daytime-0424628604296140 0 0 unused_in_current_full
299 arc-daytime-04251115 0 0 unused_in_current_full
300 arc-daytime-0425408002080101 0 0 unused_in_current_full
301 arc-daytime-04254169 0 0 unused_in_current_full
302 arc-daytime-04255075 0 0 unused_in_current_full
303 arc-daytime-04257132 0 0 unused_in_current_full
304 arc-daytime-04257134 0 0 unused_in_current_full
305 arc-daytime-042572820429532304010148022172570228229502323010 0 0 unused_in_current_full
306 arc-daytime-04259113 0 0 unused_in_current_full
307 arc-daytime-04261114 0 0 unused_in_current_full
308 arc-daytime-04263083 0 0 unused_in_current_full
309 arc-daytime-04265214 0 0 unused_in_current_full
310 arc-daytime-0426524202242265 0 0 unused_in_current_full
311 arc-daytime-04266162 0 0 unused_in_current_full
312 arc-daytime-04269146 0 0 unused_in_current_full
313 arc-daytime-04270080 0 0 unused_in_current_full
314 arc-daytime-0427021502215270 0 0 unused_in_current_full
315 arc-daytime-04271113 0 0 unused_in_current_full
316 arc-daytime-04271115 0 0 unused_in_current_full
317 arc-daytime-04272211 0 0 unused_in_current_full
318 arc-daytime-0427410502250274 0 0 unused_in_current_full
319 arc-daytime-04274157 0 0 unused_in_current_full
320 arc-daytime-04275131 0 0 unused_in_current_full
321 arc-daytime-04278130 0 0 unused_in_current_full
322 arc-daytime-04279098 0 0 unused_in_current_full
323 arc-daytime-04285147 0 0 unused_in_current_full
324 arc-daytime-042900770207709004090189 0 0 unused_in_current_full
325 arc-daytime-04295180 0 0 unused_in_current_full
326 arc-daytime-04297154 0 0 unused_in_current_full
327 arc-daytime-04297190 0 0 unused_in_current_full
328 arc-daytime-04297254 0 0 unused_in_current_full
329 arc-daytime-04300156 0 0 unused_in_current_full
330 arc-daytime-04301172 0 0 unused_in_current_full
331 arc-daytime-04301175 0 0 unused_in_current_full
332 arc-daytime-04306184 0 0 unused_in_current_full
333 arc-daytime-04307120 0 0 unused_in_current_full
334 arc-daytime-04311219 0 0 unused_in_current_full
335 arc-daytime-04313145 0 0 unused_in_current_full
336 arc-daytime-04314107 0 0 unused_in_current_full
337 arc-daytime-04314201 0 0 unused_in_current_full
338 arc-daytime-04318146 0 0 unused_in_current_full
339 arc-daytime-04323171 0 0 unused_in_current_full
340 arc-daytime-04323233 0 0 unused_in_current_full
341 arc-daytime-04325262 0 0 unused_in_current_full
342 arc-daytime-04326162 0 0 unused_in_current_full
343 arc-daytime-04326164 0 0 unused_in_current_full
344 arc-daytime-04327228 0 0 unused_in_current_full
345 arc-daytime-04331151 0 0 unused_in_current_full
346 arc-daytime-04334203 0 0 unused_in_current_full
347 arc-daytime-04336243 0 0 unused_in_current_full
348 arc-daytime-04343296 0 0 unused_in_current_full
349 arc-daytime-04346177 0 0 unused_in_current_full
350 arc-daytime-04350210 0 0 unused_in_current_full
351 arc-daytime-04352232 0 0 unused_in_current_full
352 arc-daytime-04356186 0 0 unused_in_current_full
353 arc-daytime-04358167 0 0 unused_in_current_full
354 arc-daytime-05177027 0 0 unused_in_current_full
355 arc-daytime-06172050 0 0 unused_in_current_full
356 arc-daytime-06191091 0 0 unused_in_current_full
357 arc-daytime-07207029 0 0 unused_in_current_full
358 arc-daytime-07207075 0 0 unused_in_current_full
359 arc-daytime-07357229 0 0 unused_in_current_full
360 arc-daytime-08007250 0 0 unused_in_current_full
361 arc-daytime-08024245 0 0 unused_in_current_full
362 arc-daytime-08034279 0 0 unused_in_current_full
363 arc-daytime-08057336 0 0 unused_in_current_full
364 arc-daytime-08068287 0 0 unused_in_current_full
365 arc-daytime-08189045 0 0 unused_in_current_full
366 arc-daytime-08208134 0 0 unused_in_current_full
367 arc-daytime-08241098 0 0 unused_in_current_full
368 arc-daytime-08255101 0 0 unused_in_current_full
369 arc-daytime-08350232 0 0 unused_in_current_full
370 arc-daytime-l3 0 0 unused_in_current_full
371 arc-daytime-m1 0 0 unused_in_current_full 灯弧(緑)
372 arc-daytime-m2 0 0 unused_in_current_full 灯弧(赤)
373 arc-daytime-m3 0 0 unused_in_current_full 灯弧(黄・白)
374 arc-daytime-s1 0 0 unused_in_current_full
375 arc-daytime-s2 0 0 unused_in_current_full
376 arc-daytime-s3 0 0 unused_in_current_full
377 shipfinder-hull-blue 0 0 unused_in_current_full
378 shipfinder-hull-gray 0 0 unused_in_current_full
379 shipfinder-hull-green 0 0 unused_in_current_full
380 shipfinder-hull-orange 0 0 unused_in_current_full
381 shipfinder-hull-red 0 0 unused_in_current_full
382 shipfinder-hull-yellow 0 0 unused_in_current_full
383 shipfinder-left 0 0 unused_in_current_full
384 shipfinder-lost 0 0 unused_in_current_full
385 shipfinder-right 0 0 unused_in_current_full
386 shipfinder-sog1 0 0 unused_in_current_full
387 shipfinder-sog2 0 0 unused_in_current_full
388 shipfinder-sog3 0 0 unused_in_current_full
389 shipfinder-sog4 0 0 unused_in_current_full
390 shipfinder-sog5 0 0 unused_in_current_full
391 shipfinder-sog6 0 0 unused_in_current_full
392 shipfinder-straight 0 0 unused_in_current_full
393 symbol-daytime-311362 0 0 unused_in_current_full
394 symbol-daytime-314350 0 0 unused_in_current_full
395 symbol-daytime-314351 0 0 unused_in_current_full
396 symbol-daytime-314354 0 0 unused_in_current_full
397 symbol-daytime-314355 0 0 unused_in_current_full
398 symbol-daytime-314356 0 0 unused_in_current_full
399 symbol-daytime-314357 0 0 unused_in_current_full
400 symbol-daytime-314358 0 0 unused_in_current_full
401 symbol-daytime-314359 0 0 unused_in_current_full
402 symbol-daytime-314360 0 0 unused_in_current_full
403 symbol-daytime-316350 0 0 unused_in_current_full
404 symbol-daytime-316351 0 0 unused_in_current_full
405 symbol-daytime-316354 0 0 unused_in_current_full
406 symbol-daytime-316355 0 0 unused_in_current_full
407 symbol-daytime-316356 0 0 unused_in_current_full
408 symbol-daytime-316357 0 0 unused_in_current_full
409 symbol-daytime-316358 0 0 unused_in_current_full
410 symbol-daytime-316359 0 0 unused_in_current_full
411 symbol-daytime-316360 0 0 unused_in_current_full
412 symbol-daytime-316362 0 0 unused_in_current_full
413 symbol-daytime-318350 0 0 unused_in_current_full
414 symbol-daytime-318351 0 0 unused_in_current_full
415 symbol-daytime-318354 0 0 unused_in_current_full
416 symbol-daytime-318355 0 0 unused_in_current_full
417 symbol-daytime-318356 0 0 unused_in_current_full
418 symbol-daytime-318357 0 0 unused_in_current_full
419 symbol-daytime-318358 0 0 unused_in_current_full
420 symbol-daytime-318359 0 0 unused_in_current_full
421 symbol-daytime-318360 0 0 unused_in_current_full
422 symbol-daytime-318362 0 0 unused_in_current_full
423 symbol-daytime-321350 0 0 unused_in_current_full
424 symbol-daytime-321351 0 0 unused_in_current_full
425 symbol-daytime-321354 0 0 unused_in_current_full
426 symbol-daytime-321355 0 0 unused_in_current_full
427 symbol-daytime-321356 0 0 unused_in_current_full
428 symbol-daytime-321357 0 0 unused_in_current_full
429 symbol-daytime-321358 0 0 unused_in_current_full
430 symbol-daytime-321359 0 0 unused_in_current_full
431 symbol-daytime-321360 0 0 unused_in_current_full
432 symbol-daytime-321362 0 0 unused_in_current_full
433 symbol-daytime-324354 0 0 unused_in_current_full
434 symbol-daytime-324355 0 0 unused_in_current_full
435 symbol-daytime-324356 0 0 unused_in_current_full
436 symbol-daytime-324357 0 0 unused_in_current_full
437 symbol-daytime-324358 0 0 unused_in_current_full
438 symbol-daytime-324359 0 0 unused_in_current_full
439 symbol-daytime-324362 0 0 unused_in_current_full
440 symbol-daytime-331 0 0 unused_in_current_full
441 symbol-daytime-332350 0 0 unused_in_current_full
442 symbol-daytime-332351 0 0 unused_in_current_full
443 symbol-daytime-332354 0 0 unused_in_current_full
444 symbol-daytime-332355 0 0 unused_in_current_full
445 symbol-daytime-332356 0 0 unused_in_current_full
446 symbol-daytime-332357 0 0 unused_in_current_full
447 symbol-daytime-332358 0 0 unused_in_current_full
448 symbol-daytime-332359 0 0 unused_in_current_full
449 symbol-daytime-332360 0 0 unused_in_current_full
450 symbol-daytime-332362 0 0 unused_in_current_full
451 symbol-daytime-333350 0 0 unused_in_current_full
452 symbol-daytime-333351 0 0 unused_in_current_full
453 symbol-daytime-333354 0 0 unused_in_current_full
454 symbol-daytime-333355 0 0 unused_in_current_full
455 symbol-daytime-333356 0 0 unused_in_current_full
456 symbol-daytime-333357 0 0 unused_in_current_full
457 symbol-daytime-333358 0 0 unused_in_current_full
458 symbol-daytime-333359 0 0 unused_in_current_full
459 symbol-daytime-333360 0 0 unused_in_current_full
460 symbol-daytime-333362 0 0 unused_in_current_full
461 symbol-daytime-335354 0 0 unused_in_current_full
462 symbol-daytime-335355 0 0 unused_in_current_full
463 symbol-daytime-335356 0 0 unused_in_current_full
464 symbol-daytime-335357 0 0 unused_in_current_full
465 symbol-daytime-335358 0 0 unused_in_current_full
466 symbol-daytime-335360 0 0 unused_in_current_full
467 symbol-daytime-335374 0 0 unused_in_current_full
468 symbol-daytime-590 0 0 unused_in_current_full
469 symbol-daytime-640 0 0 unused_in_current_full 煙突
470 symbol-daytime-650 0 0 unused_in_current_full 塔、やぐら、風車
471 symbol-daytime-660 0 0 unused_in_current_full 海事関係署
472 symbol-daytime-661 0 0 unused_in_current_full 漁業協同組合
473 symbol-daytime-670 0 0 unused_in_current_full
474 symbol-daytime-680 0 0 unused_in_current_full
475 symbol-daytime-681 0 0 unused_in_current_full 山頂
476 symbol-daytime-682 0 0 unused_in_current_full
477 symbol-daytime-698 0 0 unused_in_current_full その他(記念碑等)

View File

@@ -0,0 +1,34 @@
row,old_sprite_key,current_new_sprite_key,suggested_new_sprite_key,reason,used_in_newpec_style,used_in_pbf,manual_label_ja,source_page
38,symbol-daytime-314362,safe water mark,safe_water_mark,去空格,统一为下划线命名。,3,0,,
39,symbol-daytime-317,mark_bang,mark_with_topmark,原 token `bang` 语义不清,先改成可读的占位语义。,3,0,,
41,fill-daytime-420,fille_nasi,fill_nasi,`fille` 疑似拼写误差;建议统一 fill 前缀。,2,0,,
42,fill-daytime-427,fille_net_red,fill_net_red,`fille` 疑似拼写误差;建议统一 fill 前缀。,2,0,,
46,symbol-daytime-311354,light_beacon_north_cardinal_varian,light_beacon_north_cardinal_variant,修正 `varian` 拼写。,2,0,,guide115_03
47,symbol-daytime-311355,light_beacon_easte_cardinal_varian,light_beacon_east_cardinal_variant,修正 `easte/varian` 拼写。,2,0,,guide115_03
48,symbol-daytime-311357,light_beacon_sourth_cardinal_varian,light_beacon_south_cardinal_variant,修正 `sourth/varian` 拼写。,2,0,,guide115_03
55,symbol-daytime-316,mark_box_box,mark_box_box,格式可接受,先保留。,2,0,,
56,symbol-daytime-324360,special_mark,special_mark,格式可接受,先保留。,2,0,special mark,
59,symbol-daytime-407,coral_red,coral_red,格式可接受,先保留。,2,0,,
60,symbol-daytime-408,coral_black,coral_black,格式可接受,先保留。,2,0,,
62,symbol-daytime-414,tu_b,unknown_tu_b,`tu_b` 暂无法直读,建议保留 unknown 前缀等待确认。,2,0,,
68,symbol-daytime-426,t_object,unknown_t_object,`t_object` 暂无法直读,建议保留 unknown 前缀等待确认。,2,0,,
70,symbol-daytime-430,fille_box_point,fill_box_point,`fille` 疑似拼写误差;建议统一 fill 前缀。,2,0,,
75,symbol-daytime-498,fille_box_black,fill_box_black,`fille` 疑似拼写误差;建议统一 fill 前缀。,2,0,,
82,fill-daytime-175,fille_X,fill_x,`fille` 疑似拼写误差;字母建议统一小写。,1,0,,
83,fill-daytime-745,fille_mark_r,fill_mark_r,`fille` 疑似拼写误差。,1,0,,
84,fill-daytime-746,fille_mark_y,fill_mark_y,`fille` 疑似拼写误差。,1,0,,
85,fill-daytime-747,fille_mark,fill_mark,`fille` 疑似拼写误差。,1,0,,
86,fill-daytime-750,fille_point,fill_point,`fille` 疑似拼写误差。,1,0,,
87,fill-daytime-753,fille_y,fill_y,`fille` 疑似拼写误差;字母建议统一小写。,1,0,,
88,fill-daytime-755,fille_A,fill_a,`fille` 疑似拼写误差;字母建议统一小写。,1,0,,
89,fill-daytime-900,fille_box,fill_box,`fille` 疑似拼写误差。,1,0,,
94,line-daytime-712,line_a,line_a,格式可接受,先保留。,1,0,,
95,line-daytime-721,line_b,line_b,格式可接受,先保留。,1,0,,
96,line-daytime-730,line_c,line_c,格式可接受,先保留。,1,0,,
97,line-daytime-748,line_d,line_d,格式可接受,先保留。,1,0,,
99,symbol-daytime-30700001,light_up_green,light_up_green,格式可接受,先保留。,1,0,,
100,symbol-daytime-30700002,light_up_red,light_up_red,格式可接受,先保留。,1,0,,
101,symbol-daytime-311350,port-hand mark_bang,port_hand_mark_topmark,去空格与连字符,`bang` 改为更可读的 `topmark`。,1,0,左舷標識,
102,symbol-daytime-311351,starboard-hand mark_bang,starboard_hand_mark_topmark,去空格与连字符,`bang` 改为更可读的 `topmark`。,1,0,右舷標識,
107,symbol-daytime-324350,port-hand mark,port_hand_mark,去空格与连字符,统一下划线命名。,1,0,左舷標識,
108,symbol-daytime-324351,starboard-hand mark,starboard_hand_mark,去空格与连字符,统一下划线命名。,1,0,右舷標識,
1 row old_sprite_key current_new_sprite_key suggested_new_sprite_key reason used_in_newpec_style used_in_pbf manual_label_ja source_page
2 38 symbol-daytime-314362 safe water mark safe_water_mark 去空格,统一为下划线命名。 3 0
3 39 symbol-daytime-317 mark_bang mark_with_topmark 原 token `bang` 语义不清,先改成可读的占位语义。 3 0
4 41 fill-daytime-420 fille_nasi fill_nasi `fille` 疑似拼写误差;建议统一 fill 前缀。 2 0
5 42 fill-daytime-427 fille_net_red fill_net_red `fille` 疑似拼写误差;建议统一 fill 前缀。 2 0
6 46 symbol-daytime-311354 light_beacon_north_cardinal_varian light_beacon_north_cardinal_variant 修正 `varian` 拼写。 2 0 guide115_03
7 47 symbol-daytime-311355 light_beacon_easte_cardinal_varian light_beacon_east_cardinal_variant 修正 `easte/varian` 拼写。 2 0 guide115_03
8 48 symbol-daytime-311357 light_beacon_sourth_cardinal_varian light_beacon_south_cardinal_variant 修正 `sourth/varian` 拼写。 2 0 guide115_03
9 55 symbol-daytime-316 mark_box_box mark_box_box 格式可接受,先保留。 2 0
10 56 symbol-daytime-324360 special_mark special_mark 格式可接受,先保留。 2 0 special mark
11 59 symbol-daytime-407 coral_red coral_red 格式可接受,先保留。 2 0
12 60 symbol-daytime-408 coral_black coral_black 格式可接受,先保留。 2 0
13 62 symbol-daytime-414 tu_b unknown_tu_b `tu_b` 暂无法直读,建议保留 unknown 前缀等待确认。 2 0
14 68 symbol-daytime-426 t_object unknown_t_object `t_object` 暂无法直读,建议保留 unknown 前缀等待确认。 2 0
15 70 symbol-daytime-430 fille_box_point fill_box_point `fille` 疑似拼写误差;建议统一 fill 前缀。 2 0
16 75 symbol-daytime-498 fille_box_black fill_box_black `fille` 疑似拼写误差;建议统一 fill 前缀。 2 0
17 82 fill-daytime-175 fille_X fill_x `fille` 疑似拼写误差;字母建议统一小写。 1 0
18 83 fill-daytime-745 fille_mark_r fill_mark_r `fille` 疑似拼写误差。 1 0
19 84 fill-daytime-746 fille_mark_y fill_mark_y `fille` 疑似拼写误差。 1 0
20 85 fill-daytime-747 fille_mark fill_mark `fille` 疑似拼写误差。 1 0
21 86 fill-daytime-750 fille_point fill_point `fille` 疑似拼写误差。 1 0
22 87 fill-daytime-753 fille_y fill_y `fille` 疑似拼写误差;字母建议统一小写。 1 0
23 88 fill-daytime-755 fille_A fill_a `fille` 疑似拼写误差;字母建议统一小写。 1 0
24 89 fill-daytime-900 fille_box fill_box `fille` 疑似拼写误差。 1 0
25 94 line-daytime-712 line_a line_a 格式可接受,先保留。 1 0
26 95 line-daytime-721 line_b line_b 格式可接受,先保留。 1 0
27 96 line-daytime-730 line_c line_c 格式可接受,先保留。 1 0
28 97 line-daytime-748 line_d line_d 格式可接受,先保留。 1 0
29 99 symbol-daytime-30700001 light_up_green light_up_green 格式可接受,先保留。 1 0
30 100 symbol-daytime-30700002 light_up_red light_up_red 格式可接受,先保留。 1 0
31 101 symbol-daytime-311350 port-hand mark_bang port_hand_mark_topmark 去空格与连字符,`bang` 改为更可读的 `topmark`。 1 0 左舷標識
32 102 symbol-daytime-311351 starboard-hand mark_bang starboard_hand_mark_topmark 去空格与连字符,`bang` 改为更可读的 `topmark`。 1 0 右舷標識
33 107 symbol-daytime-324350 port-hand mark port_hand_mark 去空格与连字符,统一下划线命名。 1 0 左舷標識
34 108 symbol-daytime-324351 starboard-hand mark starboard_hand_mark 去空格与连字符,统一下划线命名。 1 0 右舷標識