如何在前端通过JavaScript创建修改CAD图形
背景
在之前的博文CAD图DWG解析WebGIS可视化技术分析总结、CAD_DWG图Web可视化一站式解决方案-唯杰地图-vjmap中讲解了如何把CAD的DWG格式的图纸Web可视化的方案,那在Web前端能不能通过JavaScript创建或基于现在的CAD图形进行修改呢?
现状
创建修改CAD图形,一般是基于AutoCAD进行二次开发,ObjectARX是AutoDesk公司针对AutoCAD平台上的二次开发而推出的一个开发软件包,它提供了以C++为基础的面向对象的开发环境及应用程序接口,能真正快速的访问AutoCAD图形数据库。 与以往的 AutoCAD 二次开发工具 AutoLISP 和ADS不同,ObjectARX应用程序是一个DLL(动态链接库),共享AutoCAD的地址空间,对AutoCAD进行直接函数调用。所以,使用ARX编程的函数的执行速度得以大大提高。ARX 类库采用了标准的C++类库的封装形式,这也大大提高了程序员编程的可靠度和效率。
运用ObjectARX进行二次开发,必须首先设置好ObjectARX的开发环境。常用的开发环境是Microsoft Visual C++ 6.0 、Microsoft visual studio 2005、Microsoft visual studio 2008、Microsoft visual studio 2010。同时,还需要安装ObjectARX SDK。
Visual C++、ObjectARX等开发语言和环境肯定吓跑了不少开发者。那对于一些简单的场景
,如只要根据数据自动成图
或者在现在的图形上做一些很简单的修改
,有没有一个简单的办法或语言和开发环境?
JS新建修改CAD图形
唯杰地图在前端实现了常用的AutoCAD实体封装,能通过JavaScript脚本创建新的CAD图形。
支持的CAD实体类型
类名称 | 说明 |
---|---|
DbLine | 直线 |
DbCurve | 曲线 |
Db2dPolyline | 二维折线 |
Db3dPolyline | 三维多段线 |
DbPolyline | 多段线 |
BlockReference | 块参照 |
DbArc | 圆弧 |
DbCircle | 圆 |
DbEllipse | 椭圆 |
DbHatch | 填充 |
Text | 单行文本 |
DbMText | 多行文本 |
RasterImage | 栅格图片 |
DbShape | 型实体 |
Spline | 样条曲线 |
Wipeout | 遮罩实体 |
Dimension | 标注 |
Db2LineAngularDimension | 角度标注[两条线] |
Db3PointAngularDimension | 角度标注[三点] |
DbAlignedDimension | 对齐标注 |
DbArcDimension | 圆弧标注 |
DbDiametricDimension | 直径标注 |
DbOrdinateDimension | 坐标标注 |
DbRadialDimension | 半径标注 |
DbRadialDimensionLarge | 半径折线标注 |
DbRotatedDimension | 转角标注 |
DbLayer | 图层 |
DbTextStyle | 文字样式 |
DbDimStyle | 标注样式 |
DbLinetypeStyle | 线型样式 |
DbBlock | 块定义 |
DbDocument | 数据库文档 |
下面以新建一个篮球场示意图以例,相关代码如下:
(async () => {
// --新建地图--在后台新建CAD图,然后在前端打开
// js代码
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
let doc = new vjmap.DbDocument();
let entitys = [];
let line1 = new vjmap.DbLine();
line1.start = [0, 0]
line1.end = [0, 15]
entitys.push(line1)
let line2 = new vjmap.DbLine();
line2.start = [0, 14.1]
line2.end = [2.99, 14.1]
entitys.push(line2)
let line3 = new vjmap.DbLine();
line3.start = [0, 0.9]
line3.end = [2.99, 0.9]
entitys.push(line3)
let line4 = new vjmap.DbLine();
line4.start = [0, 9.95]
line4.end = [5.8, 9.95]
entitys.push(line4)
let line5 = new vjmap.DbLine();
line5.start = [0, 5.05]
line5.end = [5.8, 5.05]
let hatch = new vjmap.DbHatch();
hatch.pattern = "SOLID";
hatch.color = 0xB43F32;
hatch.points = [line4.start, line4.end, line5.end, line5.start];
entitys.push(hatch);
entitys.push(line4)
entitys.push(line5)
let line6 = new vjmap.DbLine();
line6.start = [5.8, 5.05]
line6.end = [5.8, 9.95]
entitys.push(line6)
let arc1 = new vjmap.DbArc();
arc1.center = [5.7963, 7.504];
arc1.radius = 1.8014;
arc1.startAngle = 270 * Math.PI / 180.0;
arc1.endAngle = 90 * Math.PI / 180.0;
entitys.push(arc1)
let arc2 = new vjmap.DbArc();
arc2.center = [5.7963, 7.504];
arc2.radius = 1.8014;
arc2.startAngle = 90 * Math.PI / 180.0;
arc2.endAngle = 270 * Math.PI / 180.0;
//arc2.linetype = "DASHED"
entitys.push(arc2)
let arc3 = new vjmap.DbArc();
arc3.center = [1.575, 7.5];
arc3.radius = 6.75;
arc3.startAngle = 282 * Math.PI / 180.0;
arc3.endAngle = 78 * Math.PI / 180.0;
entitys.push(arc3)
let block = new vjmap.DbBlock();
block.name = "ball";
block.origin = [0, 0]
block.entitys = entitys;
doc.appendBlock(block);
let blockRef1 = new vjmap.DbBlockReference();
blockRef1.blockname = "ball";
blockRef1.position = [0, 0];
doc.appendEntity(blockRef1);
let blockRef2 = new vjmap.DbBlockReference();
blockRef2.blockname = "ball";
blockRef2.position = [28, 15];
blockRef2.rotation = Math.PI;
doc.appendEntity(blockRef2);
let otherEnts = [
new vjmap.DbLine({
start: [0, 15],
end: [28, 15]
}),
new vjmap.DbLine({
start: [0, 0],
end: [28, 0]
}),
new vjmap.DbLine({
start: [14, 0],
end: [14, 15],
colorIndex: 1
}),
new vjmap.DbCircle({
center:[14, 7.5],
radius: 1.83,
color: 0xFF0000
}),
new vjmap.DbText({
position: [14, 16],
contents: "篮球场示意图",
colorIndex: 1,
horizontalMode: 4,
height: 1,
})
]
doc.appendEntity(otherEnts);
// js代码
let res = await svc.updateMap({
mapid: "basketballCourt",
filedoc: doc.toDoc(),
mapopenway: vjmap.MapOpenWay.Memory,
style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
message.error(res.error)
}
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
let prj = new vjmap.GeoProjection(mapExtent);
var map = new vjmap.Map({
container: 'map', // container ID
style: svc.rasterStyle(),
center: prj.toLngLat(mapExtent.center()),
zoom: 2,
renderWorldCopies: false
});
map.attach(svc, prj);
map.fitMapBounds();
map.addControl(new vjmap.NavigationControl());
map.addControl(new vjmap.MousePositionControl({showZoom: true}));
map.enableLayerClickHighlight(svc, e => {
e && message.info(`type: ${e.name}, objectid: ${e.objectid}, layer: ${e.layerindex}`);
})
})();
创建完后,Web显示如下:
把创建的DWG图形,在AutoCAD里面可以打开此图:
修改或删除
修改通过from
属性设置 来源于哪个图,会在此图的上面进行修改或新增删除,格式如 形式为 mapid/version,如 exam/v1 .
删除的话,指定图中实体的objectID
示例代码如下:
let doc = new vjmap.DbDocument();
/** 来源于哪个图,会在此图的上面进行修改或新增删除,格式如 形式为 mapid/version,如 exam/v1 . */
doc.from = "basketballCourt/v1";
// 修改或删除实体是通过传递 `objectid` 实体句柄,如果没有 `objectid` 则表示新增
let modifyEnts = [
/*修改*/
new vjmap.DbCircle({
objectid: "71",// 实体句柄,如传了实体句柄,是表示修改或删除此实体.
colorIndex: 2
}),
/*删除*/
new vjmap.DbText({
objectid: "73",// 实体句柄,如传了实体句柄,是表示修改或删除此实体.
delete: true // 表示删除
}),
/*新增(没有传 objectid )*/
new vjmap.DbMText({
position: [14, -2],
contents: "我是多行文本",
colorIndex: 3,
attachment: 2,
height: 1,
})
]
doc.appendEntity(modifyEnts);
// js代码
let res = await svc.updateMap({
mapid: "newBasketballCourt",
filedoc: doc.toDoc(),
mapopenway: vjmap.MapOpenWay.Memory,
style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
})
结果如下:
可以访问 demo地址 https://vjmap.com/guide/newmap.html 去体验下效果
应用场景
适用于在前端有数据,需要在线创建或基于现在CAD图形进行修改或删除;如可获取全国的GeoJson数据创建一个CAD图形;对于一些经常变化的数据如工程进度图纸根据进度数据实时绘制生成DWG图纸等场景;对于专业复杂的图形绘制或编辑工作,建议使用ObjectARX对AutoCAD进行二次开发实现!