唯杰地图 logo唯杰地图
VJMAP
EN

创建符号(本地 / 服务端)

vjcad/references/insert/symbol-create.md 4.8 KB117 行
原文

示例:

  • vjcad/example/insert/symbol/01createlocal.js — IndexedDB 本地符号
  • vjcad/example/insert/symbol/02createserver.js — 服务端符号

vjcad 把"符号"理解为一组实体 + 基点 + 缩略图打包。可以保存到 本地 IndexedDB 或 服务端,两条路径对应两个 service。

1. 通用步骤

flowchart LR
    A[准备实体数组<br/>line/circle/...] --> B[buildSymbolVcadData<br/>(entities, false)]
    A --> C[generateThumbnailFromEntities<br/>(entities, 128, 128)]
    B --> D{保存目标}
    D -->|本地| E[localService.saveLocalSymbol]
    D -->|服务端| F[compressSymbolData → uint8ArrayToBase64<br/>→ service.createSymbol]

vcadData 是符号几何的序列化字符串;缩略图是完整的 Data URL(data:image/png;base64,...,128×128),可直接当 <img src>,不要再拼 data: 前缀。

2. 保存到本地(IndexedDB)

const localService = getLocalStorageService();

// 2.1 找/建分类
const categories = await localService.getLocalSymbolCategories();
let cat = categories.find(c => c.name === "示例符号");
if (!cat) cat = await localService.createLocalSymbolCategory("示例符号");

// 2.2 准备实体(必须先 setDefaults)
const line1 = new LineEnt([-10, 0], [10, 0]);
const line2 = new LineEnt([0, -10], [0, 10]);
const circle = new CircleEnt([0, 0], 8);
[line1, line2, circle].forEach(e => e.setDefaults());
Engine.addEntities([line1, line2, circle]); // 可选:在画布预览

// 2.3 打包数据 + 生成缩略图
const entities = [line1, line2, circle];
const vcadData  = await buildSymbolVcadData(entities, /* clearSourceInfo */ false);
const thumbnail = await generateThumbnailFromEntities(entities, 128, 128);

// 2.4 保存
const symbol = await localService.saveLocalSymbol({
    categoryId: cat.id,
    name: "十字圆符号",
    basePoint: [0, 0],
    thumbnail,
    vcadData,
});

完整代码:vjcad/example/insert/symbol/01createlocal.js

3. 保存到服务端

服务端要求 vcadData 经过 gzip 压缩 + base64 编码:

let service;
try {
    service = Engine.service;          // 未配置 serviceUrl 时 getter 直接抛错,不会返回空
} catch (e) {
    throw new Error("服务不可用:未配置 serviceUrl");
}

// 3.1 找/建分类
const categories = await service.getSymbolCategories();
let cat = categories.find(c => c.name === "用户自定义");
if (!cat) cat = await service.createSymbolCategory("用户自定义");

// 3.2 实体 → vcadData → 压缩 → base64
const vcadData       = await buildSymbolVcadData(entities, false);
const thumbnail      = await generateThumbnailFromEntities(entities, 128, 128);
const compressedData = await compressSymbolData(vcadData, /* level */ 6);
const base64Data     = uint8ArrayToBase64(compressedData);

// 3.3 上传
const sym = await service.createSymbol({
    categoryId: cat.id,
    name: "箭头符号_" + Date.now(),
    basePoint: [0, 0],
    thumbnail,
    data: base64Data,
});

完整代码:vjcad/example/insert/symbol/02createserver.js

4. API 速查

API 来源 作用
buildSymbolVcadData(entities, clearSourceInfo?) vjcad 顶层 实体 → vcad 字符串
generateThumbnailFromEntities(entities, w, h) vjcad 顶层 缩略图 PNG Data URL(data:image/png;base64,...)
compressSymbolData(data, level?) / uint8ArrayToBase64(arr) vjcad 顶层 服务端上传前压缩
getLocalStorageService() vjcad 顶层 IndexedDB 服务实例
localService.getLocalSymbolCategories() / createLocalSymbolCategory(name) LocalStorageService 分类
localService.saveLocalSymbol({ categoryId, name, basePoint, thumbnail, vcadData }) LocalStorageService 保存
Engine.service.getSymbolCategories() / createSymbolCategory(name) service 服务端分类
Engine.service.createSymbol({ categoryId, name, basePoint, thumbnail, data }) service 服务端创建符号

红旗

  • buildSymbolVcadData(entities, clearSourceInfo) 第二参数是是否清除来源信息(非压缩);压缩是服务端路径单独用 compressSymbolData(vcadData, level) 完成,本地保存直接存 vcad 字符串
  • generateThumbnailFromEntities 是 async,必须 await
  • 服务端创建分类需要后台权限,匿名 / 只读账号会失败,需要 try/catch
  • 保存前的实体一定要 setDefaults(),否则色 / 图层信息丢失
  • 重名符号会创建多份,建议加时间戳后缀避免冲突

参考(官方文档 MCP)

  • 示例:
  • vjcad/example/insert/symbol/01createlocal.js — IndexedDB 本地符号
  • vjcad/example/insert/symbol/02createserver.js — 服务端符号