背景
在之前的博文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進行二次開發實現!