feat: add direct edit handles behind directEdit flag
Steps 1-3 of the main map road interval editor. EditSession keeps the command stack, undo/redo and previewSeq arbitration as pure logic with no OpenLayers reference, so all of it is unit-tested in node. Pointer displacement converts to meters through EPSG:4326 and spherical distance: treating a 3857 delta as meters desyncs the geometry from the cursor by 1/cos(latitude). Handle drags project onto the axis the manifest declares and clamp to its range, so the client never writes a coordinate into a road polygon. All of it sits behind a directEdit flag that defaults to off. With the flag off the workbench requests no manifest, creates no extra source and registers no interaction, so behaviour matches main. The ol-ext probe passed its three gates but is not adopted for road handles. Transform translates by the raw pointer delta, so a handle detaches from its clamped constraint value: a drag reading -24.1 m produced a draft of -5.4 m. Production needs the handle position derived from the constraint instead, which means owning the position update, so native OL PointerInteraction will carry the drag. ol-ext stays out of package.json; the probe is kept as a manual harness. Reserve handles are unreachable with the current solver, recorded in research/ rather than worked around. Also names the dead backend when an API response is empty, instead of surfacing "Unexpected end of JSON input" from response.json(). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
68
workbench/client/probe/ol-ext-transform/README.md
Normal file
68
workbench/client/probe/ol-ext-transform/README.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# ol-ext Transform 限时探针
|
||||
|
||||
对应 `.trellis/tasks/08-26-direct-edit-map-editor/implement.md` 第 1 步。
|
||||
|
||||
这个探针只回答一个问题:**能否复用 ol-ext 通用 handle 的命中、pointer 生命周期与视觉反馈。**
|
||||
它不回答“道路语义怎么建模”——那部分由 `src/edit/` 的 `EditSession` / `projection` 负责,且已经独立单测通过。
|
||||
|
||||
## 怎么跑
|
||||
|
||||
```bash
|
||||
npm install ol-ext --no-save # 门禁通过前不进依赖清单
|
||||
npm run dev
|
||||
```
|
||||
|
||||
然后打开 <http://localhost:5173/probe/ol-ext-transform/>。
|
||||
|
||||
不需要导入 OSM,也不需要后端:页面用 `fixture.ts` 里的合成道路。
|
||||
|
||||
## 你要做的事
|
||||
|
||||
拖动地图上那个**蓝色圆点手柄**,来回拖几次,快慢都试,然后看右侧面板。
|
||||
|
||||
## 三条门禁(必须同时成立)
|
||||
|
||||
| # | 门禁 | 面板怎么读 |
|
||||
|---|---|---|
|
||||
| 1 | OL `Map` 未被重建 | “实例 #N,累计构造 N 次”两个数字必须相等。再点几次“强制 React 重渲染”,数字仍要相等。 |
|
||||
| 2 | 基线 source 未被写入 | “写入 0 次,几何未改变”。拖拽过程中这行**任何变化都算失败**。 |
|
||||
| 3 | proxy 拖拽稳定且事件能转成 draft 值 | 看**「原始位移」**那行跟手连续变化、松手不跳;手柄不粘滞、不丢命中。 |
|
||||
|
||||
门禁 3 要看的是「原始位移」,不是「约束值」。约束值带生产钳位 `±5.4 米`,
|
||||
而 5.4 米在 zoom 20 只有约 47 像素,稍微拖远就会顶到边界显示成常量——那是正常的,不代表跟踪有问题。
|
||||
「原始位移」不钳位,所以它才反映跟手质量。
|
||||
|
||||
两个数都是用生产代码算的(`signedMetersAlongAxis()` / `projectHandleValue()`),
|
||||
所以门禁 3 同时验证了“事件 → 约束值”这条链路。
|
||||
|
||||
另外面板会显示收到了多少个 `translating` 事件。这个数字和 React 渲染次数的比例是个有用的信号:
|
||||
探针已经把逐帧读数用 `requestAnimationFrame` 合并了,生产实现还要更进一步——
|
||||
ghost 直接写自己的 OL source,绝不为每次指针移动重渲染 React 树。
|
||||
|
||||
注意:**卸载/重新挂载地图会构造新的 Map,这是预期行为**,不算门禁 1 失败。门禁 1 针对的是拖拽与重渲染。
|
||||
|
||||
## 请回报给我
|
||||
|
||||
1. 三条门禁分别通过/未通过。
|
||||
2. 未通过的,面板上的具体数字或现象。
|
||||
3. 主观手感:拖拽是否顺滑,手柄命中是否可靠。
|
||||
|
||||
## 已知的、探针之外的结论
|
||||
|
||||
这些我已经查过,不用你验证,但会计入最终取舍:
|
||||
|
||||
- ol-ext 4.0.38,BSD-3-Clause,`peerDependencies: ol >= 5.3.0`,无运行时依赖。
|
||||
- **不带 TypeScript 类型,也没有 `@types/ol-ext`。** 本目录的 `ol-ext.d.ts` 是我为探针手写的最小声明;
|
||||
真要把 ol-ext 提为正式依赖,就要长期自己维护一份声明文件。
|
||||
- `Transform` 的 `translate` 分支直接对传入 feature 调 `geometry.translate()`。
|
||||
所以它只能绑一次性 proxy,绝不能绑编译产物图层——这也是门禁 2 存在的原因。
|
||||
- 它的手柄模型是 bounding box 的 scale/rotate/stretch,跟道路法线偏移、区间范围、路口 cutback 不是一回事。
|
||||
即使门禁全过,它最多承担“通用手柄的命中与拖拽生命周期”,语义投影仍然是我们自己的 `projection.ts`。
|
||||
|
||||
## 如果门禁没过
|
||||
|
||||
按 `design.md` 的回退优先级,删掉本目录,改用回退方案 1:
|
||||
原生 OL `Snap` + 小型 `PointerInteraction` adapter。
|
||||
|
||||
`HandleManifest → RoadEditOperation → RoadConstraint → preview solver` 的数据合约不变,
|
||||
所以这一步失败只换输入层,第 2 步已交付的 `EditSession` / `projection` / `meters` 全部保留。
|
||||
Reference in New Issue
Block a user