fix: 修正 Cesium 巡航车道中心对齐
This commit is contained in:
@@ -205,6 +205,28 @@ tilt_y = TILT_JITTER * math.cos(index * 0.927295)
|
||||
模型保持在**局部 ENU 坐标系**(X 东、Y 北、Z 上),靠伴生 JSON 配合
|
||||
`Cesium.Transforms.eastNorthUpToFixedFrame` 摆放。
|
||||
|
||||
### WGS84 ENU 坐标契约
|
||||
|
||||
Blender 中所有经纬度几何必须通过 `osmassets.osm.Projector` 转换。该转换必须与 Cesium
|
||||
的 `eastNorthUpToFixedFrame(anchor)` 使用同一个 WGS84 椭球语义:先将经纬度转换为
|
||||
ECEF,再将相对锚点的向量投影到 East/North 轴。禁止用固定 `111320 m/deg` 的
|
||||
equirectangular(等距圆柱)近似生成场景坐标。
|
||||
|
||||
固定米/度近似只会在锚点附近碰巧重合;纬向比例与 WGS84 实际比例不同,误差会随离锚点
|
||||
距离增长。表现为 Cesium Entity 路线在部分道路居中、在其他道路相对整个 GLB 路面同向
|
||||
平移。只验证 route 与 GeoJSON 自洽无法发现此问题,必须重新生成
|
||||
`blender,cesium,preview` 并在最终 Cesium 画面中核对。
|
||||
|
||||
修改 `Projector` 后至少执行:
|
||||
|
||||
```bash
|
||||
python3 -m unittest blender.tests.test_pure
|
||||
npm run build:area -- --config config/areas/<area>.json --stages blender,cesium,preview
|
||||
```
|
||||
|
||||
`blender.tests.test_pure.ProjectorTest` 必须断言锚点为原点、East/North 方向正确,以及局部
|
||||
经纬度增量符合 WGS84 椭球曲率半径。
|
||||
|
||||
### Cesium contract
|
||||
|
||||
新生成场景的 Cesium 导出调色写在 `catalog.MATERIALS[*]["cesium"]`,由
|
||||
@@ -278,6 +300,7 @@ tilt_y = TILT_JITTER * math.cos(index * 0.927295)
|
||||
| 直接 append vendored 资产的材质 | alpha-clip 缺失,树冠渲染成一块 |
|
||||
| 删掉"试过不行"的注释 | 下一个人重新踩同一个坑 |
|
||||
| 从 `scene-layers.js` 的 hex 换算 Blender 颜色 | 抹掉独立调过的配色 |
|
||||
| 用固定米/度比例投影经纬度 | GLB 与 Cesium Entity 随离锚点距离产生位置漂移 |
|
||||
| 加新资产不配 Cesium 调色 | Cesium 里显得发黑 |
|
||||
| 靠调 `FOLIAGE_EMISSION` 提亮植被 | 用错了旋钮,该调 albedo gain |
|
||||
| 在 `MATERIALS` 中间插入条目 | GLB 材质索引整体平移 |
|
||||
|
||||
@@ -46,6 +46,7 @@ cesium-preview.js 浏览器
|
||||
- [ ] 你在改任何被 `execFileSync` / `spawnSync` 调起的东西
|
||||
- [ ] 你在改 stage 的 stdout 打印
|
||||
- [ ] 你要新增一种在 Blender 里生成、要在 Cesium 里看的资产
|
||||
- [ ] Blender GLB 与 Cesium Entity、polyline 或 label 必须在地理位置上重合
|
||||
|
||||
---
|
||||
|
||||
@@ -161,6 +162,19 @@ OSM way 的端点不一定在原始 XML 中有三个以上相连 way;osm2stree
|
||||
**教训**:**跨阶段运行时 JSON 必须在最早消费它的 stage 从当前权威产物重建;同时要
|
||||
区分“初始化来源”和“编辑后的事实源”,不能用早期输入覆盖人工编辑。**
|
||||
|
||||
### 坑 7:GeoJSON 内部正确,但 GLB 与 Cesium 路线仍然错位
|
||||
|
||||
巡航路线曾经与 osm2streets Driving polygon 中轴逐点吻合到厘米级,仍在最终预览中出现
|
||||
部分路段偏离车道中心。原因是路线由 Cesium 直接按 WGS84 经纬度放置,而 Blender GLB
|
||||
使用固定 `111320 m/deg` 的近似投影后再放到 WGS84 ENU 锚点。两套坐标仅在锚点附近
|
||||
重合,误差随距离增长。
|
||||
|
||||
**教训**:跨坐标运行时不能只验证源数据内部自洽。凡是 Blender GLB 与 Cesium Entity
|
||||
需要重合,必须检查 `GeoJSON -> Blender local ENU -> GLB modelMatrix` 与
|
||||
`GeoJSON -> Cesium Cartesian3` 的端到端契约,并在最终画面做横截面对齐验证。
|
||||
|
||||
→ [资产生成:WGS84 ENU 坐标契约](../blender/asset-generation.md#wgs84-enu-坐标契约)
|
||||
|
||||
---
|
||||
|
||||
## 加东西时的检查清单
|
||||
|
||||
@@ -746,6 +746,9 @@ runtime 与 HTML,并写 preview manifest。预览内容实现不得回流到
|
||||
- `inputs.osm`
|
||||
- `inputs.glb`
|
||||
- `inputs.metadata`
|
||||
- `inputs.lanePolygons`
|
||||
- `inputs.network`
|
||||
- `inputs.intersectionSurface`
|
||||
- `inputs.previewCss`
|
||||
- `inputs.previewJs`
|
||||
- `outputs.cesiumPreview`
|
||||
|
||||
@@ -112,6 +112,9 @@ setLoadingMessage("Preparing view")
|
||||
window.osmPreview = { viewer, metadata, placement, assets, cruise, cameras };
|
||||
```
|
||||
|
||||
预览加载的生成式 JSON(路线和交通信号)使用 `fetch(..., { cache: "no-store" })`,因为
|
||||
这些文件保持稳定文件名但会被单独重生成;浏览器不得继续显示旧的巡航路线。
|
||||
|
||||
调试和无头检查都靠它。**加新的顶层对象就往这里挂**,不要再开新全局。
|
||||
|
||||
---
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
## 2. Signatures
|
||||
|
||||
```js
|
||||
buildVehicleRoute(osmPath) => {
|
||||
source, bounds, generatedAt, speedMetersPerSecond, loop,
|
||||
routes, segments
|
||||
buildVehicleRoute(osmPath, lanePolygonsPath, networkPath, intersectionSurfacePath) => {
|
||||
source, laneSource, networkSource, intersectionSource, bounds, generatedAt, speedMetersPerSecond, loop,
|
||||
routes, segments, diagnostics
|
||||
}
|
||||
|
||||
allowedTurns(tags, direction) => Set<"left" | "through" | "right">
|
||||
@@ -28,7 +28,14 @@ classifyConnection(incomingEdge, outgoingEdge) =>
|
||||
|
||||
- `routes` 是当前主字段;`segments` 必须是同一数组的兼容别名,供旧预览使用。
|
||||
- 每个路线至少包含 `id`、`coordinates`、`centerlineCoordinates`、`lengthMeters`、
|
||||
`maneuvers` 与 `edgeIds`。`coordinates` 是右侧车道偏移后的闭合巡航轨迹。
|
||||
`maneuvers`、`edgeIds`、`laneSegments` 与 `connectors`。道路区间来自匹配的 Driving lane polygon 中轴。
|
||||
- 路线拓扑以 `network.json` 的 internal road 和 intersection 为准;禁止把整个 OSM way 直接当作一条不可分割 edge。
|
||||
- connector 必须绑定同一个 internal intersection,并位于对应 `intersection_surface.geojson` 内或允许的边界容差内;越界时拒绝候选路线。
|
||||
- preview 必须将 `lane_polygons.geojson`、`network.json` 和 `intersection_surface.geojson` 作为强制输入;缺失或无效时在写产物前失败。
|
||||
- route 经纬度由 Cesium 按 WGS84 直接放置;最终道路 GLB 必须由 WGS84 ECEF→ENU
|
||||
`Projector` 生成。禁止以固定米/度近似投影道路,否则即使 route 与 lane polygon
|
||||
完全一致,最终画面仍会随离锚点距离产生横向偏移。
|
||||
- 单条路线无法可靠匹配时跳过并写结构化 `diagnostics`,不得回退固定或默认车道宽度。
|
||||
- 有 `oneway=yes`(及等价真值)的 way 只能按 OSM 原始方向生成 edge,绝不能生成反向
|
||||
`:backward` edge;`oneway=-1` 仅允许反向 edge。
|
||||
- 去程在路口按入边方向读取 `turn:lanes:forward` 或 `turn:lanes:backward`,只有标签中的
|
||||
@@ -36,6 +43,7 @@ classifyConnection(incomingEdge, outgoingEdge) =>
|
||||
- 返程是展示路线的原路回返,不以反向 `turn:lanes` 再次否决,但依旧不可逆行单行道。
|
||||
- 路网没有闭环时,在去程和返程端点插入平滑调头曲线;不得在 way 端点或路口瞬移。
|
||||
- 选择菜单使用 `#编号 · 长度 m · 左 N / 右 N / 直 N`,因为一条路线可跨越多个道路名称。
|
||||
- 预览只显示当前下拉框选中车辆的 route polyline,避免多条闭环轨迹在路口重叠造成错误的偏移判断。
|
||||
|
||||
## 4. Validation & Error Matrix
|
||||
|
||||
@@ -62,6 +70,8 @@ classifyConnection(incomingEdge, outgoingEdge) =>
|
||||
`node --check scripts/lib/cesium-preview.js`:保证 Node 与浏览器直载脚本语法可用。
|
||||
- 对目标区域运行 `npm run build:area -- --config config/areas/<area>.json --stages preview`,确认
|
||||
`routes` 中存在左、右、直动作,且 Cesium 下拉标签显示编号、长度与动作统计。
|
||||
- 修改地理投影时必须运行 `blender,cesium,preview`,不能只重跑 preview;最终检查青色路线
|
||||
到黄色中心线及道路边缘的横截面距离,确认两侧路线分别位于各自车道中心。
|
||||
|
||||
## 7. Wrong vs Correct
|
||||
|
||||
|
||||
Reference in New Issue
Block a user