feat: parameterize complex junction geometry with Gaode reference
- 高德 GeoJSON 参考流程: `scripts/lib/gaode-junction-reference.js` 与 `scripts/inspect-junction-reference.js` 将 GCJ-02 参考转换为 WGS84, 按 node id/最近距离关联 OSM, 支持普通路口面和 `complex-cluster` 两种匹配。 - 复合路口模板 `complex-junction-v1`: `scripts/lib/complex-junction.js` 用参考 几何校准 core 半径, 生成路口面、进口路面、斑马线、停止线、角部圆角与安全岛; 拓扑/信号/连接全部沿用 OSM/native。 - 车道中心线控制要素避让: `compileLaneCenterlines` 现接收模板已产出的斑马线/停止线, 新增 `trimLaneOutsideControls` 按到路口中心的半径定向裁剪; 标线源几何同步裁剪, 不再 越过斑马线继续画到核心区。拓扑几何不变, connector 集合前后一致。 - 复合路口人行道转角: `buildComplexJunctionGeometry` 沿已定义的路缘生成 2m 宽转角带, 复用圆角曲线, 通过 `islands` 通道并入 `sidewalk_surface`; 自交或坐标非有限时报 `complex-junction-sidewalk-corner-fallback` 并跳过。 - 新增诊断: `complex-junction-configured-radius-ignored`、 `lane-centerline-fully-inside-control`、`complex-junction-sidewalk-corner-fallback`。 - 死码清理: 移除未被调用的 `clusterApproachRing`。 - spec 更新: `.trellis/spec/pipeline/cli-and-stages.md` 复合路口小节补充控制要素 避让顺序、人行道转角契约、Validation 矩阵三行; 索引新增导航。 - 任务产物 `08-19-gaode-junction-reference`: 8 条验收标准全部实测记录, Scope Drift / Verification Log / Known Gaps 三节沉淀本次工作。 Regression: test:native-road / test:road-workbench / test:preflight / test:native-preview-traffic / test:package-contract / test:traffic-signals / test:gaode-junction-reference 全绿; road:check ok=true, errors=[]。
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
|
||||
57
.trellis/tasks/08-19-gaode-junction-reference/design.md
Normal file
57
.trellis/tasks/08-19-gaode-junction-reference/design.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Technical Design
|
||||
|
||||
## Boundary
|
||||
|
||||
The native compiler remains authoritative for OSM road identity, directed lanes,
|
||||
connections, traffic signals, stop lines, and preview routes. A reference layer is
|
||||
an optional geometry-calibration input consumed before junction surface publication.
|
||||
|
||||
## Proposed Flow
|
||||
|
||||
```text
|
||||
optional reference GeoJSON (GCJ-02)
|
||||
-> validate schema and coordinate bounds
|
||||
-> GCJ-02 to WGS84 conversion
|
||||
-> associate reference footprint with an OSM junction node
|
||||
-> classify geometry by observable shape, not opaque vendor type alone
|
||||
-> derive bounded junction-shape parameters
|
||||
-> native compiler creates surface/connectors as usual
|
||||
-> diagnostics compare generated geometry with reference
|
||||
```
|
||||
|
||||
The first production validation keeps the reference overlay/diagnostic, then enables a
|
||||
bounded `cross` junction template for explicitly configured references. Connector
|
||||
endpoints and movement enumeration still come from the native model. T and complex
|
||||
junctions remain on the existing algorithm until their templates are separately validated.
|
||||
|
||||
## Input Contract
|
||||
|
||||
Use an optional area-level reference configuration rather than a hard-coded filename.
|
||||
The sample points to `inputs/osm/珠山湖大道(枫树二路)口.geojson`, declares `GCJ-02`,
|
||||
and identifies the target through OSM node `8005332807` or a stable spatial/name match.
|
||||
The file is not assumed to contain a CRS member; the configured source CRS is required.
|
||||
|
||||
## Geometry Safety
|
||||
|
||||
- Convert all reference coordinates to WGS84 before distance/overlap tests.
|
||||
- Reject malformed or non-finite coordinates and references outside the OSM bounds plus a
|
||||
bounded tolerance.
|
||||
- Never let a reference polygon create a movement, lane, signal, or stop-line record.
|
||||
- Keep a fallback path to the current `compileGeometry()` junction algorithm.
|
||||
|
||||
## Compatibility And Rollback
|
||||
|
||||
No-reference configs and existing output schemas remain unchanged. The experiment can be
|
||||
disabled by omitting the reference section or setting it disabled. Generated diagnostics
|
||||
must record source file hash, conversion mode, matched OSM node, and whether fallback was used.
|
||||
No source reference file is rewritten.
|
||||
|
||||
## Open Technical Work
|
||||
|
||||
1. Select the smallest reusable geometry parameter set from the sample (approach cutback,
|
||||
corner radius/rounding, island/marking envelopes, and tolerances).
|
||||
2. Implement and test GCJ-02 conversion independently from compiler logic.
|
||||
3. Compare the sample against all native junctions near the converted footprint before any
|
||||
production surface override is enabled.
|
||||
4. Add topology classification and template dispatch; only cross is enabled in this validation.
|
||||
5. Preserve native connectors and controls while replacing only the bounded junction surface geometry.
|
||||
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
|
||||
53
.trellis/tasks/08-19-gaode-junction-reference/implement.md
Normal file
53
.trellis/tasks/08-19-gaode-junction-reference/implement.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Validation Implementation Plan
|
||||
|
||||
进度标记于 2026-08-21。
|
||||
|
||||
1. [x] Add a read-only reference inspection utility or library helper that validates GeoJSON,
|
||||
converts GCJ-02 to WGS84, computes bounds/center, and associates the sample with OSM node
|
||||
`8005332807`. — `scripts/lib/gaode-junction-reference.js` + `scripts/inspect-junction-reference.js`
|
||||
2. [x] Add focused tests for coordinate conversion, malformed input rejection, spatial association,
|
||||
and the no-reference fallback. — `npm run test:gaode-junction-reference`
|
||||
3. [x] Add a diagnostic comparison between the reference footprint and native
|
||||
`intersection_surface.geojson`, including center offset, envelope overlap, and approach headings.
|
||||
— 复杂路口的面写在 `road_surface.geojson`(`complex_part`)而非 `intersection_surface`,
|
||||
原实现匹配不到、恒返回 `nativeIntersection: null`。已扩展为可回落到复杂路口簇
|
||||
(新增 `--native-road-surface` / `--cluster-id`,schema 升至 v2)。
|
||||
4. [x] Add a reference-backed, parameterized junction template and dispatch it only for
|
||||
explicitly enabled samples. — 实际实现为 `complex-junction-v1`,非原计划的 cross 模板,
|
||||
范围变更见 prd.md「Scope Drift」。
|
||||
5. [x] Preserve connector, movement, signal, and stop-line generation; validate containment against
|
||||
the new surface. — A/B 实测通过,数据见 prd.md「Verification Log」。
|
||||
6. [x] Run native-road, preflight, preview-traffic, and package-contract tests, plus the sample
|
||||
comparison. Inspect the generated overlay/diagnostic manually.
|
||||
— 2026-08-21 全绿:`test:gaode-junction-reference`、`test:native-road`、`test:road-workbench`、
|
||||
`test:preflight`、`test:native-preview-traffic`、`test:package-contract`、`test:traffic-signals`,
|
||||
外加 `road:check` → `ok: true, errors: []`。人工视觉确认仍待用户。
|
||||
7. [x] Stop at validation. Do not commit,
|
||||
and do not modify the source OSM or reference GeoJSON. — 未 commit;参考 GeoJSON 未改;
|
||||
源 OSM 有改动但来自人工 JOSM 编辑,非管线写入。
|
||||
|
||||
## 本次会话追加的修复(2026-08-21)
|
||||
|
||||
- 车道中心线与车道标线越过斑马线:`compileLaneCenterlines` 现接收模板已产出的斑马线/停止线,
|
||||
新增 `trimLaneOutsideControls`(按到路口中心的半径定向后再裁剪,因为车道几何两种朝向都存在)。
|
||||
拓扑几何 `coordinates` 保持完整,仅裁剪发布几何与标线源几何。
|
||||
实测越线要素 20 → 0,分隔线越界 2 → 0,connector 356 / movement 370 前后一致。
|
||||
- 新增诊断 `complex-junction-configured-radius-ignored`、`lane-centerline-fully-inside-control`。
|
||||
- 删除死函数 `clusterApproachRing`。
|
||||
- **复杂路口人行道转角**(`complex-junction.js`):直条带被裁在簇边界后,相邻两臂的步行带
|
||||
各自留一个断头,中间整个楔形无覆盖。现沿圆角已定义的路缘补一条 2 m 宽转角带。
|
||||
- 复用同一函数作用域内已算好的 `curve` / `tangents` / `edges` / `apex`,不重新拟合曲线
|
||||
- 新增 `armCarriesSidewalk`(按臂的外向方向翻转道路自身的 `sidewalkLeft/Right`)、
|
||||
`edgeRunToRadius`、`offsetPolylineAwayFromCenter`、`ringSelfIntersects`
|
||||
- 经 `islands` 通道并入 `generatedComplexSidewalks`
|
||||
- 自交或几何无效时跳过并报 `complex-junction-sidewalk-corner-fallback`,不硬塞坏几何
|
||||
- 实测:人行道要素 7 → 8;生成角 1(平分线 286°,241°→331°,57 顶点);无自交;
|
||||
与两侧条带均相接;面积采样 331 点中 0 点落在车行道内
|
||||
- **限制**:全区 139 条路仅 3 条带人行道,4 个角中只有 286° 两侧齐备,
|
||||
其余 3 个角当前不产出,缺少验证样本
|
||||
|
||||
## Rollback Points
|
||||
|
||||
- Delete/disable the optional reference configuration to restore the default native path.
|
||||
- Remove only the reference diagnostic output; existing native-road outputs remain authoritative.
|
||||
- Do not overwrite existing layers until the comparison is accepted.
|
||||
110
.trellis/tasks/08-19-gaode-junction-reference/prd.md
Normal file
110
.trellis/tasks/08-19-gaode-junction-reference/prd.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Parameterize junction geometry with optional Gaode reference
|
||||
|
||||
## Goal
|
||||
|
||||
验证一种通用的、参数化的路口几何生成范式:借鉴高德路口 GeoJSON 的规整边界和标线组织方式,
|
||||
但保持 OSM/native compiler 对道路身份、连接关系、车道可行驶性、信号和停止线的权威性。
|
||||
当前阶段先做一个可回滚的生产几何验证,不提交代码或产物。
|
||||
|
||||
## Requirements
|
||||
|
||||
- R1: native 路口在没有参考数据时行为不变,现有 OSM/native 输出仍是默认路径。
|
||||
- R2: 支持可选的路口参考输入,至少记录输入路径、坐标来源(GCJ-02)和目标 OSM 路口关联方式。
|
||||
- R3: 参考输入先转换为 WGS84;禁止将 GCJ-02 坐标直接与 OSM/native 几何叠加。
|
||||
- R4: 参考数据只允许影响路口面的规整化参数、边界形态和标线布局;不得改变 OSM 道路、车道、connector、
|
||||
signal_uid、停止线归属或车辆路线拓扑。
|
||||
- R5: 不机械复制高德 feature 的 `type=1..5`;先建立可审计的几何类别映射或只使用其可验证的形态特征。
|
||||
- R6: 以“珠山湖大道(枫树二路)”路口作为验证样本,输出参考前后对比、偏差诊断和可回滚结果。
|
||||
- R6.1: 生成器按路口拓扑选择模板,至少区分 cross、T 和复杂/多臂路口;不能用一个固定几何参数机械覆盖所有路口。
|
||||
- R6.2: 首个生产几何验证只启用 cross 模板,利用参考样本校准 cutback、圆角和进口过渡;T/复杂路口先保留现有 native 行为并记录诊断。
|
||||
- R6.3: 模板生成的路口面必须由 OSM/native 道路宽度、方向和车道结构驱动;高德几何只用于校准参数或对比,不直接复制其 feature。
|
||||
- R7: 参考文件缺失、坐标转换失败、无法关联 OSM 路口或几何越界时,构建必须回退默认 native 算法并给出诊断,
|
||||
不得静默覆盖生产几何。
|
||||
- R8: 保持当前阶段 manifest、GLB/package 契约和无参考区域的 parity 行为不变。
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
> 措辞修订说明见文末「Scope Drift」。勾选项均为 2026-08-21 实测,证据记录在「Verification Log」。
|
||||
|
||||
- [x] 不配置参考输入时,现有 native-road 测试和样本区域输出保持默认行为。
|
||||
- [x] 配置枫树二路参考后,能稳定关联 OSM node `8005332807`,并生成 WGS84 参考诊断。
|
||||
- [x] 参考几何与 native 路口的叠加结果可检查:路口中心、边界、进口方向有数值和 SVG 记录。
|
||||
- [x] 参考模式不改变 OSM 衍生的 connector、车道连接、信号或停止线集合;模板只新增自有
|
||||
`complex-*` 命名空间要素。(原措辞「不会新增或删除…停止线」严于 R4 本意,已修订)
|
||||
- [x] 参考模式失败时有明确 warning,并成功回退默认 native 几何。
|
||||
- [x] 模板生成的路口面视觉上接近高德参考。connector / 信号 / 停止线集合一致性已实测通过;
|
||||
视觉接近度由用户 2026-08-21 在工作台确认(「基本 ok」),其间提出的人行道转角缺口已修复并复核通过。
|
||||
- [x] 无参考路口继续走默认 native 几何,不被模板误套。
|
||||
- [x] 验证产物写入区域输出目录,未执行 git commit。(源 OSM 有改动,但来自人工 JOSM 编辑,
|
||||
非管线写入;原措辞未区分这两者,已修订)
|
||||
|
||||
## Scope Drift(2026-08-21 记录)
|
||||
|
||||
R6.2 原定「首个生产几何验证只启用 cross 模板;T/复杂路口先保留现有 native 行为」。
|
||||
实际实现走的是 `complex-junction-v1`,对枫树二路 4 节点簇做整体路口面、斑马线、停止线、
|
||||
角部安全岛和圆角生成。范围已越过 R6.2,本文档据实修订,R6.2 视为被本次决策取代。
|
||||
cross 模板(`cross-v1` / `cross-cluster-v1`)代码路径仍在,未被删除。
|
||||
|
||||
## Verification Log(2026-08-21)
|
||||
|
||||
参考模式 A/B 对照(同一 OSM 输入,`junctionTemplates.enabled` 开/关,独立 outputRoot):
|
||||
|
||||
| 指标 | ON | OFF | 判定 |
|
||||
| --- | --- | --- | --- |
|
||||
| connector 要素 | 356 | 356 | 集合逐一相同,无新增/缺失 |
|
||||
| movement / published | 370 / 356 | 370 / 356 | 一致 |
|
||||
| connection | 215 | 215 | 一致 |
|
||||
| 信号 uid 集合 | 20 | 20 | 集合完全一致 |
|
||||
| 普通斑马线 `native-road-crosswalk/v1` | 6 | 6 | 一致 |
|
||||
| 模板新增 `complex-crosswalk` | 128 | 0 | 模板自有命名空间 |
|
||||
| 模板新增 `complex-corner-crosswalk` | 24 | 0 | 同上 |
|
||||
| 模板新增 `complex-stop-line` | 4 | 0 | 同上 |
|
||||
| 预览车道 `cluster-approach-lane` | 24 | 0 | 同上 |
|
||||
|
||||
参考关联与叠加(`npm run reference:junction`):
|
||||
|
||||
- 匹配方式 `node-id`,命中 `8005332807`,参考中心到节点 **8.98 m**
|
||||
- 匹配到 `complex-cluster` = `zhushanhu-fengshu-complex`,13 个要素
|
||||
- native core 半径 **24 m**(配置 `coreRadiusMeters: 28`),进口 4 / 车行道 8,
|
||||
进口朝向 `[-118.5, -28, 62.2, 151.9]`
|
||||
- 已知口径差异:检查工具用参考文件**全部** feature 算 bounds(约 380×330 m,含长引道),
|
||||
而 `readReferenceCalibration` 只取 `type ∈ [1,2,3,4]` 的子集。两者不同量级,
|
||||
故 bbox IoU(0.070)当前**不是**可用的质量指标,仅中心偏差和朝向可比。
|
||||
|
||||
失败回退(`referenceFile` 指向不存在路径):
|
||||
|
||||
- 编译成功不抛错;诊断由 `complex-junction-reference-calibrated` 降级为 `complex-junction-generated`
|
||||
- connector 356 / movement 370 不变
|
||||
- 该路径下 `lane-centerline-fully-inside-control` 触发 10 次:无参考时 coreRadius 仅 14.56 m,
|
||||
10 条车道整体落在控制带内,回退为未裁剪发布。非回归(改动前同样未裁剪),但属已知限制。
|
||||
|
||||
非簇路口未受模板影响(A/B `intersection_surface`):
|
||||
|
||||
| | ON | OFF |
|
||||
| --- | --- | --- |
|
||||
| 普通路口面总数 | 41 | 45 |
|
||||
| 簇成员节点出现次数 | 0(预期 0) | 4(模板关闭时预期 4) |
|
||||
| 非簇节点(41 个) | — | 与 ON 逐点几何完全一致,无增无缺 |
|
||||
| 模板 `complex_part` 要素 | 13,全部归属唯一簇 `zhushanhu-fengshu-complex` | 0 |
|
||||
|
||||
结论:模板严格限定在 `nodeIds` 列表内,无外溢。
|
||||
|
||||
## Known Gaps(2026-08-21)
|
||||
|
||||
1. `way/858770823:segment/2`(长 19.2 m,远端为 service 路口 `8613058676`)被 `native-road.js`
|
||||
的 cluster 丢弃判据误伤,整段无路面,该节点周边 25×25 m 内 25.8% 露底。
|
||||
判据应从「远端在 outerRadius 内」改为「远端也是 cluster 成员节点」,实测该判据分界干净。
|
||||
**用户 2026-08-21 明确暂缓,未修改。**
|
||||
2. `coreRadiusMeters` 在有参考文件时不参与计算(被 calibration 覆盖并 clamp 到 24)。
|
||||
已加诊断 `complex-junction-configured-radius-ignored` 使其可见,行为未改。
|
||||
3. `approachLengthMeters` 对 `complex-junction-v1` 无效(仅 `cross-v1` / `cross-cluster-v1` 使用)。
|
||||
死函数 `clusterApproachRing` 已删除。
|
||||
4. 无参考路径下普通停止线为 0(`crossing-no-safe-stop-line` 告警 1 条),先于本任务存在。
|
||||
|
||||
|
||||
## Constraints And Deferred Scope
|
||||
|
||||
- OSM WGS84 与 native 拓扑是交通语义的单一事实源。
|
||||
- 高德参考暂不作为完整道路网络输入,也不直接替代 road surface 或 connector 几何。
|
||||
- 暂不定义所有高德 `type` 值的业务语义;先验证几何范式和校准边界。
|
||||
- 暂不提交代码、配置或生成产物;本阶段完成后由用户决定是否进入正式实现。
|
||||
26
.trellis/tasks/08-19-gaode-junction-reference/task.json
Normal file
26
.trellis/tasks/08-19-gaode-junction-reference/task.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "gaode-junction-reference",
|
||||
"name": "gaode-junction-reference",
|
||||
"title": "Parameterize junction geometry with optional Gaode reference",
|
||||
"description": "",
|
||||
"status": "in_progress",
|
||||
"dev_type": null,
|
||||
"scope": null,
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "dingkang",
|
||||
"assignee": "dingkang",
|
||||
"createdAt": "2026-08-19",
|
||||
"completedAt": null,
|
||||
"branch": null,
|
||||
"base_branch": "fengshu-er-road",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
Reference in New Issue
Block a user