# 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 ``` 然后打开 。 不需要导入 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` 全部保留。