DrawMilitaryPlot.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. import MilitaryPlot from './/MilitaryPlot/drawingMethod/index.js'
  2. //编辑类
  3. import EntityEdit from './MilitaryPlot/EntityEdit.js';
  4. /* 引入属性编辑框 */
  5. import DialogEditProperty from './CrEditProperty_MilitaryPlot.ce.vue'
  6. /* 引入组件注册 */
  7. import {
  8. defineCustomElement
  9. } from 'vue'
  10. /**
  11. * 设置附加参数
  12. * @ignore 生成方法时不对外公开
  13. * @param {JSON} params 参数
  14. */
  15. Cesium.Entity.prototype.setParams = function(params) {
  16. this._params = params;
  17. }
  18. /**
  19. * 获取附加参数
  20. * @ignore 生成方法时不对外公开
  21. */
  22. Cesium.Entity.prototype.getParams = function() {
  23. return this._params;
  24. }
  25. /**
  26. * 设置实体是否可编辑
  27. * @ignore 生成方法时不对外公开
  28. * @param {Boolean} isEdit 是否可编辑
  29. */
  30. Cesium.Entity.prototype.setIsEdit = function(isEdit) {
  31. this._isEdit = isEdit;
  32. }
  33. /**
  34. * 获取实体是否可编辑
  35. * @ignore 生成方法时不对外公开
  36. * @return {Boolean} isEdit
  37. */
  38. Cesium.Entity.prototype.getIsEdit = function() {
  39. return this._isEdit;
  40. }
  41. /**
  42. * 军事标绘
  43. */
  44. class DrawMilitaryPlot {
  45. /**
  46. * 默认初始化
  47. * @param {Object} viewer 三维场景
  48. */
  49. constructor(options) {
  50. if (!options.viewer) throw new DeveloperError('no options.viewer object!');
  51. if (!options.Cesium) throw new DeveloperError('no options.Cesium object!');
  52. this._viewer = options.viewer;
  53. this.cesium = options.Cesium;
  54. this.drawArr = [];
  55. this.Draw = '';
  56. // 鼠标点击获取实体修改事件
  57. this.edit = new EntityEdit(this._viewer);
  58. this.edit.activate(); //激活编辑
  59. //获取得到实体 cesium回调机制
  60. this.edit.EditEndEntity.addEventListener((result) => {
  61. if (result.Type) {
  62. this.handleFirstPosition(result.Type);
  63. this.edit.DrawExample = this.Draw;
  64. }
  65. this._editEntity = result; //选中的实体
  66. })
  67. }
  68. /**
  69. * 静态方法 初始化并获取属性编辑参数
  70. */
  71. static initEditPropertyParams() {
  72. return {
  73. id: undefined, //用于标识及传递当前编辑的实体类型 内容为DrawTools.DrawType
  74. color: 'rgba(0,255,0,0.75)', //用于颜色标识
  75. outlineWidth: 0, //用于标识描边线宽度
  76. outlineColor: 'rgba(255,255,255,1)', //用于标识描边线颜色
  77. }
  78. }
  79. // 编辑时获取到实体时调用
  80. editActivate() {
  81. return this.edit
  82. }
  83. handleFirstPosition(type) {
  84. /* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
  85. this._viewer.scene.globe.depthTestAgainstTerrain = true;
  86. switch (type) {
  87. case "DrawStraightArrow":
  88. // 绘制直线箭头
  89. this.Draw = new MilitaryPlot.DrawStraightArrow({
  90. viewer: this._viewer,
  91. Cesium: this.cesium
  92. })
  93. break;
  94. case "DrawAttackArrow":
  95. // 绘制攻击箭头
  96. this.Draw = new MilitaryPlot.DrawAttackArrow({
  97. viewer: this._viewer,
  98. Cesium: this.cesium
  99. })
  100. break;
  101. case "DrawPincerArrow":
  102. //绘制钳击箭头
  103. this.Draw = new MilitaryPlot.DrawPincerArrow({
  104. viewer: this._viewer,
  105. Cesium: this.cesium
  106. })
  107. break;
  108. case "DrawGatheringPlace":
  109. this.Draw = new MilitaryPlot.DrawGatheringPlace({
  110. viewer: this._viewer,
  111. Cesium: this.cesium
  112. })
  113. break;
  114. case "DrawClosedCurve":
  115. this.Draw = new MilitaryPlot.DrawClosedCurve({
  116. viewer: this._viewer,
  117. Cesium: this.cesium
  118. })
  119. break;
  120. case "DrawSector":
  121. this.Draw = new MilitaryPlot.DrawSector({
  122. viewer: this._viewer,
  123. Cesium: this.cesium
  124. })
  125. break;
  126. case "DrawBowLine":
  127. this.Draw = new MilitaryPlot.DrawBowLine({
  128. viewer: this._viewer,
  129. Cesium: this.cesium
  130. })
  131. break;
  132. case "DrawBowPlane":
  133. this.Draw = new MilitaryPlot.DrawBowPlane({
  134. viewer: this._viewer,
  135. Cesium: this.cesium
  136. })
  137. break;
  138. case "DrawCurve":
  139. //绘制曲线
  140. this.Draw = new MilitaryPlot.DrawCurve({
  141. viewer: this._viewer,
  142. Cesium: this.cesium
  143. })
  144. break;
  145. case "DrawCurveFlag":
  146. //绘制曲线旗帜
  147. this.Draw = new MilitaryPlot.DrawCurveFlag({
  148. viewer: this._viewer,
  149. Cesium: this.cesium
  150. })
  151. break;
  152. case "DrawRectFlag":
  153. //绘制矩形直角旗帜
  154. this.Draw = new MilitaryPlot.DrawRectFlag({
  155. viewer: this._viewer,
  156. Cesium: this.cesium
  157. })
  158. break;
  159. case "DrawTriangleFlag":
  160. //绘制三角旗帜
  161. this.Draw = new MilitaryPlot.DrawTriangleFlag({
  162. viewer: this._viewer,
  163. Cesium: this.cesium
  164. })
  165. break;
  166. case "DrawPoint":
  167. //绘制点
  168. this.Draw = new MilitaryPlot.DrawPoint({
  169. viewer: this._viewer,
  170. Cesium: this.cesium
  171. })
  172. break;
  173. case "DrawPolyline":
  174. // 绘制线
  175. this.Draw = new MilitaryPlot.DrawPolyline({
  176. viewer: this._viewer,
  177. Cesium: this.cesium
  178. })
  179. break;
  180. case "DrawPolygon":
  181. // 多边形
  182. this.Draw = new MilitaryPlot.DrawPolygon({
  183. viewer: this._viewer,
  184. Cesium: this.cesium
  185. })
  186. break;
  187. case "DrawRectangle":
  188. // 绘制矩形
  189. this.Draw = new MilitaryPlot.DrawRectangle({
  190. viewer: this._viewer,
  191. Cesium: this.cesium
  192. })
  193. break;
  194. case "DrawCircle":
  195. //绘制圆
  196. this.Draw = new MilitaryPlot.DrawCircle({
  197. viewer: this._viewer,
  198. Cesium: this.cesium
  199. });
  200. break;
  201. }
  202. }
  203. // 加载数据
  204. addEntity(data) {
  205. this.handleFirstPosition(data.type);
  206. if (this.Draw) {
  207. let entity = this.Draw.addload(data.position);
  208. entity._id = data.id
  209. return entity
  210. }
  211. }
  212. }
  213. /**
  214. * 通用对外公开函数-鼠标事件
  215. */
  216. Object.assign(DrawMilitaryPlot.prototype, /** @lends DrawMilitaryPlot.prototype */ {
  217. /**
  218. * 设置鼠标为十字样式
  219. * @ignore 生成方法时不对外公开
  220. */
  221. _setMousePointerStyle() {
  222. document.querySelector('body').style.cursor = 'crosshair';
  223. },
  224. /**
  225. * 恢复鼠标指针为默认样式
  226. * @ignore 生成方法时不对外公开
  227. */
  228. _setMouseDefaultStyle() {
  229. document.querySelector('body').style.cursor = 'default';
  230. },
  231. /**
  232. * 注册鼠标左键点击事件
  233. * @ignore 生成方法时不对外公开
  234. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  235. * @param {Function} callChange 回调callChange(event)
  236. */
  237. _registerLeftClickEvent(handler, callChange) {
  238. let _self = this;
  239. if (!handler) return;
  240. handler.setInputAction(function(event) {
  241. /* 锁定点击事件 以免和移动事件冲突 */
  242. _self._lock = true;
  243. clearTimeout(_self._timer);
  244. _self._timer = setTimeout(function() {
  245. if (callChange) callChange(event);
  246. /* 解除锁定 */
  247. _self._lock = false;
  248. }, 200);
  249. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  250. },
  251. /**
  252. * 注册鼠标移动事件
  253. * @ignore 生成方法时不对外公开
  254. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  255. * @param {Function} callChange 回调callChange(event)
  256. */
  257. _registerMouseMoveEvent(handler, callChange) {
  258. let _self = this;
  259. if (!handler) return;
  260. handler.setInputAction(function(event) {
  261. if (_self._lock === undefined || _self._lock === false) {
  262. if (callChange) callChange(event);
  263. }
  264. }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  265. },
  266. /**
  267. * 注册鼠标左键按下事件
  268. * @ignore 生成方法时不对外公开
  269. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  270. * @param {Function} callChange 回调callChange(event)
  271. */
  272. _registerLeftDownEvent(handler, callChange) {
  273. if (!handler) return;
  274. handler.setInputAction(function(event) {
  275. if (callChange) callChange(event);
  276. }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
  277. },
  278. /**
  279. * 注册鼠标左键抬起事件
  280. * @ignore 生成方法时不对外公开
  281. * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
  282. * @param {Function} callChange 回调callChange(event)
  283. */
  284. _registerLeftUpEvent(handler, callChange) {
  285. if (!handler) return;
  286. handler.setInputAction(function(event) {
  287. if (callChange) callChange(event);
  288. }, Cesium.ScreenSpaceEventType.LEFT_UP);
  289. },
  290. /**
  291. * 清除事件
  292. * @ignore
  293. * @param {Cesium.ScreenSpaceEventHandler} handler
  294. */
  295. _clearEvent(handler) {
  296. if (!handler) return;
  297. /* 干掉事件句柄 释放资源 */
  298. handler.destroy();
  299. handler = null;
  300. }
  301. });
  302. /**
  303. * 属性编辑相关
  304. */
  305. Object.assign(DrawMilitaryPlot.prototype, {
  306. /**
  307. * 设置实体可编辑,编辑的实体必须包含编辑类型
  308. * @ignore 生成方法时不对外公开
  309. * @param {Cesium.Entity} entity 编辑的实体
  310. */
  311. _setEntityIsEdit(entity) {
  312. let _self = this;
  313. /* 关闭属性编辑框 */
  314. this._closePropertyEditDialog();
  315. /* 设置实体要素可编辑 */
  316. entity.setIsEdit(true);
  317. this.edit.handlePickEditEntity(entity);
  318. /* 激活编辑 并显示属性编辑框 */
  319. this._sendShowPropertyDialog(entity);
  320. /* 注册统一事件 用于单击拾取实体 */
  321. let handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
  322. this._registerLeftClickEvent(handler, function(event) {
  323. /* 只要点击 关闭属性编辑框 */
  324. _self._closePropertyEditDialog();
  325. let feature = _self._viewer.scene.pick(event.position);
  326. if (feature !== undefined && feature.id instanceof Cesium.Entity) {
  327. let editEntity = feature.id;
  328. if (
  329. editEntity.Type == 'DrawStraightArrow' ||
  330. editEntity.Type == 'DrawAttackArrow' ||
  331. editEntity.Type == 'DrawPincerArrow' ||
  332. editEntity.Type == 'DrawGatheringPlace' ||
  333. editEntity.Type == 'DrawClosedCurve' ||
  334. editEntity.Type == "DrawSector" ||
  335. editEntity.Type == "DrawBowLine" ||
  336. editEntity.Type == "DrawBowPlane" ||
  337. editEntity.Type == 'DrawCurve' ||
  338. editEntity.Type == 'DrawCurveFlag' ||
  339. editEntity.Type == 'DrawRectFlag' ||
  340. editEntity.Type == 'DrawTriangleFlag' ||
  341. editEntity.Type == 'DrawPoint' ||
  342. editEntity.Type == 'DrawPolyline' ||
  343. editEntity.Type == 'DrawPolygon' ||
  344. editEntity.Type == 'DrawRectangle' ||
  345. editEntity.Type == 'DrawCircle'
  346. ) {
  347. _self._sendShowPropertyDialog(feature.id);
  348. }
  349. }
  350. });
  351. },
  352. /**
  353. * 打开实体编辑对话框
  354. * @ignore 生成方法时不对外公开
  355. * @param {Cesium.Entity} entity
  356. */
  357. _sendShowPropertyDialog(entity) {
  358. let _self = this;
  359. /* 获取可编辑实体的类型 */
  360. let editEntityType = entity.Type;
  361. if (entity.getIsEdit() === undefined || entity.getIsEdit() === false || editEntityType === undefined) {
  362. /* 选择的实体不可编辑 */
  363. return;
  364. }
  365. /* 编辑属性 */
  366. let editProperty = entity.getParams();
  367. if (editProperty !== undefined && this.onEditProperty !== undefined) {
  368. editProperty.id = editEntityType;
  369. /* 更改测试 */
  370. _self._openPropertyEditDialog(editProperty,
  371. //编辑回调
  372. function(params) {
  373. _self.updateEditEntityProperty(params);
  374. },
  375. //移除回调
  376. function() {
  377. // _self.Draw.clear();
  378. _self._viewer.entities.remove(entity);
  379. _self.edit.clearAllEditVertex(); //禁用编辑
  380. }
  381. );
  382. }
  383. },
  384. /**
  385. * 更新当前编辑的实体属性
  386. * @param {JSON} params
  387. */
  388. updateEditEntityProperty: function(params) {
  389. let _self = this;
  390. if (this._editEntity === undefined) return;
  391. if (this._editEntity.getIsEdit() === undefined || this._editEntity.getIsEdit() === false) return;
  392. let editEntityType = this._editEntity.Type;
  393. if (editEntityType === undefined) return;
  394. let material = this._editEntity.polygon.material;
  395. if (material instanceof Cesium.ColorMaterialProperty) {
  396. let newMaterial = this._materialColorProperty({
  397. color: params.color,
  398. });
  399. this._editEntity.polygon.material = newMaterial;
  400. }
  401. if (this._editEntity.polyline !== undefined) {
  402. let newMaterial = this._materialColorProperty({
  403. color: params.outlineColor,
  404. });
  405. this._editEntity.polyline.material = newMaterial;
  406. this._editEntity.polyline.width = parseFloat(params.outlineWidth);
  407. }
  408. /* 重新关联墙实体的属性 */
  409. this._editEntity.setParams(params);
  410. },
  411. /**
  412. * 颜色材质
  413. * @ignore 生成方法时不对外公开
  414. * @param {JSON} options 配置项
  415. * @param {String} options.color 文字颜色 rgba(r,g,b,a)
  416. */
  417. _materialColorProperty(options) {
  418. let mColor = 'rgba(0,255,0,1)';
  419. if (options !== undefined && options.color !== undefined) mColor = options.color;
  420. /* 创建材质 */
  421. let colorMaterial = new Cesium.ColorMaterialProperty(Cesium.Color.fromCssColorString(mColor));
  422. colorMaterial._param = {
  423. color: mColor,
  424. }
  425. /* 返回材质 */
  426. return colorMaterial;
  427. }
  428. })
  429. /**
  430. * 通用对外公开函数
  431. */
  432. Object.assign(DrawMilitaryPlot.prototype, /** @lends DrawMilitaryPlot.prototype */ {
  433. /**
  434. * 开始绘制
  435. * @param {String} type 绘制类型 鼠标点击绘制时调用
  436. */
  437. drawActivate(type) {
  438. /* 设置鼠标样式为十字 */
  439. this._setMousePointerStyle();
  440. this.handleFirstPosition(type);
  441. this.Draw.startCreate(type)
  442. // 标绘完成返回数据
  443. this.Draw.DrawEndEvent.addEventListener((entity, positions, drawType) => {
  444. console.log({
  445. entity,
  446. positions,
  447. drawType
  448. });
  449. // 恢复鼠标指针为默认样式
  450. this._setMouseDefaultStyle();
  451. if (entity) {
  452. let entityParam = DrawMilitaryPlot.initEditPropertyParams();
  453. entity.setParams(entityParam);
  454. // 设置实体可编辑,编辑的实体必须包含编辑类型
  455. this._setEntityIsEdit(entity);
  456. }
  457. });
  458. this.drawArr.push(this.Draw);
  459. return this.Draw
  460. },
  461. /**
  462. * 删除选定图形
  463. */
  464. clearOne: function() {
  465. this.Draw.clear();
  466. // this.edit.deactivate(); //禁用编辑
  467. },
  468. /**
  469. * 删除所有图形
  470. */
  471. clearAll: function() {
  472. for (var i = 0; i < this.drawArr.length; i++) {
  473. this.drawArr[i].clear();
  474. }
  475. this.edit.deactivate(); //禁用编辑
  476. /* 关闭属性编辑框 */
  477. this._closePropertyEditDialog();
  478. /* 移除操作容器 */
  479. let buttonDiv = document.getElementById("drawButtonDiv");
  480. if (buttonDiv) {
  481. //从页面移除
  482. document.body.removeChild(buttonDiv);
  483. }
  484. },
  485. });
  486. /**
  487. * 属性编辑相关(UI)
  488. */
  489. Object.assign(DrawMilitaryPlot.prototype, {
  490. /**
  491. * 打开属性编辑窗口
  492. * @ignore
  493. * @param {JSON} params 参数
  494. * @param {Function} callEdit 编辑回调
  495. * @param {Function} callRemove 移除回调
  496. */
  497. _openPropertyEditDialog: function(params, callEdit, callRemove) {
  498. this._editPropertyDialogDomId = 'dialog-property-dom-militaryplot';
  499. this._registerDOMPropertyEdit = 'dialog-edit-property-militaryplot'
  500. /* 获取一个属性编辑组件 */
  501. let PropertyEditComponent = customElements.get(this._registerDOMPropertyEdit);
  502. /* 如果组件还未注册 则进行注册 否则不在注册 避免重复注册的BUG */
  503. if (PropertyEditComponent === undefined) {
  504. PropertyEditComponent = defineCustomElement(DialogEditProperty);
  505. customElements.define(this._registerDOMPropertyEdit, PropertyEditComponent);
  506. }
  507. /* 先关闭编辑框 */
  508. this._closePropertyEditDialog();
  509. /* 创建组件 */
  510. let dialogPropertyElement = new PropertyEditComponent({
  511. params: params,
  512. })
  513. dialogPropertyElement.id = this._editPropertyDialogDomId;
  514. dialogPropertyElement.showDialog = true;
  515. document.body.appendChild(dialogPropertyElement);
  516. /* 监听修改事件 */
  517. dialogPropertyElement.addEventListener(
  518. "submit",
  519. (e) => {
  520. if (callEdit) callEdit(e.detail[0]);
  521. },
  522. false
  523. );
  524. /* 监听移除事件 */
  525. dialogPropertyElement.addEventListener(
  526. "remove",
  527. (e) => {
  528. if (callRemove) callRemove();
  529. },
  530. false
  531. );
  532. },
  533. /**
  534. * 关闭属性编辑框
  535. * @ignore
  536. */
  537. _closePropertyEditDialog() {
  538. let dom = document.getElementById(this._editPropertyDialogDomId);
  539. if (dom !== null && dom !== undefined) {
  540. document.body.removeChild(dom);
  541. }
  542. },
  543. })
  544. export default DrawMilitaryPlot;