唯杰地图 logo唯杰地图
VJMAP
EN

editing

vjmap/references/primitive/editing.md 5.2 KB166 行
原文

本文回答:用 vjmap.Draw 编辑/绘制底座图形(线、面、点、圆弧等),导出 GeoJSON 后送入 Polyline / Polygon。

一、用途

底座图元(Polyline / Polygon)通常是"只读可视化"。如果需要用户交互绘制 / 编辑这些图元,有两条路:

  1. vjmap.Draw.Tool(本文):通用绘图控件(vjmap.Draw 是命名空间对象,可构造的是 Draw.Tool),输出 GeoJSON
  2. 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: [...] } 待吸附点集
  }
});

详见 interaction/snap-ortho。

十、与 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()));

十一、常见坑

  1. fc 坐标混乱 → Draw 是 LngLat;业务可能要 CAD;记得 fromLngLat / toLngLat 转换。
  2. 删除后图层不更新 → draw.delete 后要手动 businessLayer.setData(draw.getAll())。
  3. 禁用某些控件 → displayControlsDefault: false + controls: { ... } 白名单。
  4. Vue/React 里挂两次 → Draw 是 IControl,热更时记得 map.removeControl(draw) 再 add。
  5. 样式不好看 → Draw 有默认样式,可覆盖 styles: [...] 或直接用业务层展示,Draw 用 static 模式。