No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
jhl-hk 242b5f6ad4
README 里的 GroundMap 源码与 DLL 路径改为现址
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 14:46:16 +09:00
.github/workflows feat(ground): per-airport ground map data for the mainland packages 2026-08-07 05:33:14 +08:00
NavData feat(ground): per-airport ground map data for the mainland packages 2026-08-07 05:33:14 +08:00
PRC_FSS Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
tools GBK 机位名不再读成乱码;缺 airports/ 时不再静默产出空图 2026-09-07 15:09:51 +09:00
ZBPE Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
ZGZU Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
ZHWH Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
ZJSA Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
ZLHW Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
ZPKM Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
ZSHA Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
ZWUQ Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
ZYSH Match the original DxRender labels, and draw the two it had that we lost 2026-08-13 01:37:47 +08:00
.gitignore feat(ground): per-airport ground map data for the mainland packages 2026-08-07 05:33:14 +08:00
README.md README 里的 GroundMap 源码与 DLL 路径改为现址 2026-09-23 14:46:16 +09:00

Ground — 大陆扇区包地面图数据(每机场一文件)

DxRenderPlugin 的 CDxRenderMap.json 是流密码密文(magic 8c85ced5,各包同密钥流), 无法读取或更新。本仓库按 FIR 存替代数据:每个机场一个文件,方便手工改单个机场; tools/merge.py(CI 或手动)把每机场文件合并成各包 Plugins/GroundMap/ground.json。

地面几何来自 OpenStreetMap,跑道矩形取 .sct 自己的跑道头,机位名称按机位合并 OSM 的 ref 与 GRpluginStands.txt(旧地面插件唯一可读的部分):OSM 标了名的机位以 OSM 为准, 剩下的从站位表补齐。原来这里是全有或全无 —— 只要 OSM 给出一个机位名,整份站位表就被 丢掉,ZGGG 于是画了 370 个机位却只有 21 个号。

目录

Ground/
├── NavData/            boundaries.geojson / tracon.geojson(VATPRC 扇区 + 进近区)
├── tools/
│   ├── common.py       路径与 sct/机位解析
│   ├── fetch.py        OSM -> <FIR>/airports/<ICAO>.json(增量,每机场一文件)
│   ├── merge.py        airports + world -> Sector/<FIR>/Plugins/GroundMap/ground.json
│   └── install.py      部署 DLL + 移除 DxRender + 重排插件编号(一次性接线)
└── <FIR>/              ZBPE ZGZU ZHWH ZJSA ZLHW ZPKM ZSHA ZWUQ ZYSH PRC_FSS
    ├── airports/<ICAO>.json   每机场 OSM 数据(可手工编辑)
    └── style.json             配色与线宽([R,G,B]/[R,G,B,A],与 CDxRenderStyle.json 同约定)

扇区文件与 GRpluginStands.txt 从本仓库同级的 Sector/<FIR>/ 读取 —— 两个仓库都是 CeruleanAviationNetwork 工作区的子模块,所以在 git worktree 里也指得对,而写死的绝对路径 会悄悄改到另一份 checkout 上去。SECTOR_REPO 可以覆盖,CI 就是这么指的。合并产物直接写回 Sector/<FIR>/Plugins/GroundMap/ground.json。

流程

cd <本仓库>/tools               # Sector 默认取同级目录,无需设环境变量

python fetch.py  ZGZU          # OSM -> airports/(增量;--skip=ICAO 排除手编机场)
python fetch.py  ZGZU ZGGG     # 只抓/重抓指定机场
python merge.py  ZGZU          # 合并 -> Sector/<FIR>/Plugins/GroundMap/ground.json
python merge.py  --all         # 全部 FIR(CI 用)
python install.py ZGZU --apply # 一次性:部署 DLL + 移除 DxRender + 重排插件编号

fetch.py 已抓过的机场跳过(按文件存在与否),可安全重跑。多跑道机场(.sct ≥2 条跑道) 自动用更大的抓取框。

改完一个机场想先看一眼,不必合并再开 EuroScope:把 airports/<ICAO>.json 拖进开发者中心的 地面图预览,那页按地面插件的画法在浏览器里画(文件 不上传)。<FIR>.sct 和 GRpluginStands.txt 一起拖进去,跑道头和机位号就和 merge.py 走 同一条路,画出来和装机的那份逐字节一致。

CI 合并

两种方式任选其一(数据与包分处两个仓库,跨仓库推送需要令牌):

  1. Ground 仓库(本仓库,git.jyl.as):.github/workflows/merge.yml —— push 本仓库时 合并并推送到 GitHub 的 Sector 包。需在 Gitea 侧配置 secret SECTOR_PUSH_TOKEN (对 JianyueLab-Org/Sector 有写权限的 GitHub PAT)。
  2. Sector 仓库:.github/workflows/ground-merge.yml —— 手动 workflow_dispatch, 或配置 secret GROUND_REPO_URL(含令牌的 Ground 克隆 URL)后由 Ground 仓库 repository_dispatch 触发。

与 DxRender 的关系

  • 闭源 DxRenderPlugin 已从各包移除;地面图由开源 GroundMap 复现(Direct2D,按视野 LOD 分级,源码在 Sector/tools/RJJJ/GroundMap/GroundMap.cpp)。
  • 对齐项:GroundMap 读取 ASR 里 PLUGIN:...:Airport:<ICAO>(DxRender 的旧键)——存在时 只画该机场,ACC 屏无此键则按视野画全部可见机场。 ⚠️ 该功能在 GroundMap 源码里,需在 Windows 上用 build.bat 重新编译; 部署用的预编译 GroundMap.dll 来自 Sector/RJJJ/RJJJ/Plugins/GroundMap/,没有此键也能 按视野正常绘制(无此键时行为不变)。
  • PRC_FSS 无机场地面图(原地图为空文件),只部署 world 图层。

标牌与配色对齐原版 DxRender

闭源 DxRenderPlugin 的 CDxRenderStyle.json 是明文的,逆向笔记 (Sector/Docs/dxrender-research.md)把它整份读了出来。GroundMap 的样式当初是重新 拟的,比原版小一号也少几层,现在按原版对齐:

标牌 原版 这里
跑道号 runwaylabel 16.0 白字/黑底+白描边 同
滑行道 twylabel 12.0 白字/黑底+白描边 同
机位号 standlabel 11.0 白字,无底 同
等待点 holdinglabel 12.0 橙字/黑底+橙描边 新增
跑道长度 runavaillabel 11.0 橙字/黑底 新增

机位号无底是原版的选择,它靠的是更暗的道面:原版 apron/area-park 是 135 灰,而 这里原先是 178 的道面加 225 的机位中线 —— 白字压上去对比度只有 1.20:1,所以先前给它 加了底板。现在道面搬到原版的值(apron/stand 135、pavement 109、stand-centre 170、twy-centre 200、terminal 77、runway 84),白字对机坪回到 3.30:1,底板 就不需要了。text-outline 在 Direct2D 版的 GroundMap 里是惰性的(它只读认识的键), 自研的 CANGroundRender 会用上。

等待点名称和跑道长度来自 .ese 的 [FREETEXT](<ICAO>-HP / <ICAO>-RUN)—— 上游扇区包自己的标牌数据,两个仓库都从没读过。OSM 的 851 个 holding position 只有 28 个带名字,也完全不含跑道长度,而那里有 4202 和 395 条。同组的 TXL/GATE/RWY 没有采用:滑行道名 OSM 已有 3968 个,机位号走站位表已有 11029 个,跑道号由 .sct 的跑道头算出来,三者都比 [FREETEXT] 的那份多。

原版有而这里仍然没有的,都是缺数据源不是缺代码:道肩 shoulder、吹袭坪 blast、关闭区 area-closed、除冰区 area-deice、地面交通区 area-gndtraffic、 holding-I/holding-II 两类等待点的区分、rwy0–rwy3 四种跑道配色。OSM 里没有 对应标签,.ese 里也没有。每条跑道一个图层(原版是 rwy18L 这样,可在 ASR 里单独 显隐)是可以做的 —— 跑道名在 .sct 里 —— 但那会把三处按固定 id 建的 LOD 表 (merge.py、groundMap.ts、restamp_lod.py)都改成前缀匹配,留待需要时再做。

已知缺口

  • OSM 在部分中国机场覆盖不全(改扩建、军事区);直接编辑对应 airports/<ICAO>.json 或用 fetch.py --skip 排除后放手工数据 (参考历史 Sector 分支 e5ba255 的 ZLHW/tools/zlxy_osm.py 做法)。
  • ZLXY(咸阳)改扩建后 OSM 可能滞后,历史版本用手工 MSFS 导出;当前文件为 OSM 抓取, 如与实际不符可手工替换。
  • ZBYC 和 ZHXF 有 GMC 屏幕但没有任何地面数据,开屏是空的(ZBPE/ASRs/ZBYC_GMC.asr、 ZGZU 与 ZHWH 的 ZHXF_GMC.asr,自 f0b83bc 起就如此)。两者都不在 .sct 的 [AIRPORT] 里:ZBYC 在站位表里有 35 个机位,所以 airport_centres() 能给出中心点, 跑 python fetch.py ZBPE ZBYC 再 merge 就能补上;ZHXF 两边都没有,得先有数据来源。
  • 机位号:OSM 只有少数机场标了 ref,其余从 GRpluginStands.txt 按机位补齐(见开头)。 两边都没有的机场就没有号 —— 航路数据也补不了:Navigraph 的 parking 表在整个 Z 区 只有 154 行(且都在蒙古和朝鲜),ZBAA / ZGGG / ZSPD 等大陆机场全是 0 行,且 heading 与 radius 整列为 NULL,画不出带朝向的机位框。日本那边相反,所以 RJJJ 走 Sector/RJJJ/tools/navdata_stands.py。
  • 标牌的 LOD 上限跟着它标注的几何走(机位号 3 NM = 机位中线 3 NM)。原来机位号 2 NM 就 消失,而 96 个 GMC 屏幕里有 15 个开屏即宽于 2 NM,一载入机位号已经全是隐藏的。剩 ZBAD (4.02 NM)和 ZUTF(4.09 NM)两个巨型机场仍宽于上限,是有意的取舍:再往上抬到 4.5 NM 时机位间距只剩约 7 px 而标牌约 20 px 宽,会把另外 94 个屏幕糊掉;这两个屏幕稍微放大, 机位中线和号会一起出现(两者上限相同,不会出现无名几何)。
  • 渲染端的视野宽度在旋转屏幕上偏大,LOD 会提前触发。 viewNm 取 GetDisplayArea() 的经纬度外接框,而 96 个 GMC 屏幕全是旋转的(ZGGG_GMC 76°, 4 个正好 90°),旋转视图的外接框最多比屏幕实宽大 √2 倍 —— 每条 LOD 上限都提前触发, 标牌在还看得清时就消失;同一个值还用于米→像素换算,把线宽一并算细。改法是把雷达区 左右中点用 ConvertCoordFromPixelToPosition 转回坐标量距离,任意旋转下都准确。 已修进 Sector/tools/RJJJ/GroundMap/GroundMap.cpp,但要在 Windows 上重新 编译才生效;自研的 data/Plugins/CANGroundRender/src/CANGroundRender.cpp 是照抄这段 写的,同样有这个 bug(viewNm 与其下的 pxPerM),切换过去之前需要同样修一遍。