Initial import of NavSea pbf project
This commit is contained in:
54
tasks/NavSea_Semantic_Overlay_Validation_System.md
Normal file
54
tasks/NavSea_Semantic_Overlay_Validation_System.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# NavSea Semantic Overlay Validation System
|
||||
|
||||
## Purpose
|
||||
|
||||
Validate the NavSea semantic overlay without touching rendering logic, style configuration, or vector tile structure.
|
||||
|
||||
## Inputs
|
||||
|
||||
The task reads the existing semantic overlay and audit tables in database `pbf_analysis`, including:
|
||||
|
||||
- `canonical_layer_rules`
|
||||
- `canonical_object_rules`
|
||||
- `object_geometry_allowlist`
|
||||
- `pbf_relayer_candidates`
|
||||
- `pbf_render_compatibility`
|
||||
- `pbf_detection_catalog`
|
||||
- `style_layers`
|
||||
- `features`
|
||||
- `tile_density`
|
||||
|
||||
## Execution
|
||||
|
||||
Rebuild the semantic overlay metadata and then run validation:
|
||||
|
||||
```bash
|
||||
.venv/bin/python navsea_relayer.py
|
||||
.venv/bin/python navsea_semantic_validation.py
|
||||
```
|
||||
|
||||
## Validation Tables
|
||||
|
||||
The validation task creates or refreshes:
|
||||
|
||||
- `classification_validation`
|
||||
- `geometry_consistency`
|
||||
- `style_render_equivalence`
|
||||
- `detection_catalog_integrity`
|
||||
- `spatial_anomalies`
|
||||
- `semantic_validation_summary`
|
||||
|
||||
## Current Design Notes
|
||||
|
||||
- Rendering compatibility is verified at database level only.
|
||||
- `canonical_object_rules` is the stable object-level rule source.
|
||||
- `object_geometry_allowlist` is the geometry whitelist used to separate valid multi-geometry objects from true anomalies.
|
||||
- `spatial_anomalies` is intentionally lightweight and currently focuses on tile-density and tile-index anomalies.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- No render equivalence break
|
||||
- No classification errors
|
||||
- No geometry consistency errors
|
||||
- No detection catalog integrity errors
|
||||
- Spatial anomalies limited to acceptable warnings
|
||||
229
tasks/WeatherServer_GridBuilder
Normal file
229
tasks/WeatherServer_GridBuilder
Normal file
@@ -0,0 +1,229 @@
|
||||
# NavSea Weather Server
|
||||
Task: WeatherServer_GridBuilder
|
||||
Architecture: NavSea V11
|
||||
Codex: codex6
|
||||
Status: TODO
|
||||
|
||||
---
|
||||
|
||||
# 1 任务目标
|
||||
|
||||
实现 Weather Grid Builder 模块。
|
||||
|
||||
功能:
|
||||
|
||||
将 GRIB 数据解析为统一的 Weather Grid 数据结构。
|
||||
|
||||
输入:
|
||||
|
||||
data/grib/*.grib2
|
||||
|
||||
输出:
|
||||
|
||||
data/grid/*.json
|
||||
|
||||
Weather Grid 将作为:
|
||||
|
||||
Vector Tile Generator
|
||||
Routing Engine
|
||||
Weather Analysis
|
||||
|
||||
的基础数据源。
|
||||
|
||||
---
|
||||
|
||||
# 2 输入数据
|
||||
|
||||
GRIB 文件来自 Downloader。
|
||||
|
||||
示例:
|
||||
|
||||
data/grib/
|
||||
|
||||
20260312_00_f000.grib2
|
||||
20260312_00_f003.grib2
|
||||
20260312_00_f006.grib2
|
||||
|
||||
变量:
|
||||
|
||||
UGRD
|
||||
VGRD
|
||||
APCP
|
||||
PRMSL
|
||||
TMP
|
||||
|
||||
---
|
||||
|
||||
# 3 Weather Grid 数据结构
|
||||
|
||||
每个 grid 点结构:
|
||||
|
||||
{
|
||||
"lat": float,
|
||||
"lon": float,
|
||||
"wind_speed": float,
|
||||
"wind_dir": float,
|
||||
"rain": float,
|
||||
"temp": float,
|
||||
"pressure": float
|
||||
}
|
||||
|
||||
说明:
|
||||
|
||||
lat 纬度
|
||||
lon 经度
|
||||
|
||||
wind_speed m/s
|
||||
wind_dir 度
|
||||
|
||||
rain mm
|
||||
|
||||
temp 摄氏度
|
||||
|
||||
pressure hPa
|
||||
|
||||
---
|
||||
|
||||
# 4 风速计算
|
||||
|
||||
使用 U/V 分量计算:
|
||||
|
||||
wind_speed = sqrt(u² + v²)
|
||||
|
||||
---
|
||||
|
||||
# 5 风向计算
|
||||
|
||||
公式:
|
||||
|
||||
wind_dir = (atan2(u, v) * 180 / π + 360) % 360
|
||||
|
||||
结果:
|
||||
|
||||
0–360°
|
||||
|
||||
---
|
||||
|
||||
# 6 Grid Builder 输出
|
||||
|
||||
文件:
|
||||
|
||||
data/grid/
|
||||
|
||||
示例:
|
||||
|
||||
grid_20260312_00_f000.json
|
||||
|
||||
结构:
|
||||
|
||||
{
|
||||
"time": "20260312_00_f000",
|
||||
"points": [...]
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
# 7 创建文件
|
||||
|
||||
weather_server/grid/grid_builder.py
|
||||
|
||||
---
|
||||
|
||||
# 8 实现代码
|
||||
|
||||
```python
|
||||
import os
|
||||
import json
|
||||
import numpy as np
|
||||
import xarray as xr
|
||||
|
||||
INPUT_DIR = "data/grib"
|
||||
OUTPUT_DIR = "data/grid"
|
||||
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
|
||||
def compute_wind(u, v):
|
||||
|
||||
speed = np.sqrt(u**2 + v**2)
|
||||
|
||||
direction = (np.degrees(np.arctan2(u, v)) + 360) % 360
|
||||
|
||||
return speed, direction
|
||||
|
||||
|
||||
def process_file(path):
|
||||
|
||||
ds = xr.open_dataset(path, engine="cfgrib")
|
||||
|
||||
u = ds["u10"].values
|
||||
v = ds["v10"].values
|
||||
rain = ds["tp"].values
|
||||
pressure = ds["msl"].values
|
||||
temp = ds["t2m"].values
|
||||
|
||||
lat = ds.latitude.values
|
||||
lon = ds.longitude.values
|
||||
|
||||
wind_speed, wind_dir = compute_wind(u, v)
|
||||
|
||||
points = []
|
||||
|
||||
for i in range(len(lat)):
|
||||
|
||||
for j in range(len(lon)):
|
||||
|
||||
point = {
|
||||
|
||||
"lat": float(lat[i]),
|
||||
"lon": float(lon[j]),
|
||||
|
||||
"wind_speed": float(wind_speed[i][j]),
|
||||
"wind_dir": float(wind_dir[i][j]),
|
||||
|
||||
"rain": float(rain[i][j]),
|
||||
|
||||
"temp": float(temp[i][j]),
|
||||
|
||||
"pressure": float(pressure[i][j])
|
||||
}
|
||||
|
||||
points.append(point)
|
||||
|
||||
return points
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
for file in os.listdir(INPUT_DIR):
|
||||
|
||||
if not file.endswith(".grib2"):
|
||||
continue
|
||||
|
||||
path = os.path.join(INPUT_DIR, file)
|
||||
|
||||
print("processing", file)
|
||||
|
||||
points = process_file(path)
|
||||
|
||||
output = os.path.join(
|
||||
OUTPUT_DIR,
|
||||
f"grid_{file.replace('.grib2','')}.json"
|
||||
)
|
||||
|
||||
data = {
|
||||
|
||||
"time": file.replace(".grib2",""),
|
||||
"points": points
|
||||
}
|
||||
|
||||
with open(output, "w") as f:
|
||||
|
||||
json.dump(data, f)
|
||||
|
||||
print("saved", output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
main()
|
||||
215
tasks/WeatherServer_GridBuilder_v2.md
Normal file
215
tasks/WeatherServer_GridBuilder_v2.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# NavSea Weather Server
|
||||
Task: WeatherServer_GridBuilder_v2
|
||||
Architecture: NavSea V11
|
||||
Codex: codex6
|
||||
Status: TODO
|
||||
|
||||
---
|
||||
|
||||
# 1 任务目标
|
||||
|
||||
升级 Grid Builder:
|
||||
|
||||
grid_builder.py → GridBuilder v2
|
||||
|
||||
目标:
|
||||
|
||||
1 裁剪日本区域 grid
|
||||
2 使用数组结构保存 grid
|
||||
3 大幅减少 JSON 文件大小
|
||||
|
||||
---
|
||||
|
||||
# 2 当前问题
|
||||
|
||||
旧版 GridBuilder:
|
||||
|
||||
生成全球 grid:
|
||||
|
||||
1440 × 721
|
||||
≈ 1,038,240 points
|
||||
|
||||
JSON 文件:
|
||||
|
||||
≈ 215MB
|
||||
|
||||
这是不可接受的。
|
||||
|
||||
Downloader 已经只下载:
|
||||
|
||||
120E – 150E
|
||||
20N – 50N
|
||||
|
||||
GridBuilder 必须只输出这个区域。
|
||||
|
||||
---
|
||||
|
||||
# 3 区域范围
|
||||
|
||||
REGION:
|
||||
|
||||
lon_min = 120
|
||||
lon_max = 150
|
||||
|
||||
lat_min = 20
|
||||
lat_max = 50
|
||||
|
||||
理论 grid:
|
||||
|
||||
(150-120)/0.25 = 120
|
||||
(50-20)/0.25 = 120
|
||||
|
||||
≈ 14400 grid points
|
||||
|
||||
---
|
||||
|
||||
# 4 新 Grid 数据结构
|
||||
|
||||
旧结构:
|
||||
|
||||
points list
|
||||
|
||||
{
|
||||
"points":[
|
||||
{lat,lon,...}
|
||||
]
|
||||
}
|
||||
|
||||
新结构:
|
||||
|
||||
grid arrays
|
||||
|
||||
{
|
||||
"time": "...",
|
||||
"lat": [...],
|
||||
"lon": [...],
|
||||
"wind_speed": [...],
|
||||
"wind_dir": [...],
|
||||
"rain": [...],
|
||||
"temp": [...],
|
||||
"pressure": [...]
|
||||
}
|
||||
|
||||
优点:
|
||||
|
||||
1 文件更小
|
||||
2 读取更快
|
||||
3 tile generator 更容易
|
||||
|
||||
---
|
||||
|
||||
# 5 创建文件
|
||||
|
||||
weather_server/grid/grid_builder_v2.py
|
||||
|
||||
---
|
||||
|
||||
# 6 实现代码
|
||||
|
||||
```python
|
||||
import os
|
||||
import json
|
||||
import numpy as np
|
||||
import xarray as xr
|
||||
|
||||
INPUT_DIR = "data/grib"
|
||||
OUTPUT_DIR = "data/grid"
|
||||
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
REGION = {
|
||||
"lon_min":120,
|
||||
"lon_max":150,
|
||||
"lat_min":20,
|
||||
"lat_max":50
|
||||
}
|
||||
|
||||
|
||||
def compute_wind(u, v):
|
||||
|
||||
speed = np.sqrt(u**2 + v**2)
|
||||
|
||||
direction = (np.degrees(np.arctan2(u, v)) + 360) % 360
|
||||
|
||||
return speed, direction
|
||||
|
||||
|
||||
def process_file(path):
|
||||
|
||||
ds = xr.open_dataset(path, engine="cfgrib")
|
||||
|
||||
u = ds["u10"].values
|
||||
v = ds["v10"].values
|
||||
rain = ds["tp"].values
|
||||
pressure = ds["msl"].values
|
||||
temp = ds["t2m"].values
|
||||
|
||||
lat = ds.latitude.values
|
||||
lon = ds.longitude.values
|
||||
|
||||
wind_speed, wind_dir = compute_wind(u, v)
|
||||
|
||||
lat_idx = np.where(
|
||||
(lat >= REGION["lat_min"]) &
|
||||
(lat <= REGION["lat_max"])
|
||||
)[0]
|
||||
|
||||
lon_idx = np.where(
|
||||
(lon >= REGION["lon_min"]) &
|
||||
(lon <= REGION["lon_max"])
|
||||
)[0]
|
||||
|
||||
lat_region = lat[lat_idx]
|
||||
lon_region = lon[lon_idx]
|
||||
|
||||
wind_speed = wind_speed[np.ix_(lat_idx, lon_idx)]
|
||||
wind_dir = wind_dir[np.ix_(lat_idx, lon_idx)]
|
||||
|
||||
rain = rain[np.ix_(lat_idx, lon_idx)]
|
||||
temp = temp[np.ix_(lat_idx, lon_idx)]
|
||||
pressure = pressure[np.ix_(lat_idx, lon_idx)]
|
||||
|
||||
return {
|
||||
"lat": lat_region.tolist(),
|
||||
"lon": lon_region.tolist(),
|
||||
"wind_speed": wind_speed.tolist(),
|
||||
"wind_dir": wind_dir.tolist(),
|
||||
"rain": rain.tolist(),
|
||||
"temp": temp.tolist(),
|
||||
"pressure": pressure.tolist()
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
for file in os.listdir(INPUT_DIR):
|
||||
|
||||
if not file.endswith(".grib2"):
|
||||
continue
|
||||
|
||||
path = os.path.join(INPUT_DIR, file)
|
||||
|
||||
print("processing", file)
|
||||
|
||||
grid = process_file(path)
|
||||
|
||||
output = os.path.join(
|
||||
OUTPUT_DIR,
|
||||
f"grid_{file.replace('.grib2','')}.json"
|
||||
)
|
||||
|
||||
data = {
|
||||
"time": file.replace(".grib2",""),
|
||||
"grid": grid
|
||||
}
|
||||
|
||||
with open(output, "w") as f:
|
||||
|
||||
json.dump(data, f)
|
||||
|
||||
print("saved", output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
main()
|
||||
248
tasks/WeatherServer_VectorTileGenerator.md
Normal file
248
tasks/WeatherServer_VectorTileGenerator.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# NavSea Weather Server
|
||||
Task: WeatherServer_VectorTileGenerator
|
||||
Architecture: NavSea V11
|
||||
Codex: codex6
|
||||
Status: TODO
|
||||
|
||||
---
|
||||
|
||||
# 1 任务目标
|
||||
|
||||
实现 Vector Tile Generator。
|
||||
|
||||
功能:
|
||||
|
||||
将 Weather Grid JSON 转换为 MapLibre Vector Tile (PBF)。
|
||||
|
||||
输入:
|
||||
|
||||
data/grid/*.json
|
||||
|
||||
输出:
|
||||
|
||||
output/weather/{time}/{z}/{x}/{y}.pbf
|
||||
|
||||
用于 NavSea 客户端加载天气图层。
|
||||
|
||||
---
|
||||
|
||||
# 2 使用库
|
||||
|
||||
需要安装:
|
||||
|
||||
pip install mercantile
|
||||
pip install mapbox-vector-tile
|
||||
|
||||
---
|
||||
|
||||
# 3 输入数据
|
||||
|
||||
GridBuilder v2 生成:
|
||||
|
||||
data/grid/
|
||||
|
||||
grid_20260312_00_f000.json
|
||||
grid_20260312_00_f003.json
|
||||
|
||||
结构:
|
||||
|
||||
{
|
||||
"time": "...",
|
||||
"grid": {
|
||||
"lat": [...],
|
||||
"lon": [...],
|
||||
"wind_speed": [[...]],
|
||||
"wind_dir": [[...]],
|
||||
"rain": [[...]],
|
||||
"temp": [[...]],
|
||||
"pressure": [[...]]
|
||||
}
|
||||
}
|
||||
|
||||
grid 尺寸:
|
||||
|
||||
121 × 121
|
||||
|
||||
---
|
||||
|
||||
# 4 Tile Zoom 设计
|
||||
|
||||
Weather tile 只需要 4 个 zoom:
|
||||
|
||||
2
|
||||
4
|
||||
6
|
||||
8
|
||||
|
||||
---
|
||||
|
||||
# 5 Tile 输出结构
|
||||
|
||||
output/weather/
|
||||
|
||||
time/
|
||||
z/
|
||||
x/
|
||||
y.pbf
|
||||
|
||||
示例:
|
||||
|
||||
output/weather/20260312_00_f000/4/10/7.pbf
|
||||
|
||||
---
|
||||
|
||||
# 6 Feature 结构
|
||||
|
||||
每个 grid 点 → 一个 feature
|
||||
|
||||
geometry:
|
||||
|
||||
POINT(lon lat)
|
||||
|
||||
properties:
|
||||
|
||||
{
|
||||
"ws": wind_speed
|
||||
"wd": wind_dir
|
||||
"r": rain
|
||||
"t": temp
|
||||
"p": pressure
|
||||
}
|
||||
|
||||
字段缩写减少 tile 大小。
|
||||
|
||||
---
|
||||
|
||||
# 7 创建文件
|
||||
|
||||
weather_server/tiles/vector_tile_generator.py
|
||||
|
||||
---
|
||||
|
||||
# 8 实现代码
|
||||
|
||||
```python
|
||||
import os
|
||||
import json
|
||||
import mercantile
|
||||
import mapbox_vector_tile
|
||||
|
||||
GRID_DIR = "data/grid"
|
||||
OUTPUT_DIR = "output/weather"
|
||||
|
||||
ZOOMS = [2,4,6,8]
|
||||
|
||||
def load_grid(path):
|
||||
|
||||
with open(path) as f:
|
||||
data = json.load(f)
|
||||
|
||||
return data["time"], data["grid"]
|
||||
|
||||
|
||||
def grid_to_features(grid):
|
||||
|
||||
lat = grid["lat"]
|
||||
lon = grid["lon"]
|
||||
|
||||
ws = grid["wind_speed"]
|
||||
wd = grid["wind_dir"]
|
||||
rain = grid["rain"]
|
||||
temp = grid["temp"]
|
||||
pres = grid["pressure"]
|
||||
|
||||
features = []
|
||||
|
||||
for i in range(len(lat)):
|
||||
for j in range(len(lon)):
|
||||
|
||||
feature = {
|
||||
"geometry":{
|
||||
"type":"Point",
|
||||
"coordinates":[lon[j], lat[i]]
|
||||
},
|
||||
"properties":{
|
||||
"ws":ws[i][j],
|
||||
"wd":wd[i][j],
|
||||
"r":rain[i][j],
|
||||
"t":temp[i][j],
|
||||
"p":pres[i][j]
|
||||
}
|
||||
}
|
||||
|
||||
features.append(feature)
|
||||
|
||||
return features
|
||||
|
||||
|
||||
def generate_tiles(time, features):
|
||||
|
||||
for z in ZOOMS:
|
||||
|
||||
tiles = mercantile.tiles(120,20,150,50,z)
|
||||
|
||||
for tile in tiles:
|
||||
|
||||
bounds = mercantile.bounds(tile)
|
||||
|
||||
tile_features = []
|
||||
|
||||
for f in features:
|
||||
|
||||
lon, lat = f["geometry"]["coordinates"]
|
||||
|
||||
if (
|
||||
bounds.west <= lon <= bounds.east
|
||||
and bounds.south <= lat <= bounds.north
|
||||
):
|
||||
tile_features.append(f)
|
||||
|
||||
if not tile_features:
|
||||
continue
|
||||
|
||||
layer = {
|
||||
"weather": tile_features
|
||||
}
|
||||
|
||||
tile_data = mapbox_vector_tile.encode(layer)
|
||||
|
||||
path = os.path.join(
|
||||
OUTPUT_DIR,
|
||||
time,
|
||||
str(z),
|
||||
str(tile.x)
|
||||
)
|
||||
|
||||
os.makedirs(path, exist_ok=True)
|
||||
|
||||
filename = os.path.join(
|
||||
path,
|
||||
f"{tile.y}.pbf"
|
||||
)
|
||||
|
||||
with open(filename,"wb") as f:
|
||||
f.write(tile_data)
|
||||
|
||||
print("tile", time, z, tile.x, tile.y)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
for file in os.listdir(GRID_DIR):
|
||||
|
||||
if not file.endswith(".json"):
|
||||
continue
|
||||
|
||||
path = os.path.join(GRID_DIR, file)
|
||||
|
||||
print("processing", file)
|
||||
|
||||
time, grid = load_grid(path)
|
||||
|
||||
features = grid_to_features(grid)
|
||||
|
||||
generate_tiles(time, features)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
528
tasks/classfild.md
Normal file
528
tasks/classfild.md
Normal file
@@ -0,0 +1,528 @@
|
||||
# NavSea Data Classification & Validation Pipeline
|
||||
Version: v1.0
|
||||
|
||||
|
||||
Goal:
|
||||
|
||||
从当前数据库中的 PBF 数据自动:
|
||||
|
||||
1. 解析 at 字段
|
||||
2. 构建语义属性表
|
||||
3. 构建对象目录
|
||||
4. 自动推导对象类型
|
||||
5. 验证分类正确性
|
||||
6. 统计 tile 密度
|
||||
7. 输出 NavSea 分类报告
|
||||
|
||||
所有中间结果写入 MySQL 表。
|
||||
|
||||
数据库在 192.168.200.184. root/2chi9ks2
|
||||
可以建立数据库,也可以使用python代码,必要的时候可以下载所需的包。
|
||||
---
|
||||
|
||||
# TASK 1
|
||||
Parse AT Attributes
|
||||
|
||||
Goal:
|
||||
解析 properties 表中 k='at' 的 JSON 字符串。
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS at_attributes (
|
||||
feature_id BIGINT,
|
||||
k VARCHAR(100),
|
||||
v TEXT
|
||||
);
|
||||
```
|
||||
|
||||
Logic:
|
||||
|
||||
1. 查询
|
||||
|
||||
```sql
|
||||
SELECT feature_id, v
|
||||
FROM properties
|
||||
WHERE k='at';
|
||||
```
|
||||
|
||||
2. v 是 JSON array
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
[["レイヤ","航路標識点"],["形状分類","シーバース灯"],["灯色","W (白)"]]
|
||||
```
|
||||
|
||||
3. 解析后写入:
|
||||
|
||||
```
|
||||
feature_id | k | v
|
||||
--------------------
|
||||
2682088 | レイヤ | 航路標識点
|
||||
2682088 | 形状分類 | シーバース灯
|
||||
2682088 | 灯色 | W (白)
|
||||
```
|
||||
|
||||
Implementation:
|
||||
|
||||
Python
|
||||
Libraries:
|
||||
|
||||
```
|
||||
pymysql
|
||||
json
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
table: at_attributes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# TASK 2
|
||||
Build Feature Semantic Table
|
||||
|
||||
Goal:
|
||||
|
||||
将 feature + vt_layer + at 属性合并。
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE feature_semantic AS
|
||||
SELECT
|
||||
f.id AS feature_id,
|
||||
f.vt_layer,
|
||||
f.geom_type,
|
||||
MAX(CASE WHEN a.k='分類' THEN a.v END) AS class_name,
|
||||
MAX(CASE WHEN a.k='形状分類' THEN a.v END) AS shape_name,
|
||||
MAX(CASE WHEN a.k='レイヤ' THEN a.v END) AS layer_name
|
||||
FROM features f
|
||||
LEFT JOIN at_attributes a
|
||||
ON f.id = a.feature_id
|
||||
GROUP BY f.id;
|
||||
```
|
||||
|
||||
Output table:
|
||||
|
||||
```
|
||||
feature_semantic
|
||||
```
|
||||
|
||||
Columns:
|
||||
|
||||
```
|
||||
feature_id
|
||||
vt_layer
|
||||
geom_type
|
||||
class_name
|
||||
shape_name
|
||||
layer_name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# TASK 3
|
||||
Generate Object Catalog
|
||||
|
||||
Goal:
|
||||
|
||||
统计所有语义对象。
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE object_catalog AS
|
||||
SELECT
|
||||
layer_name,
|
||||
class_name,
|
||||
shape_name,
|
||||
vt_layer,
|
||||
geom_type,
|
||||
COUNT(*) AS feature_count
|
||||
FROM feature_semantic
|
||||
GROUP BY
|
||||
layer_name,
|
||||
class_name,
|
||||
shape_name,
|
||||
vt_layer,
|
||||
geom_type;
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
object_catalog
|
||||
```
|
||||
|
||||
Purpose:
|
||||
|
||||
得到完整对象目录。
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
魚礁 | p施設 | Point | 24683
|
||||
灯台 | p航路標識群 | Point | 18000
|
||||
等深線 | L等深線 | Line | 440000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# TASK 4
|
||||
Geometry Consistency Check
|
||||
|
||||
Goal:
|
||||
|
||||
检查对象是否使用一致 geometry。
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE geometry_consistency AS
|
||||
SELECT
|
||||
class_name,
|
||||
geom_type,
|
||||
COUNT(*) AS feature_count
|
||||
FROM feature_semantic
|
||||
GROUP BY class_name, geom_type;
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
geometry_consistency
|
||||
```
|
||||
|
||||
Purpose:
|
||||
|
||||
发现异常对象。
|
||||
|
||||
Example anomaly:
|
||||
|
||||
```
|
||||
灯台 | Polygon
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# TASK 5
|
||||
Candidate Object Type Detection
|
||||
|
||||
Goal:
|
||||
|
||||
自动推导 object_type。
|
||||
|
||||
规则优先级:
|
||||
|
||||
1 class_name
|
||||
2 shape_name
|
||||
3 vt_layer
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE object_type_candidates AS
|
||||
SELECT
|
||||
feature_id,
|
||||
COALESCE(class_name, shape_name, vt_layer) AS object_type,
|
||||
geom_type
|
||||
FROM feature_semantic;
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
object_type_candidates
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# TASK 6
|
||||
Object Type Statistics
|
||||
|
||||
Goal:
|
||||
|
||||
统计对象数量。
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE object_type_stats AS
|
||||
SELECT
|
||||
object_type,
|
||||
geom_type,
|
||||
COUNT(*) AS feature_count
|
||||
FROM object_type_candidates
|
||||
GROUP BY object_type, geom_type;
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
object_type_stats
|
||||
```
|
||||
|
||||
Purpose:
|
||||
|
||||
识别主要对象。
|
||||
|
||||
---
|
||||
|
||||
# TASK 7
|
||||
Style Cross Reference
|
||||
|
||||
Goal:
|
||||
|
||||
分析 style.json。
|
||||
|
||||
Extract:
|
||||
|
||||
```
|
||||
layer_id
|
||||
source-layer
|
||||
icon-image
|
||||
line-color
|
||||
fill-color
|
||||
```
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE style_layers (
|
||||
layer_id VARCHAR(200),
|
||||
source_layer VARCHAR(200),
|
||||
icon VARCHAR(200),
|
||||
line_color VARCHAR(200),
|
||||
fill_color VARCHAR(200)
|
||||
);
|
||||
```
|
||||
|
||||
Join:
|
||||
|
||||
```sql
|
||||
CREATE TABLE style_mapping AS
|
||||
SELECT
|
||||
s.layer_id,
|
||||
s.icon,
|
||||
o.object_type,
|
||||
o.geom_type
|
||||
FROM style_layers s
|
||||
JOIN object_type_candidates o
|
||||
ON s.source_layer = o.object_type;
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
style_mapping
|
||||
```
|
||||
|
||||
Purpose:
|
||||
|
||||
确认对象 → 图标关系。
|
||||
|
||||
---
|
||||
|
||||
# TASK 8
|
||||
Tile Density Analysis
|
||||
|
||||
Goal:
|
||||
|
||||
统计 tile feature 密度。
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE tile_density AS
|
||||
SELECT
|
||||
z,
|
||||
x,
|
||||
y,
|
||||
COUNT(*) AS feature_count
|
||||
FROM features
|
||||
GROUP BY z,x,y;
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
tile_density
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# TASK 9
|
||||
Tile Density Top 100
|
||||
|
||||
Create Table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE tile_density_top100 AS
|
||||
SELECT *
|
||||
FROM tile_density
|
||||
ORDER BY feature_count DESC
|
||||
LIMIT 100;
|
||||
```
|
||||
|
||||
Purpose:
|
||||
|
||||
识别高密度 tile。
|
||||
|
||||
---
|
||||
|
||||
# TASK 10
|
||||
Spatial Sanity Checks
|
||||
|
||||
Goal:
|
||||
|
||||
发现明显错误。
|
||||
|
||||
Examples:
|
||||
|
||||
Navigation lights not point:
|
||||
|
||||
```sql
|
||||
CREATE TABLE anomaly_navigation_geom AS
|
||||
SELECT *
|
||||
FROM feature_semantic
|
||||
WHERE class_name='灯台'
|
||||
AND geom_type!='Point';
|
||||
```
|
||||
|
||||
Reef not point/polygon:
|
||||
|
||||
```sql
|
||||
CREATE TABLE anomaly_reef_geom AS
|
||||
SELECT *
|
||||
FROM feature_semantic
|
||||
WHERE class_name='魚礁'
|
||||
AND geom_type NOT IN ('Point','Polygon');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# TASK 11
|
||||
NavSea Classification Report
|
||||
|
||||
Generate markdown:
|
||||
|
||||
```
|
||||
navsea_classification_report.md
|
||||
```
|
||||
|
||||
Content:
|
||||
|
||||
## Dataset Summary
|
||||
|
||||
Total features:
|
||||
|
||||
```sql
|
||||
SELECT COUNT(*) FROM features;
|
||||
```
|
||||
|
||||
Total object types:
|
||||
|
||||
```sql
|
||||
SELECT COUNT(DISTINCT object_type)
|
||||
FROM object_type_candidates;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Top Object Types
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM object_type_stats
|
||||
ORDER BY feature_count DESC
|
||||
LIMIT 50;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Geometry Consistency
|
||||
|
||||
```
|
||||
geometry_consistency
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Style Mapping
|
||||
|
||||
```
|
||||
style_mapping
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tile Density
|
||||
|
||||
```
|
||||
tile_density_top100
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Final Deliverables
|
||||
|
||||
Database Tables:
|
||||
|
||||
```
|
||||
at_attributes
|
||||
feature_semantic
|
||||
object_catalog
|
||||
geometry_consistency
|
||||
object_type_candidates
|
||||
object_type_stats
|
||||
style_layers
|
||||
style_mapping
|
||||
tile_density
|
||||
tile_density_top100
|
||||
anomaly_navigation_geom
|
||||
anomaly_reef_geom
|
||||
```
|
||||
|
||||
Final Document:
|
||||
|
||||
```
|
||||
navsea_classification_report.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Execution
|
||||
|
||||
Single command:
|
||||
|
||||
```
|
||||
python navsea_audit.py
|
||||
```
|
||||
|
||||
Pipeline:
|
||||
|
||||
```
|
||||
parse_at
|
||||
→ semantic_table
|
||||
→ object_catalog
|
||||
→ classification
|
||||
→ validation
|
||||
→ report
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Success Criteria
|
||||
|
||||
The system must allow answering:
|
||||
|
||||
1 What objects exist
|
||||
2 How many features each object has
|
||||
3 What geometry they use
|
||||
4 How they are styled
|
||||
5 Whether classification is consistent
|
||||
6 Whether tile density is reasonable
|
||||
151
tasks/firsttest.md
Normal file
151
tasks/firsttest.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# NavSea Weather Server Step-1
|
||||
GRIB 解析环境测试
|
||||
|
||||
目标:
|
||||
|
||||
验证服务器可以正确解析 GRIB 文件。
|
||||
|
||||
---
|
||||
|
||||
# 1 安装系统依赖
|
||||
|
||||
在 Linux 服务器执行:
|
||||
|
||||
apt update
|
||||
|
||||
apt install -y python3 python3-pip
|
||||
|
||||
apt install -y libeccodes0 libeccodes-dev
|
||||
|
||||
apt install -y python3-eccodes
|
||||
|
||||
---
|
||||
|
||||
# 2 安装 Python 库
|
||||
|
||||
pip3 install cfgrib
|
||||
pip3 install xarray
|
||||
pip3 install numpy
|
||||
|
||||
---
|
||||
|
||||
# 3 下载测试 GRIB 文件
|
||||
|
||||
创建测试目录:
|
||||
|
||||
mkdir weather_test
|
||||
cd weather_test
|
||||
|
||||
下载 NOAA GFS 示例:
|
||||
|
||||
wget https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.20260312/00/atmos/gfs.t00z.pgrb2.0p25.f003 -O test.grib2
|
||||
|
||||
(如果日期目录不存在,可以换最新日期)
|
||||
|
||||
---
|
||||
|
||||
# 4 创建测试脚本
|
||||
|
||||
创建文件:
|
||||
|
||||
test_grib.py
|
||||
|
||||
内容:
|
||||
|
||||
import xarray as xr
|
||||
|
||||
file = "test.grib2"
|
||||
|
||||
print("Opening GRIB file...")
|
||||
|
||||
ds = xr.open_dataset(file, engine="cfgrib")
|
||||
|
||||
print("Dataset loaded")
|
||||
|
||||
print(ds)
|
||||
|
||||
print("\nVariables:")
|
||||
print(ds.data_vars)
|
||||
|
||||
---
|
||||
|
||||
# 5 运行测试
|
||||
|
||||
python3 test_grib.py
|
||||
|
||||
如果成功,你会看到类似输出:
|
||||
|
||||
Dataset loaded
|
||||
|
||||
Dimensions:
|
||||
latitude: 721
|
||||
longitude: 1440
|
||||
|
||||
Variables:
|
||||
u10
|
||||
v10
|
||||
t2m
|
||||
msl
|
||||
tp
|
||||
|
||||
---
|
||||
|
||||
# 6 测试读取风数据
|
||||
|
||||
修改脚本:
|
||||
|
||||
import xarray as xr
|
||||
import numpy as np
|
||||
|
||||
file = "test.grib2"
|
||||
|
||||
ds = xr.open_dataset(file, engine="cfgrib")
|
||||
|
||||
u = ds['u10']
|
||||
v = ds['v10']
|
||||
|
||||
speed = np.sqrt(u**2 + v**2)
|
||||
|
||||
print("Wind sample:")
|
||||
|
||||
print(speed.values[0][0])
|
||||
|
||||
---
|
||||
|
||||
# 7 成功标志
|
||||
|
||||
如果成功运行:
|
||||
|
||||
说明:
|
||||
|
||||
GRIB解析正常
|
||||
Python环境正常
|
||||
可以进入 Weather Server 开发
|
||||
|
||||
---
|
||||
|
||||
# 8 常见错误
|
||||
|
||||
错误:
|
||||
|
||||
eccodes library not found
|
||||
|
||||
解决:
|
||||
|
||||
apt install libeccodes-dev
|
||||
|
||||
---
|
||||
|
||||
# 9 完成后下一步
|
||||
|
||||
下一步开发:
|
||||
|
||||
GRIB Downloader
|
||||
|
||||
模块:
|
||||
|
||||
weather_server/downloader/gfs_downloader.py
|
||||
|
||||
负责:
|
||||
|
||||
自动下载 GFS GRIB 数据。
|
||||
413
tasks/pbf/AllPbf.md
Normal file
413
tasks/pbf/AllPbf.md
Normal file
@@ -0,0 +1,413 @@
|
||||
# NavSea Server Codex Tasks v2
|
||||
|
||||
Architecture: NavSea V11 / Codex6
|
||||
Scope: **Server Side Only**
|
||||
|
||||
---
|
||||
|
||||
# Global Rules(全局强制规则)
|
||||
|
||||
以下规则适用于所有 NavSea Server Tasks。
|
||||
|
||||
## Rule 1 — 必须保留原始 PBF 属性
|
||||
|
||||
语义系统 **不得删除或覆盖任何原始 PBF feature 属性**。
|
||||
|
||||
必须保留包括但不限于:
|
||||
|
||||
* 日文对象名称
|
||||
* 海图原始属性
|
||||
* 灯塔信息
|
||||
* 深度信息
|
||||
* 渔区信息
|
||||
* 海图符号属性
|
||||
* 任何原始 metadata
|
||||
|
||||
语义字段只能 **新增**,不能替换。
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
class = 灯
|
||||
shape = 灯標
|
||||
name = 大島灯台
|
||||
```
|
||||
|
||||
新增语义字段:
|
||||
|
||||
```
|
||||
canonical_object_type = navigation_aid_light
|
||||
object_family = navigation_aid
|
||||
detection_class = navigation_mark
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rule 2 — 不得修改 style.json 依赖属性
|
||||
|
||||
任何被 style.json 使用的属性字段 **必须保持不变**。
|
||||
|
||||
典型字段包括:
|
||||
|
||||
```
|
||||
source_layer
|
||||
class
|
||||
shape
|
||||
name
|
||||
symbol
|
||||
depth
|
||||
type
|
||||
category
|
||||
```
|
||||
|
||||
语义系统 **不得重命名或删除这些字段**。
|
||||
|
||||
---
|
||||
|
||||
## Rule 3 — 语义字段只能新增
|
||||
|
||||
NavSea Semantic Overlay 只能增加字段,例如:
|
||||
|
||||
```
|
||||
canonical_object_type
|
||||
object_family
|
||||
detection_class
|
||||
capability
|
||||
detection_key
|
||||
```
|
||||
|
||||
不得改变:
|
||||
|
||||
```
|
||||
geometry
|
||||
source_layer
|
||||
original_attributes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Task 01 — Semantic Overlay Validation System v2
|
||||
|
||||
## 任务目标
|
||||
|
||||
构建验证系统,确保语义重建不会破坏原始 PBF 渲染结构。
|
||||
|
||||
验证内容包括:
|
||||
|
||||
* feature 数量一致
|
||||
* geometry 类型一致
|
||||
* style 渲染一致
|
||||
* 原始属性完整保留
|
||||
|
||||
## 输入表
|
||||
|
||||
Codex 自动检测:
|
||||
|
||||
```
|
||||
canonical_layer_rules
|
||||
pbf_relayer_candidates
|
||||
pbf_render_compatibility
|
||||
pbf_detection_catalog
|
||||
```
|
||||
|
||||
## 输出验证表
|
||||
|
||||
```
|
||||
classification_validation
|
||||
geometry_consistency
|
||||
style_render_equivalence
|
||||
attribute_preservation_check
|
||||
semantic_validation_summary
|
||||
```
|
||||
|
||||
## 新增验证
|
||||
|
||||
必须新增:
|
||||
|
||||
```
|
||||
attribute_preservation_check
|
||||
```
|
||||
|
||||
用于确认:
|
||||
|
||||
```
|
||||
原始 PBF 属性未丢失
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Task 02 — Object Taxonomy Builder v2
|
||||
|
||||
## 任务目标
|
||||
|
||||
建立稳定的海图对象分类体系。
|
||||
|
||||
## 输出表
|
||||
|
||||
```
|
||||
navsea_object_taxonomy
|
||||
```
|
||||
|
||||
## 字段
|
||||
|
||||
```
|
||||
canonical_object_type
|
||||
object_family
|
||||
detection_class
|
||||
description
|
||||
```
|
||||
|
||||
## 示例
|
||||
|
||||
```
|
||||
rock → hazard → obstacle
|
||||
wreck → hazard → obstacle
|
||||
reef → hazard → obstacle
|
||||
|
||||
light → navigation_aid → navigation_mark
|
||||
```
|
||||
|
||||
## 约束
|
||||
|
||||
Taxonomy 不能改变:
|
||||
|
||||
```
|
||||
source_layer
|
||||
original_attributes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Task 03 — Object Capability System v2
|
||||
|
||||
## 任务目标
|
||||
|
||||
定义海图对象在航行中的能力(capability)。
|
||||
|
||||
## 输出表
|
||||
|
||||
```
|
||||
navsea_object_capabilities
|
||||
```
|
||||
|
||||
## 字段
|
||||
|
||||
```
|
||||
canonical_object_type
|
||||
capability
|
||||
```
|
||||
|
||||
## 示例
|
||||
|
||||
```
|
||||
rock → collision
|
||||
wreck → collision
|
||||
reef → grounding
|
||||
fishery → entangle
|
||||
light → navigation_mark
|
||||
breakwater → wave_barrier
|
||||
```
|
||||
|
||||
## 目的
|
||||
|
||||
使检测系统可以查询:
|
||||
|
||||
```
|
||||
所有 collision 对象
|
||||
所有 grounding 对象
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Task 04 — Detection Object View v2
|
||||
|
||||
## 任务目标
|
||||
|
||||
创建统一检测对象视图。
|
||||
|
||||
## 视图
|
||||
|
||||
```
|
||||
navsea_detection_objects
|
||||
```
|
||||
|
||||
## 字段
|
||||
|
||||
```
|
||||
feature_id
|
||||
geometry
|
||||
canonical_object_type
|
||||
object_family
|
||||
detection_class
|
||||
capability
|
||||
detection_key
|
||||
```
|
||||
|
||||
## 数据来源
|
||||
|
||||
```
|
||||
pbf_relayer_candidates
|
||||
navsea_object_taxonomy
|
||||
navsea_object_capabilities
|
||||
```
|
||||
|
||||
## 约束
|
||||
|
||||
该视图:
|
||||
|
||||
```
|
||||
只读
|
||||
不修改原始数据
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Task 05 — Spatial Index Builder v2
|
||||
|
||||
## 任务目标
|
||||
|
||||
优化空间查询性能。
|
||||
|
||||
当前数据规模:
|
||||
|
||||
```
|
||||
~6.6 million features
|
||||
```
|
||||
|
||||
## Codex 任务
|
||||
|
||||
自动分析 geometry 字段并创建空间索引。
|
||||
|
||||
优化查询:
|
||||
|
||||
```
|
||||
半径查询
|
||||
航线走廊查询
|
||||
船舶前方查询
|
||||
```
|
||||
|
||||
## 目标对象
|
||||
|
||||
```
|
||||
navsea_detection_objects
|
||||
semantic feature tables
|
||||
```
|
||||
|
||||
## 约束
|
||||
|
||||
不得改变表结构。
|
||||
|
||||
---
|
||||
|
||||
# Task 08 — Semantic Layer Coverage Report v2
|
||||
|
||||
## 任务目标
|
||||
|
||||
统计语义系统覆盖率。
|
||||
|
||||
检测:
|
||||
|
||||
```
|
||||
未分类对象
|
||||
layer 覆盖率
|
||||
canonical_object 覆盖率
|
||||
```
|
||||
|
||||
## 输出表
|
||||
|
||||
```
|
||||
semantic_layer_coverage
|
||||
canonical_object_coverage
|
||||
source_layer_coverage
|
||||
unclassified_features
|
||||
coverage_summary
|
||||
```
|
||||
|
||||
## 用途
|
||||
|
||||
发现:
|
||||
|
||||
```
|
||||
规则遗漏
|
||||
新对象
|
||||
数据异常
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Task 09 — Vector Tile Semantic Drift Detection v2
|
||||
|
||||
## 任务目标
|
||||
|
||||
检测 PBF 更新导致的语义漂移。
|
||||
|
||||
## 检测内容
|
||||
|
||||
```
|
||||
新对象类型
|
||||
source_layer 变化
|
||||
geometry 类型变化
|
||||
属性结构变化
|
||||
语义规则冲突
|
||||
```
|
||||
|
||||
## 输出表
|
||||
|
||||
```
|
||||
semantic_drift_summary
|
||||
new_object_types
|
||||
source_layer_drift
|
||||
geometry_drift
|
||||
attribute_drift
|
||||
rule_conflict_report
|
||||
```
|
||||
|
||||
## 用途
|
||||
|
||||
确保新 PBF 数据不会破坏语义系统。
|
||||
|
||||
---
|
||||
|
||||
# 推荐执行顺序
|
||||
|
||||
```
|
||||
1 Semantic Overlay Validation
|
||||
2 Semantic Coverage Report
|
||||
3 Object Taxonomy
|
||||
4 Object Capability
|
||||
5 Detection Object View
|
||||
6 Spatial Index Builder
|
||||
7 Drift Detection
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 最终服务器结构
|
||||
|
||||
完成全部任务后服务器语义系统结构:
|
||||
|
||||
```
|
||||
PBF
|
||||
↓
|
||||
Semantic Reconstruction
|
||||
↓
|
||||
Taxonomy
|
||||
↓
|
||||
Capability
|
||||
↓
|
||||
Detection Objects
|
||||
↓
|
||||
Spatial Index
|
||||
↓
|
||||
Validation / Drift Monitoring
|
||||
```
|
||||
|
||||
该结构确保:
|
||||
|
||||
```
|
||||
PBF 稳定
|
||||
原始属性保留
|
||||
style.json 可安全重建
|
||||
```
|
||||
|
||||
---
|
||||
107
tasks/pbf/NavSea_Mapping_DB_Registry_v1.md
Normal file
107
tasks/pbf/NavSea_Mapping_DB_Registry_v1.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# NavSea 映射关系数据库固化方案 v1
|
||||
|
||||
版本:v1
|
||||
用途:把“旧版原始字段 / 层名 / 取值”和“新版标准化字段 / 语义 / 渲染语义”的关系正式固化到数据库里,作为后续规则审计、问题排查和构建回放的基础。
|
||||
|
||||
## 1 当前落地位置
|
||||
|
||||
本版已在 `pbf_analysis` 中建立以下正式对象:
|
||||
|
||||
- `navsea_rule_bundle`
|
||||
- `navsea_source_layer_rules`
|
||||
- `navsea_field_name_rules`
|
||||
- `navsea_field_value_rules`
|
||||
- `navsea_taxonomy_rules`
|
||||
- `navsea_render_rules`
|
||||
- `navsea_mapping_registry_vw`
|
||||
- `navsea_legacy_to_new_mapping_vw`
|
||||
- `navsea_new_to_legacy_mapping_vw`
|
||||
|
||||
## 2 规则源文件
|
||||
|
||||
数据库中的规则来自以下版本化文件:
|
||||
|
||||
- [navsea_rule_bundle_v1.yaml](/root/weather/tasks/pbf/mappings/navsea_rule_bundle_v1.yaml)
|
||||
- [navsea_source_layer_rules_v1.yaml](/root/weather/tasks/pbf/mappings/navsea_source_layer_rules_v1.yaml)
|
||||
- [navsea_field_name_rules_v1.yaml](/root/weather/tasks/pbf/mappings/navsea_field_name_rules_v1.yaml)
|
||||
- [navsea_field_value_rules_v1.yaml](/root/weather/tasks/pbf/mappings/navsea_field_value_rules_v1.yaml)
|
||||
- [navsea_taxonomy_rules_v1.yaml](/root/weather/tasks/pbf/mappings/navsea_taxonomy_rules_v1.yaml)
|
||||
- [navsea_render_rules_v1.yaml](/root/weather/tasks/pbf/mappings/navsea_render_rules_v1.yaml)
|
||||
|
||||
## 3 同步脚本
|
||||
|
||||
同步脚本:
|
||||
|
||||
- [navsea_mapping_registry_sync.py](/root/weather/navsea_mapping_registry_sync.py)
|
||||
- [navsea_mapping_registry.py](/root/weather/navsea_mapping_registry.py)
|
||||
|
||||
作用:
|
||||
|
||||
- 建表
|
||||
- 从 YAML 导入 bundle / layer / field / value / taxonomy / render 规则
|
||||
- 生成统一审计视图
|
||||
- 在运行时由 builder 直接读取数据库规则,不再在多个文件中重复维护同一份映射常量
|
||||
|
||||
## 4 双向查询口径
|
||||
|
||||
旧版查新版:
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM navsea_legacy_to_new_mapping_vw
|
||||
WHERE legacy_key = '分類番号' AND legacy_value = '428';
|
||||
```
|
||||
|
||||
新版查旧版:
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM navsea_new_to_legacy_mapping_vw
|
||||
WHERE new_key = 'chart_fill_style' AND new_value = 'fish_reef_area';
|
||||
```
|
||||
|
||||
## 5 当前 v1 覆盖内容
|
||||
|
||||
- `source-layer` 日文层名到标准层名
|
||||
- 旧字段名到标准字段名
|
||||
- 关键旧字段取值到标准值
|
||||
- taxonomy 规则
|
||||
- render 规则
|
||||
|
||||
## 6 当前边界
|
||||
|
||||
本版已经把映射关系正式固化到了数据库里,并且 builder 已开始直接消费数据库规则,当前已接入:
|
||||
|
||||
- `source-layer` 标准化
|
||||
- 旧字段值到新字段值的标准化
|
||||
- 首批 render 规则
|
||||
|
||||
但还没有把 builder 的全部 `infer_*` 分支完全改造成“只从数据库执行规则”。
|
||||
当前状态是:
|
||||
|
||||
- 规则资产已经固化在数据库
|
||||
- 代码侧只保留兜底逻辑,数据库规则优先
|
||||
- 后续可以逐步把执行层切到数据库规则驱动
|
||||
|
||||
## 6.1 未决对象处理规则
|
||||
|
||||
本体系中的“兜底”不等于“静默归入一个大筐”。
|
||||
|
||||
当前执行约束是:
|
||||
|
||||
- 如果没有命中特定 render 规则,不允许把 `REN-FALLBACK` 当成正常命中结果
|
||||
- 这类对象会被标记为 `trace_status = needs_review`
|
||||
- builder 会在每次构建后自动输出一份 `mapping_audit` 报告
|
||||
- 报告中会列出未决对象的来源层、对象类型、几何类型、样本 `fid` 和原因
|
||||
|
||||
这条约束的目的是:
|
||||
|
||||
- 不让未覆盖对象悄悄混进“正常渲染”
|
||||
- 不让规则缺口被一个泛化 fallback 掩盖
|
||||
- 让后续补规则时有明确的对象清单
|
||||
|
||||
## 7 建议下一步
|
||||
|
||||
- 增加 `navsea_feature_rule_trace` 的数据库写入
|
||||
- 让 builder 在 engineering 口径记录实际命中的 `taxonomy_rule_id` / `render_rule_id`
|
||||
- 逐步把 `infer_*` 硬编码分支迁移到规则表执行
|
||||
153
tasks/pbf/NavSea_Object_Taxonomy_Manual_Review_Task.md
Normal file
153
tasks/pbf/NavSea_Object_Taxonomy_Manual_Review_Task.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# NavSea Codex Task
|
||||
|
||||
# Object Taxonomy Manual Review Package Generator
|
||||
|
||||
Architecture: NavSea V11 / Codex6 Scope: Server Side Documentation /
|
||||
Review Preparation
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
# Task Name
|
||||
|
||||
NavSea_Object_Taxonomy_Manual_Review_Package
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
# Task Goal
|
||||
|
||||
Generate a manual review package for NavSea object taxonomy definition.
|
||||
|
||||
This task prepares a human-reviewable object classification package so
|
||||
that the user can confirm:
|
||||
|
||||
1. canonical object naming
|
||||
2. object family assignment
|
||||
3. detection class assignment
|
||||
4. whether mixed geometry objects should be unified or split
|
||||
5. whether some source layers are container layers rather than semantic
|
||||
layers
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
# Inputs
|
||||
|
||||
object_catalog object_type_stats feature_semantic object_type_candidates
|
||||
canonical_layer_rules canonical_object_rules pbf_source_object_stats
|
||||
pbf_detection_catalog
|
||||
|
||||
Optional reference:
|
||||
|
||||
style_layers style_mapping
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
# Output
|
||||
|
||||
NavSea_Object_Taxonomy_Manual_Review.md
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
# Required Structure of the Review Document
|
||||
|
||||
## 1 Review Objective
|
||||
|
||||
Explain that this package is for manual confirmation of:
|
||||
|
||||
- canonical object type naming
|
||||
- family grouping
|
||||
- detection grouping
|
||||
- geometry unification or splitting
|
||||
- ambiguous object handling
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 2 Review Priority Groups
|
||||
|
||||
Priority A --- Immediate navigation safety relevance
|
||||
|
||||
Examples: hazards, wrecks, rocks, reefs, dangerous obstacles, navigation
|
||||
marks, channels, anchorage, restricted areas, fishery hazards
|
||||
|
||||
Priority B --- Navigation context / operational relevance
|
||||
|
||||
Examples: boundaries, facilities, subsea cables / pipelines, port
|
||||
structures, land structures relevant to navigation
|
||||
|
||||
Priority C --- Background / rendering objects
|
||||
|
||||
Examples: labels, land background, rendering support layers
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 3 Manual Review Candidate Table
|
||||
|
||||
Required columns:
|
||||
|
||||
review_priority layer_name class_name shape_name vt_layer
|
||||
observed_geom_types total_feature_count suggested_canonical_object_type
|
||||
suggested_canonical_family suggested_detection_class
|
||||
suggested_review_reason needs_manual_review
|
||||
|
||||
needs_manual_review values:
|
||||
|
||||
YES NO
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 4 Ambiguity Categories
|
||||
|
||||
### Multi-Geometry Ambiguity
|
||||
|
||||
Same object appearing as multiple geometry types.
|
||||
|
||||
### Navigation Meaning Ambiguity
|
||||
|
||||
Objects implying collision / grounding / entanglement risk.
|
||||
|
||||
### Source Layer Container Ambiguity
|
||||
|
||||
Layers that may act as container or rendering layers.
|
||||
|
||||
### Regulatory / Boundary Ambiguity
|
||||
|
||||
Objects representing legal or navigational boundaries.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 5 First-Pass Recommended Review Scope
|
||||
|
||||
Focus first on classes similar to:
|
||||
|
||||
航行危険障害物 投錨注意障害物 航路標識点 航路境界等 錨泊地等
|
||||
施設・境界線等 海岸線等深線等 漁具定置箇所
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 6 Proposed Review Decisions
|
||||
|
||||
Each candidate object should include:
|
||||
|
||||
Candidate Object Suggested canonical_object_type Suggested
|
||||
canonical_family Suggested detection_class Reason Manual confirmation
|
||||
required
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 7 Layer Review Appendix
|
||||
|
||||
Columns:
|
||||
|
||||
source_layer semantic_granularity current_rule_guess review_reason
|
||||
needs_manual_review
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 8 Review Outcome Guidance
|
||||
|
||||
The user will confirm:
|
||||
|
||||
1 Confirm canonical object naming 2 Confirm family grouping 3 Confirm
|
||||
detection grouping 4 Confirm geometry unification 5 Confirm container
|
||||
layers
|
||||
|
||||
------------------------------------------------------------------------
|
||||
36
tasks/pbf/NavSea_PBF_schema_v1.md
Normal file
36
tasks/pbf/NavSea_PBF_schema_v1.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# NavSea PBF Schema v1
|
||||
|
||||
用途:定义 NavSea Vector Tile 的数据结构。
|
||||
|
||||
## 顶层字段
|
||||
|
||||
- identity
|
||||
- chart_semantics
|
||||
- labels
|
||||
- light
|
||||
- hazard
|
||||
- area
|
||||
- source_legacy
|
||||
|
||||
## identity
|
||||
|
||||
- fid
|
||||
- canonical_object_type
|
||||
- canonical_family
|
||||
- detection_key
|
||||
- render_layer
|
||||
|
||||
## chart_semantics
|
||||
|
||||
- chart_render_type
|
||||
- chart_symbol_family
|
||||
- chart_symbol_code
|
||||
- chart_priority
|
||||
- chart_visibility_min
|
||||
- chart_visibility_max
|
||||
|
||||
## labels
|
||||
|
||||
- chart_label_text
|
||||
- chart_label_subtext
|
||||
- chart_label_anchor
|
||||
226
tasks/pbf/NavSea_PBF_schema_v2.md
Normal file
226
tasks/pbf/NavSea_PBF_schema_v2.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# NavSea PBF Schema v2
|
||||
|
||||
版本:v2 Draft
|
||||
用途:定义 NavSea 交付用 Vector Tile 的字段结构,兼顾渲染、碰撞、检索和旧海图兼容。
|
||||
|
||||
## 1 设计目标
|
||||
|
||||
v2 schema 要同时满足四件事:
|
||||
|
||||
- 保持旧海图渲染内容不明显缩水
|
||||
- 支撑新的语义渲染体系
|
||||
- 支撑碰撞检测和检索
|
||||
- 控制字段职责,避免样式继续直接依赖大量原始编码
|
||||
|
||||
## 2 字段分组
|
||||
|
||||
v2 建议把交付字段分成 8 组:
|
||||
|
||||
- identity
|
||||
- taxonomy
|
||||
- render_semantics
|
||||
- labels
|
||||
- light
|
||||
- hazard_area
|
||||
- normalized_numeric
|
||||
- source_legacy
|
||||
|
||||
## 3 identity
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `fid` | string | 是 | NavSea 自有对象标识,使用可逆算法生成的 16 进制字符串 |
|
||||
| `fid_legacy_raw` | integer/string | 否 | 旧版原始 `fid`,建议只保留在 engineering 口径或 SQL trace |
|
||||
| `fid_algo_id` | string | 否 | `fid` 生成算法标识,例如 `feistel32_aes_cyclewalk_v1` |
|
||||
| `fid_key_id` | string | 否 | `fid` 生成时使用的密钥标识 |
|
||||
| `render_layer` | string | 是 | 交付瓦片中的目标图层名 |
|
||||
| `source_layer` | string | 否 | 原始图层名,建议保留到工程版或过渡期交付版 |
|
||||
|
||||
说明:
|
||||
|
||||
- 对“只做图片渲染”的产品可以弱化 `fid`
|
||||
- 对当前 NavSea 的交付目标,不建议删除 `fid`
|
||||
- 不建议继续直接暴露旧版原始 `fid`
|
||||
- 建议基于 `tasks/pbf/fiddecode.md` 的可逆算法生成 NavSea 自有 `fid`
|
||||
- 工程实现建议使用 `signed int32` 全域作为 legacy `fid` 的可逆映射范围
|
||||
|
||||
## 4 taxonomy
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `canonical_family` | string | 是 | 大类语义 |
|
||||
| `canonical_object_type` | string | 是 | 细粒度对象类型 |
|
||||
| `detection_key` | string | 是 | 用于检测和规则系统的稳定分类键 |
|
||||
| `semantic_key` | string | 否 | 内部语义归并键,过渡期可保留 |
|
||||
|
||||
## 5 render_semantics
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `chart_render_type` | string | 是 | `symbol` / `line` / `fill` / `label` / `none` |
|
||||
| `chart_symbol_family` | string | 否 | 符号族,例如 `navigation_light`、`hazard`、`depth_mark` |
|
||||
| `chart_symbol_code` | string | 否 | 稳定符号码,例如 `lighthouse`、`rock_awash` |
|
||||
| `chart_line_style` | string | 否 | 线型预设,例如 `boundary_dashed`、`contour_major` |
|
||||
| `chart_fill_style` | string | 否 | 面填充预设,例如 `depth_zone_0_5`、`reef_area` |
|
||||
| `chart_text_style` | string | 否 | 文字样式预设,例如 `place_name_sea`、`light_label` |
|
||||
| `chart_priority` | integer | 是 | 绘制优先级,用于层级和碰撞 |
|
||||
| `chart_visibility_min` | integer | 否 | 最小显示 zoom |
|
||||
| `chart_visibility_max` | integer | 否 | 最大显示 zoom |
|
||||
| `chart_collision_group` | string | 否 | 文本或符号碰撞组,例如 `place_label`、`light_label` |
|
||||
|
||||
说明:
|
||||
|
||||
- `chart_render_type` 和 `chart_priority` 建议作为最基础必填渲染字段
|
||||
- 样式层优先读取 `chart_*` 字段,不再优先读取旧编码
|
||||
|
||||
## 6 labels
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `chart_label_text` | string | 否 | 主标注文本 |
|
||||
| `chart_label_subtext` | string | 否 | 次级标注,例如灯略记 |
|
||||
| `chart_label_anchor` | string | 否 | `top` / `bottom` / `left` / `right` / `center` |
|
||||
| `chart_label_dx` | number | 否 | X 偏移 |
|
||||
| `chart_label_dy` | number | 否 | Y 偏移 |
|
||||
|
||||
说明:
|
||||
|
||||
- 旧样式中的 `名称`、`名称補助`、`日本語地名`、`英文字地名` 仍可保留
|
||||
- 新样式应优先使用 `chart_label_*`
|
||||
|
||||
## 7 light
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `light_color_code` | string | 否 | `white` / `red` / `green` / `yellow` / `mixed` |
|
||||
| `light_character_code` | string | 否 | `Fl` / `Oc` / `Iso` / `F` / `V-AIS` |
|
||||
| `light_sector_mode` | string | 否 | `sector` / `omni` / `none` |
|
||||
| `light_arc_code` | string | 否 | 灯弧附加表达,是否交付由产品决定 |
|
||||
|
||||
说明:
|
||||
|
||||
- 灯弧本身可以不渲染
|
||||
- 但灯质、灯色、略记对检索和标签仍有价值
|
||||
|
||||
## 8 hazard_area
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `hazard_class` | string | 否 | `rock` / `reef` / `wreck` / `obstruction` / `shoal` |
|
||||
| `hazard_severity` | string | 否 | `critical` / `major` / `minor` / `context` |
|
||||
| `area_usage_class` | string | 否 | `anchorage` / `route` / `fishery` / `restricted` / `water` |
|
||||
|
||||
## 9 normalized_numeric
|
||||
|
||||
建议把部分旧数值字段归一化,方便检索和规则判断。
|
||||
|
||||
| 字段 | 类型 | 必填 | 来源建议 |
|
||||
| --- | --- | --- | --- |
|
||||
| `depth_value_m` | number | 否 | 由 `水深値(m)` 归一化 |
|
||||
| `clearance_height_m` | number | 否 | 由 `高さ(m)` 归一化 |
|
||||
| `least_depth_m` | number | 否 | 由 `高さ/深度(m)` 中深度语义归一化 |
|
||||
| `bearing_deg` | number | 否 | 由 `角度` 归一化 |
|
||||
|
||||
说明:
|
||||
|
||||
- 这些字段主要服务于检索、检测和统一显示
|
||||
- 原始字段在过渡期可并存
|
||||
|
||||
## 10 source_legacy
|
||||
|
||||
以下字段是根据当前旧 `style.json` 的实际依赖,建议在 v2 过渡期继续保留的旧字段:
|
||||
|
||||
- `分類番号`
|
||||
- `形状分類番号`
|
||||
- `表示用番号`
|
||||
- `灯色`
|
||||
- `灯略記`
|
||||
- `明弧/分孤`
|
||||
- `表示位置`
|
||||
- `名称`
|
||||
- `名称補助`
|
||||
- `日本語地名`
|
||||
- `英文字地名`
|
||||
- `水深値(m)`
|
||||
- `高さ(m)`
|
||||
- `高さ/深度(m)`
|
||||
- `角度`
|
||||
|
||||
说明:
|
||||
|
||||
- 当前旧样式实际还使用了船舶动态字段 `cog`、`sog`、`hdg`、`length`、`rot`、`delay`
|
||||
- 这些字段来自其他源,不属于 NavSea 静态海图对象 schema 的核心范围
|
||||
|
||||
## 11 v2 最低交付要求
|
||||
|
||||
每个 NavSea feature 至少应满足:
|
||||
|
||||
- `fid`
|
||||
- `canonical_family`
|
||||
- `canonical_object_type`
|
||||
- `detection_key`
|
||||
- `render_layer`
|
||||
- `chart_render_type`
|
||||
- `chart_priority`
|
||||
|
||||
## 12 工程版与交付版
|
||||
|
||||
建议分两种输出口径:
|
||||
|
||||
### 12.1 delivery schema
|
||||
|
||||
用途:前端渲染、检索、碰撞、正式交付。
|
||||
|
||||
保留:
|
||||
|
||||
- identity
|
||||
- taxonomy
|
||||
- render_semantics
|
||||
- labels
|
||||
- light
|
||||
- hazard_area
|
||||
- normalized_numeric
|
||||
- 关键 `source_legacy`
|
||||
|
||||
### 12.2 engineering schema
|
||||
|
||||
用途:调试、抽查、问题复盘、映射核验。
|
||||
|
||||
在 delivery schema 基础上可额外保留:
|
||||
|
||||
- `fid_legacy_raw`
|
||||
- `fid_algo_id`
|
||||
- `fid_key_id`
|
||||
- 更完整的原始 `at`
|
||||
- 更多 `source_layer` / 原始属性
|
||||
- 临时校验字段
|
||||
|
||||
## 13 v2 与当前 builder 的差距
|
||||
|
||||
当前 `navsea_tile_builder.py` 已经输出:
|
||||
|
||||
- 原始全部属性
|
||||
- `canonical_object_type`
|
||||
- `canonical_family`
|
||||
- `semantic_key`
|
||||
- `detection_key`
|
||||
- `render_layer`
|
||||
|
||||
当前尚未系统输出的 v2 关键字段包括:
|
||||
|
||||
- `chart_render_type`
|
||||
- `chart_symbol_family`
|
||||
- `chart_symbol_code`
|
||||
- `chart_line_style`
|
||||
- `chart_fill_style`
|
||||
- `chart_text_style`
|
||||
- `chart_priority`
|
||||
- `chart_visibility_min`
|
||||
- `chart_visibility_max`
|
||||
- `chart_label_*`
|
||||
- `light_*`
|
||||
- `hazard_*`
|
||||
- `area_usage_class`
|
||||
- `normalized_numeric`
|
||||
|
||||
这部分是 builder 下一阶段的主要补齐目标。
|
||||
331
tasks/pbf/NavSea_PBF_v1_渲染语义契约草案.md
Normal file
331
tasks/pbf/NavSea_PBF_v1_渲染语义契约草案.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# NavSea PBF v1 渲染语义契约草案
|
||||
|
||||
版本:Draft v1
|
||||
用途:用于 NavSea PBF 重构讨论与 Codex 实现参考
|
||||
|
||||
---
|
||||
|
||||
# 1 重构目标
|
||||
|
||||
NavSea 当前 PBF 渲染依赖大量旧海图编码字段,例如:
|
||||
|
||||
- 分類番号
|
||||
- 形状分類番号
|
||||
- 表示用番号
|
||||
- 灯色
|
||||
- 灯略記
|
||||
- 明弧 / 分孤
|
||||
- 表示位置
|
||||
|
||||
这些字段本质上是 **旧海图绘制编码**,而不是稳定的语义描述。
|
||||
|
||||
当前系统同时存在两种表达:
|
||||
|
||||
1. 旧海图渲染编码
|
||||
2. 新的语义分类字段
|
||||
|
||||
但缺少一层专门表达 **“海图上应该如何表达该对象”** 的语义层。
|
||||
|
||||
因此本重构目标是建立:
|
||||
|
||||
NavSea PBF 的稳定 **渲染语义契约层**。
|
||||
|
||||
---
|
||||
|
||||
# 2 三层模型
|
||||
|
||||
NavSea 渲染体系应拆分为三层:
|
||||
|
||||
## A 层:对象语义层
|
||||
|
||||
回答:
|
||||
|
||||
**这个对象是什么**
|
||||
|
||||
示例字段:
|
||||
|
||||
- canonical_object_type
|
||||
- canonical_family
|
||||
- detection_key
|
||||
|
||||
示例值:
|
||||
|
||||
- 港湾灯台
|
||||
- 暗岩
|
||||
- 魚礁
|
||||
- 港則法境界
|
||||
|
||||
---
|
||||
|
||||
## B 层:渲染语义层
|
||||
|
||||
回答:
|
||||
|
||||
**在海图上应该如何表达**
|
||||
|
||||
示例字段:
|
||||
|
||||
- chart_render_type
|
||||
- chart_symbol_family
|
||||
- chart_symbol_code
|
||||
- chart_priority
|
||||
- chart_visibility_min
|
||||
- chart_visibility_max
|
||||
|
||||
---
|
||||
|
||||
## C 层:样式实现层
|
||||
|
||||
由 MapLibre Style 决定:
|
||||
|
||||
- 颜色
|
||||
- 线型
|
||||
- 图标
|
||||
- 填充
|
||||
- 文字样式
|
||||
|
||||
样式层应尽量只依赖:
|
||||
|
||||
- chart_* 渲染语义字段
|
||||
- 少量 legacy 字段
|
||||
|
||||
---
|
||||
|
||||
# 3 建议的核心渲染字段
|
||||
|
||||
## 3.1 主渲染字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|-----|------|------|
|
||||
| chart_render_type | string | symbol / line / fill / label / none |
|
||||
| chart_symbol_family | string | 符号族 |
|
||||
| chart_symbol_code | string | 符号代码 |
|
||||
| chart_priority | integer | 渲染优先级 |
|
||||
| chart_visibility_min | integer | 最小显示 zoom |
|
||||
| chart_visibility_max | integer | 最大显示 zoom |
|
||||
|
||||
---
|
||||
|
||||
## 3.2 标签字段
|
||||
|
||||
| 字段 | 类型 |
|
||||
|-----|------|
|
||||
| chart_label_text | string |
|
||||
| chart_label_subtext | string |
|
||||
| chart_label_anchor | string |
|
||||
| chart_label_dx | number |
|
||||
| chart_label_dy | number |
|
||||
|
||||
---
|
||||
|
||||
## 3.3 灯标字段
|
||||
|
||||
| 字段 | 类型 |
|
||||
|-----|------|
|
||||
| light_color_code | string |
|
||||
| light_character_code | string |
|
||||
| light_sector_mode | string |
|
||||
| light_arc_code | string |
|
||||
|
||||
示例:
|
||||
light_color_code = white
|
||||
light_character_code = Fl
|
||||
light_sector_mode = sector
|
||||
|
||||
---
|
||||
|
||||
## 3.4 危险物字段
|
||||
|
||||
| 字段 | 类型 |
|
||||
|-----|------|
|
||||
| hazard_class | string |
|
||||
| hazard_severity | string |
|
||||
|
||||
hazard_class 示例:
|
||||
|
||||
- rock
|
||||
- reef
|
||||
- wreck
|
||||
- obstruction
|
||||
- shoal
|
||||
|
||||
hazard_severity 示例:
|
||||
|
||||
- critical
|
||||
- major
|
||||
- minor
|
||||
- context
|
||||
|
||||
---
|
||||
|
||||
## 3.5 区域字段
|
||||
|
||||
| 字段 | 类型 |
|
||||
|-----|------|
|
||||
| area_usage_class | string |
|
||||
|
||||
示例:
|
||||
|
||||
- anchorage
|
||||
- route
|
||||
- fishery
|
||||
- restricted
|
||||
- facility
|
||||
- land
|
||||
- water
|
||||
|
||||
---
|
||||
|
||||
# 4 不建议直接写入 PBF 的字段
|
||||
|
||||
以下字段如果直接写入 PBF,可能会锁死样式:
|
||||
|
||||
- chart_line_style
|
||||
- chart_fill_style
|
||||
- chart_text_style
|
||||
|
||||
原因:
|
||||
|
||||
这些字段已经接近 **样式预设名称**,而不是语义。
|
||||
|
||||
例如:
|
||||
depth_zone_0_5
|
||||
boundary_dashed
|
||||
place_name
|
||||
|
||||
未来若更换视觉风格,会产生耦合。
|
||||
|
||||
因此建议 PBF 只表达:
|
||||
|
||||
- line semantic
|
||||
- fill semantic
|
||||
- label role
|
||||
|
||||
具体视觉样式交由 Style 决定。
|
||||
|
||||
---
|
||||
|
||||
# 5 建议保留的 legacy 字段
|
||||
|
||||
为了兼容旧样式与历史数据,建议继续保留:
|
||||
分類番号
|
||||
形状分類番号
|
||||
表示用番号
|
||||
灯色
|
||||
灯略記
|
||||
明弧
|
||||
分孤
|
||||
表示位置
|
||||
名称
|
||||
名称補助
|
||||
日本語地名
|
||||
英文字地名
|
||||
|
||||
用途:
|
||||
|
||||
- 样式兜底
|
||||
- 检索
|
||||
- 历史兼容
|
||||
|
||||
---
|
||||
|
||||
# 6 Feature 示例
|
||||
|
||||
## 灯台
|
||||
{
|
||||
"fid": 12345678,
|
||||
"canonical_object_type": "港湾灯台",
|
||||
"canonical_family": "navigation_aid",
|
||||
"detection_key": "symbol:港湾灯台",
|
||||
|
||||
"chart_render_type": "symbol",
|
||||
"chart_symbol_family": "navigation_light",
|
||||
"chart_symbol_code": "lighthouse",
|
||||
|
||||
"chart_priority": 900,
|
||||
"chart_visibility_min": 7,
|
||||
|
||||
"chart_label_text": "鷹島灯台",
|
||||
"chart_label_subtext": "Fl W 5s",
|
||||
|
||||
"light_color_code": "white",
|
||||
"light_character_code": "Fl"
|
||||
}## 鱼礁危险区
|
||||
{
|
||||
"fid": 23456789,
|
||||
"canonical_object_type": "魚礁",
|
||||
"canonical_family": "hazard",
|
||||
"detection_key": "mixed:魚礁",
|
||||
|
||||
"chart_render_type": "fill",
|
||||
"chart_symbol_family": "hazard",
|
||||
"chart_symbol_code": "reef_area",
|
||||
|
||||
"hazard_class": "reef",
|
||||
"hazard_severity": "major",
|
||||
|
||||
"chart_priority": 850
|
||||
}
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 7 建议的实现顺序
|
||||
|
||||
阶段 1:
|
||||
|
||||
出瓦片流程新增 chart_* 字段。
|
||||
|
||||
阶段 2:
|
||||
|
||||
PBF 同时包含:
|
||||
|
||||
- 新 taxonomy 字段
|
||||
- 新 chart semantics
|
||||
- legacy 字段
|
||||
|
||||
阶段 3:
|
||||
|
||||
样式优先读取:
|
||||
chart_render_type
|
||||
chart_symbol_family
|
||||
chart_symbol_code
|
||||
|
||||
缺失时回退 legacy 字段。
|
||||
|
||||
阶段 4:
|
||||
|
||||
逐步减少样式对 legacy 编码依赖。
|
||||
|
||||
---
|
||||
|
||||
# 8 第一阶段优先实现对象
|
||||
|
||||
建议优先完成四类对象:
|
||||
|
||||
1 灯标 / 航标
|
||||
2 危险点对象
|
||||
3 危险面对象(鱼礁 / 礁盘 / 障碍区)
|
||||
4 边界对象
|
||||
|
||||
原因:
|
||||
|
||||
这些对象最依赖旧编码,也是最复杂的渲染类型。
|
||||
|
||||
---
|
||||
|
||||
# 9 结论
|
||||
|
||||
NavSea PBF 不应继续依赖旧海图编码作为核心渲染逻辑。
|
||||
|
||||
正确方向是:
|
||||
|
||||
在 **原始属性** 与 **样式实现** 之间建立稳定的 **渲染语义层**。
|
||||
|
||||
该层应:
|
||||
|
||||
- 表达稳定语义
|
||||
- 不锁定具体视觉样式
|
||||
- 支持新旧样式共存
|
||||
- 为检测、检索、渲染提供统一数据面
|
||||
334
tasks/pbf/NavSea_Reversible_Normalization_Audit_Plan_v1.md
Normal file
334
tasks/pbf/NavSea_Reversible_Normalization_Audit_Plan_v1.md
Normal file
@@ -0,0 +1,334 @@
|
||||
# NavSea 可逆标准化审计方案 v1
|
||||
|
||||
版本:v1 Draft
|
||||
用途:定义 NavSea 可逆标准化规则的审计方案,用于验证标准化过程是否完整、可逆、稳定、可重复、对渲染无破坏。
|
||||
|
||||
## 1 审计目标
|
||||
|
||||
本审计方案要验证五件事:
|
||||
|
||||
- 原始信息有没有丢
|
||||
- 标准化规则有没有被正确应用
|
||||
- 每个结果能不能回查
|
||||
- 同一规则重复执行是否稳定
|
||||
- 标准化后渲染和业务能力有没有被破坏
|
||||
|
||||
## 2 审计对象
|
||||
|
||||
审计覆盖以下对象:
|
||||
|
||||
- 规则文件
|
||||
- SQL 规则表
|
||||
- feature trace 表
|
||||
- delivery `pbf`
|
||||
- engineering `pbf`
|
||||
- style 消费关系
|
||||
|
||||
## 3 审计维度
|
||||
|
||||
## 3.1 完整性审计
|
||||
|
||||
检查是否所有需要标准化的对象都进入了规则体系。
|
||||
|
||||
检查项:
|
||||
|
||||
- 每个实际出现的 `source_layer_jp` 都有标准化规则
|
||||
- 每个实际出现的关键原始字段都有保留策略
|
||||
- 每个 delivery feature 都有对应 trace
|
||||
|
||||
## 3.2 可逆性审计
|
||||
|
||||
检查是否能从标准值回查原始值。
|
||||
|
||||
检查项:
|
||||
|
||||
- `source_layer_std` 是否能映射回 `source_layer_jp`
|
||||
- 标准化字段是否有对应规则 ID
|
||||
- feature 是否能查到 bundle 版本
|
||||
|
||||
## 3.3 稳定性审计
|
||||
|
||||
检查相同输入在相同规则版本下是否得到相同输出。
|
||||
|
||||
检查项:
|
||||
|
||||
- 同一输入重复运行结果一致
|
||||
- 同一 `rule_id + revision` 输出不漂移
|
||||
|
||||
## 3.4 渲染兼容审计
|
||||
|
||||
检查标准化后是否破坏当前样式表现。
|
||||
|
||||
检查项:
|
||||
|
||||
- style 引用的 layer 是否仍然存在
|
||||
- 关键对象是否仍能显示
|
||||
- 旧兼容表现是否没有异常缩水
|
||||
|
||||
## 3.5 业务可用性审计
|
||||
|
||||
检查标准化后是否仍满足检索、碰撞、点击、排障需求。
|
||||
|
||||
检查项:
|
||||
|
||||
- `fid` 是否保留
|
||||
- taxonomy 字段是否保留
|
||||
- 关键内容型日文字段是否保留
|
||||
- trace 是否可回查
|
||||
|
||||
## 4 审计表设计
|
||||
|
||||
建议新增以下审计表:
|
||||
|
||||
- `navsea_normalization_audit_run`
|
||||
- `navsea_normalization_coverage_audit`
|
||||
- `navsea_normalization_reversibility_audit`
|
||||
- `navsea_normalization_stability_audit`
|
||||
- `navsea_render_compatibility_audit`
|
||||
|
||||
## 5 每次审计运行应记录
|
||||
|
||||
建议在 `navsea_normalization_audit_run` 中记录:
|
||||
|
||||
- `audit_run_id`
|
||||
- `bundle_id`
|
||||
- `bundle_version`
|
||||
- `source_snapshot`
|
||||
- `target_scope`
|
||||
- `started_at`
|
||||
- `finished_at`
|
||||
- `status`
|
||||
- `notes`
|
||||
|
||||
## 6 审计检查项
|
||||
|
||||
## 6.1 规则覆盖检查
|
||||
|
||||
目标:确认没有“实际数据里出现,但没有规则”的对象。
|
||||
|
||||
建议 SQL:
|
||||
|
||||
- 所有实际出现的 `source_layer_jp`
|
||||
- 左连接 `navsea_source_layer_rules`
|
||||
- 找出未命中项
|
||||
|
||||
通过标准:
|
||||
|
||||
- 未命中数量必须为 `0`
|
||||
|
||||
## 6.2 原值保留检查
|
||||
|
||||
目标:确认原始关键字段没有在工程体系中丢失。
|
||||
|
||||
检查字段:
|
||||
|
||||
- `fid`
|
||||
- `fid_legacy_raw`
|
||||
- `source_layer_jp`
|
||||
- `分類番号`
|
||||
- `形状分類番号`
|
||||
- `表示用番号`
|
||||
- `名称`
|
||||
- `日本語地名`
|
||||
- `at_raw`
|
||||
|
||||
通过标准:
|
||||
|
||||
- engineering 口径中必须可回查
|
||||
|
||||
## 6.2.1 `fid` 可逆检查
|
||||
|
||||
目标:确认 NavSea 自有 `fid` 不是旧 `fid` 原样外露,且能可逆回查。
|
||||
|
||||
检查项:
|
||||
|
||||
- `delivery` / `engineering` 主 `fid` 是否为 16 进制字符串
|
||||
- `fid_legacy_raw` 是否保留于 engineering / trace
|
||||
- `fid_algo_id` 是否存在
|
||||
- `fid_key_id` 是否存在
|
||||
- 是否可通过 `decrypt_number` 从 `fid_navsea_int` 还原 `fid_legacy_raw`
|
||||
|
||||
通过标准:
|
||||
|
||||
- 抽样回解正确率必须为 `100%`
|
||||
- 不允许出现“新 `fid` 与旧 `fid` 只是格式改写”的情况
|
||||
|
||||
## 6.3 规则追溯检查
|
||||
|
||||
目标:确认每个标准化结果都有 trace。
|
||||
|
||||
检查项:
|
||||
|
||||
- `source_layer_std` 是否有 `source_layer_rule_id`
|
||||
- `canonical_object_type` 是否有 `taxonomy_rule_id`
|
||||
- `chart_*` 是否有 `render_rule_id`
|
||||
|
||||
通过标准:
|
||||
|
||||
- 关键标准化字段 trace 覆盖率必须达到 `100%`
|
||||
|
||||
## 6.4 可逆回查检查
|
||||
|
||||
目标:确认能从标准值回查原值。
|
||||
|
||||
抽样要求:
|
||||
|
||||
- 随机抽样 `fid`
|
||||
- 随机抽样 `source_layer_std`
|
||||
- 随机抽样 `canonical_object_type`
|
||||
- 随机抽样 `chart_symbol_code`
|
||||
|
||||
检查:
|
||||
|
||||
- 是否能回查 `fid_legacy_raw`
|
||||
- 是否能回查原始 `source_layer_jp`
|
||||
- 是否能回查 `source_fields_used_json`
|
||||
- 是否能回查规则文件版本
|
||||
|
||||
## 6.5 重放一致性检查
|
||||
|
||||
目标:确认相同输入反复执行不会漂移。
|
||||
|
||||
方法:
|
||||
|
||||
1. 使用同一 bundle 版本运行两次
|
||||
2. 比较以下字段:
|
||||
- `source_layer_std`
|
||||
- `canonical_family`
|
||||
- `canonical_object_type`
|
||||
- `detection_key`
|
||||
- `chart_render_type`
|
||||
- `chart_symbol_code`
|
||||
|
||||
通过标准:
|
||||
|
||||
- 差异率必须为 `0`
|
||||
|
||||
## 6.6 delivery / engineering 差异检查
|
||||
|
||||
目标:确认 delivery 简化没有破坏回查能力。
|
||||
|
||||
检查项:
|
||||
|
||||
- delivery 是否去掉了一部分原值字段
|
||||
- engineering 是否仍保留完整 trace
|
||||
- 是否能通过 `fid` 从 delivery 回查到 engineering / SQL trace
|
||||
|
||||
通过标准:
|
||||
|
||||
- 回查链条必须完整
|
||||
|
||||
## 6.7 渲染覆盖检查
|
||||
|
||||
目标:确认标准化后 style 仍消费当前存在的 `source-layer`。
|
||||
|
||||
检查项:
|
||||
|
||||
- 数据侧实际 `source-layer` 集合
|
||||
- 样式侧引用的 `source-layer` 集合
|
||||
- 差集
|
||||
|
||||
通过标准:
|
||||
|
||||
- 若目标是“全覆盖样式”,差集必须为 `0`
|
||||
- 若目标是“有意忽略样式”,必须给出 ignore 清单和理由
|
||||
|
||||
## 7 审计输出
|
||||
|
||||
每次审计至少输出四类结果:
|
||||
|
||||
### 7.1 覆盖报告
|
||||
|
||||
内容:
|
||||
|
||||
- 实际 `source-layer`
|
||||
- 已映射数量
|
||||
- 未映射数量
|
||||
- 未映射列表
|
||||
|
||||
### 7.2 可逆性报告
|
||||
|
||||
内容:
|
||||
|
||||
- 可回查率
|
||||
- 无 trace feature 数量
|
||||
- 缺失规则 ID 数量
|
||||
|
||||
### 7.3 稳定性报告
|
||||
|
||||
内容:
|
||||
|
||||
- 两次重放差异数
|
||||
- 差异字段分布
|
||||
- 受影响 feature 列表
|
||||
|
||||
### 7.4 渲染兼容报告
|
||||
|
||||
内容:
|
||||
|
||||
- style 消费的 `source-layer`
|
||||
- 数据存在但样式未消费的层
|
||||
- 关键对象抽样截图或抽样核验结果
|
||||
|
||||
## 8 审计频率
|
||||
|
||||
建议分三类:
|
||||
|
||||
### 8.1 每次规则变更后
|
||||
|
||||
必须执行:
|
||||
|
||||
- 规则覆盖检查
|
||||
- 规则追溯检查
|
||||
- 可逆回查检查
|
||||
|
||||
### 8.2 每次大批量构建后
|
||||
|
||||
必须执行:
|
||||
|
||||
- delivery / engineering 差异检查
|
||||
- 渲染覆盖检查
|
||||
- 抽样渲染兼容检查
|
||||
|
||||
### 8.3 每次 bundle 升级前
|
||||
|
||||
必须执行:
|
||||
|
||||
- 重放一致性检查
|
||||
- 差异审计
|
||||
|
||||
## 9 不通过条件
|
||||
|
||||
出现以下任一情况,审计应判定不通过:
|
||||
|
||||
- 实际出现的 `source-layer` 无规则
|
||||
- 关键标准化字段无 trace
|
||||
- 无法从标准值回查原值
|
||||
- 同版本重复执行结果漂移
|
||||
- delivery 无法通过 `fid` 回查 engineering / SQL trace
|
||||
- 样式消费覆盖与目标不符且无明确豁免
|
||||
|
||||
## 10 v1 最低可执行方案
|
||||
|
||||
如果要先快速落地,建议第一阶段至少做到:
|
||||
|
||||
1. 建 `source-layer` 标准化规则表
|
||||
2. 建 `fid` 标准化规则文件和 `fid` 可逆回查检查
|
||||
3. 在 trace 表中补 `source_layer_rule_id`
|
||||
4. 建立 `source_layer_jp -> source_layer_std` 覆盖审计
|
||||
5. 建立 `fid -> trace` 回查检查
|
||||
6. 每次样式更新都跑 `source-layer` 覆盖差集
|
||||
|
||||
## 11 结论
|
||||
|
||||
NavSea 的可逆标准化不能只靠规则文档存在,必须配套审计。
|
||||
|
||||
审计的核心不是“看起来转换成功”,而是验证:
|
||||
|
||||
- 原值未丢
|
||||
- 规则有据
|
||||
- 结果可回查
|
||||
- 重放可一致
|
||||
- 渲染不被破坏
|
||||
|
||||
只有规则和审计同时成立,标准化这件事才算真正严谨。
|
||||
356
tasks/pbf/NavSea_Reversible_Normalization_Rules_v1.md
Normal file
356
tasks/pbf/NavSea_Reversible_Normalization_Rules_v1.md
Normal file
@@ -0,0 +1,356 @@
|
||||
# NavSea 可逆标准化规则 v1
|
||||
|
||||
版本:v1 Draft
|
||||
用途:定义 NavSea 在“日文原始数据 -> 标准化字段/层名/渲染语义”过程中必须遵循的可逆标准化规则,确保转换严谨、可追溯、可回退、可重复执行。
|
||||
|
||||
## 1 目标
|
||||
|
||||
NavSea 的标准化不是“清洗掉旧数据”,而是:
|
||||
|
||||
- 保留原始信息
|
||||
- 新增标准化结果
|
||||
- 记录完整映射过程
|
||||
- 允许从标准化结果反查原始值
|
||||
|
||||
一句话原则:
|
||||
|
||||
> 标准化只能增加表达层,不能破坏原始信息层。
|
||||
|
||||
## 2 适用范围
|
||||
|
||||
本规则适用于以下对象:
|
||||
|
||||
- 日文 `source-layer`
|
||||
- 原始日文字段名
|
||||
- 原始日文字段值
|
||||
- taxonomy 标准化字段
|
||||
- render 语义字段
|
||||
- 输出 `pbf`
|
||||
- SQL 规则表与 trace 表
|
||||
|
||||
## 3 核心原则
|
||||
|
||||
### 3.1 原始值不可丢
|
||||
|
||||
所有参与标准化的关键输入都必须有原始保留位。
|
||||
|
||||
包括但不限于:
|
||||
|
||||
- 原始 `source-layer`
|
||||
- 原始字段名
|
||||
- 原始字段值
|
||||
- 原始 `at`
|
||||
- 原始 `fid`
|
||||
|
||||
### 3.2 标准化结果必须新增,不可覆盖原值
|
||||
|
||||
禁止直接把原值物理改写成标准值后不留痕迹。
|
||||
|
||||
正确做法:
|
||||
|
||||
- 原值保留
|
||||
- 标准值新增
|
||||
- 二者由规则表与 trace 表关联
|
||||
|
||||
### 3.3 每一步标准化都必须有规则来源
|
||||
|
||||
任何标准化结果都必须能回答:
|
||||
|
||||
- 是哪条规则做的
|
||||
- 规则版本是什么
|
||||
- 使用了哪些原始字段
|
||||
|
||||
### 3.4 每一步标准化都必须可逆
|
||||
|
||||
可逆的含义不是“自动完全恢复所有原始结构”,而是:
|
||||
|
||||
- 能从标准值回查原始值
|
||||
- 能从 feature 回查到规则和版本
|
||||
- 能重演同一批输入得到同一批输出
|
||||
|
||||
### 3.5 delivery 可以简化,engineering 不可失真
|
||||
|
||||
delivery `pbf` 可以只暴露必要字段。
|
||||
但 engineering `pbf` / SQL 审计表必须保留足够信息,支持回查。
|
||||
|
||||
## 4 不可做的事
|
||||
|
||||
以下操作在 v1 规则下视为禁止:
|
||||
|
||||
- 直接删除原始 `source-layer`,且不保留 `source_layer_jp`
|
||||
- 直接删除原始字段值,且不保留原值副本
|
||||
- 在 SQL 里手工改结果,不回写规则文件
|
||||
- 在代码里加临时 if 分支,不形成规则 ID 和版本
|
||||
- 只保留标准化结果,不保留 trace
|
||||
|
||||
## 5 字段分层
|
||||
|
||||
NavSea 标准化后,字段应分成三层。
|
||||
|
||||
### 5.1 原始层
|
||||
|
||||
职责:完整保留输入信息。
|
||||
|
||||
建议字段:
|
||||
|
||||
- `source_layer_jp`
|
||||
- `original_properties_json`
|
||||
- `at_raw`
|
||||
- `fid`
|
||||
- 原始 `分類番号`
|
||||
- 原始 `形状分類番号`
|
||||
- 原始 `表示用番号`
|
||||
- 原始 `名称`
|
||||
- 原始 `日本語地名`
|
||||
|
||||
### 5.2 标准化层
|
||||
|
||||
职责:输出结构化、可消费的标准字段。
|
||||
|
||||
建议字段:
|
||||
|
||||
- `source_layer_std`
|
||||
- `canonical_family`
|
||||
- `canonical_object_type`
|
||||
- `detection_key`
|
||||
- `chart_render_type`
|
||||
- `chart_symbol_family`
|
||||
- `chart_symbol_code`
|
||||
- `chart_line_style`
|
||||
- `chart_fill_style`
|
||||
- `chart_text_style`
|
||||
|
||||
### 5.3 trace 层
|
||||
|
||||
职责:连接“原始层”和“标准化层”。
|
||||
|
||||
建议字段:
|
||||
|
||||
- `normalization_bundle_id`
|
||||
- `source_layer_rule_id`
|
||||
- `taxonomy_rule_id`
|
||||
- `render_rule_id`
|
||||
- `rule_revision`
|
||||
- `source_fields_used_json`
|
||||
- `trace_status`
|
||||
|
||||
## 6 可逆标准化对象
|
||||
|
||||
## 6.1 `source-layer` 标准化
|
||||
|
||||
建议采用双字段:
|
||||
|
||||
- `source_layer_jp`
|
||||
- `source_layer_std`
|
||||
|
||||
示例:
|
||||
|
||||
- `source_layer_jp = P錨泊地等`
|
||||
- `source_layer_std = anchorage_area`
|
||||
|
||||
要求:
|
||||
|
||||
- 原始日文层名不可直接丢弃
|
||||
- 标准层名必须来自规则表,不得手工散落在代码里
|
||||
|
||||
## 6.1.1 `fid` 标准化
|
||||
|
||||
NavSea 不应直接对外继续使用旧版原始 `fid` 作为最终对象 ID。
|
||||
|
||||
规则要求:
|
||||
|
||||
- `delivery` / `engineering` 对外主 `fid` 使用 NavSea 自有 `fid`
|
||||
- NavSea 自有 `fid` 由旧版 `fid` 经 `tasks/pbf/fiddecode.md` 中的可逆算法生成
|
||||
- 生成结果使用 16 进制字符串表达
|
||||
|
||||
建议定义:
|
||||
|
||||
- `fid_legacy_raw`:旧版原始整数 `fid`
|
||||
- `fid_navsea_int`:经过可逆加密后的非负整数
|
||||
- `fid`:最终对外使用的 16 进制字符串,例如固定宽度大写 HEX
|
||||
- `fid_algo_id`:例如 `feistel32_aes_cyclewalk_v1`
|
||||
- `fid_key_id`:用于标识采用了哪把密钥
|
||||
|
||||
建议生成规则:
|
||||
|
||||
1. 读取旧版 `fid`
|
||||
2. 使用 `fiddecode.md` 中的 `encrypt_number` 算法生成 `fid_navsea_int`
|
||||
3. 将 `fid_navsea_int` 编码为固定宽度 16 进制字符串
|
||||
4. 在 engineering / trace 中保留 `fid_legacy_raw`
|
||||
|
||||
补充口径:
|
||||
|
||||
- `fid` 可逆算法沿用 `fiddecode.md` 中的 Feistel + AES cycle-walking 方案
|
||||
- 为保证对真实历史数据全覆盖,工程实现应采用 `signed int32` 全域
|
||||
- 不应把示例文档中的局部样本范围误当成生产限制
|
||||
|
||||
要求:
|
||||
|
||||
- `fid` 必须可逆回查到 `fid_legacy_raw`
|
||||
- 不允许只保留新 `fid`,却丢失旧 `fid`
|
||||
- 不允许直接把旧 `fid` 原样转成 HEX 当作“新 `fid`”
|
||||
|
||||
## 6.2 原始字段名标准化
|
||||
|
||||
对原始字段名建议也采用双字段表达。
|
||||
|
||||
例如:
|
||||
|
||||
- `field_name_jp = 形状分類番号`
|
||||
- `field_name_std = shape_class_code`
|
||||
|
||||
注意:
|
||||
|
||||
- 这里只是定义映射关系
|
||||
- 不代表 delivery `pbf` 必须立刻把所有原字段名换掉
|
||||
|
||||
## 6.3 原始字段值标准化
|
||||
|
||||
例如:
|
||||
|
||||
- `灯色 = 1` -> `light_color_code = white`
|
||||
- `形状分類番号 = 335` -> `nav_mark_variant = vais`
|
||||
|
||||
要求:
|
||||
|
||||
- 原值保留
|
||||
- 标准值新增
|
||||
- 必须记录规则 ID
|
||||
|
||||
## 7 保留策略
|
||||
|
||||
## 7.1 必须保留的原始日文内容
|
||||
|
||||
以下属于“内容型日文”,不能因为标准化就删除:
|
||||
|
||||
- `名称`
|
||||
- `名称補助`
|
||||
- `日本語地名`
|
||||
- `灯略記`
|
||||
- 其他对展示、检索、业务解释有价值的原始说明文本
|
||||
|
||||
## 7.2 可标准化但需保留原值的结构型日文
|
||||
|
||||
以下属于“结构型日文”,可以标准化,但必须保留原值:
|
||||
|
||||
- 日文 `source-layer`
|
||||
- 原始字段名
|
||||
- `at` 中的结构型键值
|
||||
- 旧样式直接消费的技术性编码字段
|
||||
|
||||
## 7.3 delivery 可隐藏,engineering 必保留
|
||||
|
||||
对结构型日文建议:
|
||||
|
||||
- delivery `pbf` 可以只暴露标准字段
|
||||
- engineering `pbf` / SQL 审计表必须保留原值和映射关系
|
||||
|
||||
## 8 规则文件要求
|
||||
|
||||
为保证可逆与可重复,以下规则必须文件化:
|
||||
|
||||
- `source-layer` 标准化规则
|
||||
- taxonomy 规则
|
||||
- render 规则
|
||||
- 字段名标准化规则
|
||||
- 字段值标准化规则
|
||||
|
||||
建议目录:
|
||||
|
||||
```text
|
||||
tasks/pbf/mappings/
|
||||
navsea_fid_rules_v1.yaml
|
||||
navsea_source_layer_rules_v1.yaml
|
||||
navsea_taxonomy_rules_v1.yaml
|
||||
navsea_render_rules_v1.yaml
|
||||
navsea_field_name_rules_v1.yaml
|
||||
navsea_field_value_rules_v1.yaml
|
||||
navsea_rule_bundle_v1.yaml
|
||||
```
|
||||
|
||||
## 9 SQL 结构要求
|
||||
|
||||
为保证可逆与可查询,建议至少有以下表:
|
||||
|
||||
- `navsea_rule_bundle`
|
||||
- `navsea_source_layer_rules`
|
||||
- `navsea_taxonomy_rules`
|
||||
- `navsea_render_rules`
|
||||
- `navsea_field_name_rules`
|
||||
- `navsea_field_value_rules`
|
||||
- `navsea_feature_rule_trace`
|
||||
|
||||
## 10 feature trace 最低要求
|
||||
|
||||
每个被标准化的 feature 至少应记录:
|
||||
|
||||
- `feature_id`
|
||||
- `fid`
|
||||
- `fid_legacy_raw`
|
||||
- `fid_navsea_int`
|
||||
- `fid_algo_id`
|
||||
- `fid_key_id`
|
||||
- `source_layer_jp`
|
||||
- `source_layer_std`
|
||||
- `normalization_bundle_id`
|
||||
- `source_layer_rule_id`
|
||||
- `taxonomy_rule_id`
|
||||
- `render_rule_id`
|
||||
- `source_fields_used_json`
|
||||
- `trace_status`
|
||||
|
||||
## 11 delivery / engineering 输出要求
|
||||
|
||||
## 11.1 delivery pbf
|
||||
|
||||
目的:给前端渲染和检索使用。
|
||||
|
||||
要求:
|
||||
|
||||
- 可适度简化字段
|
||||
- 但不能影响业务使用
|
||||
- 若隐藏原值,必须仍可通过 SQL trace 回查
|
||||
|
||||
## 11.2 engineering pbf
|
||||
|
||||
目的:审计、复盘、问题定位。
|
||||
|
||||
要求:
|
||||
|
||||
- 保留原值
|
||||
- 保留标准值
|
||||
- 保留规则 ID
|
||||
- 保留 bundle 版本
|
||||
|
||||
## 12 可逆性验收条件
|
||||
|
||||
只有同时满足以下条件,才可称为“可逆标准化”:
|
||||
|
||||
1. 能从标准值回查原始值
|
||||
2. 能从 feature 回查规则 ID 和版本
|
||||
3. 能重放同一批输入并得到同一批输出
|
||||
4. 原始内容型日文未被误删
|
||||
5. delivery 的简化不影响 engineering 的回查能力
|
||||
|
||||
## 13 v1 落地建议
|
||||
|
||||
第一阶段建议先做到:
|
||||
|
||||
1. 所有日文 `source-layer` 增加 `source_layer_std`
|
||||
2. `fid` 改为 NavSea 自有 16 进制 `fid`
|
||||
3. 新增 `fid` 规则文件和 `fid` trace 字段
|
||||
4. 新增 `source-layer` 规则文件
|
||||
5. 在 trace 表中记录 `source_layer_rule_id`
|
||||
6. 保留原始内容型日文字段
|
||||
7. 严禁在没有 trace 的情况下直接删除原始结构字段
|
||||
|
||||
## 14 结论
|
||||
|
||||
NavSea 的标准化必须是:
|
||||
|
||||
- 可逆的
|
||||
- 可追溯的
|
||||
- 可重复执行的
|
||||
- 区分原始层、标准化层和 trace 层的
|
||||
|
||||
换句话说,标准化不是“替换”,而是“带证据的映射”。
|
||||
30
tasks/pbf/NavSea_object_render_mapping_table_v1.md
Normal file
30
tasks/pbf/NavSea_object_render_mapping_table_v1.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# NavSea Object → Render Mapping Table v1
|
||||
|
||||
版本:v1 Draft
|
||||
用途:定义对象语义到渲染语义的映射。
|
||||
|
||||
canonical_object_type → chart_render_type / chart_symbol_family / chart_symbol_code
|
||||
|
||||
## 灯标
|
||||
|
||||
| canonical_object_type | render_type | symbol_family | symbol_code |
|
||||
|---|---|---|---|
|
||||
| 港湾灯台 | symbol | navigation_light | lighthouse |
|
||||
| 灯柱 | symbol | navigation_light | light_beacon |
|
||||
| 灯浮標 | symbol | navigation_light | light_buoy |
|
||||
|
||||
## 危险物
|
||||
|
||||
| canonical_object_type | render_type | symbol_family | symbol_code |
|
||||
|---|---|---|---|
|
||||
| 暗岩 | symbol | hazard | rock_awash |
|
||||
| 岩礁 | symbol | hazard | reef |
|
||||
| 沈船 | symbol | hazard | wreck |
|
||||
| 障害物 | symbol | hazard | obstruction |
|
||||
|
||||
## 区域
|
||||
|
||||
| canonical_object_type | render_type | symbol_family | symbol_code |
|
||||
|---|---|---|---|
|
||||
| 魚礁 | fill | hazard | reef_area |
|
||||
| 錨地 | fill | usage_area | anchorage_area |
|
||||
165
tasks/pbf/NavSea_object_render_mapping_table_v2.md
Normal file
165
tasks/pbf/NavSea_object_render_mapping_table_v2.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# NavSea Object -> Render Mapping Table v2
|
||||
|
||||
版本:v2 Draft
|
||||
用途:定义对象语义到渲染语义的映射规则,作为 `taxonomy -> render_semantics` 的中间规范。
|
||||
|
||||
## 1 设计原则
|
||||
|
||||
- 先按 `canonical_object_type` 映射
|
||||
- 再按几何类型和旧字段细化具体样式
|
||||
- 样式层优先读取 `chart_*` 字段
|
||||
- 旧字段只保留为细节兜底,不再作为主判定入口
|
||||
|
||||
## 2 输出字段
|
||||
|
||||
映射表的目标输出至少包括:
|
||||
|
||||
- `chart_render_type`
|
||||
- `chart_symbol_family`
|
||||
- `chart_symbol_code`
|
||||
- `chart_line_style`
|
||||
- `chart_fill_style`
|
||||
- `chart_text_style`
|
||||
- `chart_priority`
|
||||
- `chart_label_text`
|
||||
- `chart_label_subtext`
|
||||
- `light_color_code`
|
||||
- `light_character_code`
|
||||
- `hazard_class`
|
||||
- `hazard_severity`
|
||||
- `area_usage_class`
|
||||
|
||||
## 3 首批强制覆盖对象
|
||||
|
||||
下表是建议优先落地的 v2 核心映射对象。
|
||||
|
||||
| canonical_family | canonical_object_type | geometry | chart_render_type | symbol_family | symbol_or_style | priority | legacy_detail_dependency |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| navigation_aid | 港湾灯台 | Point | symbol | navigation_light | `chart_symbol_code=lighthouse` | 900 | `灯色` `灯略記` `表示用番号` |
|
||||
| navigation_aid | 灯柱 | Point | symbol | navigation_light | `chart_symbol_code=light_beacon` | 890 | `灯色` `灯略記` `形状分類番号` |
|
||||
| navigation_aid | 灯浮標 | Point | symbol | navigation_light | `chart_symbol_code=light_buoy` | 880 | `灯色` `灯略記` `形状分類番号` |
|
||||
| navigation_aid | AIS航标 | Point | symbol | navigation_light | `chart_symbol_code=vais` | 870 | `表示用番号` |
|
||||
| navigation_aid | 浮標 | Point | symbol | navigation_mark | `chart_symbol_code=buoy` | 860 | `形状分類番号` `表示用番号` |
|
||||
| navigation_aid | 立標 | Point | symbol | navigation_mark | `chart_symbol_code=beacon` | 860 | `形状分類番号` `表示用番号` |
|
||||
| hazard | 暗岩 | Point | symbol | hazard | `chart_symbol_code=rock_awash` | 910 | `分類番号` |
|
||||
| hazard | 岩礁 | Point | symbol | hazard | `chart_symbol_code=reef` | 900 | `分類番号` |
|
||||
| hazard | 礁盘 | Polygon | fill | hazard | `chart_fill_style=reef_area` | 860 | `分類番号` |
|
||||
| hazard | 魚礁 | Polygon | fill | hazard | `chart_fill_style=reef_area` | 850 | `分類番号` `表示用番号` |
|
||||
| hazard | 沈船 | Point | symbol | hazard | `chart_symbol_code=wreck` | 905 | `分類番号` |
|
||||
| hazard | 障害物 | Point | symbol | hazard | `chart_symbol_code=obstruction` | 895 | `分類番号` |
|
||||
| hazard | 潜堤 | Line/Polygon | line/fill | hazard | `chart_line_style=submerged_reef` / `chart_fill_style=hazard_area` | 845 | `分類番号` |
|
||||
| depth | 水深点 | Point | label | depth_mark | `chart_text_style=depth_text` | 700 | `水深値(m)` |
|
||||
| depth | 水深区 | Polygon | fill | depth_zone | `chart_fill_style=depth_zone_*` | 650 | `分類番号` |
|
||||
| depth | 等深线 | LineString | line | contour | `chart_line_style=contour_major_or_minor` | 640 | `表示用番号` |
|
||||
| depth | 概略等深线 | LineString | line | contour | `chart_line_style=contour_overview` | 620 | `表示用番号` |
|
||||
| boundary | 危険界 | LineString | line | boundary | `chart_line_style=hazard_boundary` | 800 | `分類番号` |
|
||||
| boundary | 基本线 | LineString | line | boundary | `chart_line_style=baseline` | 780 | `分類番号` |
|
||||
| boundary | 航路境界 | LineString | line | boundary | `chart_line_style=route_boundary` | 770 | `分類番号` |
|
||||
| usage_area | 航路 | Polygon/LineString | fill/line | usage_area | `chart_fill_style=route_area` / `chart_line_style=route_axis` | 760 | `分類番号` |
|
||||
| usage_area | 錨地 | Polygon | fill | usage_area | `chart_fill_style=anchorage_area` | 750 | `分類番号` |
|
||||
| usage_area | 錨泊地 | Polygon | fill | usage_area | `chart_fill_style=anchorage_area` | 750 | `分類番号` |
|
||||
| usage_area | 漁業区 | Polygon | fill | usage_area | `chart_fill_style=fishery_area` | 740 | `分類番号` |
|
||||
| usage_area | パイロットステーション | Point | symbol | usage_area | `chart_symbol_code=pilot_station` | 735 | `表示用番号` |
|
||||
| facility | 防波堤 | LineString/Polygon | line/fill | facility | `chart_line_style=breakwater` | 730 | `分類番号` |
|
||||
| facility | 橋梁 | LineString | line | facility | `chart_line_style=bridge` | 725 | `高さ(m)` |
|
||||
| facility | 海底电缆 | LineString | line | facility | `chart_line_style=subsea_cable` | 720 | `分類番号` |
|
||||
| facility | 高さ制限 | Point/LineString | label/line | facility | `chart_text_style=clearance_label` | 715 | `高さ(m)` `高さ/深度(m)` |
|
||||
| seabed | 底質 | Point | label | seabed | `chart_text_style=seabed_text` | 500 | `名称` |
|
||||
| place | 海上地名 | Point | label | place | `chart_text_style=place_name_sea` | 450 | `日本語地名` `英文字地名` |
|
||||
| place | 陆上地名 | Point | label | place | `chart_text_style=place_name_land` | 440 | `日本語地名` `英文字地名` |
|
||||
|
||||
## 4 细化规则
|
||||
|
||||
### 4.1 灯标对象
|
||||
|
||||
主映射依据:
|
||||
|
||||
- `canonical_object_type`
|
||||
|
||||
细化字段:
|
||||
|
||||
- `灯色 -> light_color_code`
|
||||
- `灯略記 -> light_character_code` 与 `chart_label_subtext`
|
||||
- `名称 -> chart_label_text`
|
||||
- `表示用番号` / `形状分類番号` 决定具体 icon 变体
|
||||
|
||||
说明:
|
||||
|
||||
- 灯弧不必作为核心渲染对象单独保留
|
||||
- 但 `明弧/分孤` 可以继续保留,用于特殊产品或工程校验
|
||||
|
||||
### 4.2 危险物
|
||||
|
||||
主映射依据:
|
||||
|
||||
- `canonical_object_type`
|
||||
|
||||
细化输出:
|
||||
|
||||
- `hazard_class`
|
||||
- `hazard_severity`
|
||||
|
||||
建议:
|
||||
|
||||
- `暗岩`、`沈船` 默认 `hazard_severity >= major`
|
||||
- `魚礁` 按区域危险对象处理,但允许叠加 `area_usage_class=fishery`
|
||||
|
||||
### 4.3 水深和等深线
|
||||
|
||||
建议:
|
||||
|
||||
- 水深点统一转成 `chart_render_type=label`
|
||||
- 水深区统一转成 `chart_render_type=fill`
|
||||
- 等深线和概略等深线统一转成 `chart_render_type=line`
|
||||
|
||||
细化:
|
||||
|
||||
- `表示用番号` 或原 line layer 类型决定 `contour_major` / `contour_minor` / `contour_overview`
|
||||
|
||||
### 4.4 边界和区域
|
||||
|
||||
建议:
|
||||
|
||||
- “区域本体”与“边界线”分别映射
|
||||
- 航路、锚地、鱼业区优先落到 `usage_area`
|
||||
- 基本线、危险界、航路境界优先落到 `boundary`
|
||||
|
||||
## 5 label 映射规则
|
||||
|
||||
| 对象类型 | chart_label_text | chart_label_subtext | chart_text_style |
|
||||
| --- | --- | --- | --- |
|
||||
| 港湾灯台 / 灯柱 / 灯浮標 | `名称` | `灯略記` | `light_label` |
|
||||
| 水深点 | 格式化 `depth_value_m` | 空 | `depth_text` |
|
||||
| 海上地名 | `日本語地名` 优先,其次 `英文字地名` | 空 | `place_name_sea` |
|
||||
| 陆上地名 | `日本語地名` 优先,其次 `英文字地名` | 空 | `place_name_land` |
|
||||
| 高さ制限 | 规范化高度文本 | 空 | `clearance_label` |
|
||||
|
||||
## 6 v2 映射必须输出的附加字段
|
||||
|
||||
除了图形类型本身,映射表还应尽量输出:
|
||||
|
||||
- `chart_priority`
|
||||
- `chart_visibility_min`
|
||||
- `chart_visibility_max`
|
||||
- `chart_collision_group`
|
||||
|
||||
原因:
|
||||
|
||||
- 这些字段能把样式层里的很多散乱 zoom/filter 规则收回到数据侧
|
||||
|
||||
## 7 v2 当前缺口
|
||||
|
||||
相较 v1,本表仍需继续扩充以下对象:
|
||||
|
||||
- 导灯
|
||||
- 灯船
|
||||
- 信号所
|
||||
- 制限区域
|
||||
- 未测深区
|
||||
- 干出区
|
||||
- 海底管线
|
||||
- 岸壁 / 栈桥 / 码头
|
||||
- 海底线
|
||||
- 水文现象对象
|
||||
|
||||
这些建议作为 v2.1 的扩展项。
|
||||
56
tasks/pbf/NavSea_taxonomy_v1.md
Normal file
56
tasks/pbf/NavSea_taxonomy_v1.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# NavSea Taxonomy v1(对象语义分类体系)
|
||||
|
||||
版本:v1 Draft
|
||||
用途:定义 NavSea 的对象语义分类(Object Taxonomy)。
|
||||
|
||||
taxonomy 只回答一个问题:
|
||||
|
||||
> 这个对象是什么
|
||||
|
||||
而不涉及如何绘制。
|
||||
|
||||
## 结构
|
||||
|
||||
canonical_family → canonical_object_type
|
||||
|
||||
## canonical_family
|
||||
|
||||
- navigation_aid 航标
|
||||
- buoy 浮标
|
||||
- hazard 危险物
|
||||
- depth 水深
|
||||
- boundary 边界
|
||||
- facility 港口设施
|
||||
- usage_area 使用区域
|
||||
- landmark 地标
|
||||
- place 地名
|
||||
- seabed 海床
|
||||
- hydro_feature 水文现象
|
||||
|
||||
## 示例
|
||||
|
||||
navigation_aid
|
||||
|
||||
- 灯台
|
||||
- 港湾灯台
|
||||
- 灯柱
|
||||
- 灯浮標
|
||||
- AIS航标
|
||||
|
||||
hazard
|
||||
|
||||
- 暗岩
|
||||
- 岩礁
|
||||
- 礁盘
|
||||
- 沈船
|
||||
- 障害物
|
||||
- 危険物
|
||||
- 浅滩
|
||||
|
||||
depth
|
||||
|
||||
- 水深点
|
||||
- 水深区
|
||||
- 等深线
|
||||
|
||||
taxonomy 与渲染无关。
|
||||
306
tasks/pbf/NavSea_taxonomy_v2.md
Normal file
306
tasks/pbf/NavSea_taxonomy_v2.md
Normal file
@@ -0,0 +1,306 @@
|
||||
# NavSea Taxonomy v2
|
||||
|
||||
版本:v2 Draft
|
||||
用途:定义 NavSea 的对象语义分类体系(Object Taxonomy),为渲染、检索、碰撞检测和统计分析提供稳定的对象身份。
|
||||
|
||||
taxonomy 只回答一个问题:
|
||||
|
||||
> 这个对象是什么
|
||||
|
||||
taxonomy 不直接回答怎么画,也不直接替代旧海图字段。
|
||||
|
||||
## 1 设计原则
|
||||
|
||||
### 1.1 taxonomy 与 render 分层
|
||||
|
||||
- `canonical_family` / `canonical_object_type` 负责语义归类
|
||||
- `chart_*` 字段负责渲染表达
|
||||
- 旧字段如 `分類番号`、`形状分類番号`、`表示用番号` 仍可在过渡期保留,用于兼容旧样式细节
|
||||
|
||||
### 1.2 family 必须互斥
|
||||
|
||||
`canonical_family` 必须尽量稳定、互斥、可统计。
|
||||
|
||||
例如:
|
||||
|
||||
- `buoy` 不再单独作为 family
|
||||
- 灯浮标、灯柱、灯台、AIS 航标统一归到 `navigation_aid`
|
||||
- `place` 只表示地名,不包含设施或标志物
|
||||
|
||||
### 1.3 object_type 可以细分
|
||||
|
||||
`canonical_object_type` 允许保留更细粒度的对象名,用于:
|
||||
|
||||
- 检索
|
||||
- 规则判断
|
||||
- 语义统计
|
||||
- 到渲染语义的映射
|
||||
|
||||
## 2 taxonomy 层级
|
||||
|
||||
结构:
|
||||
|
||||
`canonical_family -> canonical_object_type`
|
||||
|
||||
## 3 canonical_family 定义
|
||||
|
||||
### 3.1 navigation_aid
|
||||
|
||||
定义:用于导航指示、警示、定位或电子助航的对象。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 灯台
|
||||
- 港湾灯台
|
||||
- 灯柱
|
||||
- 灯浮標
|
||||
- 導灯
|
||||
- 灯船
|
||||
- 浮標
|
||||
- 立標
|
||||
- AIS航标
|
||||
- 信号所
|
||||
|
||||
说明:
|
||||
|
||||
- 原 v1 中的 `buoy` 并入本 family
|
||||
- “浮标是不是灯浮标”属于 object_type 层的问题,不在 family 层拆开
|
||||
|
||||
### 3.2 hazard
|
||||
|
||||
定义:对航行、锚泊或作业形成风险的对象、区域或状态。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 暗岩
|
||||
- 岩礁
|
||||
- 礁盘
|
||||
- 魚礁
|
||||
- 沈船
|
||||
- 障害物
|
||||
- 危険物
|
||||
- 浅滩
|
||||
- 潜堤
|
||||
- 洞穴/穴
|
||||
|
||||
说明:
|
||||
|
||||
- 鱼礁虽然可能带有利用属性,但从航行风险角度优先归到 `hazard`
|
||||
- 若后续需要区分“危险物”和“人工利用构造”,可通过 `hazard_class` 或 `area_usage_class` 细分,而不是拆 family
|
||||
|
||||
### 3.3 depth
|
||||
|
||||
定义:描述水深、水深区、等深线和相关深度表达的对象。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 水深点
|
||||
- 水深区
|
||||
- 等深线
|
||||
- 概略等深线
|
||||
- 干出区
|
||||
- 未测深区
|
||||
|
||||
### 3.4 boundary
|
||||
|
||||
定义:描述法律、管理、航路或危险范围边界的对象。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 基本线
|
||||
- 危険界
|
||||
- 航路境界
|
||||
- 港則法による境界
|
||||
- 制限区域境界
|
||||
- 管辖边界
|
||||
|
||||
### 3.5 facility
|
||||
|
||||
定义:人工建造的固定设施、结构物和工程对象。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 防波堤
|
||||
- 岸壁
|
||||
- 栈桥
|
||||
- 桥梁
|
||||
- 海底电缆
|
||||
- 海底管线
|
||||
- 陆上构造物
|
||||
- 水上设施
|
||||
|
||||
说明:
|
||||
|
||||
- “设施”与“边界”分离
|
||||
- “设施”与“地标”分离
|
||||
|
||||
### 3.6 usage_area
|
||||
|
||||
定义:表达水域或区域用途、限制或功能属性的对象。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 錨地
|
||||
- 錨泊地
|
||||
- 漁業区
|
||||
- 航路
|
||||
- パイロットステーション
|
||||
- 禁止区域
|
||||
- 制限区域
|
||||
|
||||
说明:
|
||||
|
||||
- 如果对象主要表达“用途”而不是“实体构造”,优先归到本 family
|
||||
|
||||
### 3.7 landmark
|
||||
|
||||
定义:用于识别、定位或视觉参照的显著对象,但不属于典型助航设施。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 山顶
|
||||
- 烟囱
|
||||
- 塔
|
||||
- 目标物
|
||||
- 显著建筑
|
||||
|
||||
### 3.8 place
|
||||
|
||||
定义:地名和位置名称。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 海上地名
|
||||
- 陆上地名
|
||||
- 岬角地名
|
||||
- 港名
|
||||
|
||||
说明:
|
||||
|
||||
- 只表示名称,不表示实体类别
|
||||
- 与 `facility` 分离,避免“有名字的设施”误归到 place
|
||||
|
||||
### 3.9 seabed
|
||||
|
||||
定义:描述海床性质、底质和海底表面特征的对象。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 底質
|
||||
- 海底地形
|
||||
- 海底线
|
||||
|
||||
### 3.10 hydro_feature
|
||||
|
||||
定义:描述流、潮、涌浪、水流方向等水文现象的对象。
|
||||
|
||||
典型 object_type:
|
||||
|
||||
- 潮流
|
||||
- 流向
|
||||
- 渦流
|
||||
- 浪向
|
||||
|
||||
## 4 taxonomy 命名规则
|
||||
|
||||
### 4.1 family 命名
|
||||
|
||||
- 使用稳定英文 snake_case
|
||||
- 面向系统处理
|
||||
- 不与具体样式实现耦合
|
||||
|
||||
### 4.2 object_type 命名
|
||||
|
||||
- 允许使用与业务更贴近的中文或日文对象名
|
||||
- 但同义词必须收敛到单一标准写法
|
||||
|
||||
建议:
|
||||
|
||||
- 输出层面统一使用当前已采用的 `canonical_object_type`
|
||||
- 数据治理时维护“原始名 -> 标准对象名”的映射表
|
||||
|
||||
## 5 v2 首批强制覆盖对象
|
||||
|
||||
以下对象建议作为 v2 taxonomy 的首批强制覆盖范围,因为它们同时影响旧样式兼容和后续语义渲染:
|
||||
|
||||
- 港湾灯台
|
||||
- 灯柱
|
||||
- 灯浮標
|
||||
- AIS航标
|
||||
- 暗岩
|
||||
- 岩礁
|
||||
- 礁盘
|
||||
- 魚礁
|
||||
- 沈船
|
||||
- 障害物
|
||||
- 潜堤
|
||||
- 水深点
|
||||
- 水深区
|
||||
- 等深线
|
||||
- 概略等深线
|
||||
- 危険界
|
||||
- 基本线
|
||||
- 航路
|
||||
- 航路境界
|
||||
- 錨地
|
||||
- 錨泊地
|
||||
- 漁業区
|
||||
- 防波堤
|
||||
- 橋梁
|
||||
- 海底电缆
|
||||
- 底質
|
||||
- 海上地名
|
||||
- 陆上地名
|
||||
- 高さ制限
|
||||
|
||||
## 6 taxonomy 与旧字段的关系
|
||||
|
||||
taxonomy 不替代旧字段,但要尽量减少下游直接理解旧字段的负担。
|
||||
|
||||
建议职责划分如下:
|
||||
|
||||
- `canonical_family`:供统计、筛选、检索、碰撞分类使用
|
||||
- `canonical_object_type`:供精细语义判断和渲染映射使用
|
||||
- 旧字段:仅在兼容旧样式细节时保留
|
||||
|
||||
## 7 v2 边界决策
|
||||
|
||||
### 7.1 不再单独使用 buoy family
|
||||
|
||||
原因:
|
||||
|
||||
- 会与 `navigation_aid` 重叠
|
||||
- 对检索和渲染映射帮助有限
|
||||
|
||||
### 7.2 鱼礁优先归到 hazard
|
||||
|
||||
原因:
|
||||
|
||||
- 当前产品目标明确包含碰撞检测
|
||||
- 航行风险语义优先级高于用途语义
|
||||
|
||||
补充表达:
|
||||
|
||||
- 若需要表达作业用途,可通过渲染语义或 `area_usage_class=fishery` 补充
|
||||
|
||||
### 7.3 航路归到 usage_area,航路边界归到 boundary
|
||||
|
||||
原因:
|
||||
|
||||
- 区分“区域本身”和“边界线”
|
||||
- 有利于样式层分别控制 fill 和 line
|
||||
|
||||
## 8 v2 输出要求
|
||||
|
||||
每个交付 feature 至少应满足:
|
||||
|
||||
- 有 `canonical_family`
|
||||
- 有 `canonical_object_type`
|
||||
- 有 `detection_key`
|
||||
|
||||
如果对象未完成 taxonomy 映射,不能直接输出为空,应至少回退到:
|
||||
|
||||
- `canonical_family = unknown`
|
||||
- `canonical_object_type = 未分类对象`
|
||||
|
||||
并进入后续人工补录清单。
|
||||
21
tasks/pbf/NavSea_tile_generation_pipeline_v1.md
Normal file
21
tasks/pbf/NavSea_tile_generation_pipeline_v1.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# NavSea Tile Generation Pipeline v1
|
||||
|
||||
描述 NavSea 从原始数据到 Vector Tile 的流程。
|
||||
|
||||
raw hydro data
|
||||
↓
|
||||
taxonomy classification
|
||||
↓
|
||||
canonical_object_type
|
||||
↓
|
||||
render mapping table
|
||||
↓
|
||||
chart semantic fields
|
||||
↓
|
||||
vector tile PBF
|
||||
↓
|
||||
MapLibre style rendering
|
||||
|
||||
该流程实现:
|
||||
|
||||
数据 → 语义 → 渲染 → 屏幕。
|
||||
249
tasks/pbf/NavSea_tile_generation_pipeline_v2.md
Normal file
249
tasks/pbf/NavSea_tile_generation_pipeline_v2.md
Normal file
@@ -0,0 +1,249 @@
|
||||
# NavSea Tile Generation Pipeline v2
|
||||
|
||||
版本:v2 Draft
|
||||
用途:定义 NavSea 从原始海图数据到交付 Vector Tile 的生产流程和质量要求。
|
||||
|
||||
## 1 目标
|
||||
|
||||
v2 pipeline 不是简单“改字段名”,而是把交付链路明确拆成:
|
||||
|
||||
`原始数据 -> 语义分类 -> 渲染语义 -> 字段物化 -> PBF 交付 -> 样式渲染`
|
||||
|
||||
同时满足:
|
||||
|
||||
- 旧内容兼容
|
||||
- 新样式迁移
|
||||
- 检索和碰撞可用
|
||||
- 工程可验证
|
||||
|
||||
## 2 输入
|
||||
|
||||
### 2.1 原始输入
|
||||
|
||||
- 原始 Vector Tile:`/home/wwwroot/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles`
|
||||
- 原始要素属性:包括 `fid`、`分類番号`、`形状分類番号`、`表示用番号`、`名称`、`灯色` 等
|
||||
|
||||
### 2.2 数据库输入
|
||||
|
||||
当前数据库中已具备或部分具备:
|
||||
|
||||
- taxonomy 归类结果
|
||||
- render_layer 归并结果
|
||||
- detection 分类结果
|
||||
|
||||
现有 builder 查询表:
|
||||
|
||||
- `pbf_relayer_candidates`
|
||||
- `properties`
|
||||
|
||||
## 3 输出类型
|
||||
|
||||
建议把输出分成两类:
|
||||
|
||||
### 3.1 delivery tiles
|
||||
|
||||
用途:
|
||||
|
||||
- 正式渲染
|
||||
- 检索
|
||||
- 碰撞检测
|
||||
|
||||
要求:
|
||||
|
||||
- 保留关键旧字段
|
||||
- 输出稳定 taxonomy 字段
|
||||
- 输出新的 render_semantics 字段
|
||||
- 不包含过量调试字段
|
||||
|
||||
### 3.2 engineering tiles
|
||||
|
||||
用途:
|
||||
|
||||
- 抽样校验
|
||||
- 问题定位
|
||||
- 新旧比对
|
||||
|
||||
要求:
|
||||
|
||||
- 可保留更完整的原始字段
|
||||
- 可保留更多校验字段
|
||||
|
||||
## 4 v2 标准流程
|
||||
|
||||
### 步骤 1:读取原始瓦片
|
||||
|
||||
按 `z/x/y` 读取原始 `.pbf`,解码所有 source layer。
|
||||
|
||||
要求:
|
||||
|
||||
- 保留每个 source layer 的原始 extent
|
||||
- 不改变 feature geometry
|
||||
|
||||
### 步骤 2:按 fid/source_layer/geom_type 关联数据库记录
|
||||
|
||||
建议匹配键:
|
||||
|
||||
- `fid`
|
||||
- `source_layer`
|
||||
- `geom_type`
|
||||
|
||||
目的:
|
||||
|
||||
- 将原始 feature 与数据库里的 taxonomy / detection / render_layer 结果稳定关联
|
||||
|
||||
### 步骤 3:taxonomy 物化
|
||||
|
||||
输出:
|
||||
|
||||
- `canonical_family`
|
||||
- `canonical_object_type`
|
||||
- `detection_key`
|
||||
- `semantic_key`(可选)
|
||||
|
||||
要求:
|
||||
|
||||
- 未命中 taxonomy 的对象要进入 fallback 分类
|
||||
- 不允许静默输出空语义
|
||||
|
||||
### 步骤 4:render mapping 物化
|
||||
|
||||
依据:
|
||||
|
||||
- `canonical_object_type`
|
||||
- 几何类型
|
||||
- 必要旧字段
|
||||
|
||||
输出:
|
||||
|
||||
- `chart_render_type`
|
||||
- `chart_symbol_family`
|
||||
- `chart_symbol_code`
|
||||
- `chart_line_style`
|
||||
- `chart_fill_style`
|
||||
- `chart_text_style`
|
||||
- `chart_priority`
|
||||
- `chart_visibility_min`
|
||||
- `chart_visibility_max`
|
||||
|
||||
### 步骤 5:label / light / numeric 归一化
|
||||
|
||||
输出:
|
||||
|
||||
- `chart_label_text`
|
||||
- `chart_label_subtext`
|
||||
- `light_color_code`
|
||||
- `light_character_code`
|
||||
- `depth_value_m`
|
||||
- `clearance_height_m`
|
||||
- `least_depth_m`
|
||||
- `bearing_deg`
|
||||
|
||||
要求:
|
||||
|
||||
- 同类对象统一字段命名
|
||||
- 尽量避免样式和检索继续直接解析原始文本字段
|
||||
|
||||
### 步骤 6:决定输出 layer
|
||||
|
||||
建议优先级:
|
||||
|
||||
1. 使用数据库已确定的 `render_layer`
|
||||
2. 若无 `render_layer`,按渲染语义计算默认层
|
||||
3. 再不行才回退原 `source_layer`
|
||||
|
||||
说明:
|
||||
|
||||
- v2 的长期方向是减少直接依赖旧 source layer 命名
|
||||
- 但过渡期允许回退,保证旧 style 不崩
|
||||
|
||||
### 步骤 7:编码输出 PBF
|
||||
|
||||
要求:
|
||||
|
||||
- 保持原 feature geometry 不变
|
||||
- 保持原 layer extent 不变
|
||||
- 输出写入目标目录 `/home/wwwroot/pbf/{z}/{x}/{y}.pbf`
|
||||
|
||||
## 5 质量门禁
|
||||
|
||||
v2 pipeline 必须增加明确的 QA 检查。
|
||||
|
||||
### 5.1 文件层检查
|
||||
|
||||
- 新旧目标区域 `z/x/y.pbf` 文件名集合一致
|
||||
- 瓦片数一致
|
||||
- 输出层级目录完整
|
||||
|
||||
### 5.2 几何层检查
|
||||
|
||||
- 抽样瓦片 extent 一致
|
||||
- 抽样 feature 数量不异常缩水
|
||||
- 几何类型不发生意外变化
|
||||
|
||||
### 5.3 属性层检查
|
||||
|
||||
- `fid` 保留
|
||||
- taxonomy 字段不为空
|
||||
- 核心 render 字段存在
|
||||
- 关键旧字段未被错误清洗
|
||||
|
||||
### 5.4 渲染层检查
|
||||
|
||||
至少验证以下对象在新样式或兼容样式中可正常显示:
|
||||
|
||||
- 灯标体系
|
||||
- 危险物体系
|
||||
- 鱼礁/鱼业区
|
||||
- 水深区和等深线
|
||||
- 基本线 / 危险界 / 航路境界
|
||||
- 海上地名 / 陆上地名
|
||||
|
||||
## 6 与当前实现的差距
|
||||
|
||||
当前 `navsea_tile_builder.py` 已经完成:
|
||||
|
||||
- 原始瓦片读取
|
||||
- 数据库关联
|
||||
- taxonomy 字段叠加
|
||||
- `render_layer` 重分层
|
||||
- 原始 extent 保持
|
||||
|
||||
当前还缺:
|
||||
|
||||
- 统一的 render mapping 物化
|
||||
- label/light/numeric 归一化
|
||||
- delivery 与 engineering 两种输出口径
|
||||
- 更系统的 QA 报告
|
||||
|
||||
## 7 v2 推荐实施顺序
|
||||
|
||||
### 阶段 1:不破坏现有交付
|
||||
|
||||
- 保持当前 builder 可用
|
||||
- 在 builder 中新增 `chart_*` 字段,不删旧字段
|
||||
|
||||
### 阶段 2:构建混合样式
|
||||
|
||||
- 新样式优先读取 `chart_*`
|
||||
- 旧字段仅用于灯标细节、危险物图案和少数特例
|
||||
|
||||
### 阶段 3:建立 QA 报表
|
||||
|
||||
- 每次构建输出 coverage / feature count / extent 抽样报告
|
||||
- 对 taxonomy 未命中项输出清单
|
||||
|
||||
### 阶段 4:精简交付字段
|
||||
|
||||
- 在新样式和检索稳定后,逐步减少无用旧字段
|
||||
- 但保留 `fid`、taxonomy 和关键兼容字段
|
||||
|
||||
## 8 v2 验收标准
|
||||
|
||||
一版合格的 v2 delivery tiles 至少应满足:
|
||||
|
||||
- 与原始目标区域瓦片文件集合一致
|
||||
- 抽样瓦片 extent 正确
|
||||
- 主要对象类型 taxonomy 完整
|
||||
- `chart_*` 核心字段可用于新样式
|
||||
- 旧兼容样式仍可显示关键对象
|
||||
- 检索和碰撞可通过 `fid + taxonomy + normalized_numeric` 使用
|
||||
534
tasks/pbf/NavSea_traceable_mapping_architecture_v1.md
Normal file
534
tasks/pbf/NavSea_traceable_mapping_architecture_v1.md
Normal file
@@ -0,0 +1,534 @@
|
||||
# NavSea 可追溯映射体系设计 v1
|
||||
|
||||
版本:v1 Draft
|
||||
用途:定义 NavSea “旧版原始数据 -> 新版语义字段 / 渲染字段”的可追溯映射体系,确保后续可以稳定定位分类错误、渲染错误和规则变更影响。
|
||||
|
||||
## 1 目标
|
||||
|
||||
这套设计解决的不是“如何分类”本身,而是“分类和渲染映射的过程如何可追溯”。
|
||||
|
||||
必须满足:
|
||||
|
||||
- 能知道某个 feature 命中了哪条 taxonomy 规则
|
||||
- 能知道某个 feature 命中了哪条 render 规则
|
||||
- 能知道规则来自哪个版本
|
||||
- 能知道规则判断时参考了哪些原始字段
|
||||
- 能从最终 `pbf` 或 `fid` 回查到完整映射过程
|
||||
|
||||
一句话概括:
|
||||
|
||||
> 最终结果不是终点,规则命中过程也必须被记录成正式资产。
|
||||
|
||||
## 2 为什么必须做可追溯
|
||||
|
||||
如果只保留结果字段,例如:
|
||||
|
||||
- `canonical_family`
|
||||
- `canonical_object_type`
|
||||
- `detection_key`
|
||||
- `chart_render_type`
|
||||
|
||||
那后续虽然能看到“结果是什么”,但看不到:
|
||||
|
||||
- 为什么会分成这个结果
|
||||
- 是哪条规则起了作用
|
||||
- 如果结果错了,到底该改 taxonomy 还是改 render mapping
|
||||
- 某次规则调整影响了哪些 feature
|
||||
|
||||
而 NavSea 后续一定会反复遇到这些问题:
|
||||
|
||||
- 某个对象分错类
|
||||
- 某类对象在新样式里显示错误
|
||||
- 某次规则升级导致历史区域表现变化
|
||||
- 检索命中和渲染表现不一致
|
||||
|
||||
这时如果没有 trace,就只能人工猜。
|
||||
|
||||
## 3 设计原则
|
||||
|
||||
### 3.1 文件是规则源头
|
||||
|
||||
规则的 source of truth 必须是版本可控文件,而不是代码里的隐式判断,也不是数据库里唯一的一份规则。
|
||||
|
||||
建议:
|
||||
|
||||
- taxonomy 规则放 YAML/CSV 文件
|
||||
- render mapping 规则放 YAML/CSV 文件
|
||||
- 文档文件负责解释,不作为程序执行源
|
||||
|
||||
### 3.2 SQL 是运行时载体
|
||||
|
||||
数据库负责:
|
||||
|
||||
- 导入规则
|
||||
- 物化计算结果
|
||||
- 记录 feature 命中过程
|
||||
- 支撑查询和审计
|
||||
|
||||
但数据库不是唯一规则源头。
|
||||
|
||||
### 3.3 结果和过程都要存
|
||||
|
||||
至少要同时存两类数据:
|
||||
|
||||
- 规则定义
|
||||
- feature 命中结果
|
||||
|
||||
只存最终结果表不够。
|
||||
|
||||
### 3.4 规则必须有稳定 ID
|
||||
|
||||
每条规则必须有稳定 `rule_id`,不能只靠“第几条规则”或描述文本识别。
|
||||
|
||||
### 3.5 规则必须有版本
|
||||
|
||||
每次可影响结果的变更都要有版本号或 bundle 版本。
|
||||
|
||||
建议使用:
|
||||
|
||||
- `bundle_version`
|
||||
- `rule_revision`
|
||||
|
||||
## 4 总体架构
|
||||
|
||||
建议分成 4 层。
|
||||
|
||||
### 4.1 规则源文件层
|
||||
|
||||
建议目录:
|
||||
|
||||
- `tasks/pbf/mappings/navsea_taxonomy_rules_v1.yaml`
|
||||
- `tasks/pbf/mappings/navsea_render_rules_v1.yaml`
|
||||
- `tasks/pbf/mappings/navsea_rule_bundle_v1.yaml`
|
||||
|
||||
职责:
|
||||
|
||||
- 人可读
|
||||
- 可进入 git
|
||||
- 可 code review
|
||||
- 可回滚
|
||||
|
||||
### 4.2 规则表层
|
||||
|
||||
建议导入 MySQL 生成:
|
||||
|
||||
- `navsea_rule_bundle`
|
||||
- `navsea_taxonomy_rules`
|
||||
- `navsea_render_rules`
|
||||
|
||||
职责:
|
||||
|
||||
- 运行时查询
|
||||
- 规则生效控制
|
||||
- 按版本执行构建
|
||||
|
||||
### 4.3 结果表层
|
||||
|
||||
建议生成:
|
||||
|
||||
- `navsea_feature_taxonomy_result`
|
||||
- `navsea_feature_render_result`
|
||||
- `navsea_feature_rule_trace`
|
||||
- `navsea_mapping_run`
|
||||
|
||||
职责:
|
||||
|
||||
- 记录某次构建的命中结果
|
||||
- 记录 feature 与 rule 的关系
|
||||
- 记录本次运行使用的规则版本
|
||||
|
||||
### 4.4 交付层
|
||||
|
||||
交付层包括:
|
||||
|
||||
- delivery pbf
|
||||
- engineering pbf
|
||||
|
||||
其中:
|
||||
|
||||
- delivery pbf 只保留必要结果字段
|
||||
- engineering pbf 或内部查询表保留 trace 回查能力
|
||||
|
||||
## 5 推荐文件结构
|
||||
|
||||
建议新增目录:
|
||||
|
||||
```text
|
||||
tasks/pbf/mappings/
|
||||
navsea_rule_bundle_v1.yaml
|
||||
navsea_taxonomy_rules_v1.yaml
|
||||
navsea_render_rules_v1.yaml
|
||||
```
|
||||
|
||||
建议新增导入脚本:
|
||||
|
||||
```text
|
||||
scripts/pbf/
|
||||
import_navsea_rules.py
|
||||
run_navsea_mapping.py
|
||||
export_navsea_trace_report.py
|
||||
```
|
||||
|
||||
## 6 规则文件设计
|
||||
|
||||
## 6.1 bundle 文件
|
||||
|
||||
bundle 文件用于声明:
|
||||
|
||||
- 当前规则集版本
|
||||
- taxonomy 规则文件版本
|
||||
- render 规则文件版本
|
||||
- 适用范围
|
||||
- 是否为当前默认版本
|
||||
|
||||
示例字段:
|
||||
|
||||
- `bundle_id`
|
||||
- `bundle_version`
|
||||
- `status`
|
||||
- `effective_date`
|
||||
- `taxonomy_ruleset`
|
||||
- `render_ruleset`
|
||||
- `notes`
|
||||
|
||||
## 6.2 taxonomy 规则文件
|
||||
|
||||
每条 taxonomy 规则至少包含:
|
||||
|
||||
- `rule_id`
|
||||
- `rule_revision`
|
||||
- `priority`
|
||||
- `enabled`
|
||||
- `match_scope`
|
||||
- `match_expr`
|
||||
- `output.canonical_family`
|
||||
- `output.canonical_object_type`
|
||||
- `output.detection_key_template`
|
||||
- `reason`
|
||||
|
||||
其中:
|
||||
|
||||
- `rule_id` 是稳定主键,例如 `TAX-NAV-001`
|
||||
- `rule_revision` 是规则修订号,例如 `3`
|
||||
- `priority` 用于冲突时排序
|
||||
- `match_expr` 描述匹配条件
|
||||
- `reason` 解释为什么有这条规则
|
||||
|
||||
## 6.3 render 规则文件
|
||||
|
||||
每条 render 规则至少包含:
|
||||
|
||||
- `rule_id`
|
||||
- `rule_revision`
|
||||
- `priority`
|
||||
- `enabled`
|
||||
- `match_expr`
|
||||
- `output.chart_render_type`
|
||||
- `output.chart_symbol_family`
|
||||
- `output.chart_symbol_code`
|
||||
- `output.chart_line_style`
|
||||
- `output.chart_fill_style`
|
||||
- `output.chart_text_style`
|
||||
- `output.chart_priority`
|
||||
- `reason`
|
||||
|
||||
render 规则的输入通常包括:
|
||||
|
||||
- `canonical_object_type`
|
||||
- `canonical_family`
|
||||
- geometry type
|
||||
- 必要旧字段
|
||||
|
||||
## 7 match_expr 建议
|
||||
|
||||
不建议把匹配逻辑写成自由文本。
|
||||
|
||||
建议使用结构化表达,例如:
|
||||
|
||||
```yaml
|
||||
match_expr:
|
||||
all:
|
||||
- field: source_layer
|
||||
op: in
|
||||
value: [p航路標識群, P航行危険障害物]
|
||||
- field: class_name
|
||||
op: contains_any
|
||||
value: [港湾灯台, 灯柱, 灯浮標]
|
||||
- field: geom_type
|
||||
op: eq
|
||||
value: Point
|
||||
```
|
||||
|
||||
支持的运算建议限制在少数几类:
|
||||
|
||||
- `eq`
|
||||
- `neq`
|
||||
- `in`
|
||||
- `contains`
|
||||
- `contains_any`
|
||||
- `is_null`
|
||||
- `not_null`
|
||||
- `regex`
|
||||
|
||||
这样规则可审计、可导入、可执行。
|
||||
|
||||
## 8 SQL 表设计
|
||||
|
||||
## 8.1 `navsea_rule_bundle`
|
||||
|
||||
建议字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `bundle_id` | varchar(64) PK | 规则集 ID |
|
||||
| `bundle_version` | varchar(32) | 规则集版本 |
|
||||
| `status` | varchar(20) | `draft` / `active` / `retired` |
|
||||
| `taxonomy_ruleset` | varchar(64) | taxonomy 文件版本 |
|
||||
| `render_ruleset` | varchar(64) | render 文件版本 |
|
||||
| `effective_date` | datetime | 生效时间 |
|
||||
| `created_at` | datetime | 创建时间 |
|
||||
| `notes` | text | 备注 |
|
||||
|
||||
## 8.2 `navsea_taxonomy_rules`
|
||||
|
||||
建议字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `rule_id` | varchar(64) PK | 稳定规则 ID |
|
||||
| `bundle_id` | varchar(64) | 所属 bundle |
|
||||
| `rule_revision` | int | 修订号 |
|
||||
| `priority` | int | 优先级,值越小越先匹配 |
|
||||
| `enabled` | tinyint | 是否启用 |
|
||||
| `match_scope` | varchar(32) | `feature` / `layer` / `object` |
|
||||
| `match_expr_json` | json | 结构化匹配表达式 |
|
||||
| `canonical_family` | varchar(100) | 输出 family |
|
||||
| `canonical_object_type` | varchar(191) | 输出 object type |
|
||||
| `detection_key_template` | varchar(191) | 输出 detection 模板 |
|
||||
| `rule_reason` | text | 规则说明 |
|
||||
| `created_at` | datetime | 创建时间 |
|
||||
| `updated_at` | datetime | 更新时间 |
|
||||
|
||||
## 8.3 `navsea_render_rules`
|
||||
|
||||
建议字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `rule_id` | varchar(64) PK | 稳定规则 ID |
|
||||
| `bundle_id` | varchar(64) | 所属 bundle |
|
||||
| `rule_revision` | int | 修订号 |
|
||||
| `priority` | int | 优先级 |
|
||||
| `enabled` | tinyint | 是否启用 |
|
||||
| `match_expr_json` | json | 匹配表达式 |
|
||||
| `chart_render_type` | varchar(32) | 输出 |
|
||||
| `chart_symbol_family` | varchar(64) | 输出 |
|
||||
| `chart_symbol_code` | varchar(64) | 输出 |
|
||||
| `chart_line_style` | varchar(64) | 输出 |
|
||||
| `chart_fill_style` | varchar(64) | 输出 |
|
||||
| `chart_text_style` | varchar(64) | 输出 |
|
||||
| `chart_priority` | int | 输出 |
|
||||
| `chart_visibility_min` | int | 输出 |
|
||||
| `chart_visibility_max` | int | 输出 |
|
||||
| `rule_reason` | text | 规则说明 |
|
||||
| `created_at` | datetime | 创建时间 |
|
||||
| `updated_at` | datetime | 更新时间 |
|
||||
|
||||
## 8.4 `navsea_mapping_run`
|
||||
|
||||
记录一次完整构建执行。
|
||||
|
||||
建议字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `run_id` | bigint PK | 执行 ID |
|
||||
| `bundle_id` | varchar(64) | 本次使用的规则集 |
|
||||
| `run_type` | varchar(32) | `full` / `aoi` / `qa` |
|
||||
| `tile_scope` | text | 范围说明 |
|
||||
| `started_at` | datetime | 开始时间 |
|
||||
| `finished_at` | datetime | 结束时间 |
|
||||
| `status` | varchar(20) | `running` / `success` / `failed` |
|
||||
| `source_snapshot` | varchar(128) | 源数据快照标识 |
|
||||
| `notes` | text | 备注 |
|
||||
|
||||
## 8.5 `navsea_feature_rule_trace`
|
||||
|
||||
这是最关键的 trace 表。
|
||||
|
||||
建议字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `run_id` | bigint | 所属执行 |
|
||||
| `feature_id` | bigint | 内部 feature 主键 |
|
||||
| `fid` | varchar(191) | 原始对象标识 |
|
||||
| `z` | int | tile z |
|
||||
| `x` | int | tile x |
|
||||
| `y` | int | tile y |
|
||||
| `source_layer` | varchar(100) | 原始 layer |
|
||||
| `geom_type` | varchar(32) | 几何类型 |
|
||||
| `taxonomy_rule_id` | varchar(64) | 命中的 taxonomy 规则 |
|
||||
| `taxonomy_rule_revision` | int | taxonomy 修订号 |
|
||||
| `render_rule_id` | varchar(64) | 命中的 render 规则 |
|
||||
| `render_rule_revision` | int | render 修订号 |
|
||||
| `bundle_id` | varchar(64) | 规则集版本 |
|
||||
| `classification_basis` | varchar(64) | 使用的主要依据 |
|
||||
| `source_fields_used_json` | json | 实际参与判定的字段和值摘要 |
|
||||
| `canonical_family` | varchar(100) | 产出结果 |
|
||||
| `canonical_object_type` | varchar(191) | 产出结果 |
|
||||
| `detection_key` | varchar(191) | 产出结果 |
|
||||
| `chart_render_type` | varchar(32) | 产出结果 |
|
||||
| `chart_symbol_family` | varchar(64) | 产出结果 |
|
||||
| `chart_symbol_code` | varchar(64) | 产出结果 |
|
||||
| `chart_line_style` | varchar(64) | 产出结果 |
|
||||
| `chart_fill_style` | varchar(64) | 产出结果 |
|
||||
| `chart_text_style` | varchar(64) | 产出结果 |
|
||||
| `trace_status` | varchar(20) | `matched` / `fallback` / `manual_review` |
|
||||
| `created_at` | datetime | 记录时间 |
|
||||
|
||||
说明:
|
||||
|
||||
- `source_fields_used_json` 不要求保存整份原始属性
|
||||
- 但必须记录本次命中实际使用的关键字段和值摘要
|
||||
|
||||
例如:
|
||||
|
||||
```json
|
||||
{
|
||||
"fid": "123456",
|
||||
"分類番号": "403",
|
||||
"表示用番号": "31135504",
|
||||
"名称": "鷹島灯台",
|
||||
"geom_type": "Point"
|
||||
}
|
||||
```
|
||||
|
||||
## 9 交付与追溯分离策略
|
||||
|
||||
为了兼顾交付体积和可追溯性,建议分两条线:
|
||||
|
||||
### 9.1 delivery pbf
|
||||
|
||||
保留:
|
||||
|
||||
- 业务必需字段
|
||||
- taxonomy 结果字段
|
||||
- render 结果字段
|
||||
- 必要旧字段
|
||||
|
||||
不强制保留:
|
||||
|
||||
- 完整 trace 细节
|
||||
|
||||
### 9.2 engineering trace
|
||||
|
||||
通过以下方式保留完整追溯能力:
|
||||
|
||||
- SQL trace 表
|
||||
- engineering pbf
|
||||
- 按 `fid` / `feature_id` 回查脚本
|
||||
|
||||
建议 engineering pbf 可额外保留:
|
||||
|
||||
- `taxonomy_rule_id`
|
||||
- `render_rule_id`
|
||||
- `bundle_id`
|
||||
- `trace_status`
|
||||
|
||||
## 10 builder 接入方式
|
||||
|
||||
当前 [navsea_tile_builder.py](/root/weather/navsea_tile_builder.py) 是从 `pbf_relayer_candidates` 读取结果并写入 `pbf`。
|
||||
|
||||
建议改造成两段式:
|
||||
|
||||
### 阶段 A:规则求值阶段
|
||||
|
||||
输入:
|
||||
|
||||
- 原始 feature
|
||||
- 规则表
|
||||
|
||||
输出:
|
||||
|
||||
- `navsea_feature_taxonomy_result`
|
||||
- `navsea_feature_render_result`
|
||||
- `navsea_feature_rule_trace`
|
||||
|
||||
### 阶段 B:PBF 输出阶段
|
||||
|
||||
输入:
|
||||
|
||||
- 已物化结果表
|
||||
|
||||
输出:
|
||||
|
||||
- delivery pbf
|
||||
- engineering pbf
|
||||
|
||||
这样做的好处是:
|
||||
|
||||
- “规则判断”与“PBF 编码”解耦
|
||||
- 同一份判定结果可重复出图
|
||||
- QA 和回归检查更容易做
|
||||
|
||||
## 11 问题排查路径
|
||||
|
||||
未来排查一个对象时,建议统一走这条链路:
|
||||
|
||||
1. 先从前端或瓦片里拿到 `fid`
|
||||
2. 用 `fid` 或 `feature_id` 查 `navsea_feature_rule_trace`
|
||||
3. 看命中的 `taxonomy_rule_id` 和 `render_rule_id`
|
||||
4. 回到规则表查看该规则定义
|
||||
5. 必要时回到规则源文件查看变更历史
|
||||
6. 确认问题属于:
|
||||
- 原始数据异常
|
||||
- taxonomy 规则错误
|
||||
- render 规则错误
|
||||
- 样式解释错误
|
||||
|
||||
## 12 变更管理
|
||||
|
||||
建议所有规则变更都遵循:
|
||||
|
||||
- 改规则文件
|
||||
- 提交 git
|
||||
- 生成新 `bundle_version`
|
||||
- 导入 SQL
|
||||
- 执行局部或全量重算
|
||||
- 输出差异报告
|
||||
|
||||
不建议:
|
||||
|
||||
- 直接手改结果表
|
||||
- 直接在 SQL 里无版本地改规则
|
||||
- 直接在代码里插入一条临时 if 判断后不回写规则文件
|
||||
|
||||
## 13 最小可落地版本
|
||||
|
||||
如果要尽快开始,建议第一阶段先做到:
|
||||
|
||||
1. 新增规则源文件目录
|
||||
2. 给 taxonomy 和 render 规则都定义 `rule_id`
|
||||
3. 新增 `navsea_rule_bundle`
|
||||
4. 新增 `navsea_feature_rule_trace`
|
||||
5. builder 在出 engineering 数据时至少写出:
|
||||
- `bundle_id`
|
||||
- `taxonomy_rule_id`
|
||||
- `render_rule_id`
|
||||
- `trace_status`
|
||||
|
||||
这样即使规则体系还不完整,也已经具备“能追”的能力。
|
||||
|
||||
## 14 结论
|
||||
|
||||
NavSea 的“旧版 -> 新版”对应关系,不应只是一套结果字段,也不应只存在于代码里。
|
||||
|
||||
它应该被正式建设成一套可追溯资产,包括:
|
||||
|
||||
- 可版本化的规则文件
|
||||
- 可运行的 SQL 规则表
|
||||
- 可查询的 feature trace 表
|
||||
- 与 delivery / engineering pbf 配套的回查能力
|
||||
|
||||
后续查错、验收、回归、争议复盘,都会依赖这套体系。
|
||||
344
tasks/pbf/OutPbf.md
Normal file
344
tasks/pbf/OutPbf.md
Normal file
@@ -0,0 +1,344 @@
|
||||
# NavSea Codex Task
|
||||
# Karatsu AOI Vector Tile Build
|
||||
Architecture: NavSea V11 / Codex6
|
||||
Scope: Server Side Tile Build
|
||||
|
||||
---
|
||||
|
||||
# Task Name
|
||||
|
||||
NavSea_Karatsu_AOI_PBF_Builder
|
||||
|
||||
---
|
||||
|
||||
# Task Goal
|
||||
|
||||
Generate a NavSea Vector Tile dataset for the area surrounding **Karatsu City (唐津市)**.
|
||||
|
||||
The tile build must cover approximately:
|
||||
|
||||
```
|
||||
10 nautical mile radius
|
||||
centered on Karatsu city
|
||||
```
|
||||
|
||||
The tiles must be generated for **all zoom levels supported by NavSea**.
|
||||
|
||||
The generated tiles will be used to validate:
|
||||
|
||||
- semantic overlay
|
||||
- render compatibility
|
||||
- navigation object detection
|
||||
- tile density behavior
|
||||
- style compatibility
|
||||
|
||||
---
|
||||
|
||||
# Output Location
|
||||
|
||||
Tiles must be written to:
|
||||
|
||||
```
|
||||
/home/wwwroot/pbf
|
||||
```
|
||||
|
||||
Directory structure must follow standard vector tile layout:
|
||||
|
||||
```
|
||||
/home/wwwroot/pbf/{z}/{x}/{y}.pbf
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
/home/wwwroot/pbf/10/864/440.pbf
|
||||
```
|
||||
|
||||
Existing files in the directory may be overwritten.
|
||||
|
||||
---
|
||||
|
||||
# AOI Definition
|
||||
|
||||
Center location:
|
||||
|
||||
```
|
||||
Karatsu City
|
||||
Japan
|
||||
```
|
||||
|
||||
Recommended reference coordinate:
|
||||
|
||||
```
|
||||
Lat: 33.4425
|
||||
Lon: 129.9697
|
||||
```
|
||||
|
||||
Coverage radius:
|
||||
|
||||
```
|
||||
10 nautical miles
|
||||
≈ 18.52 km
|
||||
```
|
||||
|
||||
Codex may implement this AOI using one of the following:
|
||||
|
||||
```
|
||||
1 center point + radius
|
||||
2 bounding box derived from radius
|
||||
3 tile range approximation
|
||||
```
|
||||
|
||||
The resulting tiles must fully cover the requested radius.
|
||||
|
||||
---
|
||||
|
||||
# Zoom Levels
|
||||
|
||||
Tiles must be generated for:
|
||||
|
||||
```
|
||||
z = 0 → 14
|
||||
```
|
||||
|
||||
(Or the maximum zoom available in the dataset.)
|
||||
|
||||
---
|
||||
|
||||
# Data Sources
|
||||
|
||||
Tile features must be built from the validated NavSea semantic dataset.
|
||||
|
||||
Primary semantic source:
|
||||
|
||||
```
|
||||
pbf_relayer_candidates
|
||||
```
|
||||
|
||||
Additional required tables:
|
||||
|
||||
```
|
||||
features
|
||||
properties
|
||||
at_attributes
|
||||
feature_semantic
|
||||
```
|
||||
|
||||
These tables must be joined to reconstruct the full feature.
|
||||
|
||||
---
|
||||
|
||||
# Feature Reconstruction Rules
|
||||
|
||||
Each output tile feature must include:
|
||||
|
||||
## Geometry
|
||||
|
||||
From:
|
||||
|
||||
```
|
||||
features
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
```
|
||||
z
|
||||
x
|
||||
y
|
||||
geom_type
|
||||
```
|
||||
|
||||
The geometry encoding must match the original vector tile geometry.
|
||||
|
||||
---
|
||||
|
||||
## Original Attributes
|
||||
|
||||
All original attributes from:
|
||||
|
||||
```
|
||||
properties
|
||||
```
|
||||
|
||||
must be preserved.
|
||||
|
||||
Examples include:
|
||||
|
||||
```
|
||||
class
|
||||
shape
|
||||
name
|
||||
symbol
|
||||
depth
|
||||
category
|
||||
```
|
||||
|
||||
These attributes must **not be removed or renamed**.
|
||||
|
||||
---
|
||||
|
||||
## Semantic Attributes
|
||||
|
||||
Additional semantic fields must be included from:
|
||||
|
||||
```
|
||||
pbf_relayer_candidates
|
||||
```
|
||||
|
||||
Including:
|
||||
|
||||
```
|
||||
canonical_object_type
|
||||
canonical_family
|
||||
semantic_key
|
||||
detection_key
|
||||
render_layer
|
||||
```
|
||||
|
||||
These fields must be **added**, not replacing original fields.
|
||||
|
||||
---
|
||||
|
||||
# Feature Selection
|
||||
|
||||
Features must be selected based on tile coordinates intersecting the AOI.
|
||||
|
||||
Selection process:
|
||||
|
||||
```
|
||||
1 determine tile range covering AOI
|
||||
2 select features matching tile coordinates
|
||||
3 group features by tile
|
||||
4 encode each tile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Tile Encoding
|
||||
|
||||
Each tile must be encoded as a **Mapbox Vector Tile (MVT)**.
|
||||
|
||||
Encoding rules:
|
||||
|
||||
```
|
||||
Layer name = render_layer
|
||||
```
|
||||
|
||||
If `render_layer` is null, fallback to:
|
||||
|
||||
```
|
||||
source_layer
|
||||
```
|
||||
|
||||
Geometry must be encoded according to:
|
||||
|
||||
```
|
||||
geom_type
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Performance Requirements
|
||||
|
||||
The tile builder must:
|
||||
|
||||
```
|
||||
avoid full-table scans where possible
|
||||
use tile coordinate filtering
|
||||
process tiles incrementally
|
||||
```
|
||||
|
||||
The builder must not attempt to load the entire dataset into memory.
|
||||
|
||||
---
|
||||
|
||||
# Build Script
|
||||
|
||||
Codex must implement a script:
|
||||
|
||||
```
|
||||
navsea_tile_builder.py
|
||||
```
|
||||
|
||||
Capabilities required:
|
||||
|
||||
```
|
||||
AOI tile calculation
|
||||
database feature extraction
|
||||
tile grouping
|
||||
vector tile encoding
|
||||
parallel tile generation
|
||||
filesystem output
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Suggested Execution
|
||||
|
||||
The build script should be executable as:
|
||||
|
||||
```bash
|
||||
python navsea_tile_builder.py \
|
||||
--center-lat 33.4425 \
|
||||
--center-lon 129.9697 \
|
||||
--radius-nm 10 \
|
||||
--zmin 0 \
|
||||
--zmax 14 \
|
||||
--output /home/wwwroot/pbf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Expected Result
|
||||
|
||||
After the build completes, the directory should contain:
|
||||
|
||||
```
|
||||
/home/wwwroot/pbf/
|
||||
├─ 0/
|
||||
├─ 1/
|
||||
├─ 2/
|
||||
├─ ...
|
||||
└─ 14/
|
||||
```
|
||||
|
||||
Each containing:
|
||||
|
||||
```
|
||||
{x}/{y}.pbf
|
||||
```
|
||||
|
||||
The tiles must render correctly in MapLibre / OpenCPN / tile viewers.
|
||||
|
||||
---
|
||||
|
||||
# Verification
|
||||
|
||||
After build, the following checks should pass:
|
||||
|
||||
```
|
||||
tiles exist for requested AOI
|
||||
tile hierarchy is correct
|
||||
vector tiles decode successfully
|
||||
original attributes preserved
|
||||
semantic fields present
|
||||
```
|
||||
|
||||
Example feature should resemble:
|
||||
|
||||
```json
|
||||
{
|
||||
"class": "灯",
|
||||
"shape": "灯標",
|
||||
"name": "唐津灯台",
|
||||
|
||||
"canonical_object_type": "navigation_light",
|
||||
"canonical_family": "navigation_aid",
|
||||
"detection_key": "nav_light"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# End Task
|
||||
104
tasks/pbf/fiddecode.md
Normal file
104
tasks/pbf/fiddecode.md
Normal file
@@ -0,0 +1,104 @@
|
||||
from Crypto.Cipher import AES
|
||||
import hashlib
|
||||
import struct
|
||||
|
||||
# Example implementation updated for the full signed int32 legacy fid domain.
|
||||
# This keeps the algorithm reversible for all observed NavSea legacy fid values.
|
||||
MIN_VAL = -(1 << 31)
|
||||
MAX_VAL = (1 << 31) - 1
|
||||
N = MAX_VAL - MIN_VAL + 1 # 4294967296
|
||||
|
||||
ROUNDS = 10
|
||||
DOMAIN_BITS = 32
|
||||
DOMAIN_SIZE = 1 << DOMAIN_BITS
|
||||
|
||||
|
||||
def _prf(key: bytes, round_no: int, value: int) -> int:
|
||||
"""
|
||||
AES-based PRF, returns 16-bit integer.
|
||||
"""
|
||||
cipher = AES.new(key, AES.MODE_ECB)
|
||||
data = struct.pack(">IQ", round_no, value)
|
||||
block = hashlib.sha256(data).digest()[:16]
|
||||
out = cipher.encrypt(block)
|
||||
return int.from_bytes(out[-2:], "big")
|
||||
|
||||
|
||||
def _feistel_permute(x: int, key: bytes, encrypt: bool) -> int:
|
||||
"""
|
||||
32-bit Feistel permutation.
|
||||
"""
|
||||
if not (0 <= x < DOMAIN_SIZE):
|
||||
raise ValueError("x out of 32-bit domain")
|
||||
|
||||
l = (x >> 16) & 0xFFFF
|
||||
r = x & 0xFFFF
|
||||
|
||||
rounds = range(ROUNDS) if encrypt else reversed(range(ROUNDS))
|
||||
|
||||
for rnd in rounds:
|
||||
if encrypt:
|
||||
f = _prf(key, rnd, r)
|
||||
l, r = r, l ^ f
|
||||
else:
|
||||
f = _prf(key, rnd, l)
|
||||
l, r = r ^ f, l
|
||||
|
||||
return ((l << 16) | r) & 0xFFFFFFFF
|
||||
|
||||
|
||||
def encrypt_number(x: int, key: bytes) -> int:
|
||||
"""
|
||||
Encrypt x in [-2147483648, 2147483647]
|
||||
Return non-negative integer in [0, N-1]
|
||||
"""
|
||||
if len(key) not in (16, 24, 32):
|
||||
raise ValueError("AES key must be 16, 24, or 32 bytes")
|
||||
if not (MIN_VAL <= x <= MAX_VAL):
|
||||
raise ValueError("input out of range")
|
||||
|
||||
# Map original range to [0, N-1]
|
||||
r = x - MIN_VAL
|
||||
|
||||
# Cycle-walking into [0, N-1]
|
||||
while True:
|
||||
r = _feistel_permute(r, key, True)
|
||||
if r < N:
|
||||
return r
|
||||
|
||||
|
||||
def decrypt_number(y: int, key: bytes) -> int:
|
||||
"""
|
||||
Decrypt non-negative integer y in [0, N-1]
|
||||
Return original integer in [-2147483648, 2147483647]
|
||||
"""
|
||||
if len(key) not in (16, 24, 32):
|
||||
raise ValueError("AES key must be 16, 24, or 32 bytes")
|
||||
if not (0 <= y < N):
|
||||
raise ValueError("encrypted value out of range")
|
||||
|
||||
r = y
|
||||
|
||||
# Reverse cycle-walking
|
||||
while True:
|
||||
r = _feistel_permute(r, key, False)
|
||||
if r < N:
|
||||
return r + MIN_VAL
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
key = b"example-secret!!" # 16 bytes
|
||||
|
||||
samples = [
|
||||
-2147483648,
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
12345678,
|
||||
2147483647,
|
||||
]
|
||||
|
||||
for x in samples:
|
||||
enc = encrypt_number(x, key)
|
||||
dec = decrypt_number(enc, key)
|
||||
print(f"x={x}, enc={enc}, dec={dec}, ok={x == dec}")
|
||||
123
tasks/pbf/mappings/navsea_field_name_rules_v1.yaml
Normal file
123
tasks/pbf/mappings/navsea_field_name_rules_v1.yaml
Normal file
@@ -0,0 +1,123 @@
|
||||
ruleset: navsea_field_name_rules_v1
|
||||
bundle_id: navsea-core
|
||||
version: v1-draft
|
||||
rules:
|
||||
- field_name_jp: fid
|
||||
field_name_std: fid_legacy_raw
|
||||
field_group: identity
|
||||
keep_in_delivery: false
|
||||
keep_in_engineering: true
|
||||
normalization_class: reversible_identity
|
||||
notes: Preserve the original legacy fid only in engineering and trace outputs.
|
||||
- field_name_jp: at
|
||||
field_name_std: at_raw
|
||||
field_group: source_legacy
|
||||
keep_in_delivery: false
|
||||
keep_in_engineering: true
|
||||
normalization_class: raw_blob
|
||||
notes: Raw attribute pack remains engineering-only by default.
|
||||
- field_name_jp: 分類番号
|
||||
field_name_std: class_code
|
||||
field_group: source_legacy
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: legacy_render_code
|
||||
notes: Legacy class code used during transition and audits.
|
||||
- field_name_jp: 形状分類番号
|
||||
field_name_std: shape_class_code
|
||||
field_group: source_legacy
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: legacy_render_code
|
||||
notes: Legacy shape class code used during transition and audits.
|
||||
- field_name_jp: 表示用番号
|
||||
field_name_std: display_code
|
||||
field_group: source_legacy
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: legacy_render_code
|
||||
notes: Legacy display code retained until all rendering migrates to chart_* fields.
|
||||
- field_name_jp: 灯色
|
||||
field_name_std: light_color_raw_code
|
||||
field_group: light
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: field_value_normalization
|
||||
notes: Legacy raw color code maps into light_color_code.
|
||||
- field_name_jp: 灯略記
|
||||
field_name_std: light_character_remark
|
||||
field_group: light
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: content_text
|
||||
notes: User-visible light remark should remain reversible.
|
||||
- field_name_jp: 明弧/分孤
|
||||
field_name_std: light_sector_remark
|
||||
field_group: light
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: field_value_normalization
|
||||
notes: Legacy light sector remark maps into light_sector_mode and trace fields.
|
||||
- field_name_jp: 表示位置
|
||||
field_name_std: label_position_code_legacy
|
||||
field_group: labels
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: field_value_normalization
|
||||
notes: Legacy label position code maps into chart_label_position_code.
|
||||
- field_name_jp: 名称
|
||||
field_name_std: name_ja
|
||||
field_group: labels
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: content_text
|
||||
notes: Primary Japanese name content must remain available.
|
||||
- field_name_jp: 名称補助
|
||||
field_name_std: name_subtext_ja
|
||||
field_group: labels
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: content_text
|
||||
notes: Secondary Japanese name content must remain available.
|
||||
- field_name_jp: 日本語地名
|
||||
field_name_std: place_name_ja
|
||||
field_group: labels
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: content_text
|
||||
notes: Japanese place name content must remain available.
|
||||
- field_name_jp: 英文字地名
|
||||
field_name_std: place_name_en
|
||||
field_group: labels
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: content_text
|
||||
notes: English place name content remains available for fallback labels.
|
||||
- field_name_jp: 水深値(m)
|
||||
field_name_std: depth_value_m_legacy
|
||||
field_group: normalized_numeric
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: numeric_normalization
|
||||
notes: Legacy depth string is normalized into depth_value_m.
|
||||
- field_name_jp: 高さ(m)
|
||||
field_name_std: clearance_height_m_legacy
|
||||
field_group: normalized_numeric
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: numeric_normalization
|
||||
notes: Legacy height string is normalized into clearance_height_m.
|
||||
- field_name_jp: 高さ/深度(m)
|
||||
field_name_std: height_or_depth_m_legacy
|
||||
field_group: normalized_numeric
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: numeric_normalization
|
||||
notes: Mixed height/depth legacy string maps into least_depth_m or clearance semantics.
|
||||
- field_name_jp: 角度
|
||||
field_name_std: bearing_deg_legacy
|
||||
field_group: normalized_numeric
|
||||
keep_in_delivery: true
|
||||
keep_in_engineering: true
|
||||
normalization_class: numeric_normalization
|
||||
notes: Legacy angle string is normalized into bearing_deg.
|
||||
148
tasks/pbf/mappings/navsea_field_value_rules_v1.yaml
Normal file
148
tasks/pbf/mappings/navsea_field_value_rules_v1.yaml
Normal file
@@ -0,0 +1,148 @@
|
||||
ruleset: navsea_field_value_rules_v1
|
||||
bundle_id: navsea-core
|
||||
version: v1-draft
|
||||
rules:
|
||||
- rule_id: FVAL-LIGHT-001
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "1"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: green
|
||||
notes: Legacy light color code 1 maps to green in current data.
|
||||
- rule_id: FVAL-LIGHT-002
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "2"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: red
|
||||
notes: Legacy light color code 2 maps to red.
|
||||
- rule_id: FVAL-LIGHT-003
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "3"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: yellow
|
||||
notes: Legacy light color code 3 maps to yellow.
|
||||
- rule_id: FVAL-LIGHT-004
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "4"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: white
|
||||
notes: Legacy light color code 4 maps to white.
|
||||
- rule_id: FVAL-LIGHT-005
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "5"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: blue
|
||||
notes: Legacy light color code 5 maps to blue.
|
||||
- rule_id: FVAL-LIGHT-006
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "6"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: violet
|
||||
notes: Legacy light color code 6 maps to violet.
|
||||
- rule_id: FVAL-LIGHT-007
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "7"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: orange
|
||||
notes: Legacy light color code 7 maps to orange.
|
||||
- rule_id: FVAL-LIGHT-008
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "8"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: amber
|
||||
notes: Legacy light color code 8 maps to amber.
|
||||
- rule_id: FVAL-LIGHT-009
|
||||
rule_revision: 1
|
||||
field_name_jp: 灯色
|
||||
legacy_value: "9"
|
||||
standardized_field: light_color_code
|
||||
standardized_value: mixed
|
||||
notes: Legacy light color code 9 maps to mixed.
|
||||
- rule_id: FVAL-LABELPOS-001
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "0"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: tl
|
||||
notes: Legacy label position 0 maps to top-left.
|
||||
- rule_id: FVAL-LABELPOS-002
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "1"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: t
|
||||
notes: Legacy label position 1 maps to top.
|
||||
- rule_id: FVAL-LABELPOS-003
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "2"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: tr
|
||||
notes: Legacy label position 2 maps to top-right.
|
||||
- rule_id: FVAL-LABELPOS-004
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "4"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: l
|
||||
notes: Legacy label position 4 maps to left.
|
||||
- rule_id: FVAL-LABELPOS-005
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "5"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: c
|
||||
notes: Legacy label position 5 maps to center.
|
||||
- rule_id: FVAL-LABELPOS-006
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "6"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: r
|
||||
notes: Legacy label position 6 maps to right.
|
||||
- rule_id: FVAL-LABELPOS-007
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "8"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: bl
|
||||
notes: Legacy label position 8 maps to bottom-left.
|
||||
- rule_id: FVAL-LABELPOS-008
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "9"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: b
|
||||
notes: Legacy label position 9 maps to bottom.
|
||||
- rule_id: FVAL-LABELPOS-009
|
||||
rule_revision: 1
|
||||
field_name_jp: 表示位置
|
||||
legacy_value: "10"
|
||||
standardized_field: chart_label_position_code
|
||||
standardized_value: br
|
||||
notes: Legacy label position 10 maps to bottom-right.
|
||||
- rule_id: FVAL-CLASS-001
|
||||
rule_revision: 1
|
||||
field_name_jp: 分類番号
|
||||
legacy_value: "428"
|
||||
standardized_field: chart_symbol_code
|
||||
standardized_value: fish_reef
|
||||
geom_scope: Point
|
||||
canonical_object_scope: 魚礁
|
||||
notes: Legacy class 428 point object renders as fish reef symbol.
|
||||
- rule_id: FVAL-CLASS-002
|
||||
rule_revision: 1
|
||||
field_name_jp: 分類番号
|
||||
legacy_value: "428"
|
||||
standardized_field: chart_fill_style
|
||||
standardized_value: fish_reef_area
|
||||
geom_scope: Polygon,MultiPolygon
|
||||
canonical_object_scope: 魚礁
|
||||
notes: Legacy class 428 area object renders as fish reef area pattern.
|
||||
171
tasks/pbf/mappings/navsea_render_rules_v1.yaml
Normal file
171
tasks/pbf/mappings/navsea_render_rules_v1.yaml
Normal file
@@ -0,0 +1,171 @@
|
||||
ruleset: navsea_render_rules_v1
|
||||
bundle_id: navsea-core
|
||||
version: v1-draft
|
||||
rules:
|
||||
- rule_id: REN-NAV-001
|
||||
rule_revision: 1
|
||||
priority: 100
|
||||
enabled: true
|
||||
match_expr:
|
||||
all:
|
||||
- field: canonical_object_type
|
||||
op: eq
|
||||
value: 港湾灯台
|
||||
- field: geom_type
|
||||
op: eq
|
||||
value: Point
|
||||
output:
|
||||
chart_render_type: symbol
|
||||
chart_symbol_family: navigation_light
|
||||
chart_symbol_code: lighthouse
|
||||
chart_priority: 900
|
||||
chart_visibility_min: 7
|
||||
chart_visibility_max: 24
|
||||
reason: 港湾灯台应以高优先级灯标符号渲染。
|
||||
|
||||
- rule_id: REN-HAZ-001
|
||||
rule_revision: 1
|
||||
priority: 120
|
||||
enabled: true
|
||||
match_expr:
|
||||
all:
|
||||
- field: canonical_object_type
|
||||
op: eq
|
||||
value: 魚礁
|
||||
- field: geom_type
|
||||
op: eq
|
||||
value: Point
|
||||
output:
|
||||
chart_render_type: symbol
|
||||
chart_symbol_family: hazard
|
||||
chart_symbol_code: fish_reef
|
||||
chart_priority: 860
|
||||
area_usage_class: fishery
|
||||
hazard_class: fish_reef
|
||||
hazard_severity: major
|
||||
reason: 点状鱼礁以鱼礁专用危险物符号表达。
|
||||
|
||||
- rule_id: REN-HAZ-002
|
||||
rule_revision: 1
|
||||
priority: 121
|
||||
enabled: true
|
||||
match_expr:
|
||||
all:
|
||||
- field: canonical_object_type
|
||||
op: eq
|
||||
value: 魚礁
|
||||
- field: geom_type
|
||||
op: in
|
||||
value: [Polygon, MultiPolygon]
|
||||
output:
|
||||
chart_render_type: fill
|
||||
chart_symbol_family: hazard
|
||||
chart_fill_style: fish_reef_area
|
||||
chart_priority: 850
|
||||
area_usage_class: fishery
|
||||
hazard_class: fish_reef
|
||||
hazard_severity: major
|
||||
reason: 面状鱼礁区以鱼礁专用危险区填充表达,同时保留 fishery 用途语义。
|
||||
|
||||
- rule_id: REN-DEPTH-001
|
||||
rule_revision: 1
|
||||
priority: 200
|
||||
enabled: true
|
||||
match_expr:
|
||||
all:
|
||||
- field: canonical_object_type
|
||||
op: eq
|
||||
value: 等深线
|
||||
output:
|
||||
chart_render_type: line
|
||||
chart_symbol_family: contour
|
||||
chart_line_style: contour_minor
|
||||
chart_priority: 640
|
||||
chart_visibility_min: 8
|
||||
chart_visibility_max: 24
|
||||
reason: 等深线统一归入 contour line 体系。
|
||||
|
||||
- rule_id: REN-SEABED-001
|
||||
rule_revision: 1
|
||||
priority: 210
|
||||
enabled: true
|
||||
match_expr:
|
||||
all:
|
||||
- field: canonical_object_type
|
||||
op: eq
|
||||
value: 底質
|
||||
output:
|
||||
chart_render_type: label
|
||||
chart_symbol_family: seabed
|
||||
chart_text_style: seabed_text
|
||||
chart_priority: 500
|
||||
chart_visibility_min: 11
|
||||
chart_visibility_max: 24
|
||||
reason: 底质对象以海底属性文字渲染。
|
||||
|
||||
- rule_id: REN-PLACE-001
|
||||
rule_revision: 1
|
||||
priority: 220
|
||||
enabled: true
|
||||
match_expr:
|
||||
all:
|
||||
- field: canonical_object_type
|
||||
op: eq
|
||||
value: 海上地名
|
||||
output:
|
||||
chart_render_type: label
|
||||
chart_symbol_family: place
|
||||
chart_text_style: place_name_sea
|
||||
chart_priority: 450
|
||||
chart_visibility_min: 7
|
||||
chart_visibility_max: 24
|
||||
reason: 海上地名使用海上地名字体体系渲染。
|
||||
|
||||
- rule_id: REN-PLACE-002
|
||||
rule_revision: 1
|
||||
priority: 221
|
||||
enabled: true
|
||||
match_expr:
|
||||
all:
|
||||
- field: canonical_object_type
|
||||
op: eq
|
||||
value: 陆上地名
|
||||
output:
|
||||
chart_render_type: label
|
||||
chart_symbol_family: place
|
||||
chart_text_style: place_name_land
|
||||
chart_priority: 440
|
||||
chart_visibility_min: 7
|
||||
chart_visibility_max: 24
|
||||
reason: 陆上地名使用陆地地名字体体系渲染。
|
||||
|
||||
- rule_id: REN-USAGE-001
|
||||
rule_revision: 1
|
||||
priority: 230
|
||||
enabled: true
|
||||
match_expr:
|
||||
all:
|
||||
- field: canonical_object_type
|
||||
op: eq
|
||||
value: 錨泊地
|
||||
- field: geom_type
|
||||
op: in
|
||||
value: [Polygon, MultiPolygon]
|
||||
output:
|
||||
chart_render_type: fill
|
||||
chart_symbol_family: usage_area
|
||||
chart_fill_style: anchorage_area
|
||||
chart_priority: 750
|
||||
area_usage_class: anchorage
|
||||
reason: 锚泊地区域以 anchorage_area 语义填充表达。
|
||||
|
||||
- rule_id: REN-FALLBACK-001
|
||||
rule_revision: 1
|
||||
priority: 9999
|
||||
enabled: true
|
||||
match_expr:
|
||||
all: []
|
||||
output:
|
||||
chart_render_type: none
|
||||
chart_priority: 0
|
||||
reason: 未命中渲染规则的对象默认不进入正式语义渲染,待补录。
|
||||
12
tasks/pbf/mappings/navsea_rule_bundle_v1.yaml
Normal file
12
tasks/pbf/mappings/navsea_rule_bundle_v1.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
bundle_id: navsea-core
|
||||
bundle_version: v1-draft
|
||||
status: draft
|
||||
effective_date: 2026-03-14
|
||||
taxonomy_ruleset: navsea_taxonomy_rules_v1
|
||||
render_ruleset: navsea_render_rules_v1
|
||||
source_layer_ruleset: navsea_source_layer_rules_v1
|
||||
field_name_ruleset: navsea_field_name_rules_v1
|
||||
field_value_ruleset: navsea_field_value_rules_v1
|
||||
notes: >
|
||||
Draft rule bundle for traceable NavSea taxonomy and render mapping.
|
||||
File is intended as source-of-truth metadata and should be imported into SQL.
|
||||
151
tasks/pbf/mappings/navsea_source_layer_rules_v1.yaml
Normal file
151
tasks/pbf/mappings/navsea_source_layer_rules_v1.yaml
Normal file
@@ -0,0 +1,151 @@
|
||||
ruleset: navsea_source_layer_rules_v1
|
||||
bundle_id: navsea-core
|
||||
version: v1-draft
|
||||
rules:
|
||||
- source_layer_jp: L700
|
||||
source_layer_std: depth_zone_700
|
||||
notes: Legacy coded depth zone layer kept as stable standardized code.
|
||||
- source_layer_jp: L702
|
||||
source_layer_std: depth_zone_702
|
||||
notes: Legacy coded depth zone layer kept as stable standardized code.
|
||||
- source_layer_jp: L725
|
||||
source_layer_std: depth_zone_725
|
||||
notes: Legacy coded depth zone layer kept as stable standardized code.
|
||||
- source_layer_jp: L739
|
||||
source_layer_std: depth_zone_739
|
||||
notes: Legacy coded depth zone layer kept as stable standardized code.
|
||||
- source_layer_jp: L740
|
||||
source_layer_std: depth_zone_740
|
||||
notes: Legacy coded depth zone layer kept as stable standardized code.
|
||||
- source_layer_jp: L741
|
||||
source_layer_std: depth_zone_741
|
||||
notes: Legacy coded depth zone layer kept as stable standardized code.
|
||||
- source_layer_jp: L748
|
||||
source_layer_std: depth_zone_748
|
||||
notes: Legacy coded depth zone layer kept as stable standardized code.
|
||||
- source_layer_jp: L749
|
||||
source_layer_std: depth_zone_749
|
||||
notes: Legacy coded depth zone layer kept as stable standardized code.
|
||||
- source_layer_jp: L危険界
|
||||
source_layer_std: hazard_boundary_line
|
||||
notes: Standardized line identity for hazard boundary linework.
|
||||
- source_layer_jp: L基本線
|
||||
source_layer_std: baseline_line
|
||||
notes: Standardized line identity for baseline linework.
|
||||
- source_layer_jp: L概略等深線
|
||||
source_layer_std: depth_contour_overview
|
||||
notes: Overview contour line layer.
|
||||
- source_layer_jp: L海底地形
|
||||
source_layer_std: bathymetry_line
|
||||
notes: Bathymetry support line layer.
|
||||
- source_layer_jp: L海底線
|
||||
source_layer_std: seabed_line
|
||||
notes: Seabed line feature container.
|
||||
- source_layer_jp: L等深線
|
||||
source_layer_std: depth_contour
|
||||
notes: Standard contour line layer.
|
||||
- source_layer_jp: L航路
|
||||
source_layer_std: route_axis_line
|
||||
notes: Route axis or route line layer.
|
||||
- source_layer_jp: L陸上構造物陸
|
||||
source_layer_std: onshore_structure_line
|
||||
notes: Onshore structure line layer.
|
||||
- source_layer_jp: L高さ制限
|
||||
source_layer_std: clearance_limit_line
|
||||
notes: Clearance restriction line layer.
|
||||
- source_layer_jp: P721ククリ
|
||||
source_layer_std: clip_outline_721
|
||||
notes: Stable outline layer preserved by numeric legacy code.
|
||||
- source_layer_jp: P730ククリ
|
||||
source_layer_std: clip_outline_730
|
||||
notes: Stable outline layer preserved by numeric legacy code.
|
||||
- source_layer_jp: P754ククリ
|
||||
source_layer_std: clip_outline_754
|
||||
notes: Stable outline layer preserved by numeric legacy code.
|
||||
- source_layer_jp: pパイロットステーション
|
||||
source_layer_std: pilot_station_point
|
||||
notes: Pilot station point layer.
|
||||
- source_layer_jp: P危険界ククリ
|
||||
source_layer_std: hazard_boundary_outline
|
||||
notes: Hazard boundary outline layer.
|
||||
- source_layer_jp: p地名
|
||||
source_layer_std: place_label_sea
|
||||
notes: Marine place label point layer.
|
||||
- source_layer_jp: p地名陸
|
||||
source_layer_std: place_label_land
|
||||
notes: Land place label point layer.
|
||||
- source_layer_jp: P基本線
|
||||
source_layer_std: baseline_area
|
||||
notes: Baseline area or container layer.
|
||||
- source_layer_jp: P基本線ククリ
|
||||
source_layer_std: baseline_outline
|
||||
notes: Baseline outline layer.
|
||||
- source_layer_jp: p底質
|
||||
source_layer_std: seabed_text_point
|
||||
notes: Seabed label point layer.
|
||||
- source_layer_jp: p投錨注意障害物
|
||||
source_layer_std: anchor_caution_hazard_point
|
||||
notes: Point hazards relevant to anchoring caution.
|
||||
- source_layer_jp: P投錨注意障害物ククリ
|
||||
source_layer_std: anchor_caution_hazard_outline
|
||||
notes: Outline of anchoring caution hazard area.
|
||||
- source_layer_jp: P施設・境界線等
|
||||
source_layer_std: facility_boundary_area
|
||||
notes: Facility and boundary area container.
|
||||
- source_layer_jp: P施設・境界線等ククリ
|
||||
source_layer_std: facility_boundary_outline
|
||||
notes: Facility and boundary outline layer.
|
||||
- source_layer_jp: P施設・境界線等透明
|
||||
source_layer_std: facility_boundary_area_transparent
|
||||
notes: Transparent facility and boundary area layer.
|
||||
- source_layer_jp: P橋りょう等構造物
|
||||
source_layer_std: bridge_structure
|
||||
notes: Bridge and related structure layer.
|
||||
- source_layer_jp: P漁具定置箇所
|
||||
source_layer_std: fixed_fishing_gear_area
|
||||
notes: Fixed fishing gear area layer.
|
||||
- source_layer_jp: P潜堤
|
||||
source_layer_std: submerged_reef_area
|
||||
notes: Submerged reef area layer.
|
||||
- source_layer_jp: P穴
|
||||
source_layer_std: hole_area
|
||||
notes: Hole or depression area layer.
|
||||
- source_layer_jp: p航行危険障害物
|
||||
source_layer_std: navigation_hazard_point
|
||||
notes: Navigation hazard point layer.
|
||||
- source_layer_jp: P航行危険障害物ククリ
|
||||
source_layer_std: navigation_hazard_outline
|
||||
notes: Navigation hazard outline layer.
|
||||
- source_layer_jp: P航路
|
||||
source_layer_std: route_area
|
||||
notes: Route area layer.
|
||||
- source_layer_jp: P航路ククリ
|
||||
source_layer_std: route_outline
|
||||
notes: Route outline layer.
|
||||
- source_layer_jp: p航路境界等
|
||||
source_layer_std: route_boundary_point
|
||||
notes: Route boundary point annotation layer.
|
||||
- source_layer_jp: p航路標識群
|
||||
source_layer_std: navigation_marks
|
||||
notes: Navigation marks point layer.
|
||||
- source_layer_jp: P誘導線ククリ
|
||||
source_layer_std: leading_line_outline
|
||||
notes: Leading line outline layer.
|
||||
- source_layer_jp: p錨泊地等
|
||||
source_layer_std: anchorage_point
|
||||
notes: Anchorage point symbol layer.
|
||||
- source_layer_jp: P錨泊地等ククリ
|
||||
source_layer_std: anchorage_outline
|
||||
notes: Anchorage outline layer.
|
||||
- source_layer_jp: p陸上構造物
|
||||
source_layer_std: onshore_structure_point
|
||||
notes: Onshore structure point layer.
|
||||
- source_layer_jp: P陸上構造物陸
|
||||
source_layer_std: onshore_structure_area
|
||||
notes: Onshore structure area layer.
|
||||
- source_layer_jp: P陸域
|
||||
source_layer_std: land_area
|
||||
notes: Land area polygon layer.
|
||||
- source_layer_jp: p高さ制限
|
||||
source_layer_std: clearance_limit_point
|
||||
notes: Clearance restriction point layer.
|
||||
134
tasks/pbf/mappings/navsea_taxonomy_rules_v1.yaml
Normal file
134
tasks/pbf/mappings/navsea_taxonomy_rules_v1.yaml
Normal file
@@ -0,0 +1,134 @@
|
||||
ruleset: navsea_taxonomy_rules_v1
|
||||
bundle_id: navsea-core
|
||||
version: v1-draft
|
||||
rules:
|
||||
- rule_id: TAX-NAV-001
|
||||
rule_revision: 1
|
||||
priority: 100
|
||||
enabled: true
|
||||
match_scope: feature
|
||||
match_expr:
|
||||
all:
|
||||
- field: class_name
|
||||
op: contains_any
|
||||
value: [港湾灯台, 灯台]
|
||||
- field: geom_type
|
||||
op: eq
|
||||
value: Point
|
||||
output:
|
||||
canonical_family: navigation_aid
|
||||
canonical_object_type: 港湾灯台
|
||||
detection_key_template: symbol:港湾灯台
|
||||
reason: 港湾灯台属于典型点状助航对象。
|
||||
|
||||
- rule_id: TAX-DEPTH-001
|
||||
rule_revision: 1
|
||||
priority: 140
|
||||
enabled: true
|
||||
match_scope: layer
|
||||
match_expr:
|
||||
all:
|
||||
- field: source_layer
|
||||
op: eq
|
||||
value: L等深線
|
||||
output:
|
||||
canonical_family: depth
|
||||
canonical_object_type: 等深线
|
||||
detection_key_template: line:等深线
|
||||
reason: 等深线来源层具有稳定的深度线语义。
|
||||
|
||||
- rule_id: TAX-SEABED-001
|
||||
rule_revision: 1
|
||||
priority: 150
|
||||
enabled: true
|
||||
match_scope: layer
|
||||
match_expr:
|
||||
all:
|
||||
- field: source_layer
|
||||
op: eq
|
||||
value: p底質
|
||||
output:
|
||||
canonical_family: seabed
|
||||
canonical_object_type: 底質
|
||||
detection_key_template: label:底質
|
||||
reason: 底质标签层具有稳定的海底属性语义。
|
||||
|
||||
- rule_id: TAX-PLACE-001
|
||||
rule_revision: 1
|
||||
priority: 160
|
||||
enabled: true
|
||||
match_scope: layer
|
||||
match_expr:
|
||||
all:
|
||||
- field: source_layer
|
||||
op: eq
|
||||
value: p地名
|
||||
output:
|
||||
canonical_family: place
|
||||
canonical_object_type: 海上地名
|
||||
detection_key_template: label:海上地名
|
||||
reason: 海上地名点层具有稳定的地名语义。
|
||||
|
||||
- rule_id: TAX-PLACE-002
|
||||
rule_revision: 1
|
||||
priority: 161
|
||||
enabled: true
|
||||
match_scope: layer
|
||||
match_expr:
|
||||
all:
|
||||
- field: source_layer
|
||||
op: eq
|
||||
value: p地名陸
|
||||
output:
|
||||
canonical_family: place
|
||||
canonical_object_type: 陆上地名
|
||||
detection_key_template: label:陆上地名
|
||||
reason: 陆上地名点层具有稳定的地名语义。
|
||||
|
||||
- rule_id: TAX-USAGE-001
|
||||
rule_revision: 1
|
||||
priority: 180
|
||||
enabled: true
|
||||
match_scope: feature
|
||||
match_expr:
|
||||
all:
|
||||
- field: class_name
|
||||
op: contains_any
|
||||
value: [錨泊, 錨地]
|
||||
output:
|
||||
canonical_family: usage_area
|
||||
canonical_object_type: 錨泊地
|
||||
detection_key_template: mixed:錨泊地
|
||||
reason: 锚泊类对象统一归入 usage_area 体系。
|
||||
|
||||
- rule_id: TAX-HAZ-001
|
||||
rule_revision: 1
|
||||
priority: 120
|
||||
enabled: true
|
||||
match_scope: feature
|
||||
match_expr:
|
||||
all:
|
||||
- field: class_name
|
||||
op: contains
|
||||
value: 魚礁
|
||||
- field: geom_type
|
||||
op: in
|
||||
value: [Point, Polygon, MultiPolygon]
|
||||
output:
|
||||
canonical_family: hazard
|
||||
canonical_object_type: 魚礁
|
||||
detection_key_template: mixed:魚礁
|
||||
reason: 魚礁在当前业务目标下优先视为危险对象,并允许后续叠加用途语义。
|
||||
|
||||
- rule_id: TAX-FALLBACK-001
|
||||
rule_revision: 1
|
||||
priority: 9999
|
||||
enabled: true
|
||||
match_scope: feature
|
||||
match_expr:
|
||||
all: []
|
||||
output:
|
||||
canonical_family: unknown
|
||||
canonical_object_type: 未分类对象
|
||||
detection_key_template: unknown:{source_layer}
|
||||
reason: 所有未命中 taxonomy 规则的对象统一回退到待补录分类。
|
||||
114
tasks/pipline.md
Normal file
114
tasks/pipline.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# NavSea Weather Server
|
||||
Task: WeatherServer_Pipeline
|
||||
Architecture: NavSea V11
|
||||
Codex: codex6
|
||||
Status: TODO
|
||||
|
||||
---
|
||||
|
||||
# 1 任务目标
|
||||
|
||||
创建 Weather Pipeline。
|
||||
|
||||
Pipeline 负责自动执行整个天气数据生产流程:
|
||||
|
||||
Downloader
|
||||
→ Grid Builder
|
||||
→ Vector Tile Generator
|
||||
|
||||
输入:
|
||||
|
||||
NOAA GFS
|
||||
|
||||
输出:
|
||||
|
||||
/weather/{time}/{z}/{x}/{y}.pbf
|
||||
|
||||
用于 NavSea 客户端加载天气图层。
|
||||
|
||||
---
|
||||
|
||||
# 2 Pipeline 结构
|
||||
|
||||
weather_server/
|
||||
|
||||
downloader/
|
||||
grid/
|
||||
tiles/
|
||||
pipeline/
|
||||
|
||||
创建文件:
|
||||
|
||||
weather_server/pipeline/weather_pipeline.py
|
||||
|
||||
---
|
||||
|
||||
# 3 Pipeline 执行流程
|
||||
|
||||
step1 下载 GRIB
|
||||
|
||||
step2 生成 Weather Grid
|
||||
|
||||
step3 生成 Vector Tiles
|
||||
|
||||
---
|
||||
|
||||
# 4 创建 Pipeline 文件
|
||||
|
||||
weather_server/pipeline/weather_pipeline.py
|
||||
|
||||
---
|
||||
|
||||
# 5 实现代码
|
||||
|
||||
```python
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
DOWNLOADER = "weather_server/downloader/gfs_downloader.py"
|
||||
GRID_BUILDER = "weather_server/grid/grid_builder_v2.py"
|
||||
TILE_GENERATOR = "weather_server/tiles/vector_tile_generator.py"
|
||||
|
||||
|
||||
def run_step(name, script):
|
||||
|
||||
print("\n==========================")
|
||||
print("Running:", name)
|
||||
print("==========================\n")
|
||||
|
||||
start = time.time()
|
||||
|
||||
result = subprocess.run(
|
||||
["python", script],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
print(result.stdout)
|
||||
|
||||
if result.returncode != 0:
|
||||
print("ERROR:", result.stderr)
|
||||
raise RuntimeError(name + " failed")
|
||||
|
||||
end = time.time()
|
||||
|
||||
print("\nFinished:", name)
|
||||
print("Time:", round(end-start,2),"seconds")
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
print("\nNavSea Weather Pipeline\n")
|
||||
|
||||
run_step("Downloader", DOWNLOADER)
|
||||
|
||||
run_step("Grid Builder", GRID_BUILDER)
|
||||
|
||||
run_step("Vector Tile Generator", TILE_GENERATOR)
|
||||
|
||||
print("\nWeather pipeline completed.\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
83
tasks/test2.md
Normal file
83
tasks/test2.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# NavSea Weather Server
|
||||
Step-2 测试:GFS Downloader
|
||||
|
||||
创建文件:
|
||||
|
||||
gfs_downloader.py
|
||||
|
||||
------------------------------------------------
|
||||
|
||||
import os
|
||||
import requests
|
||||
from datetime import datetime
|
||||
|
||||
BASE_URL = "https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod"
|
||||
|
||||
FORECAST_HOURS = [
|
||||
0,3,6,9,12,15,18,21,24,
|
||||
27,30,33,36,39,42,45,
|
||||
48,51,54,57,60,63,66,
|
||||
69,72
|
||||
]
|
||||
|
||||
OUTPUT_DIR = "data/grib"
|
||||
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
|
||||
def get_cycle():
|
||||
|
||||
now = datetime.utcnow()
|
||||
|
||||
hour = (now.hour // 6) * 6
|
||||
|
||||
cycle = f"{hour:02d}"
|
||||
|
||||
date = now.strftime("%Y%m%d")
|
||||
|
||||
return date, cycle
|
||||
|
||||
|
||||
def download_file(url, path):
|
||||
|
||||
if os.path.exists(path):
|
||||
print("skip", path)
|
||||
return
|
||||
|
||||
print("downloading", url)
|
||||
|
||||
r = requests.get(url, stream=True)
|
||||
|
||||
if r.status_code != 200:
|
||||
print("failed", url)
|
||||
return
|
||||
|
||||
with open(path, "wb") as f:
|
||||
for chunk in r.iter_content(1024*1024):
|
||||
f.write(chunk)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
date, cycle = get_cycle()
|
||||
|
||||
print("cycle:", date, cycle)
|
||||
|
||||
for fh in FORECAST_HOURS:
|
||||
|
||||
fh_str = f"{fh:03d}"
|
||||
|
||||
filename = f"gfs.t{cycle}z.pgrb2.0p25.f{fh_str}"
|
||||
|
||||
url = f"{BASE_URL}/gfs.{date}/{cycle}/atmos/{filename}"
|
||||
|
||||
output = os.path.join(
|
||||
OUTPUT_DIR,
|
||||
f"{date}_{cycle}_f{fh_str}.grib2"
|
||||
)
|
||||
|
||||
download_file(url, output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
264
tasks/updatedownload.md
Normal file
264
tasks/updatedownload.md
Normal file
@@ -0,0 +1,264 @@
|
||||
# NavSea Weather Server
|
||||
Task: WeatherServer_GFS_Subset_Downloader
|
||||
Architecture: V11
|
||||
Codex: codex6
|
||||
Status: TODO
|
||||
|
||||
---
|
||||
|
||||
# 任务目标
|
||||
|
||||
升级现有 gfs_downloader.py
|
||||
|
||||
当前问题:
|
||||
|
||||
直接下载完整 GFS 文件:
|
||||
|
||||
gfs.t00z.pgrb2.0p25.f000
|
||||
|
||||
文件大小:
|
||||
|
||||
≈ 500MB
|
||||
|
||||
下载 72 小时预测需要:
|
||||
|
||||
≈ 12GB
|
||||
|
||||
这是不可接受的。
|
||||
|
||||
解决方案:
|
||||
|
||||
使用 NOAA 提供的 GRIB Subset API:
|
||||
|
||||
filter_gfs_0p25.pl
|
||||
|
||||
只下载:
|
||||
|
||||
1 指定区域
|
||||
2 指定变量
|
||||
3 指定高度层
|
||||
|
||||
目标:
|
||||
|
||||
将单个 GRIB 文件缩小到:
|
||||
|
||||
2MB – 10MB
|
||||
|
||||
---
|
||||
|
||||
# 下载区域
|
||||
|
||||
NavSea 天气服务器只需要日本附近区域:
|
||||
|
||||
leftlon = 120
|
||||
rightlon = 150
|
||||
toplat = 50
|
||||
bottomlat = 20
|
||||
|
||||
覆盖:
|
||||
|
||||
日本海
|
||||
东海
|
||||
太平洋日本海域
|
||||
|
||||
---
|
||||
|
||||
# 下载变量
|
||||
|
||||
Weather System V1 需要以下变量:
|
||||
|
||||
UGRD
|
||||
VGRD
|
||||
APCP
|
||||
PRMSL
|
||||
TMP
|
||||
HTSGW
|
||||
DIRPW
|
||||
PERPW
|
||||
|
||||
说明:
|
||||
|
||||
UGRD VGRD → 风
|
||||
APCP → 降水
|
||||
PRMSL → 气压
|
||||
TMP → 温度
|
||||
HTSGW → 浪高
|
||||
DIRPW → 浪方向
|
||||
PERPW → 浪周期
|
||||
|
||||
变量参数来自 NOAA GFS 参数列表。 :contentReference[oaicite:0]{index=0}
|
||||
|
||||
---
|
||||
|
||||
# 下载高度层
|
||||
|
||||
需要以下层:
|
||||
|
||||
10 m above ground
|
||||
surface
|
||||
mean sea level
|
||||
|
||||
参数:
|
||||
|
||||
lev_10_m_above_ground
|
||||
lev_surface
|
||||
lev_mean_sea_level
|
||||
|
||||
---
|
||||
|
||||
# URL 构造规则
|
||||
|
||||
基础地址:
|
||||
|
||||
https://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_0p25.pl
|
||||
|
||||
示例:
|
||||
|
||||
https://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_0p25.pl?
|
||||
file=gfs.t00z.pgrb2.0p25.f003
|
||||
&lev_10_m_above_ground=on
|
||||
&lev_surface=on
|
||||
&lev_mean_sea_level=on
|
||||
&var_UGRD=on
|
||||
&var_VGRD=on
|
||||
&var_APCP=on
|
||||
&var_PRMSL=on
|
||||
&var_TMP=on
|
||||
&var_HTSGW=on
|
||||
&var_DIRPW=on
|
||||
&var_PERPW=on
|
||||
&leftlon=120
|
||||
&rightlon=150
|
||||
&toplat=50
|
||||
&bottomlat=20
|
||||
&dir=%2Fgfs.20260312%2F00%2Fatmos
|
||||
|
||||
---
|
||||
|
||||
# 修改文件
|
||||
|
||||
weather_server/downloader/gfs_downloader.py
|
||||
|
||||
---
|
||||
|
||||
# 新代码
|
||||
|
||||
```python
|
||||
import os
|
||||
import requests
|
||||
from datetime import datetime
|
||||
|
||||
BASE_URL = "https://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_0p25.pl"
|
||||
|
||||
OUTPUT_DIR = "data/grib"
|
||||
|
||||
FORECAST_HOURS = [
|
||||
0,3,6,9,12,15,18,21,24,
|
||||
27,30,33,36,39,42,45,
|
||||
48,51,54,57,60,63,66,
|
||||
69,72
|
||||
]
|
||||
|
||||
REGION = {
|
||||
"leftlon":120,
|
||||
"rightlon":150,
|
||||
"toplat":50,
|
||||
"bottomlat":20
|
||||
}
|
||||
|
||||
VARIABLES = [
|
||||
"UGRD",
|
||||
"VGRD",
|
||||
"APCP",
|
||||
"PRMSL",
|
||||
"TMP",
|
||||
"HTSGW",
|
||||
"DIRPW",
|
||||
"PERPW"
|
||||
]
|
||||
|
||||
LEVELS = [
|
||||
"lev_10_m_above_ground",
|
||||
"lev_surface",
|
||||
"lev_mean_sea_level"
|
||||
]
|
||||
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
|
||||
def get_cycle():
|
||||
|
||||
now = datetime.utcnow()
|
||||
|
||||
hour = (now.hour // 6) * 6
|
||||
|
||||
cycle = f"{hour:02d}"
|
||||
|
||||
date = now.strftime("%Y%m%d")
|
||||
|
||||
return date, cycle
|
||||
|
||||
|
||||
def build_url(date, cycle, fh):
|
||||
|
||||
filename = f"gfs.t{cycle}z.pgrb2.0p25.f{fh}"
|
||||
|
||||
params = {
|
||||
"file": filename,
|
||||
"leftlon": REGION["leftlon"],
|
||||
"rightlon": REGION["rightlon"],
|
||||
"toplat": REGION["toplat"],
|
||||
"bottomlat": REGION["bottomlat"],
|
||||
"dir": f"/gfs.{date}/{cycle}/atmos"
|
||||
}
|
||||
|
||||
for v in VARIABLES:
|
||||
params[f"var_{v}"] = "on"
|
||||
|
||||
for l in LEVELS:
|
||||
params[l] = "on"
|
||||
|
||||
return BASE_URL, params
|
||||
|
||||
|
||||
def download_file(url, params, path):
|
||||
|
||||
if os.path.exists(path):
|
||||
print("skip", path)
|
||||
return
|
||||
|
||||
print("downloading", path)
|
||||
|
||||
r = requests.get(url, params=params, stream=True)
|
||||
|
||||
if r.status_code != 200:
|
||||
print("failed", r.status_code)
|
||||
return
|
||||
|
||||
with open(path, "wb") as f:
|
||||
for chunk in r.iter_content(1024*1024):
|
||||
f.write(chunk)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
date, cycle = get_cycle()
|
||||
|
||||
print("cycle:", date, cycle)
|
||||
|
||||
for fh in FORECAST_HOURS:
|
||||
|
||||
fh_str = f"{fh:03d}"
|
||||
|
||||
url, params = build_url(date, cycle, fh_str)
|
||||
|
||||
output = os.path.join(
|
||||
OUTPUT_DIR,
|
||||
f"{date}_{cycle}_f{fh_str}.grib2"
|
||||
)
|
||||
|
||||
download_file(url, params, output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user