277 lines
13 KiB
Markdown
277 lines
13 KiB
Markdown
# Config:区域配置
|
||
|
||
> 覆盖 `config/areas/*.json`、`config/examples/template.json`、`config/default.json`。
|
||
> 无运行时——这是**管线三层共同消费的契约**,改一个字段会同时影响 Node、Blender、
|
||
> 预览页。
|
||
|
||
---
|
||
|
||
## 两层配置
|
||
|
||
用户只写第一层;legacy QGIS 链路需要时才生成第二层中间产物:
|
||
|
||
```
|
||
config/areas/<id>.json ← 你写的
|
||
│ scripts/lib/area-config.js: normalizeAreaConfig()
|
||
│ 补默认值 + 推导输出路径
|
||
▼
|
||
<areaDir>/_pipeline/osm2streets-qgis.config.json ← legacy 生成的,不要手改
|
||
│
|
||
▼ build-osm2streets-qgis.js / reimport-gpkg.js
|
||
```
|
||
|
||
派生配置落在 `_pipeline/` 而不是临时目录——**构建失败时它还在**,可以直接拿去复现。
|
||
|
||
`config/default.json` 和 `config/hanyang-block.json` 是**低层脚本**
|
||
(`npm run build:qgis`)用的旧格式配置,与 `config/areas/` 不是一回事。
|
||
新工作一律用 `config/areas/`。
|
||
|
||
---
|
||
|
||
## 新增一个区域
|
||
|
||
```bash
|
||
cp config/examples/template.json config/areas/my-area.json
|
||
```
|
||
|
||
改 `id` 和 `input` 就能跑。其余全有默认值。
|
||
|
||
---
|
||
|
||
## 字段全表
|
||
|
||
### 顶层
|
||
|
||
| 字段 | 必填 | 默认 | 说明 |
|
||
|---|---|---|---|
|
||
| `id` | ✅ | — | 区域标识。**同时是默认输出目录名和全部产物的文件名 stem** |
|
||
| `input` | ✅ | — | OSM XML 的**绝对路径**。不存在直接抛错 |
|
||
| `outputRoot` | | `<repo>/outputs` | 输出根目录 |
|
||
| `qgisApp` | | `/Applications/QGIS.app` | 也可用环境变量 `QGIS_APP` |
|
||
| `blenderApp` | | `/Applications/Blender.app` | |
|
||
| `stages` | | 见下 | 各阶段默认开关 |
|
||
| `qgis` | | 见下 | QGIS/osm2streets 旋钮 |
|
||
| `turnLaneArrows` | | 见下 | 从 OSM `turn:lanes:*` 生成自定义车道箭头的发布开关 |
|
||
| `osm2streets` | | 见下 | 透传给 osm2streets 的选项 |
|
||
| `blender` | | 见下 | Blender 侧选项 |
|
||
| `nativeRoad` | | 见下 | 原生道路编译选项 |
|
||
| `v2xPreview` | | 见下 | 可选的 Cesium 预览实时 V2X 叠加设置 |
|
||
| `compress` | | 见下 | 默认交付压缩阶段的 GLB 压缩选项 |
|
||
| `budget` | | 见下 | 区域 GLB 性能与体量预算 |
|
||
| `outputs` | | 从 `id` 推导 | 输出路径覆盖,逃生舱 |
|
||
|
||
**路径一律绝对**。`normalizeAreaConfig` 对每一项都做 `path.resolve`,相对路径会
|
||
相对于**进程 cwd** 解析,不是相对于配置文件——所以别用。
|
||
|
||
### `stages`
|
||
|
||
| 字段 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `intermediates` | `false` | native-only 默认;旧名 `qgis` 仍被接受,显式开启才运行 legacy |
|
||
| `blender` | `true` | |
|
||
| `cesium` | `true` | |
|
||
| `compress` | `true` | 压缩 staged GLB,供随后发布使用 |
|
||
| `package` | `true` | 将通过校验的静态模型原子发布到 `package/` |
|
||
| `preview` | `true` | 基于已发布 package 写验证预览及 `_preview/` 动态资源 |
|
||
|
||
`reimport` **在这里配也没用**——`normalizeAreaConfig` 把它硬编码为 `false`,只能靠
|
||
`--stages` 显式请求。`compress`、`package` 和 `preview` 始终默认开启。
|
||
|
||
> 恢复动作(reimport)不该被一份配置文件变成默认行为;压缩、发布和验证预览是标准交付链的一部分。
|
||
|
||
`--stages` 会整体覆盖这里的默认值。
|
||
|
||
### `qgis`
|
||
|
||
| 字段 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `arrowScale` | `0.8` | 导出前对 osm2streets 车道箭头多边形的缩放 |
|
||
| `arrowMergeTriangles` | `true` | 把箭头的三角网合并成一个合法多边形。**保留原箭头形状和转向**,同时消掉共享三角边处的渲染缝隙 |
|
||
| `arrowOutlineSimplifyMeters` | `0.05` | 去掉合并后箭头外轮廓上的亚分米级折角。默认值刚好去掉两个畸形尾顶点而**不动箭头头部**,剩下的尾边与杆身垂直 |
|
||
| `intersectionCornerSourceMaxDimensionMeters` | `2.6` | 只保留小尺寸的 `sidewalk corner` 多边形。**大的路口标记多边形不当人行道处理**,因为它们会盖住可行驶的路口 |
|
||
| `clipPad` | `0.002` | 送进 osm2streets 的裁剪框外扩(度) |
|
||
| `canvasPad` | `0.001` | QGIS 画布范围外扩(度) |
|
||
| `previewPad` | `0.0007` | 预览图范围外扩(度) |
|
||
| `canvasExtent` | `null` | 显式画布范围,覆盖 `canvasPad` |
|
||
| `previewExtent` | `null` | 显式预览范围,覆盖 `previewPad` |
|
||
| `layerPrefix` | `"osm2streets"` | QGIS 图层名前缀 |
|
||
|
||
三个 pad 单位是**度不是米**,且必须 `>= 0`(`build-osm2streets-qgis.js:49-53` 校验)。
|
||
`arrowScale` 必须 `> 0`。
|
||
|
||
> 这四个 arrow/corner 旋钮的默认值都是调出来的,**改之前先看 README 里记的理由**。
|
||
> 尤其 `arrowOutlineSimplifyMeters`——调大会开始削箭头头部。
|
||
|
||
### `turnLaneArrows`
|
||
|
||
| 字段 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `enabled` | `false` | 仅在样张经用户确认后启用。启用时从 `turn:lanes:forward` / `turn:lanes:backward` 追加经过测试的自定义箭头;未测试素材永不参与映射。 |
|
||
|
||
该开关经 `normalizeAreaConfig()` 和 `writeDerivedConfig()` 传入 intermediates 阶段。必须用
|
||
`??` 保留 `false`;不要将它改为按隐式标签或环境变量自动启用。
|
||
|
||
### `osm2streets`
|
||
|
||
原样透传给 `JsStreetNetwork` 构造函数(`build-osm2streets-qgis.js:77`)。默认:
|
||
|
||
```json
|
||
{
|
||
"debug_each_step": false,
|
||
"dual_carriageway_experiment": false,
|
||
"sidepath_zipping_experiment": false,
|
||
"inferred_sidewalks": true,
|
||
"osm2lanes": true
|
||
}
|
||
```
|
||
|
||
⚠️ **给了就整体替换,不做逐字段合并**(`raw.osm2streets || {...}`)。
|
||
只想改一个开关也必须把五个字段全写上,否则其余四个会退到 osm2streets 自己的默认值。
|
||
|
||
### `blender`
|
||
|
||
| 字段 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `treeStyle` | `"natural"` | 合法值见 `generate_scene.py` 的 `TREE_STYLES`(`natural`、`procedural`、`shapespark`) |
|
||
| `officeOverrides` | `""` | 旧名 `office_overrides` 仍被接受 |
|
||
| `roadProvider` | `"native"` | Blender 道路来源。`"native"` 时仅使用 `native-road/` 的道路、路口和人行道面;`"osm2streets"` 仅用于显式 legacy/debug 构建。 |
|
||
|
||
### `nativeRoad`
|
||
|
||
| 字段 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `edgeLines` | `false` | 是否输出道路边缘线。 |
|
||
| `junctionTemplates.enabled` | `false` | 启用显式绑定的参数化路口模板。 |
|
||
| `junctionTemplates.references` | `[]` | 仅支持 `cross-v1`;每项必须给出 OSM `nodeId`,可带 GCJ-02 `referenceFile` 作校准与有效性检查。 |
|
||
| `junctionTemplates.clusters` | `[]` | `cross-cluster-v1` 的相邻 OSM 节点簇。输出各外部进口的参数化渐变道路面,簇内短段与节点级路口面保留;`approachWidthMultiplier` / `approachLengthMeters` 控制渐变。可选 `referenceFile` 记录 GCJ-02 校准来源,不合并节点级道路、connector、信号或停止线语义。 |
|
||
| `junctionTemplates.clusters[].cornerRadiusMeters` | `12`(4–25) | 仅 `complex-junction-v1`:相邻进口夹角处路缘圆角的半径。圆角切于两侧最外道路边缘,只补齐夹角处的路面,不改变 connector、信号或停止线。 |
|
||
| `junctionTemplates.clusters[].outerRadiusExtraMeters` | `18`(18–35) | 仅 `complex-junction-v1`:路口中心到外部进口交接边界的额外半径。用于让圆角包住角部斑马线;未配置时保持原有 18 m。 |
|
||
|
||
### `v2xPreview`
|
||
|
||
这是 Cesium 验证预览的可选实时叠加层,不进入发布的 `package/`。默认值:
|
||
|
||
```json
|
||
{
|
||
"enabled": false,
|
||
"apiBaseUrl": "/api",
|
||
"wsBaseUrl": "/websocket",
|
||
"crossCode": ""
|
||
}
|
||
```
|
||
|
||
`apiBaseUrl` 和 `wsBaseUrl` 应使用同源反向代理路径,不能写入私有上游主机、账号或令牌。
|
||
V2X 接口返回的地图数据是 GCJ-02;浏览器预览在创建 Cesium entity 前一次性转为 WGS84,
|
||
而 native package 的 WGS84/ENU 契约保持不变。详见
|
||
[`docs/v2x-cesium-preview.md`](../../../docs/v2x-cesium-preview.md)。
|
||
|
||
### `compress`
|
||
|
||
完整构建和显式 `--stages compress` 都使用此配置。默认压缩链是 texture resize + WebP
|
||
transcode,成功后替换**package staging** 中的主 GLB 与 manifest;未压缩源只保留在构建临时目录。
|
||
只有随后的 `package` 阶段才会原子发布到 `package/`。
|
||
|
||
| 字段 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `textureSize` | `768` | 最大纹理宽高,范围 `64..4096` |
|
||
| `quality` | `82` | WebP 质量,范围 `1..100` |
|
||
| `effort` | `80` | WebP 编码 effort,范围 `0..100` |
|
||
| `meshopt` | `false` | 是否追加 `EXT_meshopt_compression`。开启前要单独验证 Cesium 兼容性 |
|
||
|
||
### `budget`
|
||
|
||
`budget` 是 `diagnose:area`、`check:area` 和 Cesium / compress manifest 共用的 GLB
|
||
限制。未配置时采用全局默认;用户字段统一用 MB 或整数,归一化后内部使用 bytes / counts:
|
||
|
||
| 字段 | 默认 | 说明 |
|
||
|---|---:|---|
|
||
| `glbSizeMb` | `25` | GLB 文件总大小(MB) |
|
||
| `nodes` | `1000` | GLB node 数量 |
|
||
| `images` | `24` | GLB image 数量 |
|
||
| `triangles` | `250000` | node 实例化后的 render triangles,不是唯一 mesh 的静态 triangles |
|
||
| `embeddedImageBytesMb` | `20` | GLB 内嵌图片字节(MB) |
|
||
| `reason` | `""` | 任一值高于默认时必填,记录区域例外原因 |
|
||
|
||
所有数值必须为正数,`nodes` / `images` / `triangles` 必须为正整数。收紧任何默认值不需要
|
||
`reason`;放宽任一默认值而没有非空 `reason` 会在配置归一化时失败。
|
||
|
||
### `outputs`(逃生舱)
|
||
|
||
默认全部从 `id` 推导。发布给下游的静态资产固定在
|
||
`<outputRoot>/<id>/package/`(含 `models/` 与可控信号灯 `runtime/`),临时静态资产在
|
||
`_pipeline/package-staging/`,预览专用车辆/路线资源在 `<outputRoot>/<id>/_preview/`。需要定制时逐项覆盖:
|
||
|
||
```json
|
||
{
|
||
"outputs": {
|
||
"areaDir": "/absolute/path/to/custom-area",
|
||
"blend": "/absolute/path/to/custom.blend",
|
||
"packageDir": "/absolute/path/to/custom-package",
|
||
"cesiumPreview": "/absolute/path/to/custom-preview.html"
|
||
}
|
||
}
|
||
```
|
||
|
||
可覆盖的键(`scripts/lib/area-config.js`):`areaDir`、`fileStem`、`geojsonDir`、`gpkg`、
|
||
`qgisProject`、`qgisPreview`、`blend`、`render`、`glb`、`metadata`、`cesiumPreview`、
|
||
`vehicleRoute`、`vehicleModel`、`pipelineDir`、`stageManifestDir`。
|
||
|
||
静态发布路径另有 `packageDir`、`packageStagingDir`、`packageManifest`、
|
||
`packageStagingManifest`、`packageModelDir`、`packageStagingModelDir` 与
|
||
`packagePrimaryGlb`;预览路径另有 `previewDir`、`previewDescriptor` 与
|
||
`trafficSimulation`(native preview 的可迁移仿真描述符)。除非在迁移旧调用,
|
||
不要覆盖 `glb` / `metadata`:它们是 staging 内部路径,不是下游资产入口。
|
||
|
||
**优先改 `fileStem` 或 `areaDir`**——它们能一次性影响全部派生路径。逐个覆盖容易漏。
|
||
|
||
---
|
||
|
||
## 加一个配置字段
|
||
|
||
1. `normalizeAreaConfig`(`scripts/lib/area-config.js`)里加进对应的分组,**用 `??` 不用 `||`**
|
||
(`false` / `0` 可能是合法值)
|
||
2. 只写两级 fallback:`raw.<group>?.<key> ?? 默认值`。
|
||
**不要**制造新的顶层平铺别名——那三级写法是历史兼容,不是模式
|
||
3. 若要传给低层脚本,加进 `writeDerivedConfig` 的 `derivedConfig` 对象
|
||
4. 若是数值,在消费侧加 `Number.isFinite` + 范围校验,**在任何副作用之前**
|
||
5. 更新 `config/examples/template.json`
|
||
6. 若字段影响区域质量门,确认 `diagnose:area`、`check:area` 和 stage manifest 共用同一
|
||
个评估 helper,不能在入口脚本各自比较阈值
|
||
7. 更新本文档的字段表
|
||
|
||
若新字段产出新文件,同时在 `outputs` 里加一行路径推导。
|
||
|
||
---
|
||
|
||
## 已沉淀的区域
|
||
|
||
- `config/areas/nantaizi-lake-innovation-valley.json`(默认构建目标)
|
||
- `config/areas/hanyang-block.json`
|
||
|
||
两者都是 parity 校验的样本区域(`parity.js:26` 的 `DEFAULT_AREAS`)——
|
||
**改动它们会影响基线比对**。
|
||
|
||
---
|
||
|
||
## 反模式
|
||
|
||
| 反模式 | 后果 |
|
||
|---|---|
|
||
| 用相对路径 | 相对 cwd 解析,换个目录跑就错 |
|
||
| 手改 `_pipeline/*.config.json` | 下次构建被覆盖 |
|
||
| 只写 `osm2streets` 的一个字段 | 其余四个静默退到 osm2streets 默认值 |
|
||
| 布尔字段用 `\|\|` 兜底 | `false` 被翻转 |
|
||
| 给新字段造顶层平铺别名 | 扩大历史包袱 |
|
||
| 逐个覆盖 `outputs` 而不用 `fileStem` | 漏掉某个产物路径 |
|
||
| 将 `glb` / `metadata` 当作下游入口 | 它们位于 staging;应只读取 `package/manifest.json` |
|
||
| 在 `stages` 里配 `reimport` | 无效,被硬编码为 false |
|
||
| 加数值字段不做范围校验 | 错配置在中途才崩,输出已被破坏 |
|
||
|
||
---
|
||
|
||
## 相关
|
||
|
||
- [CLI 与阶段](../pipeline/cli-and-stages.md):配置怎么被读取和派生
|
||
- [外部工具调用](../pipeline/external-tools.md):`qgisApp` / `blenderApp` 怎么用
|
||
- README「区域配置」节:面向使用者的说明
|