唯杰地图 logo唯杰地图
VJMAP
EN

vjmapext(唯杰地图 2D 扩展包)二次开发技能

Use when building CAD drawing/editing features on top of vjmap with vjmapext (唯杰地图 2D 扩展包, MapCadLayer) — creating CAD entities (LineEnt / CircleEnt / PolylineEnt / ArcEnt / TextEnt / MTextEnt / HatchEnt / SplineEnt / EllipseEnt / PointEnt / BlockRefEnt / dimensions / MLeaderEnt), executing drawing commands (LINE / PLINE / CIRCLE / MOVE / executeCommand), custom commands and CommandRegistry, InputManager getPoint/getSelections, snapping / grips / preview, EventBus events (entity:added / command:ended / selection:changed), batch entity add & mapdata query, undo/redo, serialize toJSON/fromJSON, fx GPU effects, entity render performance (buckets / dynamic / styleChanged), plugins, i18n and themes. Keywords vjmapext MapCadLayer CAD绘图 实体 命令 捕捉 夹点 标注 批量 EventBus fx 性能. Requires vjmap (use vjmap skill for base map). Excludes vjmap base map API, vjmap3d, vjcad.

vjmapext/SKILL.md 15.2 KB192 行
原文

面向 vjmapext —— 挂在 vjmap.Map 上的 CAD 绘图扩展(MapCadLayer)。底座地图 API 见 vjmap skill(本包依赖它);三维见 vjmap3d skill。

〇、文档与示例来源(路径约定)

本 skill 的 references/ 已按 vjmapext@1.0.1 的 dist/vjmapext.d.ts 与 playground 示例核对。更深细节:

来源 用法
官方文档/示例 MCP https://vjmap.com/server/aimcp/mcp?products=mapext(list_docs / search_docs / get_doc_content)。路径前缀:mapext/docs/...(官方文档,24 个主题目录)、mapext/example/...(playground 示例源码)
npm 包类型定义 node_modules/vjmapext/dist/vjmapext.d.ts
底座 API vjmap skill references/ 或 map2d/... 文档路径

示例中的 env.serviceUrl / env.accessToken 由 playground 注入;自己项目里替换为实际服务地址与 token。冲突时以 .d.ts 与示例为准。

一、适用范围

包 角色 包含 不包含
vjmapext CAD 绘图扩展(MapCadLayer 作为 IControl 挂在 vjmap.Map 上) 15+ CAD 实体 / 30+ 命令 / InputManager / SnapManager 捕捉 / 夹点 / 注释 / mapdata 联动 / 动画 / fx GPU / 插件 / EventBus / i18n / 主题 —
vjmap Web 地图底座 — 不在范围,见 vjmap skill
vjmap3d / vjcad 三维 / 纯 CAD 编辑器 — 不在范围

二、安装与引入

npm:

npm i vjmap vjmapext        # vjmapext 依赖 vjmap(package.json 已声明依赖,但样式/初始化仍要按 vjmap 流程)
import vjmap from "vjmap";
import "vjmap/dist/vjmap.min.css";
import { MapCadLayer, LineEnt, TextEnt, VjmapextEvents } from "vjmapext";

CDN / 全局对象(必须先 vjmap 后 vjmapext,顺序错了 UMD 拿不到 peer):

<link rel="stylesheet" href="https://unpkg.com/vjmap@1.0.161/dist/vjmap.min.css">
<script src="https://unpkg.com/vjmap@1.0.161/dist/vjmap.min.js"></script>
<script src="https://unpkg.com/vjmapext@1.0.1/dist/vjmapext.min.js"></script>
<!-- 全局对象 vjmapext:const { MapCadLayer, LineEnt } = vjmapext -->

起步模板(复制即用):templates/vite-app/(npm + Vite,README)与 templates/cdn/(单 HTML),含空白 CAD 画布 + MapCadLayer + createUI + 实体添加完整流程。

三、心智模型

vjmap.Map(底座,见 vjmap skill)
   │
   │  map.addControl(mapcadLayer)   ← MapCadLayer 是一个 IControl
   v
+----------------------------+
| MapCadLayer                |   创建顺序:
|  - EntityStore(实体增删改)|   1. await map.onLoad()          (vjmap 流程)
|  - RenderPipeline           |   2. const cad = new MapCadLayer(options?)
|    (cold/hot/dynamic/fx)    |   3. map.addControl(cad)
|  - CommandRegistry          |   4. cad.createUI({theme:'dark'}) (可选,要工具栏才调)
|    (LINE/CIRCLE/MOVE/...)   |   5. cad.addEntity(ent) / cad.executeCommand('LINE')
|  - InputManager             |
|    (getPoint/getSelections) |
|  - CoordMapper (CAD<->经纬) |
|  - EventBus                 |
|    (entity:*/command:*/...) |
+----------------------------+

关键认知(均经 d.ts / 示例核对):

  1. MapCadLayer 不是图层文件里的 map.addLayer,而是 map.addControl(cad) 挂上去的控件;推荐先 await map.onLoad()(提前挂也行——onAdd 内部会等 load 事件再接管)。
  2. 实体构造是位置参数不是 options 对象:new LineEnt([0,0],[100,100])、new TextEnt([x,y],'文字',字高)、new PolylineEnt([[x,y],...], isClosed)。
  3. ent.color 是 0xRRGGBB 整数(如 0xff0000),不是 CSS 字符串,也不支持 CAD/ACI 色号(写 1 会渲染成近黑 #000001);程序化直接构造的实体(new LineEnt(...) 等)默认白色 0xffffff。MapCadLayerOptions.defaultColor 只作交互命令绘图的默认色,且 localStorage 已保存的绘图默认色优先于它。
  4. createUI 是方法不是构造选项:new MapCadLayer({createUI:true}) 无效,要 cad.createUI({ theme })。
  5. 执行命令:await cad.executeCommand('LINE')(Promise);命令结束监听 VjmapextEvents.CommandEnded("command:ended")。
  6. 交互命令的 entity:added 时机不一:PLINE/SPLINE 结束时一次性 add 最终实体;LINE 每段即时 add 最终 LineEnt;DLINE 会先 add 再改端点(斜接/封口)甚至 U 删除——要拿最终结果请在 command:ended 后读。

四、最小可运行模板(MRT)

在 vjmap MRT(见 vjmap skill)await map.onLoad() 之后追加:

// CDN 全局方式:const { MapCadLayer, LineEnt, TextEnt, VjmapextEvents } = vjmapext;
const cad = new MapCadLayer();          // 不要传 { createUI: true },那是无效字段
map.addControl(cad);
cad.createUI({ theme: 'dark' });        // 可选:要内置工具栏才调

const line = new LineEnt([0, 0], [100, 100]);   // 位置参数 (startPoint, endPoint)
line.color = 0xffcc00;                          // 数字色值
cad.addEntity(line);

const label = new TextEnt([0, 120], '示例文字', 20);
label.color = 0xffffff;
cad.addEntity(label);

// 执行内置绘图命令
cad.eventBus.on(VjmapextEvents.CommandEnded, e => console.log('命令结束', e));
await cad.executeCommand('LINE');               // 用户开始交互式画线

参考示例:mapext/example/basic/01blankMap.js(空白图 + 多实体)、02cadMap.js(叠加到 CAD 底图)。

五、按用户场景速查

标 【vjmap】 的条目属底座能力,文件在 ../vjmap/references/。

用户问题 去读
创建 CAD 实体(LineEnt / CircleEnt / TextEnt…)? entity/overview + entity/line-polyline + entity/circle-arc-ellipse + entity/text
实体生命周期 / dirty / changed? entity/lifecycle
实体样式属性(color/lineWidth/linetype/transparency)? entity/style-props
实体变换(move/rotate/scale/transform)? entity/transform
标注 / 引线 / 尺寸? entity/dimensions + entity/leader
块参照 / 图案填充 / 样条 / 云线 / 点? entity/block-reference + entity/hatch + entity/spline + entity/revcloud + entity/point
文字字体 / 自定义实体? entity/font-text + entity/custom-entity
执行 LINE / CIRCLE / MOVE 命令? drawing/execute-command + drawing/builtin-draw + drawing/builtin-edit
自定义命令? drawing/custom-command
命令里取点 / 选实体(InputManager)? drawing/input-manager
捕捉 / 夹点 / 拖动预览 / 快捷键 / 模式? drawing/snap + drawing/grip + drawing/preview + drawing/shortcuts + drawing/mode
undo/redo 事务? drawing/undo-redo
实体序列化 toJSON / fromJSON? drawing/serialize
监听命令结束 / 实体增删改 / 选集变化? event/bus-command-mode + event/bus-entity + event/bus-selection
渲染层 / 存储层事件? event/bus-render-store
批量加实体不卡? batch/entity-bulk-add + perf/batch-rendering
一条 SQL 从后端拉回批量 DWG 实体? batch/mapdata-query
FeatureCollection → 实体? batch/features-to-entities
隐藏原图实体避免双重显示? batch/mapdata-hider
大量实体只改样式? batch/bulk-style-update + perf/style-only-fast-path
上万实体卡顿? perf/render-buckets + perf/dynamic-entities + perf/batch-rendering
告警光圈 / 流动线 / GPU 特效? perf/fx-overview + perf/fx-presets + perf/fx-quality
强制重绘 / RenderCache 失效? perf/render-cache
CAD 坐标 ↔ 渲染经纬度(CoordMapper)? coord/cad-mapper
createUI 主题不生效? trouble/createui-no-theme
批量操作卡顿? trouble/batch-lag
fromJSON 后看不到实体? trouble/fromjson-fit
【vjmap】打开 DWG / 初始化地图 / Marker / Popup / 互联网底图? ../vjmap/references/ 对应主题

六、完整文件地图

CAD 实体 (entity/)
overview · lifecycle · style-props · transform · line-polyline · circle-arc-ellipse · spline · point · hatch · text · font-text · block-reference · dimensions · leader · revcloud · custom-entity

绘图命令 (drawing/)
overview · execute-command · builtin-draw · builtin-edit · input-manager · snap · grip · preview · undo-redo · serialize · custom-command · shortcuts · mode

批量 (batch/)
overview · entity-bulk-add · mapdata-query · features-to-entities · mapdata-hider · bulk-style-update

事件 EventBus (event/)
bus-entity · bus-selection · bus-command-mode · bus-render-store(事件清理 off/offAll 见 vjmap skill event/cleanup)

性能 (perf/)
render-buckets · dynamic-entities · style-only-fast-path · render-cache · fx-overview · fx-quality · fx-presets · batch-rendering

坐标 (coord/)
cad-mapper(坐标空间概念见 vjmap skill coord/concepts)

常见坑 (trouble/)
createui-no-theme · batch-lag · fromjson-fit

七、约定与红旗

命名

  • cad / mapcadLayer = MapCadLayer 实例;VjmapextEvents = 事件常量表("entity:added" / "command:ended" / "selection:changed"…)。
  • 实体一律 new LineEnt(...) / new TextEnt(...) 等位置参数(不是 options 对象)→ 设属性 → cad.addEntity(ent)。

Top 8 红旗

  1. new MapCadLayer({ createUI: true }) → createUI 不是构造选项,工具栏出不来;要 cad.createUI({ theme })。
  2. vjmapext.min.js 在 vjmap.min.js 之前加载 → peer 未就绪报错。
  3. map.onLoad() 之前就 addControl(cad) → 其实安全(onAdd 在 !map.loaded() 时挂 map.on('load') 延后初始化);但仍推荐先 await map.onLoad()(官方示例均如此),并紧接着挂——onLoad 之后又 await 其它异步、地图正在加载新瓦片时才挂,map.loaded() 可能为 false 而 load 不会再发,层永不接管(见 drawing/overview)。
  4. ent.color = "#f00"(CSS 字符串)→ 不生效;色值是 0xRRGGBB 整数(0xff0000),ent.color = 1 这类 CAD 色号也不认(变近黑)。
  5. 循环里逐条 addEntity + setDirty → 卡;用批量姿势(batch/entity-bulk-add)。
  6. 把 DLINE 等命令中途的 entity:added 当最终结果 → 端点之后还会被改/删;等 command:ended 再读。
  7. eventBus.on 没配对 off → 组件卸载后回调残留(泄漏排查见 vjmap skill trouble/listener-leak)。
  8. fromJSON(doc) 后忘 zoomExtents() → 实体在屏外"看不到"(trouble/fromjson-fit)。