editing
本文回答:用
vjmap.Draw编辑/绘制底座图形(线、面、点、圆弧等),导出 GeoJSON 后送入 Polyline / Polygon。
一、用途
底座图元(Polyline / Polygon)通常是"只读可视化"。如果需要用户交互绘制 / 编辑这些图元,有两条路:
- vjmap.Draw.Tool(本文):通用绘图控件(
vjmap.Draw是命名空间对象,可构造的是Draw.Tool),输出 GeoJSON - map.createDrawLayer / vjmap.Draw.actionDraw*:便捷创建 / 原子绘制命令(详见 interaction/draw-tools)
本文聚焦:用 vjmap.Draw 画完形状 → 拿到 GeoJSON → 用 Polyline / Polygon 重渲染到业务层。
二、最小示例
// 1) 在地图上挂 Draw 控件
const draw = new vjmap.Draw.Tool({
displayControlsDefault: false,
controls: { polygon: true, trash: true, line_string: true, point: true }
});
map.addControl(draw);
// 2) 切到绘面模式
draw.changeMode("draw_polygon");
// 3) 监听绘制完成
map.on("draw.create", e => {
const featureCollection = draw.getAll();
// 把最后一条 feature 作为业务图元
const last = e.features[e.features.length - 1];
console.log("新增几何", last);
// 业务层渲染
polygonLayer.setData(draw.getAll());
});
map.on("draw.update", () => polygonLayer.setData(draw.getAll()));
map.on("draw.delete", () => polygonLayer.setData(draw.getAll()));
三、核心模式
| mode | 说明 |
|---|---|
simple_select |
默认:选中已存在要素 |
direct_select |
选中单个 feature 并显示顶点,可拖顶点 |
draw_point |
画点 |
draw_line_string |
画线 |
draw_polygon |
画面 |
static |
禁用一切交互 |
draw.changeMode("draw_polygon");
四、事件
| 事件 | 触发 |
|---|---|
draw.create |
新要素产生(绘制完成) |
draw.update |
已存在要素被拖 / 改变 |
draw.delete |
删除 |
draw.selectionchange |
选择集改变 |
draw.modechange |
切换模式 |
draw.render |
每帧渲染 |
五、API 摘要
draw.getAll(); // { type: "FeatureCollection", features: [...] }
draw.get(id); // 取单个
draw.getSelected(); // 当前选中
draw.getSelectedIds(); // 选中 id 数组
draw.getMode(); // 当前模式
draw.add(feature); // 增
draw.set(featureCollection); // 全量替换
draw.delete(id); // 删
draw.deleteAll(); // 清空
draw.changeMode(mode, opts); // 改模式
// 选中
draw.changeMode("simple_select", { featureIds: [id] });
六、把 Draw 的结果转 CAD 坐标
vjmap.Draw 以 LngLat 存 feature。要在 CAD 坐标系保存:
const lnglatFc = draw.getAll();
const cadFc = map.fromLngLat(lnglatFc); // 反投影回 CAD
saveToBackend(cadFc);
七、把 CAD 数据反灌进 Draw 进行二次编辑
const cadFc = loadFromBackend();
draw.set(map.toLngLat(cadFc));
draw.changeMode("simple_select");
八、只想编辑(不允许新增)
const draw = new vjmap.Draw.Tool({
displayControlsDefault: false,
controls: { trash: false }
});
map.addControl(draw);
draw.set(existingFc);
draw.changeMode("simple_select", { featureIds: existingFc.features.map(f => f.id) });
// 禁用用户新增:只监听 update / delete
九、吸附(snap)
结合 vjmapext 的 SnapManager(mapcadLayer.snapManager,见 vjmapext skill 的 drawing/snap),或对 Draw 自定义 snap:
const draw = new vjmap.Draw.Tool({
api: {
getSnapFeatures: snapObj // { features: [...] } 待吸附点集
}
});
十、与 Polyline / Polygon 的对接
推荐流程:
draw.create ──► draw.getAll() ──► setData 到 vjmap.Polygon / Polyline
(业务图层,用真实样式)
draw.update ──► 同上
draw.delete ──► 同上
业务层和编辑层分开:
- Draw 图层:简单样式、可交互
- 业务图层:自己的色彩、filter、hoverPopup 等
const businessLayer = new vjmap.Polygon({
data: { type: "FeatureCollection", features: [] },
fillColor: "#0af",
fillOpacity: 0.6
});
businessLayer.addTo(map);
map.on("draw.create", () => businessLayer.setData(draw.getAll()));
map.on("draw.update", () => businessLayer.setData(draw.getAll()));
map.on("draw.delete", () => businessLayer.setData(draw.getAll()));
十一、常见坑
- fc 坐标混乱 → Draw 是 LngLat;业务可能要 CAD;记得
fromLngLat/toLngLat转换。 - 删除后图层不更新 →
draw.delete后要手动businessLayer.setData(draw.getAll())。 - 禁用某些控件 →
displayControlsDefault: false+controls: { ... }白名单。 - Vue/React 里挂两次 → Draw 是 IControl,热更时记得
map.removeControl(draw)再 add。 - 样式不好看 → Draw 有默认样式,可覆盖
styles: [...]或直接用业务层展示,Draw 用 static 模式。