Initialize Trellis project guidelines

This commit is contained in:
2026-08-03 10:56:21 +08:00
parent 7f4ebe8fb7
commit 4c5981c555
166 changed files with 28564 additions and 0 deletions

View File

@@ -0,0 +1,187 @@
# Config区域配置
> 覆盖 `config/areas/*.json`、`config/examples/template.json`、`config/default.json`。
> 无运行时——这是**管线三层共同消费的契约**,改一个字段会同时影响 Node、Blender、
> 预览页。
---
## 两层配置
用户只写第一层,第二层是机器生成的中间产物:
```
config/areas/<id>.json ← 你写的
│ build-area.js: normalizeAreaConfig() 补默认值 + 推导 14 个输出路径
<areaDir>/_pipeline/osm2streets-qgis.config.json ← 生成的,不要手改
▼ 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 旋钮 |
| `osm2streets` | | 见下 | 透传给 osm2streets 的选项 |
| `blender` | | 见下 | Blender 侧选项 |
| `outputs` | | 从 `id` 推导 | 输出路径覆盖,逃生舱 |
**路径一律绝对**`normalizeAreaConfig` 对每一项都做 `path.resolve`,相对路径会
相对于**进程 cwd** 解析,不是相对于配置文件——所以别用。
### `stages`
| 字段 | 默认 | 说明 |
|---|---|---|
| `intermediates` | `true` | 旧名 `qgis` 仍被接受 |
| `blender` | `true` | |
| `cesium` | `true` | |
`reimport``preview` **在这里配也没用**——`normalizeAreaConfig:117-118` 把它们
硬编码为 `false`,只能靠 `--stages` 显式请求。
> 恢复动作reimport和补丁动作preview不该被一份配置文件变成默认行为。
`--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`——调大会开始削箭头头部。
### `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
}
```
⚠️ **给了就整体替换,不做逐字段合并**`build-area.js:132``raw.osm2streets || {...}`)。
只想改一个开关也必须把五个字段全写上,否则其余四个会退到 osm2streets 自己的默认值。
### `blender`
| 字段 | 默认 | 说明 |
|---|---|---|
| `treeStyle` | `"natural"` | 合法值见 `generate_scene.py:144``TREE_STYLES``natural``procedural`,加上 `tree.py` 注册的模型 style |
| `officeOverrides` | `""` | 旧名 `office_overrides` 仍被接受 |
### `outputs`(逃生舱)
默认全部从 `id` 推导为 `<outputRoot>/<id>/<fileStem>.<ext>`。需要定制时逐项覆盖:
```json
{
"outputs": {
"areaDir": "/absolute/path/to/custom-area",
"blend": "/absolute/path/to/custom.blend",
"glb": "/absolute/path/to/custom.glb",
"cesiumPreview": "/absolute/path/to/custom-preview.html"
}
}
```
可覆盖的键(`build-area.js:87-102``areaDir``fileStem``geojsonDir``gpkg`
`qgisProject``qgisPreview``blend``render``glb``metadata``cesiumPreview`
`vehicleRoute``vehicleModel``pipelineDir`
**优先改 `fileStem` 或 `areaDir`**——它们能一次性影响全部派生路径。逐个覆盖容易漏。
---
## 加一个配置字段
1. `normalizeAreaConfig``build-area.js:74`)里加进对应的分组,**用 `??` 不用 `||`**
`false` / `0` 可能是合法值)
2. 只写两级 fallback`raw.<group>?.<key> ?? 默认值`
**不要**制造新的顶层平铺别名——那三级写法是历史兼容,不是模式
3. 若要传给低层脚本,加进 `writeDerivedConfig``:189`)的 `derivedConfig` 对象
4. 若是数值,在消费侧加 `Number.isFinite` + 范围校验,**在任何副作用之前**
5. 更新 `config/examples/template.json`
6. 更新本文档的字段表
若新字段产出新文件,同时在 `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` | 漏掉某个产物路径 |
| 在 `stages` 里配 `reimport` / `preview` | 无效,被硬编码为 false |
| 加数值字段不做范围校验 | 错配置在中途才崩,输出已被破坏 |
---
## 相关
- [CLI 与阶段](../pipeline/cli-and-stages.md):配置怎么被读取和派生
- [外部工具调用](../pipeline/external-tools.md)`qgisApp` / `blenderApp` 怎么用
- README「区域配置」节面向使用者的说明