Skip to content

编辑器概览(@geoverse/editor-*)

GeoVerse 的要素编辑能力由三个相互独立的包组成:一个框架无关的编辑引擎,加两个分别接入 OpenLayers 与 MapLibre 的适配器。

@geoverse/editor-core   纯 TS 引擎(撤销重做 / 命令 / 校验 / 吸附 / 后端同步)——不依赖任何地图库
   ├──► @geoverse/editor-ol      OpenLayers 适配器(peer: geoverse、ol)
   └──► @geoverse/editor-libre   MapLibre 适配器(peer: @geoverse/core-libre、maplibre-gl)
作用peerDependencies
@geoverse/editor-core编辑引擎与全部命令、几何运算、校验、吸附、后端同步。禁止 import 任何地图库(由 lint 强制)。无(仅运行时 deps:@turf/*jstsrbushnanoid
@geoverse/editor-olol/interaction(Draw/Modify/Translate/Pointer)归一成引擎命令。geoverseol@geoverse/editor-core
@geoverse/editor-libreMapLibre 无内置编辑,适配器自绘顶点/手柄并接管鼠标手势。@geoverse/core-libremaplibre-gl@geoverse/editor-core

实验性(0.1.0)

编辑器三包当前为 0.1.0,公共 API 可能在正式发布前微调。生产使用建议锁定版本并关注变更说明。

能力矩阵

创建 / 修改 / 节点编辑 / 拆分 / 合并 / 面·线运算 × 点(Point)/ 线(Line)/ 面(Polygon),全部经统一的命令与类型校验落地:

分类能力线命令
创建绘制AddFeatureCommand
创建复制 / 粘贴EditSession.copy() / AddFeaturesCommand
修改移动TranslateCommand
修改旋转 / 缩放 / 镜像RotateCommand / ScaleCommand / MirrorCommand
修改偏移复制OffsetCommand
节点增 / 删 / 移动节点AddVertexCommand / DeleteVertexCommand / MoveVertexCommand
拆分点拆分多点SplitMultiPointCommand
拆分线打断SplitLineCommand
拆分按线拆面SplitPolygonByLineCommand
拆分多线 / 多面拆分SplitMultiLineStringCommand / SplitMultiPolygonCommand
合并点合并MergePointsCommand
合并线合并(端点相接)MergeLinesCommand
合并线组合(→ 多线)CombineLinesCommand
合并面合并(并集)MergePolygonsCommand
面运算差集(A−B)DifferencePolygonsCommand
面运算挖洞 / 填洞PunchHoleCommand / FillHoleCommand
面运算开洞 / 消洞OpenHoleCommand(线驱动,适配器 open-hole 模式画切割线) / CloseHoleCommand(一键封上所有凹湾,无需交互)

外加贯穿全部操作的撤销/重做类型校验(不适用的几何类型会被命令拦截)。详见核心概念

差集 vs 挖洞:差集是布尔运算(B 跨边界会切缺口、完全在内则成洞);挖洞是结构插入内环(精确保留外边界,要求 B 完全落在 A 内部),与填洞互为逆操作。差集 / 挖洞均为「选 2 个面、第一个为目标 A」的二元运算。各轨命令与坐标单位差异见 OpenLayers 适配器(米)/ MapLibre 适配器(度)。

开洞 / 消洞(「非分离切」,一对互逆操作):与上面几个都不同——**开洞(线驱动)**是一条切割线从外边界进入某个内环(洞),把洞经一条细通道连到外边界成「凹湾」(洞环并入外环,面仍是 1 块、少一个内环);**消洞(一键,无需交互)把外边界的所有凹湾(缺口)**自动封回内环洞,与「面填洞」对称(填洞去掉所有内环、消洞封上所有凹湾),是开洞的逆向能力。区别于「按线拆面」(须贯穿外环、切成 2 块)与「挖洞/填洞」(结构插入/移除内环)。消洞用凸包自动定出全部凹湾,无需点选位置;面上没有凹湾(外边界为凸,如普通带洞面)时明确拒绝——那种情况若只是想去掉洞请用「面填洞」。通道宽度按面 bbox 对角线 0.5% 自适应(可 { width } 覆写),结果是合法的单面。

安装

OpenLayers 轨:

shell
pnpm add @geoverse/editor-core @geoverse/editor-ol geoverse ol

MapLibre 轨:

shell
pnpm add @geoverse/editor-core @geoverse/editor-libre @geoverse/core-libre maplibre-gl

5 分钟上手(OpenLayers)

ts
import { GMap } from '@geoverse/core-ol';
import { EditSession, SplitLineCommand } from '@geoverse/editor-core';
import { OlEditorAdapter } from '@geoverse/editor-ol';

const map = new GMap({
  target: 'map',
  base: 'gd-vec',
  center: [118.18, 24.49],
  zoom: 15,
});
const crs = map.getView().getProjection().getCode(); // 工作 CRS = 视图投影(默认 EPSG:3857)

const session = new EditSession({
  crs,
  features: [
    {
      id: 'l1',
      geometry: {
        type: 'LineString',
        coordinates: [
          /* …投影坐标… */
        ],
      },
      properties: {},
    },
  ],
});

const adapter = new OlEditorAdapter(map, {
  crs,
  onSelect: (id, additive) => {
    if (id) session.select([id], additive);
    else if (!additive) session.clearSelection();
    adapter.setSelection(session.getSelected());
  },
});

session.attach(adapter); // 绑定交互 + 订阅渲染,返回解绑函数
adapter.setMode('select'); // 切换工具模式

// 撤销 / 重做
session.engine.undo();
session.engine.redo();

5 分钟上手(MapLibre)

ts
import { GMap } from '@geoverse/core-libre';
import { EditSession } from '@geoverse/editor-core';
import { LibreEditorAdapter } from '@geoverse/editor-libre';

const map = new GMap({
  container: 'map',
  base: 'carto-light',
  center: [118.15, 24.56],
  zoom: 14,
});

const session = new EditSession({ crs: 'EPSG:4326' }); // MapLibre 的 GeoJSON 即 lng/lat
const adapter = new LibreEditorAdapter(map, {
  onSelect: (id, additive) => {
    if (id) session.select([id], additive);
    else if (!additive) session.clearSelection();
    adapter.setSelection(session.getSelected());
  },
});
session.attach(adapter);
adapter.setMode('select');

FeatureEditor 的区别

geoverse 内置的 FeatureEditor 只做基础顶点拖拽编辑(单要素、无撤销/打断/合并/拓扑/后端)。需要工程级编辑(撤销重做、打断合并、变换、节点增删、拓扑校验、后端同步)时用编辑器三包。两者可共存,但同一场景二选一。

下一步

在线示例:仓库 examples/editor/(OL)与 examples/editor-libre/(MapLibre)(pnpm dev:examples/editor//editor-libre/)。在线 Playground 的「要素编辑全功能」预设(OpenLayers / MapLibre 两轨)把上表的全部模式与命令做成可一键试用的工具条——含撤销/重做、复制粘贴、面差集 / 挖洞 / 填洞 / 开洞 / 消洞、多部件拆分、Mock 后端同步与冲突演示。