Parcourir la source

军事标绘,没有轮廓线

DESKTOP-CRQ4N2U\jintian il y a 2 ans
Parent
commit
907ca9e3d1
21 fichiers modifiés avec 8057 ajouts et 391 suppressions
  1. 62 41
      src/jtMap3d/Widgets/DrawTools/CrEditProperty_MilitaryPlot.ce.vue
  2. 478 350
      src/jtMap3d/Widgets/DrawTools/DrawMilitaryPlot.js
  3. 672 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/EntityEdit.js
  4. 534 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawArc.js
  5. 574 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawAttackArrow.js
  6. 251 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawCircle.js
  7. 597 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawClosedCurve.js
  8. 510 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawCurve.js
  9. 463 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawCurveFlag.js
  10. 609 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawGatheringPlace.js
  11. 536 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawLune.js
  12. 656 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawPincerArrow.js
  13. 138 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawPoint.js
  14. 229 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawPolygon.js
  15. 223 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawPolyline.js
  16. 289 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawRectFlag.js
  17. 228 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawRectangle.js
  18. 327 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawSector.js
  19. 348 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawStraightArrow.js
  20. 286 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawTriangleFlag.js
  21. 47 0
      src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/index.js

+ 62 - 41
src/jtMap3d/Widgets/DrawTools/CrEditProperty_MilitaryPlot.ce.vue

@@ -9,15 +9,7 @@
 
 			<template #default>
 				<div class="odin-dialog__content">
-
-					<div class="jt-drawing-row" v-show="isShowLineWidth">
-						<div class="col-left">线宽</div>
-						<div class="col-main">
-							<el-input v-model="lineWidth" placeholder="输入宽度值" clearable />
-						</div>
-					</div>
-
-					<div class="jt-drawing-row" v-show="isShowColor">
+					<div class="jt-drawing-row">
 						<div class="col-left">颜色</div>
 						<div class="col-main">
 							<el-config-provider :locale="locale">
@@ -25,22 +17,26 @@
 							</el-config-provider>
 						</div>
 					</div>
-
-
-					<div class="jt-drawing-row" v-show="isShowOutlineWidth">
+					<!-- <div class="jt-drawing-row">
+						<div class="col-left">是否边框</div>
+						<div class="col-main">
+							<el-switch v-model="isShowOutline" />
+						</div>
+					</div>
+					<div class="jt-drawing-row" v-show="isShowOutline">
 						<div class="col-left">描边宽度</div>
 						<div class="col-main">
-							<el-input v-model="outlineWidth" placeholder="输入宽度值" clearable />
+							<el-input-number v-model="outlineWidth" :min="0" :max="100" />
 						</div>
 					</div>
-					<div class="jt-drawing-row" v-show="isShowOutlineColor">
+					<div class="jt-drawing-row" v-show="isShowOutline">
 						<div class="col-left">描边颜色</div>
 						<div class="col-main">
 							<el-config-provider :locale="locale">
 								<el-color-picker v-model="outlineColor" show-alpha :predefine="predefineColors" label="12" />
 							</el-config-provider>
 						</div>
-					</div>
+					</div> -->
 
 
 					<div class="el-body-foot">
@@ -74,13 +70,19 @@
 	import {
 		ElDialog,
 		ElInput,
+		ElSelect,
+		ElOption,
+		ElSwitch,
 		ElButtonGroup,
 		ElConfigProvider,
 		ElColorPicker,
 		ElRadioButton,
 		ElButton,
 		ElRadioGroup,
-		ElInputNumber
+		ElInputNumber,
+		ElCollapse,
+		ElCollapseItem,
+		ElIcon
 	} from 'element-plus';
 
 	/* 引入element-plus字体 */
@@ -117,10 +119,6 @@
 				type: String,
 				default: () => '255,255,0,0.9'
 			},
-			lineWidth: {
-				type: Number,
-				default: () => 2
-			},
 			outlineWidth: {
 				type: Number,
 				default: () => 0
@@ -159,14 +157,10 @@
 	/* 初始赋值 */
 	const title = ref('属性编辑');
 	const dialogVisible = ref(props.showDialog);
+	const isShowOutline = ref(false);
 
-	const isShowColor = ref(false);
-	const isShowLineWidth = ref(false);
-	const isShowOutlineWidth = ref(false);
-	const isShowOutlineColor = ref(false);
 
 	const color = ref(props.params.color);
-	const lineWidth = ref(0);
 	const outlineWidth = ref(0);
 	const outlineColor = ref(props.params.outlineColor);
 
@@ -180,23 +174,52 @@
 	function updateParams(params) {
 		/* 保存到本地 */
 		proxy._params = params;
-		_setShowControls(false);
+		// _setShowControls(false);
+
 		/* 根据参数的显示不同的内容 */
-		if (params.id === DrawMilitaryPlot.DrawType.StraightArrow) {
-			title.value = '直线箭头标绘';
-			isShowColor.value = true;
-		} else if (params.id === DrawMilitaryPlot.DrawType.AttackArrow) {
-			title.value = '攻击箭头编辑';
-			isShowColor.value = true;
-		} else if (params.id === DrawMilitaryPlot.DrawType.PincerArrow) {
-			title.value = '钳击箭头编辑';
-			isShowColor.value = true;
-		} else {
-			_setShowControls(false);
+		switch (params.id) {
+			case "DrawStraightArrow":
+				title.value = '绘制直线箭头';
+				break;
+			case "DrawAttackArrow":
+				title.value = '绘制攻击箭头';
+				break;
+			case "DrawPincerArrow":
+				title.value = '绘制钳击箭头';
+				break;
+			case "DrawGatheringPlace":
+				title.value = '绘制集结地';
+				break;
+			case "DrawClosedCurve":
+				title.value = '绘制闭合曲面';
+				break;
+			case "DrawSector":
+				title.value = '绘制扇形';
+				break;
+
+			case "DrawArc":
+				title.value = '绘制弓形';
+				break;
+			case "DrawLune":
+				title.value = '绘制弓形面';
+				break;
+
+			case "DrawCurve":
+				title.value = '绘制曲线';
+				break;
+			case "DrawCurveFlag":
+				title.value = '绘制曲线旗帜';
+				break;
+			case "DrawRectFlag":
+				title.value = '绘制矩形直角旗帜';
+				break;
+			case "DrawTriangleFlag":
+				title.value = '绘制三角旗帜';
+				break;
+
 		}
 
 		color.value = params.color;
-		lineWidth.value = params.lineWidth;
 		outlineColor.value = params.outlineColor;
 		outlineWidth.value = params.outlineWidth;
 	}
@@ -206,8 +229,7 @@
 	 * @param {Boolean} isShow 是否显示
 	 */
 	function _setShowControls(isShow) {
-		isShowColor.value = isShow;	
-		isShowLineWidth.value = isShow;
+		isShowColor.value = isShow;
 		isShowOutlineColor.value = isShow;
 		isShowOutlineWidth.value = isShow;
 	}
@@ -225,7 +247,6 @@
 	function submit() {
 		let outParam = proxy._params;
 		outParam.color = color.value;
-		outParam.lineWidth = lineWidth.value;
 		outParam.outlineColor = outlineColor.value;
 		outParam.outlineWidth = outlineWidth.value;
 		emit('submit', outParam);

+ 478 - 350
src/jtMap3d/Widgets/DrawTools/DrawMilitaryPlot.js

@@ -1,17 +1,52 @@
-import {
-	StraightArrow,
-	AttackArrow,
-	PincerArrow
-} from "./drawArrow/arrowClass.js";
+import MilitaryPlot from './/MilitaryPlot/drawingMethod/index.js'
+
+//编辑类
+import EntityEdit from './MilitaryPlot/EntityEdit.js';
 
 /* 引入属性编辑框 */
-import DialogEditProperty from './CrEditProperty.ce.vue'
+import DialogEditProperty from './CrEditProperty_MilitaryPlot.ce.vue'
 /* 引入组件注册 */
 import {
 	defineCustomElement
 } from 'vue'
 
 /**
+ * 设置附加参数
+ * @ignore 生成方法时不对外公开
+ * @param {JSON} params 参数
+ */
+Cesium.Entity.prototype.setParams = function(params) {
+	this._params = params;
+}
+
+/**
+ * 获取附加参数
+ * @ignore 生成方法时不对外公开
+ */
+Cesium.Entity.prototype.getParams = function() {
+	return this._params;
+}
+
+
+/**
+ * 设置实体是否可编辑
+ * @ignore 生成方法时不对外公开
+ * @param {Boolean} isEdit 是否可编辑
+ */
+Cesium.Entity.prototype.setIsEdit = function(isEdit) {
+	this._isEdit = isEdit;
+}
+
+/**
+ * 获取实体是否可编辑
+ * @ignore 生成方法时不对外公开
+ * @return {Boolean} isEdit
+ */
+Cesium.Entity.prototype.getIsEdit = function() {
+	return this._isEdit;
+}
+
+/**
  * 军事标绘
  */
 class DrawMilitaryPlot {
@@ -19,108 +54,421 @@ class DrawMilitaryPlot {
 	 * 默认初始化
 	 * @param {Object} viewer 三维场景
 	 */
-	constructor(viewer) {
-		if (!viewer) throw new DeveloperError('no viewer object!');
-		this.viewer = viewer;
-		this.isActivate = false;
+	constructor(options) {
+		if (!options.viewer) throw new DeveloperError('no options.viewer object!');
+		if (!options.Cesium) throw new DeveloperError('no options.Cesium object!');
+
+		this._viewer = options.viewer;
+		this.cesium = options.Cesium;
+
 		this.drawArr = [];
-		this.handler = null;
-		this.nowArrowObj = null;
-		this.init();
+		this.Draw = '';
+		// 鼠标点击获取实体修改事件
+		this.edit = new EntityEdit(this._viewer);
+		this.edit.activate(); //激活编辑
+		//获取得到实体 cesium回调机制
+		this.edit.EditEndEntity.addEventListener((result) => {
+			if (result.Type) {
+				this.handleFirstPosition(result.Type);
+				this.edit.DrawExample = this.Draw;
+			}
+			this._editEntity = result; //选中的实体
+		})
 	}
 
-	init() {
-		if (!this.isActivate) {
-			this.isActivate = true;
-			this.bindEdit();
+	/**
+	 * 静态方法 初始化并获取属性编辑参数
+	 */
+	static initEditPropertyParams() {
+		return {
+			id: undefined, //用于标识及传递当前编辑的实体类型 内容为DrawTools.DrawType
+			color: 'rgba(0,255,0,0.75)', //用于颜色标识
+			outlineWidth: 0, //用于标识描边线宽度
+			outlineColor: 'rgba(255,255,255,1)', //用于标识描边线颜色
 		}
+	}
 
-		this._closePropertyEditDialog();
+	// 编辑时获取到实体时调用
+	editActivate() {
+		return this.edit
 	}
 
+	handleFirstPosition(type) {
+		/* 开启地形检测 必须开启 否则会导致获取地形高度时异常 导致鼠标移动时位置哆嗦 */
+		this._viewer.scene.globe.depthTestAgainstTerrain = true;
+		
+		switch (type) {
+			case "DrawStraightArrow":
+				// 绘制直线箭头
+				this.Draw = new MilitaryPlot.DrawStraightArrow({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawAttackArrow":
+				// 绘制攻击箭头
+				this.Draw = new MilitaryPlot.DrawAttackArrow({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawPincerArrow":
+				//绘制钳击箭头
+				this.Draw = new MilitaryPlot.DrawPincerArrow({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawGatheringPlace":
+				this.Draw = new MilitaryPlot.DrawGatheringPlace({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawClosedCurve":
+				this.Draw = new MilitaryPlot.DrawClosedCurve({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawSector":
+				this.Draw = new MilitaryPlot.DrawSector({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawArc":
+				this.Draw = new MilitaryPlot.DrawArc({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawLune":
+				this.Draw = new MilitaryPlot.DrawLune({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawCurve":
+				//绘制曲线
+				this.Draw = new MilitaryPlot.DrawCurve({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawCurveFlag":
+				//绘制曲线旗帜
+				this.Draw = new MilitaryPlot.DrawCurveFlag({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawRectFlag":
+				//绘制矩形直角旗帜
+				this.Draw = new MilitaryPlot.DrawRectFlag({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawTriangleFlag":
+				//绘制三角旗帜
+				this.Draw = new MilitaryPlot.DrawTriangleFlag({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+
+			case "DrawPoint":
+				//绘制点
+				this.Draw = new MilitaryPlot.DrawPoint({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawPolyline":
+				// 绘制线
+				this.Draw = new MilitaryPlot.DrawPolyline({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawPolygon":
+				// 多边形
+				this.Draw = new MilitaryPlot.DrawPolygon({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawRectangle":
+				// 绘制矩形
+				this.Draw = new MilitaryPlot.DrawRectangle({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				})
+				break;
+			case "DrawCircle":
+				//绘制圆
+				this.Draw = new MilitaryPlot.DrawCircle({
+					viewer: this._viewer,
+					Cesium: this.cesium
+				});
+				break;
+		}
+	}
+
+	// 加载数据
+	addEntity(data) {
+		this.handleFirstPosition(data.type);
+		if (this.Draw) {
+			let entity = this.Draw.addload(data.position);
+			entity._id = data.id
+			return entity
+		}
+	}
+}
+
+/**
+ * 通用对外公开函数-鼠标事件 
+ */
+Object.assign(DrawMilitaryPlot.prototype, /** @lends DrawMilitaryPlot.prototype */ {
 	/**
-	 * 编辑事件
+	 * 设置鼠标为十字样式
+	 * @ignore 生成方法时不对外公开
+	 */
+	_setMousePointerStyle() {
+		document.querySelector('body').style.cursor = 'crosshair';
+	},
+
+	/**
+	 * 恢复鼠标指针为默认样式
+	 * @ignore 生成方法时不对外公开
+	 */
+	_setMouseDefaultStyle() {
+		document.querySelector('body').style.cursor = 'default';
+	},
+
+	/**
+	 * 注册鼠标左键点击事件
+	 * @ignore 生成方法时不对外公开
+	 * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
+	 * @param {Function} callChange 回调callChange(event)
+	 */
+	_registerLeftClickEvent(handler, callChange) {
+		let _self = this;
+		if (!handler) return;
+
+		handler.setInputAction(function(event) {
+			/* 锁定点击事件 以免和移动事件冲突 */
+			_self._lock = true;
+			clearTimeout(_self._timer);
+			_self._timer = setTimeout(function() {
+				if (callChange) callChange(event);
+				/* 解除锁定 */
+				_self._lock = false;
+			}, 200);
+		}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+	},
+
+	/**
+	 * 注册鼠标移动事件
+	 * @ignore 生成方法时不对外公开
+	 * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
+	 * @param {Function} callChange 回调callChange(event)
+	 */
+	_registerMouseMoveEvent(handler, callChange) {
+		let _self = this;
+		if (!handler) return;
+
+		handler.setInputAction(function(event) {
+			if (_self._lock === undefined || _self._lock === false) {
+				if (callChange) callChange(event);
+			}
+		}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+	},
+
+	/**
+	 * 注册鼠标左键按下事件
+	 * @ignore 生成方法时不对外公开
+	 * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
+	 * @param {Function} callChange 回调callChange(event)
+	 */
+	_registerLeftDownEvent(handler, callChange) {
+		if (!handler) return;
+		handler.setInputAction(function(event) {
+			if (callChange) callChange(event);
+		}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+	},
+
+	/**
+	 * 注册鼠标左键抬起事件
+	 * @ignore 生成方法时不对外公开
+	 * @param {Cesium.ScreenSpaceEventHandler} handler 事件句柄
+	 * @param {Function} callChange 回调callChange(event)
+	 */
+	_registerLeftUpEvent(handler, callChange) {
+		if (!handler) return;
+		handler.setInputAction(function(event) {
+			if (callChange) callChange(event);
+		}, Cesium.ScreenSpaceEventType.LEFT_UP);
+	},
+
+	/**
+	 * 清除事件
 	 * @ignore
+	 * @param {Cesium.ScreenSpaceEventHandler} handler
 	 */
-	bindEdit() {
-		var _self = this;
-		this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
-		this.handler.setInputAction(function(evt) { //单机开始绘制
+	_clearEvent(handler) {
+		if (!handler) return;
+
+		/* 干掉事件句柄 释放资源 */
+		handler.destroy();
+		handler = null;
+	}
+
+});
+
+/**
+ * 属性编辑相关
+ */
+Object.assign(DrawMilitaryPlot.prototype, {
+
+	/**
+	 * 设置实体可编辑,编辑的实体必须包含编辑类型
+	 * @ignore 生成方法时不对外公开
+	 * @param {Cesium.Entity} entity 编辑的实体
+	 */
+	_setEntityIsEdit(entity) {
+		let _self = this;
+
+		/* 关闭属性编辑框 */
+		this._closePropertyEditDialog();
+
+		/* 设置实体要素可编辑 */
+		entity.setIsEdit(true);
+		this.edit.handlePickEditEntity(entity);
+
+		/* 激活编辑 并显示属性编辑框 */
+		this._sendShowPropertyDialog(entity);
+
+		/* 注册统一事件 用于单击拾取实体 */
+		let handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
+		this._registerLeftClickEvent(handler, function(event) {
+			/* 只要点击 关闭属性编辑框 */
 			_self._closePropertyEditDialog();
-			if (_self.nowArrowObj) {
-				// _self.nowArrowObj.disableHandler();
-				// _self.nowArrowObj.floatPoint.show = false;
-				
-				if (_self.nowArrowObj.firstPoint) {
-					_self.nowArrowObj.firstPoint.show = false;
-				}
-				if (_self.nowArrowObj.floatPoint) {
-					_self.nowArrowObj.floatPoint.show = false;
-				}
-				if (_self.nowArrowObj.pointArr) {
-					for (var i = 0; i < _self.nowArrowObj.pointArr.length; i++) {
-						_self.nowArrowObj.pointArr[i].show = false;
-					}
+
+			let feature = _self._viewer.scene.pick(event.position);
+			if (feature !== undefined && feature.id instanceof Cesium.Entity) {
+				let editEntity = feature.id;
+				if (
+					editEntity.Type == 'DrawStraightArrow' ||
+					editEntity.Type == 'DrawAttackArrow' ||
+					editEntity.Type == 'DrawPincerArrow' ||
+					editEntity.Type == 'DrawGatheringPlace' ||
+					editEntity.Type == 'DrawClosedCurve' ||
+					editEntity.Type == "DrawSector" ||
+					editEntity.Type == "DrawArc" ||
+					editEntity.Type == "DrawLune" ||
+					editEntity.Type == 'DrawCurve' ||
+					editEntity.Type == 'DrawCurveFlag' ||
+					editEntity.Type == 'DrawRectFlag' ||
+					editEntity.Type == 'DrawTriangleFlag' ||
+
+					editEntity.Type == 'DrawPoint' ||
+					editEntity.Type == 'DrawPolyline' ||
+					editEntity.Type == 'DrawPolygon' ||
+					editEntity.Type == 'DrawRectangle' ||
+					editEntity.Type == 'DrawCircle'
+				) {
+					_self._sendShowPropertyDialog(feature.id);
 				}
 			}
-			var pick = _self.viewer.scene.pick(evt.position);
-			if (Cesium.defined(pick) && pick.id) {
-
-				for (var i = 0; i < _self.drawArr.length; i++) {
-
-					if (pick.id.objId == _self.drawArr[i].objId) {
-						_self.nowArrowObj = _self.drawArr[i];
-						//图形修改
-						_self.nowArrowObj.startModify({
-							onComplete: function(pickObjId) {
-
-								for (var i = 0; i < _self.drawArr.length; i++) {
-									_self.drawArr[i].disableHandler();
-
-									if (pickObjId == _self.drawArr[i].objId) {
-
-										_self.nowArrowObj = _self.drawArr[i];
-										//图形修改
-										_self.nowArrowObj.startModify({
-											onComplete: function(pickObjId) {
-												var editProperty = _self.nowArrowObj._param;
-												if (editProperty !== undefined && _self.onEditProperty !== undefined) {
-													// _self.onEditProperty(editProperty);
-
-													/* 更改测试 */
-													_self._openPropertyEditDialog(editProperty, function(params) {
-														_self.updateEditEntityProperty(params);
-													}, function() {
-														_self.clearOne();
-													});
-												}
-											}
-										});
-									}
-								}
-							}
-						});
-
-						//监听编辑属性
-						var editProperty = _self.nowArrowObj._param;
-						if (editProperty !== undefined && _self.onEditProperty !== undefined) {
-							// _self.onEditProperty(editProperty);
-
-							/* 更改测试 */
-							_self._openPropertyEditDialog(editProperty, function(params) {
-								_self.updateEditEntityProperty(params);
-							}, function() {
-								_self.clearOne();
-							});
-						}
-
-						break;
-					}
+		});
+	},
+
+	/**
+	 * 打开实体编辑对话框
+	 * @ignore 生成方法时不对外公开
+	 * @param {Cesium.Entity} entity
+	 */
+	_sendShowPropertyDialog(entity) {
+
+		let _self = this;
+		/* 获取可编辑实体的类型 */
+		let editEntityType = entity.Type;
+		if (entity.getIsEdit() === undefined || entity.getIsEdit() === false || editEntityType === undefined) {
+			/* 选择的实体不可编辑 */
+			return;
+		}
+
+		/* 编辑属性 */
+		let editProperty = entity.getParams();
+		if (editProperty !== undefined && this.onEditProperty !== undefined) {
+			editProperty.id = editEntityType;
+
+			/* 更改测试 */
+			_self._openPropertyEditDialog(editProperty,
+				//编辑回调
+				function(params) {
+					_self.updateEditEntityProperty(params);
+				},
+				//移除回调
+				function() {
+					// _self.Draw.clear();
+					_self._viewer.entities.remove(entity);
+					_self.edit.clearAllEditVertex(); //禁用编辑
 				}
-			}
-		}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+			);
+		}
+	},
+	
+	/**
+	 * 更新当前编辑的实体属性
+	 * @param {JSON} params
+	 */
+	updateEditEntityProperty: function(params) {
+		let _self = this;
+		
+		if (this._editEntity === undefined) return;
+		if (this._editEntity.getIsEdit() === undefined || this._editEntity.getIsEdit() === false) return;
+		let editEntityType = this._editEntity.Type;
+		if (editEntityType === undefined) return;
+		
+		let material = this._editEntity.polygon.material;
+		if (material instanceof Cesium.ColorMaterialProperty) {
+			let newMaterial = this._materialColorProperty({
+				color: params.color,
+			});
+			this._editEntity.polygon.material = newMaterial;
+		}
+		if (this._editEntity.polyline !== undefined) {
+			let newMaterial = this._materialColorProperty({
+				color: params.outlineColor,
+			});
+			this._editEntity.polyline.material = newMaterial;
+			this._editEntity.polyline.width = parseFloat(params.outlineWidth);
+		}
+		/* 重新关联墙实体的属性 */
+		this._editEntity.setParams(params);
+	},
+	
+	/**
+	 * 颜色材质
+	 * @ignore 生成方法时不对外公开
+	 * @param {JSON} options 配置项
+	 * @param {String} options.color 文字颜色 rgba(r,g,b,a)
+	 */
+	_materialColorProperty(options) {
+		let mColor = 'rgba(0,255,0,1)';
+		if (options !== undefined && options.color !== undefined) mColor = options.color;
+		/* 创建材质 */
+		let colorMaterial = new Cesium.ColorMaterialProperty(Cesium.Color.fromCssColorString(mColor));
+		colorMaterial._param = {
+			color: mColor,
+		}
+		/* 返回材质 */
+		return colorMaterial;
 	}
-}
+})
 
 /**
  * 通用对外公开函数 
@@ -129,208 +477,60 @@ Object.assign(DrawMilitaryPlot.prototype, /** @lends DrawMilitaryPlot.prototype
 
 	/**
 	 * 开始绘制
-	 * @param {String} type 绘制类型
-	 * @param {Object} options 
-	 * @param {String} [options.polygonColor] 面填充颜色
-	 * @param {Function} [options.onComplete(points)] 完成回调 可选
+	 * @param {String} type 绘制类型 鼠标点击绘制时调用
 	 */
-	draw: function(type, options) {
-		let _self = this;
+	drawActivate(type) {
+		/* 设置鼠标样式为十字 */
+		this._setMousePointerStyle();
 
-		for (var i = 0; i < this.drawArr.length; i++) {
-			this.drawArr[i].disableHandler();
-		}
+		this.handleFirstPosition(type);
+		this.Draw.startCreate(type)
 
-		switch (type) {
-			case DrawMilitaryPlot.DrawType.StraightArrow: //直箭头
-				var straightArrow = new StraightArrow(this.viewer, options);
-				straightArrow.startDraw({
-					onComplete: function(catesian3, Latlng) {
-
-						//绘制完成后,启用图形修改
-						straightArrow.startModify({
-							onComplete: function(pickObjId) {
-								for (var i = 0; i < _self.drawArr.length; i++) {
-									_self.drawArr[i].disableHandler();
-									if (pickObjId == _self.drawArr[i].objId) {
-										_self.nowArrowObj = _self.drawArr[i];
-										//图形修改
-										_self.nowArrowObj.startModify({
-											onComplete: function(pickObjId) {
-												var editProperty = _self.nowArrowObj._param;
-												if (editProperty !== undefined && _self.onEditProperty !== undefined) {
-													// _self.onEditProperty(editProperty);
-
-													/* 更改测试 */
-													_self._openPropertyEditDialog(editProperty, function(params) {
-														_self.updateEditEntityProperty(params);
-													}, function() {
-														_self.clearOne();
-													});
-												}
-											}
-										});
-									}
-								}
-							}
-						});
-
-						var editProperty = _self.nowArrowObj._param;
-						if (editProperty !== undefined && _self.onEditProperty !== undefined) {
-							// _self.onEditProperty(editProperty);
-
-							/* 更改测试 */
-							_self._openPropertyEditDialog(editProperty, function(params) {
-								_self.updateEditEntityProperty(params);
-							}, function() {
-								_self.clearOne();
-							});
-						}
-
-						/* 返回坐标 */
-						if (options.onComplete) options.onComplete(catesian3, Latlng);
-					}
-				});
-				this.nowArrowObj = straightArrow;
-				this.drawArr.push(straightArrow);
-				break;
-			case DrawMilitaryPlot.DrawType.AttackArrow: //攻击箭头
-				var attackArrow = new AttackArrow(this.viewer, options);
-				attackArrow.startDraw({
-					onComplete: function(catesian3, Latlng) {
-						//图形修改
-						attackArrow.startModify({
-							onComplete: function(pickObjId) {
-								for (var i = 0; i < _self.drawArr.length; i++) {
-									_self.drawArr[i].disableHandler();
-									if (pickObjId == _self.drawArr[i].objId) {
-										_self.nowArrowObj = _self.drawArr[i];
-										//图形修改
-										_self.nowArrowObj.startModify({
-											onComplete: function(pickObjId) {
-												var editProperty = _self.nowArrowObj._param;
-												if (editProperty !== undefined && _self.onEditProperty !== undefined) {
-													// _self.onEditProperty(editProperty);
-
-													/* 更改测试 */
-													_self._openPropertyEditDialog(editProperty, function(params) {
-														_self.updateEditEntityProperty(params);
-													}, function() {
-														_self.clearOne();
-													});
-												}
-											}
-										});
-									}
-								}
-							}
-						});
-
-						var editProperty = _self.nowArrowObj._param;
-						if (editProperty !== undefined && _self.onEditProperty !== undefined) {
-							// _self.onEditProperty(editProperty);
-
-							/* 更改测试 */
-							_self._openPropertyEditDialog(editProperty, function(params) {
-								_self.updateEditEntityProperty(params);
-							}, function() {
-								_self.clearOne();
-							});
-						}
-
-						/* 返回坐标 */
-						if (options.onComplete) options.onComplete(catesian3, Latlng);
-					}
-				});
-				this.nowArrowObj = attackArrow;
-				this.drawArr.push(attackArrow);
-				break;
-			case DrawMilitaryPlot.DrawType.PincerArrow: //钳击箭头
-				var pincerArrow = new PincerArrow(this.viewer, options);
-				pincerArrow.startDraw({
-					onComplete: function(catesian3, Latlng) {
-						//图形修改
-						pincerArrow.startModify({
-							onComplete: function(pickObjId) {
-								for (var i = 0; i < _self.drawArr.length; i++) {
-									_self.drawArr[i].disableHandler();
-									if (pickObjId == _self.drawArr[i].objId) {
-										_self.nowArrowObj = _self.drawArr[i];
-										//图形修改
-										_self.nowArrowObj.startModify({
-											onComplete: function(pickObjId) {
-												var editProperty = _self.nowArrowObj._param;
-												if (editProperty !== undefined && _self.onEditProperty !== undefined) {
-													// _self.onEditProperty(editProperty);
-
-													/* 更改测试 */
-													_self._openPropertyEditDialog(editProperty, function(params) {
-														_self.updateEditEntityProperty(params);
-													}, function() {
-														_self.clearOne();
-													});
-												}
-											}
-										});
-									}
-								}
-							}
-						});
-
-						var editProperty = _self.nowArrowObj._param;
-						if (editProperty !== undefined && _self.onEditProperty !== undefined) {
-							// _self.onEditProperty(editProperty);
-
-							/* 更改测试 */
-							_self._openPropertyEditDialog(editProperty, function(params) {
-
-								_self.updateEditEntityProperty(params);
-							}, function() {
-								_self.clearOne();
-							});
-						}
-
-						/* 返回坐标 */
-						if (options.onComplete) options.onComplete(catesian3, Latlng);
-					}
-				});
-				this.nowArrowObj = pincerArrow;
-				this.drawArr.push(pincerArrow);
-			default:
-				break;
-		}
-	},
+		// 标绘完成返回数据
+		this.Draw.DrawEndEvent.addEventListener((entity, positions, drawType) => {
+			console.log({
+				entity,
+				positions,
+				drawType
+			});
 
-	/**
-	 * 编辑属性
-	 * @param {Object} params
-	 */
-	updateEditEntityProperty(params) {
-		params.polygonColor = params.color;
-		this.nowArrowObj._updatePolygonProperty(params); //编辑属性
+			// 恢复鼠标指针为默认样式
+			this._setMouseDefaultStyle();
+
+			if (entity) {
+
+
+				let entityParam = DrawMilitaryPlot.initEditPropertyParams();
+				entity.setParams(entityParam);
+
+				// 设置实体可编辑,编辑的实体必须包含编辑类型
+				this._setEntityIsEdit(entity);
+			}
+		});
+
+		this.drawArr.push(this.Draw);
+
+		return this.Draw
 	},
 
 	/**
 	 * 删除选定图形
 	 */
 	clearOne: function() {
-		var $this = this;
-		$this.nowArrowObjID = $this.nowArrowObj.objId
-		for (var i = 0; i < $this.drawArr.length; i++) {
-			if ($this.nowArrowObjID == $this.drawArr[i].objId) {
-				$this.drawArr[i].clear();
-				$this.drawArr.splice(i, 1);
-			}
-		}
+
+		this.Draw.clear();
+		// this.edit.deactivate(); //禁用编辑
 	},
 
 	/**
 	 * 删除所有图形
 	 */
 	clearAll: function() {
+
 		for (var i = 0; i < this.drawArr.length; i++) {
 			this.drawArr[i].clear();
 		}
+		this.edit.deactivate(); //禁用编辑
 
 		/* 关闭属性编辑框 */
 		this._closePropertyEditDialog();
@@ -341,68 +541,6 @@ Object.assign(DrawMilitaryPlot.prototype, /** @lends DrawMilitaryPlot.prototype
 			document.body.removeChild(buttonDiv);
 		}
 	},
-
-	/**
-	 * 保存绘图坐标
-	 */
-	saveData: function() { //保存用户数据
-
-		return new Promise((resolve, reject) => {
-			var jsonData = {
-				straightArrowData: [],
-				attackArrowData: [],
-				pincerArrowData: []
-			}
-			for (var step = 0; step < this.drawArr.length; step++) {
-				var item = this.drawArr[step];
-				var positions = item.getLnglats();
-				if (item.type == "StraightArrow") {
-					jsonData.straightArrowData.push(positions);
-				} else if (item.type == "AttackArrow") {
-					jsonData.attackArrowData.push(positions);
-				} else {
-					jsonData.pincerArrowData.push(positions);
-				}
-			}
-			// console.log("保存的数据:" + JSON.stringify(jsonData));
-
-			resolve(jsonData);
-		});
-	},
-
-	/**
-	 * 根据已知数据进行展示
-	 * @param {Object} jsonData
-	 */
-	showData: function(jsonData) { //展示用户保存的数据
-		if (!jsonData) return;
-		var straightArrowArr = jsonData.straightArrowData;
-		var attackArrowArr = jsonData.attackArrowData;
-		var pincerArrowArr = jsonData.pincerArrowData;
-		//展示直线箭头
-		for (var i = 0; i < straightArrowArr.length; i++) {
-			var item = straightArrowArr[i];
-			var straightArrow = new StraightArrow(viewer);
-			straightArrow.createByData(item);
-			this.drawArr.push(straightArrow);
-		}
-
-		//展示攻击箭头
-		for (var j = 0; j < attackArrowArr.length; j++) {
-			var item = attackArrowArr[j];
-			var attackArrow = new AttackArrow(viewer);
-			attackArrow.createByData(item);
-			this.drawArr.push(attackArrow);
-		}
-		//展示钳击箭头
-		for (var z = 0; z < pincerArrowArr.length; z++) {
-			var item = pincerArrowArr[z];
-			var pincerArrow = new PincerArrow(viewer);
-			pincerArrow.createByData(item);
-			this.drawArr.push(pincerArrow);
-		}
-	},
-
 });
 
 /**
@@ -417,8 +555,8 @@ Object.assign(DrawMilitaryPlot.prototype, {
 	 * @param {Function} callRemove 移除回调
 	 */
 	_openPropertyEditDialog: function(params, callEdit, callRemove) {
-		this._editPropertyDialogDomId = 'dialog-property-dom2';
-		this._registerDOMPropertyEdit = 'dialog-edit-property2'
+		this._editPropertyDialogDomId = 'dialog-property-dom-militaryplot';
+		this._registerDOMPropertyEdit = 'dialog-edit-property-militaryplot'
 		/* 获取一个属性编辑组件 */
 		let PropertyEditComponent = customElements.get(this._registerDOMPropertyEdit);
 		/* 如果组件还未注册 则进行注册 否则不在注册 避免重复注册的BUG */
@@ -468,14 +606,4 @@ Object.assign(DrawMilitaryPlot.prototype, {
 
 })
 
-
-/**
- * 绘制类型
- */
-DrawMilitaryPlot.DrawType = Object.freeze({
-	StraightArrow: 'straightArrow', //直箭头
-	AttackArrow: 'attackArrow', //攻击箭头
-	PincerArrow: 'pincerArrow', //钳击箭头
-})
-
 export default DrawMilitaryPlot;

+ 672 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/EntityEdit.js

@@ -0,0 +1,672 @@
+import * as turf from "@turf/turf"
+
+export default class EntityEdit {
+	constructor(viewer) {
+		this.viewer = viewer;
+		this.DrawExample = '';
+		this.midVertexEntities = [];
+		this.initEventHandler();
+	}
+
+	//鼠标事件
+	initEventHandler() {
+		this.eventHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+		this.EditEndEvent = new Cesium.Event();
+		this.EditEndEntity = new Cesium.Event();
+	}
+
+	//激活编辑
+	activate() {
+		this.deactivate();
+		//鼠标左键点击事件 鼠标左键点击拾取需要编辑的对象
+		this.initLeftClickEventHandler();
+	}
+
+	//禁用编辑
+	deactivate() {
+		this.DrawExample = '';
+		this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+		this.unRegisterEvents();
+		this.clearAllEditVertex();
+	}
+
+	//清空编辑节点
+	clearAllEditVertex() {
+		this.clearEditVertex();
+		this.clearMidVertex();
+	}
+
+	//左键点击事件
+	initLeftClickEventHandler() {
+		this.eventHandler.setInputAction(e => {
+
+			let id = this.viewer.scene.pick(e.position);
+			if (!id || !id.id) {
+				this.handleEditEntity();
+				return; // 没有拾取到对象 直接返回 不做任何操作
+			}
+
+			// 拾取到对象 判断拾取到的对象类型
+			if (!id.id || !id.id.Type) return;
+			//重复点击同一个对象
+			if (this.editEntity && this.editEntity.id == id.id.id) return;
+			// if (this.editEntity) return
+			//拾取到新的GeoPlot对象
+			this.handleEditEntity(); //处理上一个编辑对象
+			this.handlePickEditEntity(id.id);
+		}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+	}
+
+	//处理编辑对象
+	handleEditEntity() {
+		this.unRegisterEvents();
+		this.clearAllEditVertex();
+		let editEntity = this.editEntity;
+		if (!editEntity) return;
+		this.closeEntityEditMode();
+		this.editEntity = undefined;
+		if (!this.isEdited) return; //没有任何编辑 直接返回   
+
+		// console.log("对象被编辑过是否需要保存操作??");
+
+		//触发编辑事件  
+		this.EditEndEvent.raiseEvent(editEntity);
+		this.isEdited = false;
+		this.isEditing = false;
+	}
+
+	//处理拾取到的对象
+	handlePickEditEntity(pickId) {
+		const EditableTypes = ["DrawAttackArrow", "DrawCircle", "DrawCurve", 'DrawPincerArrow', 'DrawPoint', 'DrawPolygon', 'DrawPolyline', 'DrawRectangle', 'DrawStraightArrow', 'DrawGatheringPlace', 'DrawSector', 'DrawClosedCurve', 'DrawArc', 'DrawLune', 'DrawRectFlag', 'DrawTriangleFlag', 'DrawCurveFlag'];
+		if (EditableTypes.indexOf(pickId.Type) == -1) return;
+		this.editEntity = pickId;
+		this.EditEndEntity.raiseEvent(this.editEntity);
+		this.isEditing = false;
+		this.isEdited = false;
+
+		this.editPositions = this.getEditEntityPositions();
+		this.EditMoveCenterPositoin = this.getCenterPosition();
+
+		this.openEntityEditModel();
+
+		this.clearAllEditVertex();
+		this.unRegisterEvents();
+		this.createEditVertex();
+		this.createMidVertex();
+		this.registerEvents();
+	}
+
+	openEntityEditModel() {
+		if (this.DrawExample == '') return
+		switch (this.editEntity.Type) {
+			case "DrawStraightArrow":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+			case "DrawAttackArrow":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+			case "DrawPincerArrow":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+			case "DrawGatheringPlace":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+			case "DrawClosedCurve":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions).PolygonHierarchy;
+				}, false);
+				this.editEntity.polyline.positions = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions).pList;
+				}, false);
+				break;
+			case "DrawCircle":
+				this.editEntity.position = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions).position
+				}, false)
+				this.editEntity.ellipse.semiMinorAxis = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions).r
+				}, false);
+				this.editEntity.ellipse.semiMajorAxis = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions).r
+				}, false);
+				break;
+			case "DrawCurve":
+				this.editEntity.polyline.positions = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+
+			case "DrawPoint":
+				this.editEntity.position = new Cesium.CallbackProperty(e => {
+					return this.editPositions[0];
+				}, false);
+				break;
+			case "DrawPolygon":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+			case "DrawPolyline":
+				this.editEntity.polyline.positions = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+			case "DrawRectangle":
+				this.editEntity.rectangle.coordinates = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+
+			case "DrawSector":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+
+			case "DrawArc":
+				this.editEntity.polyline.positions = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+			case "DrawLune":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions);
+				}, false);
+				break;
+			case "DrawRectFlag":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions)[0]
+				}, false);
+				this.editEntity.polyline.positions = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions)[1];
+				}, false);
+				break;
+
+			case "DrawTriangleFlag":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions)[0]
+				}, false);
+				this.editEntity.polyline.positions = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions)[1];
+				}, false);
+				break;
+
+			case "DrawCurveFlag":
+				this.editEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions)[0]
+				}, false);
+				this.editEntity.polyline.positions = new Cesium.CallbackProperty(e => {
+					return this.DrawExample.computePosition(this.editPositions)[1];
+				}, false);
+				break;
+		}
+	}
+
+	closeEntityEditMode() {
+		if (this.DrawExample == '') return
+		let position = '';
+		switch (this.editEntity.Type) {
+			case "DrawStraightArrow":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawAttackArrow":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawPincerArrow":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawGatheringPlace":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawClosedCurve":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position.PolygonHierarchy;
+				this.editEntity.polyline.positions = position.pList;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawCircle":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.position = position.position
+				this.editEntity.ellipse.semiMinorAxis = position.r;
+				this.editEntity.ellipse.semiMajorAxis = position.r;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawCurve":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polyline.positions = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+
+			case "DrawPoint":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.position = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawPolygon":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawPolyline":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polyline.positions = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawRectangle":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.rectangle.coordinates = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+
+			case "DrawSector":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+
+			case "DrawArc":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polyline.positions = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+			case "DrawLune":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position;
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+
+			case "DrawRectFlag":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position[0];
+				this.editEntity.polyline.positions = position[1];
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+
+			case "DrawTriangleFlag":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position[0];
+				this.editEntity.polyline.positions = position[1];
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+
+			case "DrawCurveFlag":
+				position = this.DrawExample.computePosition(this.editPositions);
+				this.editEntity.polygon.hierarchy = position[0];
+				this.editEntity.polyline.positions = position[1];
+				this.editEntity.Position = this.DrawExample.getData();
+				break;
+		}
+	}
+
+	getEditEntityPositions() {
+		let position = this.editEntity.Position;
+		let positionArr = [];
+		switch (this.editEntity.Type) {
+			case "DrawAttackArrow":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawCircle":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawCurve":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawPincerArrow":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawPoint":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawPolygon":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawPolyline":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawRectangle":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawStraightArrow":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawGatheringPlace":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawSector":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawClosedCurve":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawArc":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawLune":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+			case "DrawRectFlag":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+
+			case "DrawTriangleFlag":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+
+			case "DrawCurveFlag":
+				for (let i = 0; i < position.length; i++) {
+					positionArr.push(this.LatlngTocartesian(position[i]))
+				}
+				return positionArr;
+		}
+	}
+
+	//注册事件监听
+	registerEvents() {
+		//鼠标左键按下事件 当有对象被选中时 如果拾取到编辑辅助要素 表示开始改变对象的位置
+		this.initLeftDownEventHandler();
+		//鼠标移动事件 鼠标移动 如果有编辑对象 表示改变编辑对象的位置
+		this.initMouseMoveEventHandler();
+		//鼠标左键抬起事件 当有编辑对象时  
+		this.initLeftUpEventHandler();
+	}
+
+	//取消事件监听
+	unRegisterEvents() {
+		this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
+		this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
+		this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+	}
+
+	//场景鼠标左键按下事件
+	initLeftDownEventHandler() {
+		this.eventHandler.setInputAction((e) => {
+			let id = this.viewer.scene.pick(e.position);
+			// 拾取到对象 判断拾取到的对象类型 
+			if (!id || !id.id || !id.id.type) return;
+			//拾取到具有type 属性的entity对象 
+			if (id.id.type == "EditVertex" || id.id.type == "EditMove") {
+				this.isEditing = true;
+				//禁用场景的旋转移动功能 保留缩放功能
+				this.viewer.scene.screenSpaceCameraController.enableRotate = false;
+				//改变鼠标状态
+				this.viewer.enableCursorStyle = false;
+				this.viewer._element.style.cursor = '';
+				document.body.style.cursor = "move";
+				this.editVertext = id.id;
+				this.editVertext.show = false;
+				this.clearMidVertex();
+			} else if (id.id.type == "EditMidVertex") {
+				this.editPositions.splice(id.id.vertexIndex, 0, id.id.position._value);
+				this.clearAllEditVertex();
+				this.createEditVertex();
+				this.createMidVertex();
+				this.isEdited = true;
+			} else {
+				return
+			}
+		}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+	}
+
+	//场景鼠标左键抬起事件
+	initLeftUpEventHandler() {
+		this.eventHandler.setInputAction(((e) => {
+			if (!this.isEditing) return;
+			this.viewer.enableCursorStyle = true;
+			document.body.style.cursor = "default";
+			this.viewer.scene.screenSpaceCameraController.enableRotate = true;
+			this.editVertext.show = true;
+			this.isEditing = false;
+			this.clearMidVertex();
+			this.createMidVertex();
+		}), Cesium.ScreenSpaceEventType.LEFT_UP);
+	}
+
+	//场景鼠标移动事件
+	initMouseMoveEventHandler() {
+		this.eventHandler.setInputAction(((e) => {
+			var position = e.endPosition;
+			var ray = this.viewer.scene.camera.getPickRay(position);
+			var cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+			if (!cartesian) return;
+
+			if (!this.isEditing) return;
+			if (this.editVertext.type == "EditMove") {
+				let startPosition = this.EditMoveCenterPositoin;
+				if (!startPosition) return;
+				this.moveEntityByOffset(startPosition, cartesian);
+			} else if (this.editVertext.type == "EditVertex" || this.editVertext.type == "EditMidVertex") {
+				this.editPositions[this.editVertext.vertexIndex] = cartesian;
+			}
+			this.isEdited = true;
+			this.EditMoveCenterPositoin = this.getCenterPosition();
+		}), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+	}
+
+	//获取编辑对象中心点
+	getCenterPosition() {
+		let points = [];
+		let maxHeight = 0;
+		//如果是点 返回第一个点作为移动点
+		if (this.editEntity.Type == "DrawCircle" || this.editEntity.Type == "DrawPoint" || this.editEntity.Type == "DrawSector") {
+			return this.editPositions[0];
+		}
+
+		//获取所有节点的最高位置
+		this.editPositions.forEach(position => {
+			const point3d = this.cartesian3ToPoint3D(position);
+			points.push([point3d.x, point3d.y]);
+			if (maxHeight < point3d.z) maxHeight = point3d.z;
+		})
+
+		//构建turf.js  lineString
+		let geo = turf.lineString(points);
+		let bbox = turf.bbox(geo);
+		let bboxPolygon = turf.bboxPolygon(bbox);
+		let pointOnFeature = turf.center(bboxPolygon);
+		let lonLat = pointOnFeature.geometry.coordinates;
+		return Cesium.Cartesian3.fromDegrees(lonLat[0], lonLat[1], maxHeight);
+	}
+
+	//根据偏移量移动实体
+	moveEntityByOffset(startPosition, endPosition) {
+		let startPoint3d = this.cartesian3ToPoint3D(startPosition);
+		let endPoint3d = this.cartesian3ToPoint3D(endPosition);
+		let offsetX = endPoint3d.x - startPoint3d.x;
+		let offsetY = endPoint3d.y - startPoint3d.y;
+		//设置偏移量
+		let element;
+		for (let i = 0; i < this.editPositions.length; i++) {
+			element = this.cartesian3ToPoint3D(this.editPositions[i]);
+			element.x += offsetX;
+			element.y += offsetY;
+			this.editPositions[i] = Cesium.Cartesian3.fromDegrees(element.x, element.y, element.z)
+		}
+	}
+
+	//创建编辑节点
+	createEditVertex() {
+		this.vertexEntities = [];
+		this.editPositions.forEach((p, index) => {
+			const entity = this.viewer.entities.add({
+				position: new Cesium.CallbackProperty(e => {
+					return this.editPositions[index];
+				}, false),
+				type: "EditVertex",
+				vertexIndex: index, //节点索引 
+				point: {
+					show: true,
+					pixelSize: 10,
+					color: new Cesium.Color(0, 0, 1, 1),
+					outlineWidth: 1,
+					outlineColor: new Cesium.Color(1, 1, 1, 1),
+					disableDepthTestDistance: 1.5e12, //小于该数值后关闭深度检测默认为空
+					heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+				},
+			})
+			this.vertexEntities.push(entity);
+		});
+		// 如果是圆则隐藏中心点
+		if (this.editEntity.Type == 'DrawCircle') {
+			this.vertexEntities[0].show = false
+		}
+		if (this.editPositions.length == 1) { //只有一个节点表示点类型 不需要创建整体移动节点
+			return;
+		}
+		this.createEditMoveCenterEntity();
+	}
+
+	//整体移动
+	createEditMoveCenterEntity() {
+		this.EditMoveCenterEntity = this.viewer.entities.add({
+			position: new Cesium.CallbackProperty(e => {
+				return this.EditMoveCenterPositoin;
+			}, false),
+			type: "EditMove",
+			point: {
+				show: true,
+				pixelSize: 12,
+				color: new Cesium.Color(0, 1, 0, 0.1),
+				outlineWidth: 2,
+				outlineColor: new Cesium.Color(1, 1, 1, 1),
+				disableDepthTestDistance: 1.5e12, //小于该数值后关闭深度检测默认为空
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			},
+		})
+	}
+
+	//清空编辑节点
+	clearEditVertex() {
+		if (this.vertexEntities) {
+			this.vertexEntities.forEach(item => {
+				this.viewer.entities.remove(item);
+			})
+		}
+		this.vertexEntities = [];
+		this.viewer.entities.remove(this.EditMoveCenterEntity);
+	}
+
+	//创建中点节点
+	createMidVertex() {
+		if (this.editEntity.Type == 'DrawCircle' || this.editEntity.Type == 'DrawPincerArrow' || this.editEntity.Type == 'DrawRectangle' || this.editEntity.Type == 'DrawStraightArrow' || this.editEntity.Type == 'DrawGatheringPlace' || this.editEntity.Type == "DrawSector" || this.editEntity.Type == "DrawArc" || this.editEntity.Type == "DrawLune" || this.editEntity.Type == "DrawRectFlag" || this.editEntity.Type == "DrawTriangleFlag" || this.editEntity.Type == "DrawCurveFlag") {
+			return
+		}
+		this.midVertexEntities = [];
+		for (let i = 0; i < this.editPositions.length; i++) {
+			const p1 = this.editPositions[i];
+			const p2 = this.editPositions[i + 1];
+			let mideP = this.midPosition(p1, p2);
+			const entity = this.viewer.entities.add({
+				position: mideP,
+				type: "EditMidVertex",
+				vertexIndex: i + 1, //节点索引 
+				point: {
+					show: true,
+					pixelSize: 10,
+					color: new Cesium.Color(0, 1, 0, 1),
+					outlineWidth: 1,
+					outlineColor: new Cesium.Color(1, 1, 1, 1),
+					disableDepthTestDistance: 1.5e12, //小于该数值后关闭深度检测默认为空
+					heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+				},
+			})
+			this.midVertexEntities.push(entity);
+		}
+	}
+
+	//清空中点节点
+	clearMidVertex() {
+		if (this.midVertexEntities) {
+			this.midVertexEntities.forEach(item => {
+				this.viewer.entities.remove(item);
+			})
+		}
+		this.midVertexEntities = [];
+	}
+
+	//笛卡尔坐标转为经纬度xyz
+	cartesian3ToPoint3D(position) {
+		const cartographic = Cesium.Cartographic.fromCartesian(position);
+		const lon = Cesium.Math.toDegrees(cartographic.longitude);
+		const lat = Cesium.Math.toDegrees(cartographic.latitude);
+		return {
+			x: lon,
+			y: lat,
+			z: cartographic.height
+		};
+	}
+
+	//获取两个节点的中心点
+	midPosition(first, second) {
+		if (!first || !second) return null;
+		let point3d1 = this.cartesian3ToPoint3D(first);
+		let point3d2 = this.cartesian3ToPoint3D(second);
+		let midLonLat = {
+			x: (point3d1.x + point3d2.x) / 2,
+			y: (point3d1.y + point3d2.y) / 2,
+			z: (point3d1.z + point3d2.z) / 2
+		}
+		return Cesium.Cartesian3.fromDegrees(midLonLat.x, midLonLat.y, midLonLat.z);
+	}
+
+
+	cartesianToLatlng(cartesian) {
+		let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		let lat = new Cesium.Math.toDegrees(cartographic.latitude);
+		let lng = new Cesium.Math.toDegrees(cartographic.longitude);
+		let alt = cartographic.height;
+		return [lng, lat];
+	}
+
+	LatlngTocartesian(latlng) {
+		let cartesian3 = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+		return cartesian3
+	}
+}

+ 534 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawArc.js

@@ -0,0 +1,534 @@
+
+/*
+九、绘制弓形
+ */
+class DrawArc {
+	constructor(arg) {
+		this.viewer = arg.viewer;
+		this.Cesium = arg.Cesium;
+		this.tt = 0.4;
+		this.floatingPoint = null; //标识点
+		this.drawHandler = null; //画事件
+		this.DrawArc = null; //弓形
+		this._DrawArcLast = null; //最后一个弓形
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_PincerArrow = []; //脏数据
+		this._DrawArcData = null; //用于构造弓形
+		this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+		this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+		
+	}
+
+	//返回弓形
+	get PincerArrow() {
+		return this._DrawArcLast;
+	}
+
+	//返回弓形数据用于加载弓形
+	getData() {
+		return this._DrawArcData;
+	}
+
+	// 修改编辑调用计算
+	computePosition(data) {
+		var $this = this;
+		if (data.length < 3) {
+			return;
+		}
+		var DrawArc = [];
+		let positions = [];
+		for (var i = 0; i < data.length; i++) {
+			positions.push($this.cartesianToLatlng(data[i]));
+			var cart3 = $this.lonLatToMercator($this.cartesianToLatlng(data[i]));
+			DrawArc.push(cart3);
+		}
+		let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawArc[0], DrawArc[2], DrawArc[1], null, null];
+		let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
+		let radius = $this.MathDistance(pnt1, center)
+		let angle1 = $this.getAzimuth(pnt1, center)
+		let angle2 = $this.getAzimuth(pnt2, center)
+		if ($this.isClockWise(pnt1, pnt2, pnt3)) {
+			startAngle = angle2
+			endAngle = angle1
+		} else {
+			startAngle = angle1
+			endAngle = angle2
+		}
+		let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
+		let pHierarchy = [];
+		for (var l = 0; l < getArcPoint.length; l++) {
+			var cart3 = $this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
+			pHierarchy.push(cart3);
+		}
+		$this._DrawArcData = positions
+		return pHierarchy
+	}
+
+	//加载
+	addload(data) {
+		var $this = this;
+		if (data.length < 3) {
+			return;
+		}
+		var DrawArc = [];
+		for (var i = 0; i < data.length; i++) {
+			var cart3 = $this.lonLatToMercator(data[i]);
+			DrawArc.push(cart3);
+		}
+		let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawArc[0], DrawArc[2], DrawArc[1], null, null];
+		let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
+		let radius = $this.MathDistance(pnt1, center)
+		let angle1 = $this.getAzimuth(pnt1, center)
+		let angle2 = $this.getAzimuth(pnt2, center)
+		if ($this.isClockWise(pnt1, pnt2, pnt3)) {
+			startAngle = angle2
+			endAngle = angle1
+		} else {
+			startAngle = angle1
+			endAngle = angle2
+		}
+		let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
+		// console.log(getArcPoint)
+		let pHierarchy = [];
+		for (var l = 0; l < getArcPoint.length; l++) {
+			var cart3 = $this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
+			pHierarchy.push(cart3);
+		}
+		var arrowEntity = $this.viewer.entities.add({
+			Type: 'DrawArc',
+			Position: data,
+			id: data.id || $this.objId,
+			polyline: {
+				positions: pHierarchy,
+				show: true,
+				material: $this.Cesium.Color.YELLOW,
+				width: 3,
+				clampToGround: true
+			}
+		})
+		return arrowEntity
+	}
+
+
+	// 开始创建
+	startCreate(drawType) {
+		this.drawType = drawType
+		var $this = this;
+		this.handler = new $this.Cesium.ScreenSpaceEventHandler($this.viewer.scene.canvas);
+		this.handler.setInputAction(function(event) {
+			//屏幕坐标转世界坐标
+			var position = event.position;
+			if (!$this.Cesium.defined(position)) {
+				return;
+			}
+			var ray = $this.viewer.camera.getPickRay(position);
+			if (!$this.Cesium.defined(ray)) {
+				return;
+			}
+			var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
+			if (!$this.Cesium.defined(cartesian)) {
+				return;
+			}
+
+			if ($this._positions.length == 0) {
+				$this._positions.push(cartesian.clone());
+				$this.floatingPoint = $this.createPoint(cartesian);
+			}
+
+			if ($this._positions.length <= 2) {
+				$this.createPoint(cartesian); // 绘制点
+				$this._positions.push(cartesian);
+			}
+		}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+
+		this.handler.setInputAction(function(event) { //移动时绘制面
+			//console.log("_positions",_positions);
+			if ($this._positions.length < 2) {
+				return;
+			}
+
+			//屏幕坐标转世界坐标
+			var position = event.endPosition;
+			if (!$this.Cesium.defined(position)) {
+				return;
+			}
+			var ray = $this.viewer.camera.getPickRay(position);
+			if (!$this.Cesium.defined(ray)) {
+				return;
+			}
+			var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
+			if (!$this.Cesium.defined(cartesian)) {
+				return;
+			}
+			//console.log("点击地图移动采集的点:",cartesian);
+			if (!$this.Cesium.defined($this.DrawArc)) {
+				$this.DrawArc = $this.createDrawArc();
+			}
+			$this.floatingPoint.position.setValue(cartesian);
+			if ($this.DrawArc) {
+				//替换最后一个点
+				// _positions.pop();
+				// _positions.push(cartesian);
+				//替换中间点
+				if ($this._positions.length == 3) {
+					$this._positions[1] = cartesian;
+				} else {
+					$this._positions.pop();
+					$this._positions.push(cartesian);
+				}
+
+			}
+		}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+
+		//右击停止采集
+		this.handler.setInputAction(function(movement) {
+
+			if ($this._positions.length >= 3) {
+				$this._DrawArcData = $this._positions.concat();
+				$this.viewer.entities.remove($this.DrawArc); //移除
+				$this.DrawArc = null;
+				var lnglatArr = [];
+				for (var i = 0; i < $this._DrawArcData.length; i++) {
+					var lnglat = $this.cartesianToLatlng($this._DrawArcData[i]);
+					lnglatArr.push(lnglat)
+				}
+				$this._DrawArcData = lnglatArr;
+				var pincerArrow = $this.addload(lnglatArr); //加载
+				$this._entities_PincerArrow.push(pincerArrow);
+				$this._DrawArcLast = pincerArrow;
+				$this.viewer.entities.remove($this.floatingPoint);
+				$this.floatingPoint = null;
+
+				//删除关键点
+				$this.clearPoint();
+				$this.destroy()
+			}
+		}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+	}
+
+	//创建弓形
+	createDrawArc() {
+		let $this = this
+		var DrawArcEntity = $this.viewer.entities.add({
+			polyline: {
+				positions: new $this.Cesium.CallbackProperty(function() {
+					if ($this._positions.length < 3) {
+						return;
+					}
+					var DrawArc = [];
+					for (var i = 0; i < $this._positions.length; i++) {
+						var cart3 = $this.lonLatToMercator($this.cartesianToLatlng($this._positions[i]));
+						DrawArc.push(cart3);
+					}
+					let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawArc[0], DrawArc[2], DrawArc[1], null, null];
+					let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
+					let radius = $this.MathDistance(pnt1, center)
+					let angle1 = $this.getAzimuth(pnt1, center)
+					let angle2 = $this.getAzimuth(pnt2, center)
+					if ($this.isClockWise(pnt1, pnt2, pnt3)) {
+						startAngle = angle2
+						endAngle = angle1
+					} else {
+						startAngle = angle1
+						endAngle = angle2
+					}
+					let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
+					// console.log(getArcPoint)
+					let pHierarchy = [];
+					for (var l = 0; l < getArcPoint.length; l++) {
+						var cart3 = $this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
+						pHierarchy.push(cart3);
+					}
+					return pHierarchy
+				}, false),
+				show: true,
+				material: $this.Cesium.Color.YELLOW,
+				width: 3,
+				clampToGround: true
+			}
+		})
+		//$this._entities_DrawArc.push(DrawArcEntity);
+		// DrawArcEntity.valueFlag = "value";
+		$this._entities_PincerArrow.push(DrawArcEntity);
+		return DrawArcEntity
+	}
+
+	//创建点
+	createPoint(cartesian) {
+		var $this = this;
+		var point = this.viewer.entities.add({
+			position: cartesian,
+			point: {
+				pixelSize: 10,
+				color: $this.Cesium.Color.RED,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			}
+		});
+		$this._entities_point.push(point);
+		return point;
+	}
+
+	cartesianToLatlng(cartesian) {
+		let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		let lat = this.Cesium.Math.toDegrees(cartographic.latitude);
+		let lng = this.Cesium.Math.toDegrees(cartographic.longitude);
+		let alt = cartographic.height;
+		return [lng, lat];
+	}
+
+	//销毁
+	destroy() {
+		if (this.handler) {
+			this.handler.destroy();
+			this.handler = null;
+		}
+	}
+
+	clearPoint() {
+		this.DrawEndEvent.raiseEvent(this._DrawArcLast, this._DrawArcData, this.drawType);
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		this._entities_point = []; //脏数据
+	}
+
+	//清空实体对象
+	clear() {
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		for (var i = 0; i < this._entities_PincerArrow.length; i++) {
+			this.viewer.entities.remove(this._entities_PincerArrow[i]);
+		}
+
+		this.floatingPoint = null; //标识点
+		this._PincerArrow = null; //活动弓形
+		this._PincerArrowLast = null; //最后一个弓形
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_PincerArrow = []; //脏数据
+		this._PincerArrowData = null; //用于构造弓形数据
+	}
+
+	getCatesian3FromPX(px) {
+		var cartesian;
+		var ray = this.viewer.camera.getPickRay(px);
+		if (!ray) return null;
+		cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+		return cartesian;
+	}
+
+	_computeTempPositions() {
+		var _this = this;
+
+		var pnts = [].concat(_this._positions);
+		var num = pnts.length;
+		var first = pnts[0];
+		var last = pnts[num - 1];
+		if (_this._isSimpleXYZ(first, last) == false) {
+			pnts.push(first);
+			num += 1;
+		}
+		_this.tempPositions = [];
+		for (var i = 1; i < num; i++) {
+			var p1 = pnts[i - 1];
+			var p2 = pnts[i];
+			var cp = _this._computeCenterPotition(p1, p2);
+			_this.tempPositions.push(p1);
+			_this.tempPositions.push(cp);
+		}
+	}
+
+	_isSimpleXYZ(p1, p2) {
+		if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+			return true;
+		}
+		return false;
+	}
+
+	_computeCenterPotition(p1, p2) {
+		var _this = this;
+		var c1 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p1);
+		var c2 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p2);
+		var cm = new _this.Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+		var cp = _this.viewer.scene.globe.ellipsoid.cartographicToCartesian(cm);
+		return cp;
+	}
+	/**
+	 * 笛卡尔坐标转经纬度坐标
+	 */
+	getLonLat(cartesian) {
+		var cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		cartographic.height = this.viewer.scene.globe.getHeight(cartographic);
+		var pos = {
+			lon: cartographic.longitude,
+			lat: cartographic.latitude,
+			alt: cartographic.height
+		};
+		pos.lon = this.Cesium.Math.toDegrees(pos.lon);
+		pos.lat = this.Cesium.Math.toDegrees(pos.lat);
+		return pos;
+	}
+
+	LatlngTocartesian(latlng) {
+		let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+		return cartesian3
+	}
+
+	/**
+	 * 经纬度坐标转墨卡托坐标
+	 */
+	// 墨卡托坐标系:展开地球,赤道作为x轴,向东为x轴正方,本初子午线作为y轴,向北为y轴正方向。
+	// 数字20037508.34是地球赤道周长的一半:地球半径6378137米,赤道周长2*PI*r = 2 * 20037508.3427892,墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892]
+	lonLatToMercator(Latlng) {
+		var E = Latlng[0];
+		var N = Latlng[1];
+		var x = E * 20037508.34 / 180;
+		var y = Math.log(Math.tan((90 + N) * Math.PI / 360)) / (Math.PI / 180);
+		y = y * 20037508.34 / 180;
+		return [x, y]
+	}
+	/**
+	 * 墨卡托坐标转经纬度坐标转
+	 */
+	WebMercator2lonLat(mercator) {
+		let x = mercator[0] / 20037508.34 * 180;
+		let ly = mercator[1] / 20037508.34 * 180;
+		let y = 180 / Math.PI * (2 * Math.atan(Math.exp(ly * Math.PI / 180)) - Math.PI / 2)
+		return [x, y];
+	}
+
+	////////////////////////////////////////弓形/////////////////////////////////////////////////////
+	/**
+	 * 通过三个点确定一个圆的中心点
+	 * @param point1
+	 * @param point2
+	 * @param point3
+	 */
+	getCircleCenterOfThreePoints(point1, point2, point3) {
+		let pntA = [(point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2]
+		let pntB = [pntA[0] - point1[1] + point2[1], pntA[1] + point1[0] - point2[0]]
+		let pntC = [(point1[0] + point3[0]) / 2, (point1[1] + point3[1]) / 2]
+		let pntD = [pntC[0] - point1[1] + point3[1], pntC[1] + point1[0] - point3[0]]
+		return this.getIntersectPoint(pntA, pntB, pntC, pntD)
+	}
+
+	/**
+	 * 获取交集的点
+	 * @param pntA
+	 * @param pntB
+	 * @param pntC
+	 * @param pntD
+	 * @returns {[*,*]}
+	 */
+	getIntersectPoint(pntA, pntB, pntC, pntD) {
+		if (pntA[1] === pntB[1]) {
+			let f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
+			let x = f * (pntA[1] - pntC[1]) + pntC[0]
+			let y = pntA[1]
+			return [x, y]
+		}
+		if (pntC[1] === pntD[1]) {
+			let e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
+			let x = e * (pntC[1] - pntA[1]) + pntA[0]
+			let y = pntC[1]
+			return [x, y]
+		}
+		let e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
+		let f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
+		let y = (e * pntA[1] - pntA[0] - f * pntC[1] + pntC[0]) / (e - f)
+		let x = e * y - e * pntA[1] + pntA[0]
+		return [x, y]
+	}
+
+
+	/**
+	 * 计算两个坐标之间的距离
+	 * @ignore
+	 * @param pnt1
+	 * @param pnt2
+	 * @returns {number}
+	 * @constructor
+	 */
+	MathDistance(pnt1, pnt2) {
+		return (Math.sqrt(Math.pow((pnt1[0] - pnt2[0]), 2) + Math.pow((pnt1[1] - pnt2[1]), 2)))
+	}
+
+
+	/**
+	 * 获取方位角(地平经度)
+	 * @param startPoint
+	 * @param endPoint
+	 * @returns {*}
+	 */
+	getAzimuth(startPoint, endPoint) {
+		let azimuth
+		let angle = Math.asin(Math.abs(endPoint[1] - startPoint[1]) / (this.MathDistance(startPoint, endPoint)))
+		if (endPoint[1] >= startPoint[1] && endPoint[0] >= startPoint[0]) {
+			azimuth = angle + Math.PI
+		} else if (endPoint[1] >= startPoint[1] && endPoint[0] < startPoint[0]) {
+			azimuth = Math.PI * 2 - angle
+		} else if (endPoint[1] < startPoint[1] && endPoint[0] < startPoint[0]) {
+			azimuth = angle
+		} else if (endPoint[1] < startPoint[1] && endPoint[0] >= startPoint[0]) {
+			azimuth = Math.PI - angle
+		}
+		return azimuth
+	}
+
+	/**
+	 * 判断是否是顺时针
+	 * @param pnt1
+	 * @param pnt2
+	 * @param pnt3
+	 * @returns {boolean}
+	 */
+	isClockWise(pnt1, pnt2, pnt3) {
+		return ((pnt3[1] - pnt1[1]) * (pnt2[0] - pnt1[0]) > (pnt2[1] - pnt1[1]) * (pnt3[0] - pnt1[0]))
+	}
+
+
+	/**
+	 * 插值弓形线段点
+	 * @param center
+	 * @param radius
+	 * @param startAngle
+	 * @param endAngle
+	 * @returns {null}
+	 */
+	getArcPoints(center, radius, startAngle, endAngle) {
+		let [x, y, pnts, angleDiff] = [null, null, [], (endAngle - startAngle)]
+		angleDiff = ((angleDiff < 0) ? (angleDiff + (Math.PI * 2)) : angleDiff)
+		for (let i = 0; i <= 100; i++) {
+			let angle = startAngle + angleDiff * i / 100
+			x = center[0] + radius * Math.cos(angle)
+			y = center[1] + radius * Math.sin(angle)
+			pnts.push([x, y])
+		}
+		return pnts
+	}
+
+}
+
+export default DrawArc

+ 574 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawAttackArrow.js

@@ -0,0 +1,574 @@
+import {
+	createTooltip
+} from "../../../common/common.js";
+
+import {
+	isRuntimeApp,
+	isRuntimeWeb,
+	createOperationMainDom,
+	showTooltipMessage
+} from "../../../common/RuntimeEnvironment.js";
+
+/*
+七、绘制攻击箭头
+ */
+class DrawAttackArrow {
+	constructor(arg) {
+		//设置唯一id 备用
+		this.objId = Number((new Date()).getTime() + "" + Number(Math.random() * 1000).toFixed(0));
+		this.viewer = arg.viewer;
+		this.Cesium = arg.Cesium;
+		// this.callback=arg.callback;
+		this.floatingPoint = null; //标识点
+		this._AttackArrow = null; //活动箭头
+		this._AttackArrowLast = null; //最后一个箭头
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_AttackArrow = []; //脏数据
+		this._AttackArrowData = null; //用于构造箭头数据
+		this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+		this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+
+		this._tooltip = createTooltip(this.viewer.container);
+
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+	}
+
+	//返回箭头
+	get AttackArrow() {
+		return this._AttackArrowLast;
+	}
+
+	//返回箭头数据用于加载箭头
+	getData() {
+		return this._AttackArrowData;
+	}
+
+	//加载箭头
+	addload(data) {
+		var $this = this;
+		if (data.length < 3) {
+			return null;
+		}
+		var res = $this.fineArrow(data);
+		var returnData = res.polygonalPoint;
+		var arrowEntity = $this.viewer.entities.add({
+			Type: 'DrawAttackArrow',
+			Position: data,
+			id: data.id || $this.objId,
+			polygon: {
+				hierarchy: new $this.Cesium.PolygonHierarchy(returnData),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			}
+		});
+		return arrowEntity
+	}
+
+	// 修改编辑调用计算
+	computePosition(data) {
+		//计算面
+		let $this = this
+		var lnglatArr = [];
+		for (var i = 0; i < data.length; i++) {
+			var lnglat = $this.cartesianToLatlng(data[i]);
+			lnglatArr.push(lnglat)
+		}
+		$this._AttackArrowData = lnglatArr;
+		var res = $this.fineArrow(lnglatArr);
+		var returnData = res.polygonalPoint;
+		return new $this.Cesium.PolygonHierarchy(returnData)
+	}
+
+	//开始创建
+	startCreate(drawType) {
+		if (isRuntimeApp()) {
+			showTooltipMessage("点击开始绘制");
+		}
+
+		var $this = this;
+
+		this.drawType = drawType;
+		this.handler = new $this.Cesium.ScreenSpaceEventHandler($this.viewer.scene.canvas);
+
+		//单击开始绘制
+		this.handler.setInputAction(function(evt) {
+
+			if (isRuntimeApp()) {
+
+				//屏幕坐标转地形上坐标
+				var cartesian = $this.getCatesian3FromPX(evt.position);
+				if (!cartesian) {
+					return;
+				}
+
+				$this.createPoint(cartesian); // 绘制点
+				$this._positions.push(cartesian);
+
+				if ($this._positions.length > 2) {
+					showTooltipMessage("点击添加点,点击完成按钮,结束绘制");
+				} else {
+					showTooltipMessage("点击添加点");
+					if ($this._positions.length === 2) {
+						if (!$this.Cesium.defined($this._AttackArrow)) {
+							$this._AttackArrow = $this.createAttackArrow();
+
+							//创建按钮
+							createOperationMainDom();
+							//完成绘制
+							document.getElementById("btnDrawComplete").onclick = () => {
+
+								$this._AttackArrowData = $this._positions.concat();
+								$this.viewer.entities.remove($this._AttackArrow); //移除
+								$this._AttackArrow = null;
+								$this._positions = [];
+
+								let lnglatArr = [];
+								for (var i = 0; i < $this._AttackArrowData.length; i++) {
+									var lnglat = $this.cartesianToLatlng($this._AttackArrowData[i]);
+									lnglatArr.push(lnglat)
+								}
+								$this._AttackArrowData = lnglatArr;
+								var straightArrow = $this.addload(lnglatArr); //加载
+								$this._entities_AttackArrow.push(straightArrow);
+								$this._AttackArrowLast = straightArrow;
+								$this.clearPoint();
+								$this.destroy();
+
+								let buttonDiv = document.getElementById("drawButtonDiv");
+								if (buttonDiv) {
+									//从页面移除
+									document.body.removeChild(buttonDiv);
+								}
+							}
+						}
+					}
+				}
+			} else {
+
+				console.log('监听鼠标事件', '单击')
+
+				/* 锁定点击事件 以免和双击事件冲突 */
+				clearTimeout($this._timer);
+				$this._timer = setTimeout(function() {
+					//屏幕坐标转地形上坐标
+					var cartesian = $this.getCatesian3FromPX(evt.position);
+					if (!cartesian) {
+						return;
+					}
+					if ($this._positions.length == 0) {
+						// $this._positions.push(cartesian.clone());
+						$this.floatingPoint = $this.createPoint(cartesian);
+						$this.createPoint(cartesian); // 绘制点
+					}
+					if ($this._positions.length == 1) {
+						$this._positions.push(cartesian.clone());
+						$this.createPoint(cartesian); // 绘制点
+					}
+					$this._positions.push(cartesian);
+
+				}, 200);
+			}
+
+		}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+		//移动时绘制面
+		this.handler.setInputAction(function(evt) {
+
+			/* 如果运行环境是App 则禁止使用鼠标移动事件 */
+			if (isRuntimeApp()) return;
+
+			// console.log('监听鼠标事件', '移动')
+
+			if ($this._positions.length == 0) {
+				$this._tooltip.showAt(evt.endPosition, "点击开始绘制");
+			} else {
+				$this._tooltip.showAt(evt.endPosition, "点击添加点");
+			}
+
+			if ($this._positions.length < 3) return;
+
+			// $this._tooltip.showAt(evt.endPosition, "点击添加点,右键删除点,双击结束绘制");
+			$this._tooltip.showAt(evt.endPosition, "点击添加点,双击结束绘制");
+
+			if (!$this.Cesium.defined($this._AttackArrow)) {
+				$this._AttackArrow = $this.createAttackArrow();
+			}
+
+			var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+			if (!cartesian) {
+				return;
+			}
+
+			$this.floatingPoint.position.setValue(cartesian);
+			if ($this._AttackArrow) {
+				$this._positions.pop();
+				$this._positions.push(cartesian);
+			}
+		}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+		//右键结束改为双击结束
+		this.handler.setInputAction(function(evt) {
+			// var cartesian = $this.getCatesian3FromPX(evt.position);
+			// $this._positions.pop();
+			// // $this._positions.push(cartesian);
+			// $this._AttackArrowData = $this._positions.concat();
+			// $this.viewer.entities.remove($this._AttackArrow); //移除
+			// $this._AttackArrow = null;
+			// $this._positions = [];
+			// $this.floatingPoint.position.setValue(cartesian);
+			// let lnglatArr = [];
+			// for (var i = 0; i < $this._AttackArrowData.length; i++) {
+			// 	var lnglat = $this.cartesianToLatlng($this._AttackArrowData[i]);
+			// 	lnglatArr.push(lnglat)
+			// }
+			// $this._AttackArrowData = lnglatArr;
+			// var straightArrow = $this.addload(lnglatArr); //加载
+			// $this._entities_AttackArrow.push(straightArrow);
+			// $this._AttackArrowLast = straightArrow;
+			// $this.clearPoint();
+			// $this.destroy()
+		}, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+		//双击结束
+		this.handler.setInputAction(function(evt) {
+
+			/* 如果运行环境是App 则禁止使用鼠标双击事件 */
+			if (isRuntimeApp()) return;
+
+			console.log('监听鼠标事件', '双击')
+
+			/* 解除锁定 */
+			clearTimeout($this._timer);
+
+			var cartesian = $this.getCatesian3FromPX(evt.position);
+			$this._positions.pop();
+			$this._positions.push(cartesian);
+			$this._AttackArrowData = $this._positions.concat();
+			$this.viewer.entities.remove($this._AttackArrow); //移除
+			$this._AttackArrow = null;
+			$this._positions = [];
+			$this.floatingPoint.position.setValue(cartesian);
+			let lnglatArr = [];
+			for (var i = 0; i < $this._AttackArrowData.length; i++) {
+				var lnglat = $this.cartesianToLatlng($this._AttackArrowData[i]);
+				lnglatArr.push(lnglat)
+			}
+			$this._AttackArrowData = lnglatArr;
+			var straightArrow = $this.addload(lnglatArr); //加载
+			$this._entities_AttackArrow.push(straightArrow);
+			$this._AttackArrowLast = straightArrow;
+			$this.clearPoint();
+			$this.destroy();
+
+			$this._tooltip.setVisible(false);
+
+		}, $this.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+	}
+
+	//创建攻击箭头
+	createAttackArrow() {
+		var $this = this;
+		var arrowEntity = $this.viewer.entities.add({
+			polygon: {
+				hierarchy: new $this.Cesium.CallbackProperty(
+					function() {
+						//计算面
+						var lnglatArr = [];
+						for (var i = 0; i < $this._positions.length; i++) {
+							var lnglat = $this.cartesianToLatlng($this._positions[i]);
+							lnglatArr.push(lnglat)
+						}
+						var res = $this.fineArrow(lnglatArr);
+						var returnData = res.polygonalPoint;
+						return new $this.Cesium.PolygonHierarchy(returnData);
+					}, false),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			}
+		})
+		$this._entities_AttackArrow.push(arrowEntity);
+		return arrowEntity
+	}
+
+	//创建点
+	createPoint(cartesian) {
+		var $this = this;
+		var point = this.viewer.entities.add({
+			position: cartesian,
+			point: {
+				pixelSize: 10,
+				color: $this.Cesium.Color.RED,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			}
+		});
+		point.objId = this.objId;
+		$this._entities_point.push(point);
+		return point;
+	}
+
+	cartesianToLatlng(cartesian) {
+		let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		let lat = this.Cesium.Math.toDegrees(cartographic.latitude);
+		let lng = this.Cesium.Math.toDegrees(cartographic.longitude);
+		let alt = cartographic.height;
+		return [lng, lat, alt];
+	}
+
+	//销毁
+	destroy() {
+		if (this.handler) {
+			this.handler.destroy();
+			this.handler = null;
+		}
+	}
+
+	clearPoint() {
+		this.DrawEndEvent.raiseEvent(this._AttackArrowLast, this._AttackArrowData, this.drawType);
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		this._entities_point = []; //脏数据
+	}
+
+	//清空实体对象
+	clear() {
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		for (var i = 0; i < this._entities_AttackArrow.length; i++) {
+			this.viewer.entities.remove(this._entities_AttackArrow[i]);
+		}
+
+		this.floatingPoint = null; //标识点
+		this._AttackArrow = null; //活动箭头
+		this._AttackArrowLast = null; //最后一个箭头
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_AttackArrow = []; //脏数据
+		this._AttackArrowData = null; //用于构造箭头数据
+	}
+
+	getCatesian3FromPX(px) {
+		var cartesian;
+		var ray = this.viewer.camera.getPickRay(px);
+		if (!ray) return null;
+		cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+		return cartesian;
+	}
+
+	////////////////////////////////////////求取箭头坐标函数/////////////////////////////////////////////////////
+	//箭头配置函数
+	fineArrowDefualParam() {
+		return {
+			headHeightFactor: .18,
+			headWidthFactor: .3,
+			neckHeightFactor: .85,
+			neckWidthFactor: .15,
+			tailWidthFactor: .1,
+			headTailFactor: .8,
+			swallowTailFactor: 1
+		}
+	}
+
+	fineArrow(inputPoint) {
+		var $this = this;
+		inputPoint = $this.dereplication(inputPoint);
+		let tailWidthFactor = $this.fineArrowDefualParam().tailWidthFactor;
+		let swallowTailFactor = $this.fineArrowDefualParam().swallowTailFactor;
+		let swallowTailPnt = $this.fineArrowDefualParam().swallowTailPnt;
+		//控制点
+		var result = {
+			controlPoint: null,
+			polygonalPoint: null
+		};
+		result.controlPoint = inputPoint;
+		var t = inputPoint.length;
+		if (!(2 > t)) {
+			if (2 == inputPoint.length) {
+				result.polygonalPoint = inputPoint;
+				return result;
+			}
+			var o = inputPoint,
+				e = o[0],
+				r = o[1];
+			$this.isClockWise(o[0], o[1], o[2]) && (e = o[1], r = o[0]);
+			var n = $this.mid(e, r),
+				g = [n].concat(o.slice(2)),
+				i = $this.getAttackArrowHeadPoints(g, e, r, $this.fineArrowDefualParam()),
+				s = i[0],
+				a = i[4],
+				l = $this.distance(e, r),
+				u = $this.getBaseLength(g),
+				c = u * tailWidthFactor * swallowTailFactor;
+			swallowTailPnt = $this.getThirdPoint(g[1], g[0], 0, c, !0);
+			var p = l / u,
+				h = $this.getAttackArrowBodyPoints(g, s, a, p),
+				t = h.length,
+				d = [e].concat(h.slice(0, t / 2));
+			d.push(s);
+			var f = [r].concat(h.slice(t / 2, t));
+			var newArray = [];
+			f.push(a),
+				d = $this.getQBSplinePoints(d),
+				f = $this.getQBSplinePoints(f),
+				newArray = $this.array2Dto1D(d.concat(i, f.reverse(), [swallowTailPnt, d[0]]));
+			result.polygonalPoint = $this.Cesium.Cartesian3.fromDegreesArray(newArray);
+		}
+		return result;
+	}
+
+	getArrowBodyPoints(t, o, e, r) {
+		var $this = this;
+		for (var n = $this.wholeDistance(t), g = $this.getBaseLength(t), i = g * r, s = $this.distance(o, e), a = (i - s) / 2, l = 0, u = [], c = [], p = 1; p < t.length - 1; p++) {
+			var h = $this.getAngleOfThreePoints(t[p - 1], t[p], t[p + 1]) / 2;
+			l += $this.distance(t[p - 1], t[p]);
+			var d = (i / 2 - l / n * a) / Math.sin(h),
+				f = $this.getThirdPoint(t[p - 1], t[p], Math.PI - h, d, !0),
+				E = $this.getThirdPoint(t[p - 1], t[p], h, d, !1);
+			u.push(f),
+				c.push(E)
+		}
+		return u.concat(c)
+	}
+
+	getAttackArrowHeadPoints(t, o, e, defaultParam) {
+		var $this = this;
+		let headHeightFactor = defaultParam.headHeightFactor;
+		let headTailFactor = defaultParam.headTailFactor;
+		let headWidthFactor = defaultParam.headWidthFactor;
+		let neckWidthFactor = defaultParam.neckWidthFactor;
+		let neckHeightFactor = defaultParam.neckHeightFactor;
+		var r = $this.getBaseLength(t),
+			n = r * headHeightFactor,
+			g = t[t.length - 1];
+		r = $this.distance(g, t[t.length - 2]);
+		var i = $this.distance(o, e);
+		n > i * headTailFactor && (n = i * headTailFactor);
+		var s = n * headWidthFactor,
+			a = n * neckWidthFactor;
+		n = n > r ? r : n;
+		var l = n * neckHeightFactor,
+			u = $this.getThirdPoint(t[t.length - 2], g, 0, n, !0),
+			c = $this.getThirdPoint(t[t.length - 2], g, 0, l, !0),
+			p = $this.getThirdPoint(g, u, Math.PI / 2, s, !1),
+			h = $this.getThirdPoint(g, u, Math.PI / 2, s, !0),
+			d = $this.getThirdPoint(g, c, Math.PI / 2, a, !1),
+			f = $this.getThirdPoint(g, c, Math.PI / 2, a, !0);
+		return [d, p, g, h, f]
+	}
+
+	getAttackArrowBodyPoints = function(t, o, e, r) {
+		var $this = this;
+		for (var n = $this.wholeDistance(t), g = $this.getBaseLength(t), i = g * r, s = $this.distance(o, e), a = (i - s) / 2, l = 0, u = [], c = [], p = 1; p < t.length - 1; p++) {
+			var h = $this.getAngleOfThreePoints(t[p - 1], t[p], t[p + 1]) / 2;
+			l += $this.distance(t[p - 1], t[p]);
+			var d = (i / 2 - l / n * a) / Math.sin(h),
+				f = $this.getThirdPoint(t[p - 1], t[p], Math.PI - h, d, !0),
+				E = $this.getThirdPoint(t[p - 1], t[p], h, d, !1);
+			u.push(f),
+				c.push(E)
+		}
+		return u.concat(c)
+	}
+
+	getAngleOfThreePoints(t, o, e) {
+		var r = this.getAzimuth(o, t) - this.getAzimuth(o, e);
+		return 0 > r ? r + Math.PI * 2 : r
+	}
+
+	dereplication(array) {
+		var last = array[array.length - 1];
+		var change = false;
+		var newArray = [];
+		newArray = array.filter(function(i) {
+			if (i[0] != last[0] && i[1] != last[1]) {
+				return i;
+			}
+			change = true;
+		});
+		if (change) newArray.push(last);
+		return newArray;
+	}
+
+	getBaseLength(t) {
+		return Math.pow(this.wholeDistance(t), .99)
+	}
+
+	wholeDistance(t) {
+		for (var o = 0, e = 0; e < t.length - 1; e++) o += this.distance(t[e], t[e + 1]);
+		return o
+	}
+
+	distance(t, o) {
+		return Math.sqrt(Math.pow(t[0] - o[0], 2) + Math.pow(t[1] - o[1], 2))
+	}
+
+	getThirdPoint(t, o, e, r, n) {
+		var g = this.getAzimuth(t, o),
+			i = n ? g + e : g - e,
+			s = r * Math.cos(i),
+			a = r * Math.sin(i);
+		return [o[0] + s, o[1] + a]
+	}
+
+	getAzimuth(t, o) {
+		var e, r = Math.asin(Math.abs(o[1] - t[1]) / this.distance(t, o));
+		return o[1] >= t[1] && o[0] >= t[0] ? e = r + Math.PI : o[1] >= t[1] && o[0] < t[0] ? e = 2 * Math.PI - r : o[1] < t[1] && o[0] < t[0] ? e = r : o[1] < t[1] && o[0] >= t[0] && (e = Math.PI - r), e
+	}
+
+	isClockWise(t, o, e) {
+		return (e[1] - t[1]) * (o[0] - t[0]) > (o[1] - t[1]) * (e[0] - t[0])
+	}
+
+	mid(t, o) {
+		return [(t[0] + o[0]) / 2, (t[1] + o[1]) / 2]
+	}
+
+	getQBSplinePoints = function(t) {
+		if (t.length <= 2) return t;
+		var o = 2,
+			e = [],
+			r = t.length - o - 1,
+			y = 0;
+		e.push(t[0]);
+		for (var n = 0; r >= n; n++)
+			for (var g = 0; 1 >= g; g += .05) {
+				for (var i = y = 0, s = 0; o >= s; s++) {
+					var a = this.getQuadricBSplineFactor(s, g);
+					i += a * t[n + s][0], y += a * t[n + s][1]
+				}
+				e.push([i, y])
+			}
+		return e.push(t[t.length - 1]), e
+	}
+	getQuadricBSplineFactor = function(t, o) {
+		return 0 == t ? Math.pow(o - 1, 2) / 2 : 1 == t ? (-2 * Math.pow(o, 2) + 2 * o + 1) / 2 : 2 == t ? Math.pow(o, 2) / 2 : 0
+	}
+	array2Dto1D = function(array) {
+		var newArray = [];
+		array.forEach(function(elt) {
+			newArray.push(elt[0]);
+			newArray.push(elt[1]);
+		});
+		return newArray;
+	}
+}
+
+export default DrawAttackArrow

+ 251 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawCircle.js

@@ -0,0 +1,251 @@
+// 四、圆
+/*
+绘制圆
+ */
+class DrawCircle {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        this._cicle = null; //活动圆
+        this.floatingPoint = null;
+        this._cicleLast = null; //最后一个圆
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_cicle = [];  //脏数据
+        this._cicleData = null; //用于构造圆形数据
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+ 
+    get cicle() {
+        return this._cicleLast;
+    }
+ 
+    //加载圆
+    addload(data) {
+        var that = this;
+        let lnglatArr = [];
+            for (var i = 0; i < data.length; i++) {
+                var lnglat = that.LatlngTocartesian(data[i]);
+                lnglatArr.push(lnglat)
+        }
+        var value = lnglatArr;
+        var r = Math.sqrt(
+            Math.pow(value[0].x - value[value.length - 1].x, 2) +
+            Math.pow(value[0].y - value[value.length - 1].y, 2)
+        );
+        var position = value[0];
+        var shape = that.viewer.entities.add({
+            Type:'DrawCircle',
+            Position:[data[0],data[data.length - 1]],
+            position: position,
+            id:data.id || that.objId,
+            ellipse: {
+                semiMinorAxis: r,
+                semiMajorAxis: r,
+                material: that.Cesium.Color.RED.withAlpha(0.9),
+                // outline: true,
+                show: true,
+                clampToGround: true,
+            }
+        });
+        return shape;
+    }
+ 
+    //返回数据
+    getData() {
+        return this._cicleData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data){
+        var that = this;
+        let lnglatArr = [];
+            for (var i = 0; i < data.length; i++) {
+                var lnglat = that.cartesianToLatlng(data[i]);
+                lnglatArr.push(lnglat)
+        }
+        that._cicleData = lnglatArr;
+        var value = data;
+        var r = Math.sqrt(
+            Math.pow(value[0].x - value[value.length - 1].x, 2) +
+            Math.pow(value[0].y - value[value.length - 1].y, 2)
+        );
+        var position = value[0];
+        return   {position,r}
+    }
+ 
+    startCreate(drawType) {
+        this.drawType = drawType
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.viewer.scene.globe.depthTestAgainstTerrain = true;
+        var $this = this;
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            $this.viewer.scene.globe.depthTestAgainstTerrain = true;
+            //屏幕坐标转地形上坐标
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if ($this._positions.length == 0) {
+                $this._positions.push(cartesian.clone());
+                $this.floatingPoint = $this.createPoint(cartesian);
+                $this._positions.push(cartesian);
+            }
+            if (!$this._cicle) {
+                $this.createPoint(cartesian);// 绘制点
+            }
+            
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制圆
+            if ($this._positions.length < 1) return;
+            var cartesian = $this.viewer.scene.pickPosition(evt.endPosition);// $this.getCatesian3FromPX(evt.endPosition);
+            if (!$this.Cesium.defined($this._cicle)) {
+                $this._cicle = $this.createCicle();
+            }
+            $this.floatingPoint.position.setValue(cartesian);
+            if ($this._cicle) {
+                $this._positions.pop();
+                $this._positions.push(cartesian);
+            }
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.setInputAction(function (evt) {
+            if (!$this._cicle) return;
+            $this.viewer.scene.globe.depthTestAgainstTerrain = false;
+            var cartesian = $this.viewer.scene.pickPosition(evt.position); // $this.getCatesian3FromPX(evt.position);
+            $this._positions.pop();
+            $this._positions.push(cartesian);
+            $this._cicleData = $this._positions.concat();
+            $this.viewer.entities.remove($this._cicle); //移除
+            $this._cicle = null;
+            $this._positions = [];
+            $this.floatingPoint.position.setValue(cartesian);
+            let lnglatArr = [];
+            for (var i = 0; i < $this._cicleData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this._cicleData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this._cicleData = lnglatArr;
+            var cicle = $this.addload($this._cicleData); //加载
+            $this._entities_cicle.push(cicle);
+            $this._cicleLast = cicle;
+            $this.clearPoint();
+            // if(typeof $this.callback=="function"){
+            //     $this.callback(cicle);
+            // }
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+ 
+    //创建圆
+    createCicle() {
+        var that = this;
+        var shape = this.viewer.entities.add({
+            position: that._positions[0],
+            ellipse: {
+                semiMinorAxis: new that.Cesium.CallbackProperty(function () {
+                    //半径 两点间距离
+                    var r = Math.sqrt(
+                        Math.pow(that._positions[0].x - that._positions[that._positions.length - 1].x, 2) +
+                        Math.pow(that._positions[0].y - that._positions[that._positions.length - 1].y, 2)
+                    );
+                    return r ? r : r + 1;
+                }, false),
+                semiMajorAxis: new that.Cesium.CallbackProperty(function () {
+                    var r = Math.sqrt(
+                        Math.pow(that._positions[0].x - that._positions[that._positions.length - 1].x, 2) +
+                        Math.pow(that._positions[0].y - that._positions[that._positions.length - 1].y, 2)
+                    );
+                    return r ? r : r + 1;
+                }, false),
+                material: that.Cesium.Color.RED.withAlpha(0.5),
+                outline: true
+            }
+        });
+        that._entities_cicle.push(shape);
+        return shape;
+    }
+ 
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });;
+        $this._entities_point.push(point);
+        return point;
+    }
+ 
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+
+    cartesianToLatlng(cartesian) {
+        let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        let lat = this.Cesium.Math.toDegrees(cartographic.latitude);
+        let lng = this.Cesium.Math.toDegrees(cartographic.longitude);
+        let alt = cartographic.height;
+        return [lng, lat];
+    }
+    LatlngTocartesian(latlng){
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0],latlng[1],0);
+        return cartesian3
+    }
+ 
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+ 
+    clearPoint(){
+        this.DrawEndEvent.raiseEvent(this._cicleLast, this._cicleData, this.drawType);
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        this._entities_point = [];  //脏数据
+    }
+    clear() {
+ 
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+ 
+        for (var i = 0; i < this._entities_cicle.length; i++) {
+            this.viewer.entities.remove(this._entities_cicle[i]);
+        }
+        this._cicle = null; //活动圆
+        this.floatingPoint = null;
+        this._cicleLast = null; //最后一个圆
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_cicle = [];  //脏数据
+        this._cicleData = null; //用于构造圆形数据
+    }
+}
+ 
+export default DrawCircle

+ 597 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawClosedCurve.js

@@ -0,0 +1,597 @@
+import {
+	createTooltip
+} from "../../../common/common.js";
+
+import {
+	isRuntimeApp,
+	isRuntimeWeb,
+	createOperationMainDom,
+	showTooltipMessage
+} from "../../../common/RuntimeEnvironment.js";
+
+
+// 闭合曲面
+class DrawClosedCurve {
+	constructor(arg) {
+		this.viewer = arg.viewer;
+		this.Cesium = arg.Cesium;
+		this.floatingPoint = null; //标识点
+		this._ClosedCurve = null; //活动闭合曲面
+		this._ClosedCurveLast = null; //最后一个闭合曲面
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_ClosedCurve = []; //脏数据
+		this._ClosedCurveData = null; //用于构造闭合曲面数据
+		this.ZERO_TOLERANCE = 0.0001;
+		this.FITTING_COUNT = 100;
+		this.t = 0.3
+		this.objId = Number((new Date()).getTime() + "" + Number(Math.random() * 1000).toFixed(0));
+		this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+		this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+
+		this._tooltip = createTooltip(this.viewer.container);
+
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+	}
+
+	//返回闭合曲面
+	get ClosedCurve() {
+		return this._ClosedCurveLast;
+	}
+
+	//返回闭合曲面数据用于加载闭合曲面
+	getData() {
+		return this._ClosedCurveData;
+	}
+
+	// 修改编辑调用计算
+	computePosition(data) {
+		let $this = this;
+		if (data.length < 2) return
+		let pnts = []
+		for (let p = 0; p < data.length; p++) {
+			pnts.push($this.cartesianToLatlng(data[p]))
+		}
+		this._ClosedCurveData = Array.from(pnts);
+		pnts.push(pnts[0], pnts[1])
+		let [normals, pList] = [
+			[],
+			[]
+		]
+		for (let i = 0; i < pnts.length - 2; i++) {
+			let normalPoints = $this.getBisectorNormals($this.t, pnts[i], pnts[i + 1], pnts[i + 2])
+			normals = normals.concat(normalPoints)
+		}
+		let count = normals.length
+		normals = [normals[count - 1]].concat(normals.slice(0, count - 1))
+		for (let i = 0; i < pnts.length - 2; i++) {
+			let pnt1 = pnts[i]
+			let pnt2 = pnts[i + 1]
+			pList.push($this.LatlngTocartesian(pnt1))
+			for (let t = 0; t <= $this.FITTING_COUNT; t++) {
+				let pnt = $this.getCubicValue(t / $this.FITTING_COUNT, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)
+				pList.push($this.LatlngTocartesian(pnt))
+			}
+			pList.push($this.LatlngTocartesian(pnt2))
+		}
+		let PolygonHierarchy = new $this.Cesium.PolygonHierarchy(pList);
+		return {
+			PolygonHierarchy,
+			pList
+		}
+	}
+
+	//加载闭合曲面
+	addload(data) {
+		let $this = this
+		if (data.length < 2) return
+		let pnts = Array.from(data);
+		pnts.push(pnts[0], pnts[1])
+		let [normals, pList] = [
+			[],
+			[]
+		]
+		for (let i = 0; i < pnts.length - 2; i++) {
+			let normalPoints = $this.getBisectorNormals($this.t, pnts[i], pnts[i + 1], pnts[i + 2])
+			normals = normals.concat(normalPoints)
+		}
+		let count = normals.length
+		normals = [normals[count - 1]].concat(normals.slice(0, count - 1))
+		for (let i = 0; i < pnts.length - 2; i++) {
+			let pnt1 = pnts[i]
+			let pnt2 = pnts[i + 1]
+			pList.push($this.LatlngTocartesian(pnt1))
+			for (let t = 0; t <= $this.FITTING_COUNT; t++) {
+				let pnt = $this.getCubicValue(t / $this.FITTING_COUNT, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)
+				pList.push($this.LatlngTocartesian(pnt))
+			}
+			pList.push($this.LatlngTocartesian(pnt2))
+		}
+		console.log(data, pnts)
+		var arrowEntity = $this.viewer.entities.add({
+			Type: 'DrawClosedCurve',
+			Position: data,
+			id: data.id || $this.objId,
+			polygon: {
+				hierarchy: new $this.Cesium.PolygonHierarchy(pList),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			},
+			polyline: {
+				positions: pList,
+				show: true,
+				material: new Cesium.PolylineDashMaterialProperty({
+					color: Cesium.Color.YELLOW,
+				}),
+				width: 3,
+				clampToGround: true
+			}
+
+		});
+		return arrowEntity;
+	}
+
+	//开始创建
+	startCreate(drawType) {
+
+		if (isRuntimeApp()) {
+			showTooltipMessage("点击开始绘制");
+		}
+
+		var $this = this;
+
+		this.drawType = drawType;
+		this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+		//单击开始绘制
+		this.handler.setInputAction(function(evt) {
+			if (isRuntimeApp()) {
+
+				//屏幕坐标转地形上坐标
+				var cartesian = $this.getCatesian3FromPX(evt.position);
+				if (!cartesian) {
+					return;
+				}
+
+				$this.createPoint(cartesian); // 绘制点
+				$this._positions.push(cartesian);
+
+				if ($this._positions.length > 2) {
+					showTooltipMessage("点击添加点,点击完成按钮,结束绘制");
+					if ($this._positions.length === 3) {
+						
+						if (!$this.Cesium.defined($this._ClosedCurve)) {
+							$this._ClosedCurve = $this.createClosedCurve();
+
+							//创建按钮
+							createOperationMainDom();
+							//完成绘制
+							document.getElementById("btnDrawComplete").onclick = () => {
+
+								$this._ClosedCurveData = $this._positions.concat();
+								$this.viewer.entities.remove($this._ClosedCurve); //移除
+								$this._ClosedCurve = null;
+								$this._positions = [];
+								var lnglatArr = [];
+								for (var i = 0; i < $this._ClosedCurveData.length; i++) {
+									var lnglat = $this.cartesianToLatlng($this._ClosedCurveData[i]);
+									lnglatArr.push(lnglat)
+								}
+								$this._ClosedCurveData = lnglatArr;
+								var ClosedCurve = $this.addload(lnglatArr); //加载
+								$this._entities_ClosedCurve.push(ClosedCurve);
+								$this._ClosedCurveLast = ClosedCurve;
+								$this.clearPoint();
+								$this.destroy();
+
+								let buttonDiv = document.getElementById("drawButtonDiv");
+								if (buttonDiv) {
+									//从页面移除
+									document.body.removeChild(buttonDiv);
+								}
+							}
+						}
+					}
+
+				} else {
+					showTooltipMessage("点击添加点");
+				}
+
+			} else {
+				console.log('监听鼠标事件', '单击')
+
+				/* 锁定点击事件 以免和双击事件冲突 */
+				clearTimeout($this._timer);
+				$this._timer = setTimeout(function() {
+					//屏幕坐标转地形上坐标
+					var cartesian = $this.getCatesian3FromPX(evt.position);
+					if ($this._positions.length == 0) {
+						$this.floatingPoint = $this.createPoint(cartesian);
+					}
+					$this._positions.push(cartesian);
+					$this.createPoint(cartesian);
+				}, 200);
+			}
+		}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+		//移动时绘制面
+		this.handler.setInputAction(function(evt) {
+
+			/* 如果运行环境是App 则禁止使用鼠标移动事件 */
+			if (isRuntimeApp()) return;
+
+			if ($this._positions.length == 0) {
+				$this._tooltip.showAt(evt.endPosition, "点击开始绘制");
+			} else {
+				$this._tooltip.showAt(evt.endPosition, "点击添加点");
+			}
+
+			if ($this._positions.length < 2) return;
+
+			$this._tooltip.showAt(evt.endPosition, "点击添加点,双击结束绘制");
+
+			var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+			if ($this._positions.length == 2) {
+				$this._positions.push(cartesian);
+			}
+			$this._positions.pop();
+			$this._positions.push(cartesian);
+			if (!$this.Cesium.defined($this._ClosedCurve)) {
+				$this._ClosedCurve = $this.createClosedCurve();
+			}
+
+		}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+		//右击停止采集改为双击结束
+		this.handler.setInputAction(function(evt) {
+			// if (!$this._ClosedCurve) return;
+			// var cartesian = $this.getCatesian3FromPX(evt.position);
+			// $this._positions.pop();
+			// $this._positions.push(cartesian);
+			// $this._ClosedCurveData = $this._positions.concat();
+			// $this.viewer.entities.remove($this._ClosedCurve); //移除
+			// $this._ClosedCurve = null;
+			// $this._positions = [];
+			// $this.floatingPoint.position.setValue(cartesian);
+			// var lnglatArr = [];
+			// for (var i = 0; i < $this._ClosedCurveData.length; i++) {
+			// 	var lnglat = $this.cartesianToLatlng($this._ClosedCurveData[i]);
+			// 	lnglatArr.push(lnglat)
+			// }
+			// $this._ClosedCurveData = lnglatArr;
+			// var ClosedCurve = $this.addload(lnglatArr); //加载
+			// $this._entities_ClosedCurve.push(ClosedCurve);
+			// $this._ClosedCurveLast = ClosedCurve;
+			// $this.clearPoint();
+			// $this.destroy()
+		}, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+		//双击结束
+		this.handler.setInputAction(function(evt) {
+			/* 如果运行环境是App 则禁止使用鼠标双击事件 */
+			if (isRuntimeApp()) return;
+
+			console.log('监听鼠标事件', '双击')
+
+			/* 解除锁定 */
+			clearTimeout($this._timer);
+
+			if (!$this._ClosedCurve) return;
+
+			var cartesian = $this.getCatesian3FromPX(evt.position);
+			$this._positions.pop();
+			$this._positions.push(cartesian);
+			$this._ClosedCurveData = $this._positions.concat();
+			$this.viewer.entities.remove($this._ClosedCurve); //移除
+			$this._ClosedCurve = null;
+			$this._positions = [];
+			$this.floatingPoint.position.setValue(cartesian);
+			var lnglatArr = [];
+			for (var i = 0; i < $this._ClosedCurveData.length; i++) {
+				var lnglat = $this.cartesianToLatlng($this._ClosedCurveData[i]);
+				lnglatArr.push(lnglat)
+			}
+			$this._ClosedCurveData = lnglatArr;
+			var ClosedCurve = $this.addload(lnglatArr); //加载
+			$this._entities_ClosedCurve.push(ClosedCurve);
+			$this._ClosedCurveLast = ClosedCurve;
+			$this.clearPoint();
+			$this.destroy();
+
+			$this._tooltip.setVisible(false);
+		}, $this.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+	}
+
+	//创建直线闭合曲面
+	createClosedCurve() {
+		// console.log(this._positions)
+		var $this = this;
+		$this.pLists = ''
+		var arrowEntity = $this.viewer.entities.add({
+			polygon: {
+				hierarchy: new $this.Cesium.CallbackProperty(
+					function() {
+						if ($this._positions.length < 2) return
+						let pnts = []
+						for (let p = 0; p < $this._positions.length; p++) {
+							pnts.push($this.cartesianToLatlng($this._positions[p]))
+						}
+						pnts.push(pnts[0], pnts[1])
+						let [normals, pList] = [
+							[],
+							[]
+						]
+						for (let i = 0; i < pnts.length - 2; i++) {
+							let normalPoints = $this.getBisectorNormals($this.t, pnts[i], pnts[i + 1], pnts[i + 2])
+							normals = normals.concat(normalPoints)
+						}
+						let count = normals.length
+						normals = [normals[count - 1]].concat(normals.slice(0, count - 1))
+						for (let i = 0; i < pnts.length - 2; i++) {
+							let pnt1 = pnts[i]
+							let pnt2 = pnts[i + 1]
+							pList.push($this.LatlngTocartesian(pnt1))
+							for (let t = 0; t <= $this.FITTING_COUNT; t++) {
+								let pnt = $this.getCubicValue(t / $this.FITTING_COUNT, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)
+								pList.push($this.LatlngTocartesian(pnt))
+							}
+							pList.push($this.LatlngTocartesian(pnt2))
+						}
+						$this.pLists = pList
+						return new $this.Cesium.PolygonHierarchy(pList);
+					}, false),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			},
+			polyline: {
+				positions: new $this.Cesium.CallbackProperty(
+					function() {
+						return $this.pLists
+					}, false
+				),
+				show: true,
+				material: new Cesium.PolylineDashMaterialProperty({
+					color: Cesium.Color.YELLOW,
+				}),
+				width: 3,
+				clampToGround: true
+			}
+		})
+		$this._entities_ClosedCurve.push(arrowEntity);
+		return arrowEntity
+	}
+
+	//创建点
+	createPoint(cartesian) {
+		var $this = this;
+		var point = this.viewer.entities.add({
+			position: cartesian,
+			point: {
+				pixelSize: 10,
+				color: $this.Cesium.Color.RED,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			}
+		});
+		$this._entities_point.push(point);
+		return point;
+	}
+
+
+	/**
+	 * 世界坐标转经纬度
+	 */
+	cartesianToLatlng(cartesian) {
+		var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+		var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+		return [lng, lat];
+	}
+
+	/**
+	 * 经纬度转世界坐标
+	 */
+	LatlngTocartesian(latlng) {
+		let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+		return cartesian3
+	}
+
+	/**
+	 * 经纬度坐标转墨卡托坐标
+	 */
+	// 墨卡托坐标系:展开地球,赤道作为x轴,向东为x轴正方,本初子午线作为y轴,向北为y轴正方向。
+	// 数字20037508.34是地球赤道周长的一半:地球半径6378137米,赤道周长2*PI*r = 2 * 20037508.3427892,墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892]
+	lonLatToMercator(Latlng) {
+		var E = Latlng[0];
+		var N = Latlng[1];
+		var x = E * 20037508.34 / 180;
+		var y = Math.log(Math.tan((90 + N) * Math.PI / 360)) / (Math.PI / 180);
+		y = y * 20037508.34 / 180;
+		return [x, y]
+	}
+	/**
+	 * 墨卡托坐标转经纬度坐标转
+	 */
+	WebMercator2lonLat(mercator) {
+		let x = mercator[0] / 20037508.34 * 180;
+		let ly = mercator[1] / 20037508.34 * 180;
+		let y = 180 / Math.PI * (2 * Math.atan(Math.exp(ly * Math.PI / 180)) - Math.PI / 2)
+		return [x, y];
+	}
+
+	//销毁
+	destroy() {
+		if (this.handler) {
+			this.handler.destroy();
+			this.handler = null;
+		}
+	}
+
+	clearPoint() {
+		this.DrawEndEvent.raiseEvent(this._ClosedCurveLast, this._ClosedCurveData);
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		this._entities_point = []; //脏数据
+	}
+
+	//清空实体对象
+	clear() {
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		for (var i = 0; i < this._entities_ClosedCurve.length; i++) {
+			this.viewer.entities.remove(this._entities_ClosedCurve[i]);
+		}
+		this.floatingPoint = null; //标识点
+		this._ClosedCurve = null; //活动闭合曲面
+		this._ClosedCurveLast = null; //最后一个闭合曲面
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_ClosedCurve = []; //脏数据
+		this._ClosedCurveData = null; //用于构造闭合曲面数据
+	}
+
+	getCatesian3FromPX(px) {
+		var cartesian;
+		var ray = this.viewer.camera.getPickRay(px);
+		if (!ray) return null;
+		cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+		return cartesian;
+	}
+
+	// 求取闭合曲面坐标函数/
+	//闭合曲面配置函数
+	/**
+	 * getBisectorNormals
+	 * @param t
+	 * @param pnt1
+	 * @param pnt2
+	 * @param pnt3
+	 * @returns {[*,*]}
+	 */
+	getBisectorNormals(t, pnt1, pnt2, pnt3) {
+		let $this = this
+		let normal = $this.getNormal(pnt1, pnt2, pnt3)
+		let [bisectorNormalRight, bisectorNormalLeft, dt, x, y] = [null, null, null, null, null]
+		let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
+		let uX = normal[0] / dist
+		let uY = normal[1] / dist
+		let d1 = $this.MathDistance(pnt1, pnt2)
+		let d2 = $this.MathDistance(pnt2, pnt3)
+
+		if (dist > $this.ZERO_TOLERANCE) {
+			if ($this.isClockWise(pnt1, pnt2, pnt3)) {
+				dt = t * d1
+				x = pnt2[0] - dt * uY
+				y = pnt2[1] + dt * uX
+				bisectorNormalRight = [x, y]
+				dt = t * d2
+				x = pnt2[0] + dt * uY
+				y = pnt2[1] - dt * uX
+				bisectorNormalLeft = [x, y]
+			} else {
+				dt = t * d1
+				x = pnt2[0] + dt * uY
+				y = pnt2[1] - dt * uX
+				bisectorNormalRight = [x, y]
+				dt = t * d2
+				x = pnt2[0] - dt * uY
+				y = pnt2[1] + dt * uX
+				bisectorNormalLeft = [x, y]
+			}
+		} else {
+			x = pnt2[0] + t * (pnt1[0] - pnt2[0])
+			y = pnt2[1] + t * (pnt1[1] - pnt2[1])
+			bisectorNormalRight = [x, y]
+			x = pnt2[0] + t * (pnt3[0] - pnt2[0])
+			y = pnt2[1] + t * (pnt3[1] - pnt2[1])
+			bisectorNormalLeft = [x, y]
+		}
+		return [bisectorNormalRight, bisectorNormalLeft]
+	}
+
+
+	/**
+	 * 获取默认三点的内切圆
+	 * @param pnt1
+	 * @param pnt2
+	 * @param pnt3
+	 * @returns {[*,*]}
+	 */
+	getNormal(pnt1, pnt2, pnt3) {
+		let dX1 = pnt1[0] - pnt2[0]
+		let dY1 = pnt1[1] - pnt2[1]
+		let d1 = Math.sqrt(dX1 * dX1 + dY1 * dY1)
+		dX1 /= d1
+		dY1 /= d1
+		let dX2 = pnt3[0] - pnt2[0]
+		let dY2 = pnt3[1] - pnt2[1]
+		let d2 = Math.sqrt(dX2 * dX2 + dY2 * dY2)
+		dX2 /= d2
+		dY2 /= d2
+		let uX = dX1 + dX2
+		let uY = dY1 + dY2
+		return [uX, uY]
+	}
+
+	/**
+	 * 计算两个坐标之间的距离
+	 * @ignore
+	 * @param pnt1
+	 * @param pnt2
+	 * @returns {number}
+	 * @constructor
+	 */
+	MathDistance(pnt1, pnt2) {
+		return (Math.sqrt(Math.pow((pnt1[0] - pnt2[0]), 2) + Math.pow((pnt1[1] - pnt2[1]), 2)))
+	}
+
+	/**
+	 * 判断是否是顺时针
+	 * @param pnt1
+	 * @param pnt2
+	 * @param pnt3
+	 * @returns {boolean}
+	 */
+	isClockWise(pnt1, pnt2, pnt3) {
+		return ((pnt3[1] - pnt1[1]) * (pnt2[0] - pnt1[0]) > (pnt2[1] - pnt1[1]) * (pnt3[0] - pnt1[0]))
+	}
+
+	/**
+	 * 获取立方值
+	 * @param t
+	 * @param startPnt
+	 * @param cPnt1
+	 * @param cPnt2
+	 * @param endPnt
+	 * @returns {[*,*]}
+	 */
+	getCubicValue(t, startPnt, cPnt1, cPnt2, endPnt) {
+		t = Math.max(Math.min(t, 1), 0)
+		let [tp, t2] = [(1 - t), (t * t)]
+		let t3 = t2 * t
+		let tp2 = tp * tp
+		let tp3 = tp2 * tp
+		let x = (tp3 * startPnt[0]) + (3 * tp2 * t * cPnt1[0]) + (3 * tp * t2 * cPnt2[0]) + (t3 * endPnt[0])
+		let y = (tp3 * startPnt[1]) + (3 * tp2 * t * cPnt1[1]) + (3 * tp * t2 * cPnt2[1]) + (t3 * endPnt[1])
+		return [x, y]
+	}
+
+}
+
+export default DrawClosedCurve

+ 510 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawCurve.js

@@ -0,0 +1,510 @@
+// 三、曲线
+// DrawCurve
+/*
+绘制曲线
+ */
+class DrawCurve {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        this.floatingPoint = null;//标识点
+        this._curveline = null; //活动曲线
+        this._curvelineLast = null; //最后一条曲线
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_line = [];  //脏数据
+        this._curvelineData = null; //用于构造曲线数据
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+        this.ZERO_TOLERANCE = 0.0001;
+        this.FITTING_COUNT = 100;
+        this.t = 0.3;
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+
+    //返回最后活动曲线
+    get curveline() {
+        return this._curvelineLast;
+    }
+
+    //返回线数据用于加载线
+    getData() {
+        return this._curvelineData;
+    }
+
+    //加载曲线
+    addload(data) {
+        var $this = this;
+        let pnts = []
+        for (let p = 0; p < data.length; p++) {
+            pnts.push($this.lonLatToMercator(data[p]))
+        }
+        let CurvePoints = $this.getCurvePoints(pnts)
+        let point = [];
+        for (let i = 0; i < CurvePoints.length; i++) {
+            point.push($this.LatlngTocartesian($this.WebMercator2lonLat(CurvePoints[i])))
+        }
+        var polyline = this.viewer.entities.add({
+            Type: 'DrawCurve',
+            Position: data,
+            id: data.id || $this.objId,
+            polyline: {
+                positions: point,
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 3,
+                clampToGround: true
+            }
+        });
+        return polyline;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data) {
+        let pnts = [];
+        let position = [];
+        for (let p = 0; p < data.length; p++) {
+            position.push(this.cartesianToLatlng(data[p]));
+            pnts.push(this.lonLatToMercator(this.cartesianToLatlng(data[p])))
+        }
+        this._curvelineData = position;
+        let CurvePoints = this.getCurvePoints(pnts)
+        let point = [];
+        for (let i = 0; i < CurvePoints.length; i++) {
+            point.push(this.LatlngTocartesian(this.WebMercator2lonLat(CurvePoints[i])))
+        }
+        return point;
+    }
+
+    //开始创建
+    startCreate(drawType) {
+        this.drawType = drawType
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            //屏幕坐标转地形上坐标
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if ($this._positions.length == 0) {
+                $this._positions.push(cartesian.clone());
+                $this.floatingPoint = $this.createPoint(cartesian);
+                $this.createPoint(cartesian);// 绘制点
+            }
+            $this._positions.push(cartesian);
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制线
+            if ($this._positions.length < 3) return;
+            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+            if (!$this.Cesium.defined($this._curveline)) {
+                $this._curveline = $this.createCurveline();
+            }
+            $this.floatingPoint.position.setValue(cartesian);
+            if ($this._curveline) {
+                $this._positions.pop();
+                $this._positions.push(cartesian);
+            }
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.setInputAction(function (evt) {
+            if (!$this._curveline) return;
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            $this._positions.pop();
+            $this._positions.push(cartesian);
+            $this.createPoint(cartesian);// 绘制点
+            $this._curvelineData = $this._positions.concat();
+            $this.viewer.entities.remove($this._curveline); //移除
+            $this._curveline = null;
+            $this._positions = [];
+            $this.floatingPoint.position.setValue(cartesian);
+            let lnglatArr = [];
+            for (var i = 0; i < $this._curvelineData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this._curvelineData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this._curvelineData = lnglatArr;
+            var line = $this.addload($this._curvelineData); //加载曲线
+            $this._entities_line.push(line);
+            $this._curvelineLast = line;
+            $this.clearPoint()
+            $this.destroy()
+
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+               pixelSize: 10,
+               color: $this.Cesium.Color.RED,
+               heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this._entities_point.push(point);
+        return point;
+    }
+
+    //创建曲线
+    createCurveline() {
+        var $this = this;
+        var polyline = this.viewer.entities.add({
+            polyline: {
+                //使用cesium的peoperty
+                positions: new $this.Cesium.CallbackProperty(function () {
+                    let pnts = []
+                    for (let p = 0; p < $this._positions.length; p++) {
+                        pnts.push($this.lonLatToMercator($this.cartesianToLatlng($this._positions[p])))
+                    }
+                    let CurvePoints = $this.getCurvePoints(pnts)
+                    let point = [];
+                    for (let i = 0; i < CurvePoints.length; i++) {
+                        point.push($this.LatlngTocartesian($this.WebMercator2lonLat(CurvePoints[i])))
+                    }
+                    return point;
+                }, false),
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 3,
+                clampToGround: true
+            }
+        });
+        $this._entities_line.push(polyline);
+        return polyline;
+    }
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this._curvelineLast, this._curvelineData, this.drawType);
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        this._entities_point = [];  //脏数据
+    }
+
+    //销毁
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        for (var i = 0; i < this._entities_line.length; i++) {
+            this.viewer.entities.remove(this._entities_line[i]);
+        }
+        this.floatingPoint = null;//标识点
+        this._curveline = null; //活动曲线
+        this._curvelineLast = null; //最后一条曲线
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_line = [];  //脏数据
+        this._curvelineData = null; //用于构造曲线数据
+    }
+
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+
+    cartesianToLatlng(cartesian) {
+        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+        var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+        return [lng, lat];
+    }
+
+    LatlngTocartesian(latlng) {
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+        return cartesian3
+    }
+
+    /**
+     * 经纬度坐标转墨卡托坐标
+     */
+    // 墨卡托坐标系:展开地球,赤道作为x轴,向东为x轴正方,本初子午线作为y轴,向北为y轴正方向。
+    // 数字20037508.34是地球赤道周长的一半:地球半径6378137米,赤道周长2*PI*r = 2 * 20037508.3427892,墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892]
+    lonLatToMercator(Latlng) {
+        var E = Latlng[0];
+        var N = Latlng[1];
+        var x = E * 20037508.34 / 180;
+        var y = Math.log(Math.tan((90 + N) * Math.PI / 360)) / (Math.PI / 180);
+        y = y * 20037508.34 / 180;
+        return [x, y]
+    }
+    /**
+     * 墨卡托坐标转经纬度坐标转
+     */
+    WebMercator2lonLat(mercator) {
+        let x = mercator[0] / 20037508.34 * 180;
+        let ly = mercator[1] / 20037508.34 * 180;
+        let y = 180 / Math.PI * (2 * Math.atan(Math.exp(ly * Math.PI / 180)) - Math.PI / 2)
+        return [x, y];
+    }
+
+
+
+    /**
+     * 插值曲线点
+     * @param t
+     * @param controlPoints
+     * @returns {null}
+     */
+    getCurvePoints( controlPoints) {
+        let leftControl = this.getLeftMostControlPoint(controlPoints, this.t)
+        let [pnt1, pnt2, pnt3, normals, points] = [null, null, null, [leftControl], []]
+        for (let i = 0; i < controlPoints.length - 2; i++) {
+            [pnt1, pnt2, pnt3] = [controlPoints[i], controlPoints[i + 1], controlPoints[i + 2]]
+            let normalPoints = this.getBisectorNormals(this.t, pnt1, pnt2, pnt3)
+            normals = normals.concat(normalPoints)
+        }
+        let rightControl = this.getRightMostControlPoint(controlPoints, this.t)
+        if (rightControl) {
+            normals.push(rightControl)
+        }
+        for (let i = 0; i < controlPoints.length - 1; i++) {
+            pnt1 = controlPoints[i]
+            pnt2 = controlPoints[i + 1]
+            points.push(pnt1)
+            for (let t = 0; t < this.FITTING_COUNT; t++) {
+                let pnt = this.getCubicValue(t / this.FITTING_COUNT, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)
+                points.push(pnt)
+            }
+            points.push(pnt2)
+        }
+        return points
+    }
+
+
+
+
+    /**
+     * 获取左边控制点
+     * @param controlPoints
+     * @returns {[*,*]}
+     */
+    getLeftMostControlPoint(controlPoints, t) {
+        let [pnt1, pnt2, pnt3, controlX, controlY] = [controlPoints[0], controlPoints[1], controlPoints[2], null, null]
+        let pnts = this.getBisectorNormals(0, pnt1, pnt2, pnt3)
+        let normalRight = pnts[0]
+        let normal = this.getNormal(pnt1, pnt2, pnt3)
+        let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
+        if (dist > this.ZERO_TOLERANCE) {
+            let mid = this.Mid(pnt1, pnt2)
+            let pX = pnt1[0] - mid[0]
+            let pY = pnt1[1] - mid[1]
+            let d1 = this.MathDistance(pnt1, pnt2)
+            let n = 2.0 / d1
+            let nX = -n * pY
+            let nY = n * pX
+            let a11 = nX * nX - nY * nY
+            let a12 = 2 * nX * nY
+            let a22 = nY * nY - nX * nX
+            let dX = normalRight[0] - mid[0]
+            let dY = normalRight[1] - mid[1]
+            controlX = mid[0] + a11 * dX + a12 * dY
+            controlY = mid[1] + a12 * dX + a22 * dY
+        } else {
+            controlX = pnt1[0] + t * (pnt2[0] - pnt1[0])
+            controlY = pnt1[1] + t * (pnt2[1] - pnt1[1])
+        }
+        return [controlX, controlY]
+    }
+
+
+    /**
+     * getBisectorNormals
+     * @param t
+     * @param pnt1
+     * @param pnt2
+     * @param pnt3
+     * @returns {[*,*]}
+     */
+    getBisectorNormals(t, pnt1, pnt2, pnt3) {
+        let normal = this.getNormal(pnt1, pnt2, pnt3)
+        let [bisectorNormalRight, bisectorNormalLeft, dt, x, y] = [null, null, null, null, null]
+        let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
+        let uX = normal[0] / dist
+        let uY = normal[1] / dist
+        let d1 = this.MathDistance(pnt1, pnt2)
+        let d2 = this.MathDistance(pnt2, pnt3)
+        if (dist > this.ZERO_TOLERANCE) {
+            if (this.isClockWise(pnt1, pnt2, pnt3)) {
+                dt = t * d1
+                x = pnt2[0] - dt * uY
+                y = pnt2[1] + dt * uX
+                bisectorNormalRight = [x, y]
+                dt = t * d2
+                x = pnt2[0] + dt * uY
+                y = pnt2[1] - dt * uX
+                bisectorNormalLeft = [x, y]
+            } else {
+                dt = t * d1
+                x = pnt2[0] + dt * uY
+                y = pnt2[1] - dt * uX
+                bisectorNormalRight = [x, y]
+                dt = t * d2
+                x = pnt2[0] - dt * uY
+                y = pnt2[1] + dt * uX
+                bisectorNormalLeft = [x, y]
+            }
+        } else {
+            x = pnt2[0] + t * (pnt1[0] - pnt2[0])
+            y = pnt2[1] + t * (pnt1[1] - pnt2[1])
+            bisectorNormalRight = [x, y]
+            x = pnt2[0] + t * (pnt3[0] - pnt2[0])
+            y = pnt2[1] + t * (pnt3[1] - pnt2[1])
+            bisectorNormalLeft = [x, y]
+        }
+        return [bisectorNormalRight, bisectorNormalLeft]
+    }
+
+
+
+    /**
+     * 获取默认三点的内切圆
+     * @param pnt1
+     * @param pnt2
+     * @param pnt3
+     * @returns {[*,*]}
+     */
+    getNormal(pnt1, pnt2, pnt3) {
+        let dX1 = pnt1[0] - pnt2[0]
+        let dY1 = pnt1[1] - pnt2[1]
+        let d1 = Math.sqrt(dX1 * dX1 + dY1 * dY1)
+        dX1 /= d1
+        dY1 /= d1
+        let dX2 = pnt3[0] - pnt2[0]
+        let dY2 = pnt3[1] - pnt2[1]
+        let d2 = Math.sqrt(dX2 * dX2 + dY2 * dY2)
+        dX2 /= d2
+        dY2 /= d2
+        let uX = dX1 + dX2
+        let uY = dY1 + dY2
+        return [uX, uY]
+    }
+
+
+
+    /**
+     * 判断是否是顺时针
+     * @param pnt1
+     * @param pnt2
+     * @param pnt3
+     * @returns {boolean}
+     */
+    isClockWise(pnt1, pnt2, pnt3) {
+        return ((pnt3[1] - pnt1[1]) * (pnt2[0] - pnt1[0]) > (pnt2[1] - pnt1[1]) * (pnt3[0] - pnt1[0]))
+    }
+
+
+    /**
+     * 求取两个坐标的中间值
+     * @param point1
+     * @param point2
+     * @returns {[*,*]}
+     * @constructor
+     */
+    Mid(point1, point2) {
+        return [(point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2]
+    }
+
+
+    /**
+     * 计算两个坐标之间的距离
+	 * @ignore
+     * @param pnt1
+     * @param pnt2
+     * @returns {number}
+     * @constructor
+     */
+    MathDistance(pnt1, pnt2) {
+        return (Math.sqrt(Math.pow((pnt1[0] - pnt2[0]), 2) + Math.pow((pnt1[1] - pnt2[1]), 2)))
+    }
+
+
+    /**
+     * 获取右边控制点
+     * @param controlPoints
+     * @param t
+     * @returns {[*,*]}
+     */
+    getRightMostControlPoint(controlPoints, t) {
+        let count = controlPoints.length
+        let pnt1 = controlPoints[count - 3]
+        let pnt2 = controlPoints[count - 2]
+        let pnt3 = controlPoints[count - 1]
+        let pnts = this.getBisectorNormals(0, pnt1, pnt2, pnt3)
+        let normalLeft = pnts[1]
+        let normal = this.getNormal(pnt1, pnt2, pnt3)
+        let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
+        let [controlX, controlY] = [null, null]
+        if (dist > this.ZERO_TOLERANCE) {
+            let mid = this.Mid(pnt2, pnt3)
+            let pX = pnt3[0] - mid[0]
+            let pY = pnt3[1] - mid[1]
+            let d1 = this.MathDistance(pnt2, pnt3)
+            let n = 2.0 / d1
+            let nX = -n * pY
+            let nY = n * pX
+            let a11 = nX * nX - nY * nY
+            let a12 = 2 * nX * nY
+            let a22 = nY * nY - nX * nX
+            let dX = normalLeft[0] - mid[0]
+            let dY = normalLeft[1] - mid[1]
+            controlX = mid[0] + a11 * dX + a12 * dY
+            controlY = mid[1] + a12 * dX + a22 * dY
+        } else {
+            controlX = pnt3[0] + t * (pnt2[0] - pnt3[0])
+            controlY = pnt3[1] + t * (pnt2[1] - pnt3[1])
+        }
+        return [controlX, controlY]
+    }
+
+
+    /**
+     * 获取立方值
+     * @param t
+     * @param startPnt
+     * @param cPnt1
+     * @param cPnt2
+     * @param endPnt
+     * @returns {[*,*]}
+     */
+    getCubicValue(t, startPnt, cPnt1, cPnt2, endPnt) {
+        t = Math.max(Math.min(t, 1), 0)
+        let [tp, t2] = [(1 - t), (t * t)]
+        let t3 = t2 * t
+        let tp2 = tp * tp
+        let tp3 = tp2 * tp
+        let x = (tp3 * startPnt[0]) + (3 * tp2 * t * cPnt1[0]) + (3 * tp * t2 * cPnt2[0]) + (t3 * endPnt[0])
+        let y = (tp3 * startPnt[1]) + (3 * tp2 * t * cPnt1[1]) + (3 * tp * t2 * cPnt2[1]) + (t3 * endPnt[1])
+        return [x, y]
+    }
+
+
+
+}
+
+export default DrawCurve

+ 463 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawCurveFlag.js

@@ -0,0 +1,463 @@
+
+// DrawCurveFlag
+/*
+绘制曲线旗标
+ */
+class DrawCurveFlag {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        this.identificationPoint = null; //标识点位
+        this.CurveFlag = null; 
+        this.CurveFlagLast = null; // 曲线旗标数据
+        this.positions = [];  // 经纬度
+        this.entitiesPoint = [];   // 实体点位
+        this.entitiesCurveFlag = [];  
+        this.CurveFlagData = null; 
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+ 
+    //返回曲线旗标数据
+    getData() {
+        return this.CurveFlagData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data){
+        //计算面
+        let $this = this
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.cartesianToLatlng(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        // 取第一个
+        let startPoint = lnglatArr[0]
+        // 取最后一个
+        let endPoint =lnglatArr[lnglatArr.length - 1]
+        // 上曲线起始点
+        let point1 = startPoint
+        // 上曲线第一控制点
+        let point2 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
+        // 上曲线第二个点
+        let point3 = [(startPoint[0] + endPoint[0]) / 2, startPoint[1]]
+        // 上曲线第二控制点
+        let point4 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], -(endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
+        // 上曲线结束点
+        let point5 = [endPoint[0], startPoint[1]]
+        // 下曲线结束点
+        let point6 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        // 下曲线第二控制点
+        let point7 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 3 / 8 + startPoint[1]]
+        // 下曲线第二个点
+        let point8 = [(startPoint[0] + endPoint[0]) / 2, (startPoint[1] + endPoint[1]) / 2]
+        // 下曲线第一控制点
+        let point9 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 5 / 8 + startPoint[1]]
+        // 下曲线起始点
+        let point10 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        // 旗杆底部点
+        let point11 = [startPoint[0], endPoint[1]]
+        // 计算上曲线
+        let curve1 = $this.getBezierPoints([point1, point2, point3, point4, point5])
+        // 计算下曲线
+        let curve2 = $this.getBezierPoints([point6, point7, point8, point9, point10])
+        // 面合并
+        let componentspolygon = [];
+        componentspolygon = curve1.concat(curve2)
+        let PolygonHierarchy = new $this.Cesium.PolygonHierarchy(componentspolygon)
+        // 线边合并
+        let componentspolyline = [];
+        componentspolyline = curve1.concat(curve2)
+        componentspolyline.push($this.LatlngTocartesian(point1))
+        componentspolyline.push($this.LatlngTocartesian(point11))
+        
+        $this.CurveFlagData = lnglatArr;
+        return [PolygonHierarchy,componentspolyline];
+    }
+ 
+    //加载
+    addload(data) {
+        var $this = this;
+        if (data.length < 2) return;
+        // 取第一个
+        let startPoint = data[0]
+        // 取最后一个
+        let endPoint =data[data.length - 1]
+        // 上曲线起始点
+        let point1 = startPoint
+        // 上曲线第一控制点
+        let point2 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
+        // 上曲线第二个点
+        let point3 = [(startPoint[0] + endPoint[0]) / 2, startPoint[1]]
+        // 上曲线第二控制点
+        let point4 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], -(endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
+        // 上曲线结束点
+        let point5 = [endPoint[0], startPoint[1]]
+        // 下曲线结束点
+        let point6 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        // 下曲线第二控制点
+        let point7 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 3 / 8 + startPoint[1]]
+        // 下曲线第二个点
+        let point8 = [(startPoint[0] + endPoint[0]) / 2, (startPoint[1] + endPoint[1]) / 2]
+        // 下曲线第一控制点
+        let point9 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 5 / 8 + startPoint[1]]
+        // 下曲线起始点
+        let point10 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        // 旗杆底部点
+        let point11 = [startPoint[0], endPoint[1]]
+        // 计算上曲线
+        let curve1 = $this.getBezierPoints([point1, point2, point3, point4, point5])
+        // 计算下曲线
+        let curve2 = $this.getBezierPoints([point6, point7, point8, point9, point10])
+        // 合并
+        let componentspolygon = [];
+        componentspolygon = curve1.concat(curve2)
+        let componentspolyline = [];
+        componentspolyline = curve1.concat(curve2)
+        componentspolyline.push($this.LatlngTocartesian(point1))
+        componentspolyline.push($this.LatlngTocartesian(point11))
+        
+        var shape = this.viewer.entities.add({
+            Type:'DrawCurveFlag',
+            Position:data,
+            id:data.id || $this.objId,
+            polygon: {
+                hierarchy: new $this.Cesium.PolygonHierarchy(componentspolygon),
+                extrudedHeight: 1,
+                material: $this.Cesium.Color.RED,
+            },
+            polyline: {
+                //使用cesium的peoperty
+                positions: componentspolyline,
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 5,
+                clampToGround: true
+            }
+        });
+        $this.entitiesCurveFlag.push(shape);
+        return shape;
+    }
+ 
+    //开始创建
+    startCreate(drawType) {
+        this.drawType = drawType;
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            //屏幕坐标转地形上坐标
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if ($this.positions.length == 0) {
+                $this.positions.push(cartesian.clone());
+                $this.identificationPoint = $this.createPoint(cartesian);
+                $this.createPoint(cartesian);// 绘制点
+                $this.positions.push(cartesian);
+            }
+            // if ($this.positions.length == 2) {
+            //     $this.positions.push(cartesian);
+            // }
+            
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制线
+            if ($this.positions.length < 2) return;
+            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+            if (!$this.Cesium.defined($this.CurveFlag)) {
+                $this.CurveFlag = $this.createCurveFlag();
+            }
+            $this.identificationPoint.position.setValue(cartesian);
+            if ($this.CurveFlag) {
+                $this.positions.pop();
+                $this.positions.push(cartesian);
+            }
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.setInputAction(function (evt) {
+            if (!$this.CurveFlag) return;
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            $this.positions.pop();
+            $this.positions.push(cartesian);
+            $this.createPoint(cartesian);// 绘制点
+            $this.CurveFlagData = $this.positions.concat();
+            $this.viewer.entities.remove($this.CurveFlag); //移除
+            $this.CurveFlag = null;
+            $this.positions = [];
+            $this.identificationPoint.position.setValue(cartesian);
+            var lnglatArr = [];
+            for (var i = 0; i < $this.CurveFlagData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this.CurveFlagData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this.CurveFlagData = lnglatArr;
+            var CurveFlag = $this.addload([$this.CurveFlagData[0],$this.CurveFlagData[$this.CurveFlagData.length -1 ]]); //加载
+            $this.entitiesCurveFlag.push(CurveFlag);
+            $this.CurveFlagLast = CurveFlag;
+            $this.clearPoint();
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+ 
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this.entitiesPoint.push(point);
+        return point;
+    }
+ 
+    //创建曲线旗标
+    createCurveFlag() {
+        var $this = this;
+        var polygon = this.viewer.entities.add({
+            polygon: {
+                hierarchy: new $this.Cesium.CallbackProperty(function () {
+                    if($this.positions.length < 2) return 
+                    let lonlat = [];
+                    let components = [];
+                    let length = $this.positions.length
+                    for (let i=0; i<length; i++){
+                        lonlat.push($this.cartesianToLatlng($this.positions[i]))
+                    }
+                    // 取第一个
+                    let startPoint = lonlat[0]
+                    // 取最后一个
+                    let endPoint =lonlat[lonlat.length - 1]
+                    // 上曲线起始点
+                    let point1 = startPoint
+                    // 上曲线第一控制点
+                    let point2 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
+                    // 上曲线第二个点
+                    let point3 = [(startPoint[0] + endPoint[0]) / 2, startPoint[1]]
+                    // 上曲线第二控制点
+                    let point4 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], -(endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
+                    // 上曲线结束点
+                    let point5 = [endPoint[0], startPoint[1]]
+                    // 下曲线结束点
+                    let point6 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    // 下曲线第二控制点
+                    let point7 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 3 / 8 + startPoint[1]]
+                    // 下曲线第二个点
+                    let point8 = [(startPoint[0] + endPoint[0]) / 2, (startPoint[1] + endPoint[1]) / 2]
+                    // 下曲线第一控制点
+                    let point9 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 5 / 8 + startPoint[1]]
+                    // 下曲线起始点
+                    let point10 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    // 旗杆底部点
+                    let point11 = [startPoint[0], endPoint[1]]
+                    // 计算上曲线
+                    let curve1 = $this.getBezierPoints([point1, point2, point3, point4, point5])
+                    // 计算下曲线
+                    let curve2 = $this.getBezierPoints([point6, point7, point8, point9, point10])
+                    // 合并
+                    components = curve1.concat(curve2)
+                    // components.push(point11)
+                    // let components = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point0])
+                    
+                    return new $this.Cesium.PolygonHierarchy(components);
+                }, false),
+                extrudedHeight: 1,
+                material: $this.Cesium.Color.RED,
+            },
+            polyline: {
+                //使用cesium的peoperty
+                positions: new $this.Cesium.CallbackProperty(function () {
+                    if($this.positions.length < 2) return 
+                    let lonlat = [];
+                    let components = [];
+                    let length = $this.positions.length
+                    for (let i=0; i<length; i++){
+                        lonlat.push($this.cartesianToLatlng($this.positions[i]))
+                    }
+                    // 取第一个
+                    let startPoint = lonlat[0]
+                    // 取最后一个
+                    let endPoint =lonlat[lonlat.length - 1]
+                    // 上曲线起始点
+                    let point1 = startPoint
+                    // 上曲线第一控制点
+                    let point2 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
+                    // 上曲线第二个点
+                    let point3 = [(startPoint[0] + endPoint[0]) / 2, startPoint[1]]
+                    // 上曲线第二控制点
+                    let point4 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], -(endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
+                    // 上曲线结束点
+                    let point5 = [endPoint[0], startPoint[1]]
+                    // 下曲线结束点
+                    let point6 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    // 下曲线第二控制点
+                    let point7 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 3 / 8 + startPoint[1]]
+                    // 下曲线第二个点
+                    let point8 = [(startPoint[0] + endPoint[0]) / 2, (startPoint[1] + endPoint[1]) / 2]
+                    // 下曲线第一控制点
+                    let point9 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 5 / 8 + startPoint[1]]
+                    // 下曲线起始点
+                    let point10 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    // 旗杆底部点
+                    let point11 = [startPoint[0], endPoint[1]]
+                    // 计算上曲线
+                    let curve1 = $this.getBezierPoints([point1, point2, point3, point4, point5])
+                    // 计算下曲线
+                    let curve2 = $this.getBezierPoints([point6, point7, point8, point9, point10])
+                    // 合并
+                    components = curve1.concat(curve2)
+                    components.push($this.LatlngTocartesian(point1))
+                    components.push($this.LatlngTocartesian(point11))
+                    
+                    return components
+                }, false),
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 5,
+                clampToGround: true
+            }
+        });
+        $this.entitiesCurveFlag.push(polygon);
+        return polygon;
+    }
+
+    cartesianToLatlng(cartesian) {
+        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+        var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+        return [lng, lat];
+    }
+
+    LatlngTocartesian(latlng) {
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+        return cartesian3
+    }
+
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this.CurveFlagLast, [this.CurveFlagData[0],this.CurveFlagData[this.CurveFlagData.length -1 ]], this.drawType);
+        for (var i = 0; i < this.entitiesPoint.length; i++) {
+            this.viewer.entities.remove(this.entitiesPoint[i]);
+        }
+        this.entitiesPoint = [];  //脏数据
+    }
+ 
+    //销毁
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+ 
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this.entitiesPoint.length; i++) {
+            this.viewer.entities.remove(this.entitiesPoint[i]);
+        }
+        for (var i = 0; i < this.entitiesCurveFlag.length; i++) {
+            this.viewer.entities.remove(this.entitiesCurveFlag[i]);
+        }
+        this.identificationPoint = null; //标识点位
+        this.CurveFlag = null; 
+        this.CurveFlagLast = null; // 曲线旗标数据
+        this.positions = [];  // 经纬度
+        this.entitiesPoint = [];   // 实体点位
+        this.entitiesCurveFlag = [];  
+        this.CurveFlagData = null; 
+    }
+ 
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+
+    // 贝塞尔曲线
+    getBezierPoints (points) {
+        let $this = this
+        if (points.length <= 2) {
+          return points
+        } else {
+          let bezierPoints = []
+          let n = points.length - 1
+          for (let t = 0; t <= 1; t += 0.01) {
+            let [x, y] = [0, 0]
+            for (let index = 0; index <= n; index++) {
+              let factor = $this.getBinomialFactor(n, index)
+              let a = Math.pow(t, index)
+              let b = Math.pow((1 - t), (n - index))
+              x += factor * a * b * points[index][0]
+              y += factor * a * b * points[index][1]
+            }
+            bezierPoints.push($this.LatlngTocartesian([x, y]))
+          }
+          bezierPoints.push($this.LatlngTocartesian(points[n]))
+          return bezierPoints
+        }
+    }
+
+
+        /**
+     * 获取二项分布
+     * @param n
+     * @param index
+     * @returns {number}
+     */
+    getBinomialFactor(n, index) {
+        return (this.getFactorial(n) / (this.getFactorial(index) * this.getFactorial(n - index)))
+    }
+
+    /**
+    * 获取阶乘数据
+    * @param n
+    * @returns {number}
+    */
+    getFactorial (n) {
+        let result = 1
+        switch (n) {
+        case (n <= 1):
+            result = 1
+            break
+        case (n === 2):
+            result = 2
+            break
+        case (n === 3):
+            result = 6
+            break
+        case (n === 24):
+            result = 24
+            break
+        case (n === 5):
+            result = 120
+            break
+        default:
+            for (let i = 1; i <= n; i++) {
+            result *= i
+            }
+            break
+        }
+        return result
+    }
+}
+ 
+export default DrawCurveFlag
+

+ 609 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawGatheringPlace.js

@@ -0,0 +1,609 @@
+import {
+	createTooltip
+} from "../../../common/common.js";
+
+import {
+	isRuntimeApp,
+	isRuntimeWeb,
+	createOperationMainDom,
+	showTooltipMessage
+} from "../../../common/RuntimeEnvironment.js";
+
+/*
+九、绘制集结地
+ */
+class DrawGatheringPlace {
+	constructor(arg) {
+		this.viewer = arg.viewer;
+		this.Cesium = arg.Cesium;
+		this.tt = 0.4;
+		this.floatingPoint = null; //标识点
+		this.drawHandler = null; //画事件
+		this.gatheringPlace = null; //集结地
+		this._gatheringPlaceLast = null; //最后一个箭头
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_PincerArrow = []; //脏数据
+		this._gatheringPlaceData = null; //用于构造集结地
+		this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+		this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+
+		this._tooltip = createTooltip(this.viewer.container);
+
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+	}
+
+	//返回箭头
+	get PincerArrow() {
+		return this._gatheringPlaceLast;
+	}
+
+	//返回箭头数据用于加载箭头
+	getData() {
+		return this._gatheringPlaceData;
+	}
+
+	// 修改编辑调用计算
+	computePosition(data) {
+		var $this = this;
+		if (data.length < 3) {
+			return;
+		}
+		var gatheringPlace = [];
+		var lonLats = [];
+		var res = $this.fineGatheringPlace(data);
+		for (var i = 0; i < res.length; i++) {
+			var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
+			gatheringPlace.push(cart3);
+		}
+		for (let q = 0; q < data.length; q++) {
+			lonLats.push($this.cartesianToLatlng(data[q]));
+		}
+		this._gatheringPlaceData = lonLats;
+		return new $this.Cesium.PolygonHierarchy(gatheringPlace);
+	}
+
+	//加载箭头
+	addload(data) {
+		var $this = this;
+		if (data.length < 3) {
+			return;
+		}
+		var gatheringPlace = [];
+		var lnglatArr = [];
+		for (var i = 0; i < data.length; i++) {
+			var lnglat = $this.LatlngTocartesian(data[i]);
+			lnglatArr.push(lnglat)
+		}
+		var res = $this.fineGatheringPlace(lnglatArr);
+		for (var i = 0; i < res.length; i++) {
+			var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
+			gatheringPlace.push(cart3);
+		}
+		var pHierarchy = new $this.Cesium.PolygonHierarchy(gatheringPlace);
+		var arrowEntity = $this.viewer.entities.add({
+			Type: 'DrawGatheringPlace',
+			Position: data,
+			id: data.id || $this.objId,
+			polygon: {
+				hierarchy: pHierarchy,
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			}
+		})
+		return arrowEntity
+	}
+
+
+	// 开始创建
+	startCreate(drawType) {
+		if (isRuntimeApp()) {
+			showTooltipMessage("点击开始绘制");
+		}
+
+		var $this = this;
+
+		this.drawType = drawType
+		this.handler = new $this.Cesium.ScreenSpaceEventHandler($this.viewer.scene.canvas);
+		//单击开始绘制
+		this.handler.setInputAction(function(event) {
+			if (isRuntimeApp()) {
+				//屏幕坐标转地形上坐标
+				var cartesian = $this.getCatesian3FromPX(event.position);
+				if (!cartesian) {
+					return;
+				}
+
+				$this.createPoint(cartesian); // 绘制点
+				$this._positions.push(cartesian);
+
+				if ($this._positions.length < 3) {
+					showTooltipMessage("点击添加点");
+				}
+
+				if ($this._positions.length === 3) {
+					showTooltipMessage("点击完成按钮,结束绘制");
+					$this.destroy();
+					if (!$this.Cesium.defined($this.gatheringPlace)) {
+						$this.gatheringPlace = $this.createGatheringPlace();
+
+						//创建按钮
+						createOperationMainDom();
+						//完成绘制
+						document.getElementById("btnDrawComplete").onclick = () => {
+
+							$this._gatheringPlaceData = $this._positions.concat();
+							$this.viewer.entities.remove($this.gatheringPlace); //移除
+							$this.gatheringPlace = null;
+							var lnglatArr = [];
+							for (var i = 0; i < $this._gatheringPlaceData.length; i++) {
+								var lnglat = $this.cartesianToLatlng($this._gatheringPlaceData[i]);
+								lnglatArr.push(lnglat)
+							}
+							$this._gatheringPlaceData = lnglatArr;
+							var pincerArrow = $this.addload(lnglatArr); //加载
+							$this._entities_PincerArrow.push(pincerArrow);
+							$this._gatheringPlaceLast = pincerArrow;
+							$this.viewer.entities.remove($this.floatingPoint);
+							$this.floatingPoint = null;
+
+							//删除关键点
+							$this.clearPoint();
+							$this.destroy();
+
+							let buttonDiv = document.getElementById("drawButtonDiv");
+							if (buttonDiv) {
+								//从页面移除
+								document.body.removeChild(buttonDiv);
+							}
+						}
+					}
+				}
+			} else {
+
+				console.log('监听鼠标事件', '单击')
+
+				/* 锁定点击事件 以免和双击事件冲突 */
+				clearTimeout($this._timer);
+				$this._timer = setTimeout(function() {
+					//屏幕坐标转世界坐标
+					var position = event.position;
+					if (!$this.Cesium.defined(position)) {
+						return;
+					}
+					var ray = $this.viewer.camera.getPickRay(position);
+					if (!$this.Cesium.defined(ray)) {
+						return;
+					}
+					var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
+					if (!$this.Cesium.defined(cartesian)) {
+						return;
+					}
+
+					if ($this._positions.length == 0) {
+						$this._positions.push(cartesian.clone());
+						$this.floatingPoint = $this.createPoint(cartesian);
+					}
+
+					if ($this._positions.length <= 2) {
+						$this.createPoint(cartesian); // 绘制点
+						$this._positions.push(cartesian);
+					}
+
+				}, 200);
+			}
+		}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+		//移动时绘制面
+		this.handler.setInputAction(function(event) {
+			//console.log("_positions",_positions);
+
+			/* 如果运行环境是App 则禁止使用鼠标移动事件 */
+			if (isRuntimeApp()) return;
+
+			if ($this._positions.length == 0) {
+				$this._tooltip.showAt(event.endPosition, "点击开始绘制");
+			} else {
+				$this._tooltip.showAt(event.endPosition, "点击添加点");
+			}
+
+			if ($this._positions.length < 2) {
+				return;
+			}
+
+			if ($this._positions.length == 3) {
+				$this._tooltip.showAt(event.endPosition, "双击结束绘制");
+			}
+
+
+			//屏幕坐标转世界坐标
+			var position = event.endPosition;
+			if (!$this.Cesium.defined(position)) {
+				return;
+			}
+			var ray = $this.viewer.camera.getPickRay(position);
+			if (!$this.Cesium.defined(ray)) {
+				return;
+			}
+			var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
+			if (!$this.Cesium.defined(cartesian)) {
+				return;
+			}
+			//console.log("点击地图移动采集的点:",cartesian);
+			if (!$this.Cesium.defined($this.gatheringPlace)) {
+				$this.gatheringPlace = $this.createGatheringPlace();
+			}
+			$this.floatingPoint.position.setValue(cartesian);
+			if ($this.gatheringPlace) {
+				//替换最后一个点
+				// _positions.pop();
+				// _positions.push(cartesian);
+				//替换中间点
+				if ($this._positions.length == 3) {
+					$this._positions[1] = cartesian;
+				} else {
+					$this._positions.pop();
+					$this._positions.push(cartesian);
+				}
+
+			}
+		}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+		//右击停止采集改为双击结束
+		this.handler.setInputAction(function(movement) {
+			// if ($this._positions.length >= 3) {
+			// 	$this._gatheringPlaceData = $this._positions.concat();
+			// 	$this.viewer.entities.remove($this.gatheringPlace); //移除
+			// 	$this.gatheringPlace = null;
+			// 	var lnglatArr = [];
+			// 	for (var i = 0; i < $this._gatheringPlaceData.length; i++) {
+			// 		var lnglat = $this.cartesianToLatlng($this._gatheringPlaceData[i]);
+			// 		lnglatArr.push(lnglat)
+			// 	}
+			// 	$this._gatheringPlaceData = lnglatArr;
+			// 	var pincerArrow = $this.addload(lnglatArr); //加载
+			// 	$this._entities_PincerArrow.push(pincerArrow);
+			// 	$this._gatheringPlaceLast = pincerArrow;
+			// 	$this.viewer.entities.remove($this.floatingPoint);
+			// 	$this.floatingPoint = null;
+
+			// 	//删除关键点
+			// 	$this.clearPoint();
+			// 	$this.destroy()
+			// }
+		}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+		//双击结束
+		this.handler.setInputAction(function(movement) {
+
+			/* 如果运行环境是App 则禁止使用鼠标双击事件 */
+			if (isRuntimeApp()) return;
+
+			console.log('监听鼠标事件', '双击')
+
+			/* 解除锁定 */
+			clearTimeout($this._timer);
+
+			if ($this._positions.length >= 3) {
+				$this._gatheringPlaceData = $this._positions.concat();
+				$this.viewer.entities.remove($this.gatheringPlace); //移除
+				$this.gatheringPlace = null;
+				var lnglatArr = [];
+				for (var i = 0; i < $this._gatheringPlaceData.length; i++) {
+					var lnglat = $this.cartesianToLatlng($this._gatheringPlaceData[i]);
+					lnglatArr.push(lnglat)
+				}
+				$this._gatheringPlaceData = lnglatArr;
+				var pincerArrow = $this.addload(lnglatArr); //加载
+				$this._entities_PincerArrow.push(pincerArrow);
+				$this._gatheringPlaceLast = pincerArrow;
+				$this.viewer.entities.remove($this.floatingPoint);
+				$this.floatingPoint = null;
+
+				//删除关键点
+				$this.clearPoint();
+				$this.destroy();
+
+				$this._tooltip.setVisible(false);
+			}
+		}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+	}
+
+	//创建集结地
+	createGatheringPlace() {
+		let $this = this
+		var gatheringPlaceEntity = $this.viewer.entities.add({
+			polygon: {
+				hierarchy: new $this.Cesium.CallbackProperty(function() {
+					if ($this._positions.length < 3) {
+						return;
+					}
+					var gatheringPlace = [];
+					var res = $this.fineGatheringPlace($this._positions);
+					for (var i = 0; i < res.length; i++) {
+						var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
+						gatheringPlace.push(cart3);
+					}
+					var pHierarchy = new $this.Cesium.PolygonHierarchy(gatheringPlace);
+					var lonLats = $this.cartesianToLatlng($this._positions);
+					pHierarchy.keyPoints = lonLats;
+					return pHierarchy
+				}, false),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			}
+		})
+		//$this._entities_gatheringPlace.push(gatheringPlaceEntity);
+		// gatheringPlaceEntity.valueFlag = "value";
+		$this._entities_PincerArrow.push(gatheringPlaceEntity);
+		return gatheringPlaceEntity
+	}
+
+	//创建点
+	createPoint(cartesian) {
+		var $this = this;
+		var point = this.viewer.entities.add({
+			position: cartesian,
+			point: {
+				pixelSize: 10,
+				color: $this.Cesium.Color.RED,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			}
+		});
+		$this._entities_point.push(point);
+		return point;
+	}
+
+	cartesianToLatlng(cartesian) {
+		let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		let lat = this.Cesium.Math.toDegrees(cartographic.latitude);
+		let lng = this.Cesium.Math.toDegrees(cartographic.longitude);
+		let alt = cartographic.height;
+		return [lng, lat, alt];
+	}
+
+	//销毁
+	destroy() {
+		if (this.handler) {
+			this.handler.destroy();
+			this.handler = null;
+		}
+	}
+
+	clearPoint() {
+		this.DrawEndEvent.raiseEvent(this._gatheringPlaceLast, this._gatheringPlaceData, this.drawType);
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		this._entities_point = []; //脏数据
+	}
+
+	//清空实体对象
+	clear() {
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		for (var i = 0; i < this._entities_PincerArrow.length; i++) {
+			this.viewer.entities.remove(this._entities_PincerArrow[i]);
+		}
+
+		this.floatingPoint = null; //标识点
+		this._PincerArrow = null; //活动箭头
+		this._PincerArrowLast = null; //最后一个箭头
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_PincerArrow = []; //脏数据
+		this._PincerArrowData = null; //用于构造箭头数据
+	}
+
+	getCatesian3FromPX(px) {
+		var cartesian;
+		var ray = this.viewer.camera.getPickRay(px);
+		if (!ray) return null;
+		cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+		return cartesian;
+	}
+
+	_computeTempPositions() {
+		var _this = this;
+
+		var pnts = [].concat(_this._positions);
+		var num = pnts.length;
+		var first = pnts[0];
+		var last = pnts[num - 1];
+		if (_this._isSimpleXYZ(first, last) == false) {
+			pnts.push(first);
+			num += 1;
+		}
+		_this.tempPositions = [];
+		for (var i = 1; i < num; i++) {
+			var p1 = pnts[i - 1];
+			var p2 = pnts[i];
+			var cp = _this._computeCenterPotition(p1, p2);
+			_this.tempPositions.push(p1);
+			_this.tempPositions.push(cp);
+		}
+	}
+
+	_isSimpleXYZ(p1, p2) {
+		if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+			return true;
+		}
+		return false;
+	}
+
+	_computeCenterPotition(p1, p2) {
+		var _this = this;
+		var c1 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p1);
+		var c2 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p2);
+		var cm = new _this.Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+		var cp = _this.viewer.scene.globe.ellipsoid.cartographicToCartesian(cm);
+		return cp;
+	}
+	/**
+	 * 笛卡尔坐标转经纬度坐标
+	 */
+	getLonLat(cartesian) {
+		var cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		cartographic.height = this.viewer.scene.globe.getHeight(cartographic);
+		var pos = {
+			lon: cartographic.longitude,
+			lat: cartographic.latitude,
+			alt: cartographic.height
+		};
+		pos.lon = this.Cesium.Math.toDegrees(pos.lon);
+		pos.lat = this.Cesium.Math.toDegrees(pos.lat);
+		return pos;
+	}
+
+	LatlngTocartesian(latlng) {
+		let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+		return cartesian3
+	}
+
+	////////////////////////////////////////集结地/////////////////////////////////////////////////////
+	fineGatheringPlace(gatherPosition) {
+		let $this = this
+		let points = gatherPosition.length;
+		if (points < 2) {
+			return false
+		} else {
+			let pnts = new Array();
+			gatherPosition.forEach(function(item) {
+				var posLonLat = $this.getLonLat(item);
+				pnts.push([posLonLat.lon, posLonLat.lat]);
+			});
+			//console.log("pnts6666",pnts);
+			// pnts.push(tailPoint);
+			// pnts.push(headerPoint);
+
+			if (pnts.length === 2) {
+				let mid = $this.mid(pnts[0], pnts[1])
+				//let d = utils.MathDistance(pnts[0], mid) / 0.9
+				let d = $this.distance(pnts[0], mid) / 0.9
+				//console.log("d",d);
+				let pnt = $this.getThirdPoint(pnts[0], mid, Math.PI / 2, d, true)
+				pnts = [pnts[0], pnt, pnts[1]];
+				//console.log("pnt",pnt);
+				//createPoint(Cesium.Cartesian3.fromDegrees(pnt[0], pnt[1]));
+			}
+			let mid = $this.mid(pnts[0], pnts[2])
+			pnts.push(mid, pnts[0], pnts[1])
+			//console.log("3333");
+
+			let [normals, pnt1, pnt2, pnt3, pList] = [
+				[], undefined, undefined, undefined, []
+			]
+			for (let i = 0; i < pnts.length - 2; i++) {
+				pnt1 = pnts[i]
+				pnt2 = pnts[i + 1]
+				pnt3 = pnts[i + 2]
+				let normalPoints = $this.getBisectorNormals($this.tt, pnt1, pnt2, pnt3)
+				normals = normals.concat(normalPoints)
+			}
+			let count = normals.length
+			normals = [normals[count - 1]].concat(normals.slice(0, count - 1))
+			for (let i = 0; i < pnts.length - 2; i++) {
+				pnt1 = pnts[i]
+				pnt2 = pnts[i + 1]
+				pList = pList.concat(pnt1)
+				for (let t = 0; t <= 100; t++) {
+					let pnt = $this.getCubicValue(t / 100, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)
+					pList = pList.concat(pnt)
+				}
+				pList = pList.concat(pnt2)
+			}
+			return Cesium.Cartesian3.fromDegreesArray(pList);
+		}
+	}
+
+	mid(t, o) {
+		return [(t[0] + o[0]) / 2, (t[1] + o[1]) / 2]
+	}
+
+	distance(t, o) {
+		return Math.sqrt(Math.pow(t[0] - o[0], 2) + Math.pow(t[1] - o[1], 2))
+	}
+
+	getThirdPoint(t, o, e, r, n) {
+		var g = this.getAzimuth(t, o),
+			i = n ? g + e : g - e,
+			s = r * Math.cos(i),
+			a = r * Math.sin(i);
+		return [o[0] + s, o[1] + a]
+	}
+
+	getAzimuth(t, o) {
+		var e, r = Math.asin(Math.abs(o[1] - t[1]) / this.distance(t, o));
+		return o[1] >= t[1] && o[0] >= t[0] ? e = r + Math.PI : o[1] >= t[1] && o[0] < t[0] ? e = 2 * Math.PI - r : o[1] < t[1] && o[0] < t[0] ? e = r : o[1] < t[1] && o[0] >= t[0] && (e = Math.PI - r), e
+	}
+
+	getBisectorNormals(t, o, e, r) {
+		var n = this.getNormal(o, e, r),
+			g = Math.sqrt(n[0] * n[0] + n[1] * n[1]),
+			i = n[0] / g,
+			s = n[1] / g,
+			a = this.distance(o, e),
+			l = this.distance(e, r);
+		if (g > 1e-4)
+			if (this.isClockWise(o, e, r)) {
+				var u = t * a,
+					c = e[0] - u * s,
+					p = e[1] + u * i,
+					h = [c, p];
+				u = t * l, c = e[0] + u * s, p = e[1] - u * i;
+				var d = [c, p]
+			} else u = t * a, c = e[0] + u * s, p = e[1] - u * i, h = [c, p], u = t * l, c = e[0] - u * s, p = e[1] + u * i, d = [c, p];
+		else c = e[0] + t * (o[0] - e[0]), p = e[1] + t * (o[1] - e[1]), h = [c, p], c = e[0] + t * (r[0] - e[0]), p = e[1] + t * (r[1] - e[1]), d = [c, p];
+		return [h, d]
+	}
+
+	getNormal(t, o, e) {
+		var r = t[0] - o[0],
+			n = t[1] - o[1],
+			g = Math.sqrt(r * r + n * n);
+		r /= g, n /= g;
+		var i = e[0] - o[0],
+			s = e[1] - o[1],
+			a = Math.sqrt(i * i + s * s);
+		i /= a, s /= a;
+		var l = r + i,
+			u = n + s;
+		return [l, u]
+	}
+
+	isClockWise(t, o, e) {
+		return (e[1] - t[1]) * (o[0] - t[0]) > (o[1] - t[1]) * (e[0] - t[0])
+	}
+
+	getCubicValue(t, o, e, r, n) {
+		t = Math.max(Math.min(t, 1), 0);
+		var g = 1 - t,
+			i = t * t,
+			s = i * t,
+			a = g * g,
+			l = a * g,
+			u = l * o[0] + 3 * a * t * e[0] + 3 * g * i * r[0] + s * n[0],
+			c = l * o[1] + 3 * a * t * e[1] + 3 * g * i * r[1] + s * n[1];
+		return [u, c]
+	}
+
+}
+
+export default DrawGatheringPlace

+ 536 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawLune.js

@@ -0,0 +1,536 @@
+// DrawLune
+/*
+九、绘制弓形
+ */
+class DrawLune {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        this.tt = 0.4;
+        this.floatingPoint = null;//标识点
+        this.drawHandler = null;//画事件
+        this.DrawLune = null;//弓形
+        this._DrawLuneLast = null; //最后一个弓形
+        this._positions = [];//活动点
+        this._entities_point = [];//脏数据
+        this._entities_PincerArrow = [];//脏数据
+        this._DrawLuneData = null; //用于构造弓形
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+
+    //返回弓形
+    get PincerArrow() {
+        return this._DrawLuneLast;
+    }
+
+    //返回弓形数据用于加载弓形
+    getData() {
+        return this._DrawLuneData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data) {
+        var $this = this;
+        if (data.length < 3) {
+            return;
+        }
+        var DrawLune = [];
+        let positions = [];
+        for (var i = 0; i < data.length; i++) {
+            positions.push($this.cartesianToLatlng(data[i]));
+            var cart3 =$this.lonLatToMercator($this.cartesianToLatlng(data[i]));
+            DrawLune.push(cart3);
+        }
+        let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawLune[0], DrawLune[2], DrawLune[1], null, null];
+        let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
+        let radius = $this.MathDistance(pnt1, center)
+        let angle1 = $this.getAzimuth(pnt1, center)
+        let angle2 = $this.getAzimuth(pnt2, center)
+        if ($this.isClockWise(pnt1, pnt2, pnt3)) {
+            startAngle = angle2
+            endAngle = angle1
+            } else {
+            startAngle = angle1
+            endAngle = angle2
+        }
+        let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
+        let pHierarchy = [];
+        for (var l = 0; l < getArcPoint.length; l++) {
+            var cart3 =$this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
+            pHierarchy.push(cart3);
+        }
+        pHierarchy.push(pHierarchy[0])
+        $this._DrawLuneData = positions
+        return new $this.Cesium.PolygonHierarchy(pHierarchy)
+    }
+
+    //加载
+    addload(data) {
+        var $this = this;
+        if (data.length < 3) {
+            return;
+        }
+        var DrawLune = [];
+        for (var i = 0; i < data.length; i++) {
+            var cart3 =$this.lonLatToMercator(data[i]);
+            DrawLune.push(cart3);
+        }
+        let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawLune[0], DrawLune[2], DrawLune[1], null, null];
+        let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
+        let radius = $this.MathDistance(pnt1, center)
+        let angle1 = $this.getAzimuth(pnt1, center)
+        let angle2 = $this.getAzimuth(pnt2, center)
+        if ($this.isClockWise(pnt1, pnt2, pnt3)) {
+            startAngle = angle2
+            endAngle = angle1
+          } else {
+            startAngle = angle1
+            endAngle = angle2
+        }
+        let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
+        let pHierarchy = [];
+        for (var l = 0; l < getArcPoint.length; l++) {
+            var cart3 =$this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
+            pHierarchy.push(cart3);
+        }
+        pHierarchy.push(pHierarchy[0])
+        var arrowEntity = $this.viewer.entities.add({
+            Type: 'DrawLune',
+            Position: data,
+            id: data.id || $this.objId,
+            polygon: {
+                hierarchy: new $this.Cesium.PolygonHierarchy(pHierarchy),
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 3,
+                clampToGround: true,
+                outlineWidth:3,
+                outline: true,
+                outlineColor: Cesium.Color.MAGENTA,
+            }
+        }
+        )
+        return arrowEntity
+    }
+
+
+    // 开始创建
+    startCreate(drawType) {
+        this.drawType = drawType
+        var $this = this;
+        this.handler = new $this.Cesium.ScreenSpaceEventHandler($this.viewer.scene.canvas);
+        this.handler.setInputAction(function (event) {
+            //屏幕坐标转世界坐标
+            var position = event.position;
+            if (!$this.Cesium.defined(position)) {
+                return;
+            }
+            var ray = $this.viewer.camera.getPickRay(position);
+            if (!$this.Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
+            if (!$this.Cesium.defined(cartesian)) {
+                return;
+            }
+
+            if ($this._positions.length == 0) {
+                $this._positions.push(cartesian.clone());
+                $this.floatingPoint = $this.createPoint(cartesian);
+            }
+
+            if ($this._positions.length <= 2) {
+                $this.createPoint(cartesian); // 绘制点
+                $this._positions.push(cartesian);
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+
+        this.handler.setInputAction(function (event) { //移动时绘制面
+            //console.log("_positions",_positions);
+            if ($this._positions.length < 2) {
+                return;
+            }
+
+            //屏幕坐标转世界坐标
+            var position = event.endPosition;
+            if (!$this.Cesium.defined(position)) {
+                return;
+            }
+            var ray = $this.viewer.camera.getPickRay(position);
+            if (!$this.Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
+            if (!$this.Cesium.defined(cartesian)) {
+                return;
+            }
+            //console.log("点击地图移动采集的点:",cartesian);
+            if (!$this.Cesium.defined($this.DrawLune)) {
+                $this.DrawLune = $this.createDrawLune();
+            }
+            $this.floatingPoint.position.setValue(cartesian);
+            if ($this.DrawLune) {
+                //替换最后一个点
+                // _positions.pop();
+                // _positions.push(cartesian);
+                //替换中间点
+                if ($this._positions.length == 3) {
+                    $this._positions[1] = cartesian;
+                } else {
+                    $this._positions.pop();
+                    $this._positions.push(cartesian);
+                }
+
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+
+        //右击停止采集
+        this.handler.setInputAction(function (movement) {
+
+            if ($this._positions.length >= 3) {
+                $this._DrawLuneData = $this._positions.concat();
+                $this.viewer.entities.remove($this.DrawLune); //移除
+                $this.DrawLune = null;
+                var lnglatArr = [];
+                for (var i = 0; i < $this._DrawLuneData.length; i++) {
+                    var lnglat = $this.cartesianToLatlng($this._DrawLuneData[i]);
+                    lnglatArr.push(lnglat)
+                }
+                $this._DrawLuneData = lnglatArr;
+                var pincerArrow = $this.addload(lnglatArr); //加载
+                $this._entities_PincerArrow.push(pincerArrow);
+                $this._DrawLuneLast = pincerArrow;
+                $this.viewer.entities.remove($this.floatingPoint);
+                $this.floatingPoint = null;
+
+                //删除关键点
+                $this.clearPoint();
+                $this.destroy()
+            }
+        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+    }
+
+    //创建弓形
+    createDrawLune() {
+        let $this = this
+        var DrawLuneEntity = $this.viewer.entities.add({
+            polygon: {
+                hierarchy: new $this.Cesium.CallbackProperty(function () {
+                    if ($this._positions.length < 3) {
+                        return;
+                    }
+                    var DrawLune = [];
+                    for (var i = 0; i < $this._positions.length; i++) {
+                        var cart3 =$this.lonLatToMercator($this.cartesianToLatlng($this._positions[i]));
+                        DrawLune.push(cart3);
+                    }
+                    let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawLune[0], DrawLune[2], DrawLune[1], null, null];
+                    let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
+                    let radius = $this.MathDistance(pnt1, center)
+                    let angle1 = $this.getAzimuth(pnt1, center)
+                    let angle2 = $this.getAzimuth(pnt2, center)
+                    if ($this.isClockWise(pnt1, pnt2, pnt3)) {
+                        startAngle = angle2
+                        endAngle = angle1
+                      } else {
+                        startAngle = angle1
+                        endAngle = angle2
+                    }
+                    let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
+                    let pHierarchy = [];
+                    for (var l = 0; l < getArcPoint.length; l++) {
+                        var cart3 =$this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
+                        pHierarchy.push(cart3);
+                    }
+                    pHierarchy.push(pHierarchy[0])
+                    return new $this.Cesium.PolygonHierarchy(pHierarchy)
+                }, false),
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                clampToGround: true
+            }
+        }
+        )
+        $this._entities_PincerArrow.push(DrawLuneEntity);
+        return DrawLuneEntity
+    }
+
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this._entities_point.push(point);
+        return point;
+    }
+
+    cartesianToLatlng(cartesian) {
+        let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        let lat = this.Cesium.Math.toDegrees(cartographic.latitude);
+        let lng = this.Cesium.Math.toDegrees(cartographic.longitude);
+        let alt = cartographic.height;
+        return [lng, lat];
+    }
+
+    //销毁
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this._DrawLuneLast, this._DrawLuneData, this.drawType);
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        this._entities_point = [];  //脏数据
+    }
+
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        for (var i = 0; i < this._entities_PincerArrow.length; i++) {
+            this.viewer.entities.remove(this._entities_PincerArrow[i]);
+        }
+
+        this.floatingPoint = null;//标识点
+        this._PincerArrow = null; //活动弓形
+        this._PincerArrowLast = null; //最后一个弓形
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_PincerArrow = [];  //脏数据
+        this._PincerArrowData = null; //用于构造弓形数据
+    }
+
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+
+    _computeTempPositions() {
+        var _this = this;
+
+        var pnts = [].concat(_this._positions);
+        var num = pnts.length;
+        var first = pnts[0];
+        var last = pnts[num - 1];
+        if (_this._isSimpleXYZ(first, last) == false) {
+            pnts.push(first);
+            num += 1;
+        }
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+    }
+
+    _isSimpleXYZ(p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    }
+
+    _computeCenterPotition(p1, p2) {
+        var _this = this;
+        var c1 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p2);
+        var cm = new _this.Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.viewer.scene.globe.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    }
+    /**
+     * 笛卡尔坐标转经纬度坐标
+     */
+    getLonLat(cartesian) {
+        var cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = this.viewer.scene.globe.getHeight(cartographic);
+        var pos = {
+            lon: cartographic.longitude,
+            lat: cartographic.latitude,
+            alt: cartographic.height
+        };
+        pos.lon = this.Cesium.Math.toDegrees(pos.lon);
+        pos.lat = this.Cesium.Math.toDegrees(pos.lat);
+        return pos;
+    }
+
+    LatlngTocartesian(latlng) {
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+        return cartesian3
+    }
+
+     /**
+     * 经纬度坐标转墨卡托坐标
+     */
+    // 墨卡托坐标系:展开地球,赤道作为x轴,向东为x轴正方,本初子午线作为y轴,向北为y轴正方向。
+    // 数字20037508.34是地球赤道周长的一半:地球半径6378137米,赤道周长2*PI*r = 2 * 20037508.3427892,墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892]
+    lonLatToMercator(Latlng) {
+        var E = Latlng[0];
+        var N = Latlng[1];
+        var x = E * 20037508.34 / 180;
+        var y = Math.log(Math.tan((90 + N) * Math.PI / 360)) / (Math.PI / 180);
+        y = y * 20037508.34 / 180;
+        return [x, y]
+    }
+    /**
+     * 墨卡托坐标转经纬度坐标转
+     */
+    WebMercator2lonLat(mercator) {
+        let x = mercator[0] / 20037508.34 * 180;
+        let ly = mercator[1] / 20037508.34 * 180;
+        let y = 180 / Math.PI * (2 * Math.atan(Math.exp(ly * Math.PI / 180)) - Math.PI / 2)
+        return [x, y];
+    }
+
+    ////////////////////////////////////////弓形/////////////////////////////////////////////////////
+    /**
+ * 通过三个点确定一个圆的中心点
+ * @param point1
+ * @param point2
+ * @param point3
+ */
+    getCircleCenterOfThreePoints(point1, point2, point3) {
+        let pntA = [(point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2]
+        let pntB = [pntA[0] - point1[1] + point2[1], pntA[1] + point1[0] - point2[0]]
+        let pntC = [(point1[0] + point3[0]) / 2, (point1[1] + point3[1]) / 2]
+        let pntD = [pntC[0] - point1[1] + point3[1], pntC[1] + point1[0] - point3[0]]
+        return this.getIntersectPoint(pntA, pntB, pntC, pntD)
+    }
+
+    /**
+   * 获取交集的点
+   * @param pntA
+   * @param pntB
+   * @param pntC
+   * @param pntD
+   * @returns {[*,*]}
+   */
+    getIntersectPoint(pntA, pntB, pntC, pntD) {
+        if (pntA[1] === pntB[1]) {
+            let f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
+            let x = f * (pntA[1] - pntC[1]) + pntC[0]
+            let y = pntA[1]
+            return [x, y]
+        }
+        if (pntC[1] === pntD[1]) {
+            let e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
+            let x = e * (pntC[1] - pntA[1]) + pntA[0]
+            let y = pntC[1]
+            return [x, y]
+        }
+        let e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
+        let f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
+        let y = (e * pntA[1] - pntA[0] - f * pntC[1] + pntC[0]) / (e - f)
+        let x = e * y - e * pntA[1] + pntA[0]
+        return [x, y]
+    }
+
+
+    /**
+   * 计算两个坐标之间的距离
+   * @ignore
+   * @param pnt1
+   * @param pnt2
+   * @returns {number}
+   * @constructor
+   */
+    MathDistance(pnt1, pnt2) {
+        return (Math.sqrt(Math.pow((pnt1[0] - pnt2[0]), 2) + Math.pow((pnt1[1] - pnt2[1]), 2)))
+    }
+
+
+    /**
+   * 获取方位角(地平经度)
+   * @param startPoint
+   * @param endPoint
+   * @returns {*}
+   */
+    getAzimuth(startPoint, endPoint) {
+        let azimuth
+        let angle = Math.asin(Math.abs(endPoint[1] - startPoint[1]) / (this.MathDistance(startPoint, endPoint)))
+        if (endPoint[1] >= startPoint[1] && endPoint[0] >= startPoint[0]) {
+            azimuth = angle + Math.PI
+        } else if (endPoint[1] >= startPoint[1] && endPoint[0] < startPoint[0]) {
+            azimuth = Math.PI * 2 - angle
+        } else if (endPoint[1] < startPoint[1] && endPoint[0] < startPoint[0]) {
+            azimuth = angle
+        } else if (endPoint[1] < startPoint[1] && endPoint[0] >= startPoint[0]) {
+            azimuth = Math.PI - angle
+        }
+        return azimuth
+    }
+
+    /**
+     * 判断是否是顺时针
+     * @param pnt1
+     * @param pnt2
+     * @param pnt3
+     * @returns {boolean}
+     */
+    isClockWise (pnt1, pnt2, pnt3) {
+        return ((pnt3[1] - pnt1[1]) * (pnt2[0] - pnt1[0]) > (pnt2[1] - pnt1[1]) * (pnt3[0] - pnt1[0]))
+    }
+
+
+    /**
+   * 插值弓形线段点
+   * @param center
+   * @param radius
+   * @param startAngle
+   * @param endAngle
+   * @returns {null}
+   */
+    getArcPoints(center, radius, startAngle, endAngle) {
+        let [x, y, pnts, angleDiff] = [null, null, [], (endAngle - startAngle)]
+        angleDiff = ((angleDiff < 0) ? (angleDiff + (Math.PI * 2)) : angleDiff)
+        for (let i = 0; i <= 100; i++) {
+            let angle = startAngle + angleDiff * i / 100
+            x = center[0] + radius * Math.cos(angle)
+            y = center[1] + radius * Math.sin(angle)
+            pnts.push([x, y])
+        }
+        return pnts
+    }
+
+}
+
+export default DrawLune

+ 656 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawPincerArrow.js

@@ -0,0 +1,656 @@
+import {
+	createTooltip
+} from "../../../common/common.js";
+
+import {
+	isRuntimeApp,
+	isRuntimeWeb,
+	createOperationMainDom,
+	showTooltipMessage
+} from "../../../common/RuntimeEnvironment.js";
+
+/*
+九、绘制钳击箭头
+ */
+class DrawPincerArrow {
+	constructor(arg) {
+		this.viewer = arg.viewer;
+		this.Cesium = arg.Cesium;
+		// this.callback=arg.callback;
+		this.floatingPoint = null; //标识点
+		this._PincerArrow = null; //活动箭头
+		this._PincerArrowLast = null; //最后一个箭头
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_PincerArrow = []; //脏数据
+		this._PincerArrowData = null; //用于构造箭头数据
+		this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+		this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+
+		this._tooltip = createTooltip(this.viewer.container);
+
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+	}
+
+	//返回箭头
+	get PincerArrow() {
+		return this._PincerArrowLast;
+	}
+
+	//返回箭头数据用于加载箭头
+	getData() {
+		return this._PincerArrowData;
+	}
+
+	//加载箭头
+	addload(data) {
+		var $this = this;
+		if (data.length < 3) {
+			return;
+		}
+		//计算面
+		var res = $this.doubleArrow(data);
+		var returnData = res.polygonalPoint;
+		var arrowEntity = $this.viewer.entities.add({
+			Type: 'DrawPincerArrow',
+			Position: data,
+			id: data.id || $this.objId,
+			polygon: {
+				hierarchy: new $this.Cesium.PolygonHierarchy(returnData),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			}
+		})
+		return arrowEntity
+	}
+
+	// 修改编辑调用计算
+	computePosition(data) {
+		let $this = this
+		var lnglatArr = [];
+		for (var i = 0; i < data.length; i++) {
+			var lnglat = $this.cartesianToLatlng(data[i]);
+			lnglatArr.push(lnglat)
+		}
+		$this._PincerArrowData = lnglatArr;
+		var res = $this.doubleArrow(lnglatArr);
+		var returnData = res.polygonalPoint;
+		return new $this.Cesium.PolygonHierarchy(returnData)
+	}
+
+	//开始创建
+	startCreate(drawType) {
+		if (isRuntimeApp()) {
+			showTooltipMessage("点击开始绘制");
+		}
+
+		var $this = this;
+
+		this.drawType = drawType;
+		this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+
+		//单击开始绘制
+		this.handler.setInputAction(function(evt) {
+
+			if (isRuntimeApp()) {
+				//屏幕坐标转地形上坐标
+				var cartesian = $this.getCatesian3FromPX(evt.position);
+				if (!cartesian) {
+					return;
+				}
+
+				$this.createPoint(cartesian); // 绘制点
+				$this._positions.push(cartesian);
+
+				if ($this._positions.length < 3 || $this._positions.length === 4) {
+					showTooltipMessage("点击添加点");
+				}
+
+				if ($this._positions.length === 2) {
+					if (!$this.Cesium.defined($this._PincerArrow)) {
+						$this._PincerArrow = $this.createPincerArrow();
+					}
+				}
+				if ($this._positions.length === 3) {
+					$this._positions.pop();
+					$this._positions.push(cartesian);
+
+					//创建按钮
+					createOperationMainDom();
+					showTooltipMessage("点击添加点,点击完成按钮,结束绘制");
+					//完成绘制
+					document.getElementById("btnDrawComplete").onclick = () => {
+
+
+						$this._PincerArrowData = $this._positions.concat();
+						$this.viewer.entities.remove($this._PincerArrow); //移除
+						$this._PincerArrow = null;
+						$this._positions = [];
+						var lnglatArr = [];
+						for (var i = 0; i < $this._PincerArrowData.length; i++) {
+							var lnglat = $this.cartesianToLatlng($this._PincerArrowData[i]);
+							lnglatArr.push(lnglat)
+						}
+						$this._PincerArrowData = lnglatArr;
+						var pincerArrow = $this.addload(lnglatArr); //加载
+						$this._entities_PincerArrow.push(pincerArrow);
+						$this._PincerArrowLast = pincerArrow;
+						$this.clearPoint();
+						$this.destroy();
+
+						let buttonDiv = document.getElementById("drawButtonDiv");
+						if (buttonDiv) {
+							//从页面移除
+							document.body.removeChild(buttonDiv);
+						}
+					}
+				}
+
+				if ($this._positions.length === 5) {
+					showTooltipMessage("点击完成按钮,结束绘制");
+					$this.destroy();
+				}
+
+			} else {
+				console.log('监听鼠标事件', '单击')
+
+				/* 锁定点击事件 以免和双击事件冲突 */
+				clearTimeout($this._timer);
+				$this._timer = setTimeout(function() {
+					var cartesian = $this.getCatesian3FromPX(evt.position);
+					if (!cartesian) {
+						return;
+					}
+					if ($this._positions.length == 0) {
+						$this.floatingPoint = $this.createPoint(cartesian);
+					}
+					if ($this._positions.length < 5) {
+						$this._positions.push(cartesian);
+						$this.createPoint(cartesian); // 绘制点
+					}
+					if ($this._positions.length == 5) {
+						$this._positions[4] = cartesian;
+						$this.floatingPoint.position.setValue(cartesian);
+					}
+				}, 200);
+			}
+		}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+		//移动时绘制面
+		this.handler.setInputAction(function(evt) {
+
+			/* 如果运行环境是App 则禁止使用鼠标移动事件 */
+			if (isRuntimeApp()) return;
+
+			if ($this._positions.length == 0) {
+				$this._tooltip.showAt(evt.endPosition, "点击开始绘制");
+			} else {
+				$this._tooltip.showAt(evt.endPosition, "点击添加点");
+			}
+
+			var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+			if (!cartesian) return;
+			if ($this._positions.length < 2) return;
+
+			if (!$this.Cesium.defined($this._PincerArrow)) {
+				if ($this._positions.length == 2) {
+					$this._positions.push(cartesian);
+				}
+				$this._PincerArrow = $this.createPincerArrow();
+			}
+			$this.floatingPoint.position.setValue(cartesian);
+			if ($this._positions.length == 3) {
+				$this._positions[2] = cartesian;
+
+				// $this._tooltip.showAt(evt.endPosition, "点击添加点,右键删除点,双击结束绘制");
+				$this._tooltip.showAt(evt.endPosition, "点击添加点,双击结束绘制");
+			}
+
+			if ($this._positions.length > 3) {
+				$this._positions.pop();
+				$this._positions.push(cartesian);
+
+				if ($this._positions === 4) {
+					$this._tooltip.showAt(evt.endPosition, "点击添加点");
+				}
+
+				if ($this._positions.length == 5) {
+					$this._tooltip.showAt(evt.endPosition, "双击结束绘制");
+				}
+			}
+
+			console.log($this._positions.length);
+		}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+		//右键结束改为双击结束
+		this.handler.setInputAction(function(evt) {
+			// if (!$this._PincerArrow) {
+			// 	return
+			// } else {
+			// 	// if(typeof $this.callback=="function"){
+			// 	//     $this.callback();
+			// 	// }
+			// };
+			// var cartesian = $this.getCatesian3FromPX(evt.position);
+			// if (!cartesian) return;
+			// $this._positions.pop();
+			// $this._positions.push(cartesian);
+			// $this._PincerArrowData = $this._positions.concat();
+			// $this.viewer.entities.remove($this._PincerArrow); //移除
+			// $this._PincerArrow = null;
+			// $this._positions = [];
+			// $this.floatingPoint.position.setValue(cartesian);
+			// var lnglatArr = [];
+			// for (var i = 0; i < $this._PincerArrowData.length; i++) {
+			// 	var lnglat = $this.cartesianToLatlng($this._PincerArrowData[i]);
+			// 	lnglatArr.push(lnglat)
+			// }
+			// $this._PincerArrowData = lnglatArr;
+			// var pincerArrow = $this.addload(lnglatArr); //加载
+			// $this._entities_PincerArrow.push(pincerArrow);
+			// $this._PincerArrowLast = pincerArrow;
+			// $this.clearPoint();
+			// $this.destroy();
+		}, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+		//双击结束
+		this.handler.setInputAction(function(evt) {
+
+			/* 如果运行环境是App 则禁止使用鼠标双击事件 */
+			if (isRuntimeApp()) return;
+
+			console.log('监听鼠标事件', '双击')
+
+			/* 解除锁定 */
+			clearTimeout($this._timer);
+
+			if (!$this._PincerArrow) {
+				return
+			} else {
+				// if(typeof $this.callback=="function"){
+				//     $this.callback();
+				// }
+			};
+			var cartesian = $this.getCatesian3FromPX(evt.position);
+			if (!cartesian) return;
+
+			$this._positions.pop();
+			// $this._positions.push(cartesian);
+			$this._PincerArrowData = $this._positions.concat();
+			$this.viewer.entities.remove($this._PincerArrow); //移除
+			$this._PincerArrow = null;
+			$this._positions = [];
+			$this.floatingPoint.position.setValue(cartesian);
+			var lnglatArr = [];
+			for (var i = 0; i < $this._PincerArrowData.length; i++) {
+				var lnglat = $this.cartesianToLatlng($this._PincerArrowData[i]);
+				lnglatArr.push(lnglat)
+			}
+			$this._PincerArrowData = lnglatArr;
+			var pincerArrow = $this.addload(lnglatArr); //加载
+			$this._entities_PincerArrow.push(pincerArrow);
+			$this._PincerArrowLast = pincerArrow;
+			$this.clearPoint();
+			$this.destroy();
+
+			$this._tooltip.setVisible(false);
+
+		}, $this.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+	}
+
+	//创建钳击箭头
+	createPincerArrow() {
+		var $this = this;
+		$this._computeTempPositions();
+		var arrowEntity = $this.viewer.entities.add({
+			polygon: {
+				hierarchy: new $this.Cesium.CallbackProperty(
+					function() {
+						//计算面
+						var lnglatArr = [];
+						for (var i = 0; i < $this._positions.length; i++) {
+							var lnglat = $this.cartesianToLatlng($this._positions[i]);
+							lnglatArr.push(lnglat)
+						}
+						var res = $this.doubleArrow(lnglatArr);
+						var returnData = res.polygonalPoint;
+						return new $this.Cesium.PolygonHierarchy(returnData);
+					}, false),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			}
+		})
+		$this._entities_PincerArrow.push(arrowEntity);
+		return arrowEntity
+	}
+
+	//创建点
+	createPoint(cartesian) {
+		var $this = this;
+		var point = this.viewer.entities.add({
+			position: cartesian,
+			point: {
+				pixelSize: 10,
+				color: $this.Cesium.Color.RED,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			}
+		});
+		$this._entities_point.push(point);
+		return point;
+	}
+
+	cartesianToLatlng(cartesian) {
+		let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		let lat = this.Cesium.Math.toDegrees(cartographic.latitude);
+		let lng = this.Cesium.Math.toDegrees(cartographic.longitude);
+		let alt = cartographic.height;
+		return [lng, lat, alt];
+	}
+
+	//销毁
+	destroy() {
+		if (this.handler) {
+			this.handler.destroy();
+			this.handler = null;
+		}
+	}
+
+	clearPoint() {
+		this.DrawEndEvent.raiseEvent(this._PincerArrowLast, this._PincerArrowData, this.drawType);
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		this._entities_point = []; //脏数据
+	}
+
+	//清空实体对象
+	clear() {
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		for (var i = 0; i < this._entities_PincerArrow.length; i++) {
+			this.viewer.entities.remove(this._entities_PincerArrow[i]);
+		}
+
+		this.floatingPoint = null; //标识点
+		this._PincerArrow = null; //活动箭头
+		this._PincerArrowLast = null; //最后一个箭头
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_PincerArrow = []; //脏数据
+		this._PincerArrowData = null; //用于构造箭头数据
+	}
+
+	getCatesian3FromPX(px) {
+		var cartesian;
+		var ray = this.viewer.camera.getPickRay(px);
+		if (!ray) return null;
+		cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+		return cartesian;
+	}
+
+	_computeTempPositions() {
+		var _this = this;
+
+		var pnts = [].concat(_this._positions);
+		var num = pnts.length;
+		var first = pnts[0];
+		var last = pnts[num - 1];
+		if (_this._isSimpleXYZ(first, last) == false) {
+			pnts.push(first);
+			num += 1;
+		}
+		_this.tempPositions = [];
+		for (var i = 1; i < num; i++) {
+			var p1 = pnts[i - 1];
+			var p2 = pnts[i];
+			var cp = _this._computeCenterPotition(p1, p2);
+			_this.tempPositions.push(p1);
+			_this.tempPositions.push(cp);
+		}
+	}
+
+	_isSimpleXYZ(p1, p2) {
+		if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+			return true;
+		}
+		return false;
+	}
+
+	_computeCenterPotition(p1, p2) {
+		var _this = this;
+		var c1 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p1);
+		var c2 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p2);
+		var cm = new _this.Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+		var cp = _this.viewer.scene.globe.ellipsoid.cartographicToCartesian(cm);
+		return cp;
+	}
+
+	////////////////////////////////////////求取箭头坐标函数/////////////////////////////////////////////////////
+	//箭头配置函数
+	doubleArrow(inputPoint) {
+		var $this = this;
+		this.connPoint = null;
+		this.tempPoint4 = null;
+		this.points = inputPoint;
+		var result = {
+			controlPoint: null,
+			polygonalPoint: null
+		};
+		//获取已经点击的坐标数
+		var t = inputPoint.length;
+		if (!(2 > t)) {
+			if (2 == t) return inputPoint;
+			var o = this.points[0], //第一个点
+				e = this.points[1], //第二个点
+				r = this.points[2], //第三个点
+				t = inputPoint.length; //获取已经点击的坐标数
+			//下面的是移动点位后的坐标
+			3 == t ? this.tempPoint4 = $this.getTempPoint4(o, e, r) : this.tempPoint4 = this.points[3],
+				3 == t || 4 == t ? this.connPoint = $this.mid(o, e) : this.connPoint = this.points[4];
+			var n, g;
+			$this.isClockWise(o, e, r) ? (n = $this.getArrowPoints(o, this.connPoint, this.tempPoint4, !1), g = $this.getArrowPoints(this.connPoint, e, r, !0)) : (n = $this.getArrowPoints(e, this.connPoint, r, !1), g = $this.getArrowPoints(this.connPoint, o, this.tempPoint4, !0));
+			var i = n.length,
+				s = (i - 5) / 2,
+				a = n.slice(0, s),
+				l = n.slice(s, s + 5),
+				u = n.slice(s + 5, i),
+				c = g.slice(0, s),
+				p = g.slice(s, s + 5),
+				h = g.slice(s + 5, i);
+			c = $this.getBezierPoints(c);
+			var d = $this.getBezierPoints(h.concat(a.slice(1)));
+			u = $this.getBezierPoints(u);
+			var f = c.concat(p, d, l, u);
+			var newArray = $this.array2Dto1D(f);
+			result.controlPoint = [o, e, r, this.tempPoint4, this.connPoint];
+			result.polygonalPoint = $this.Cesium.Cartesian3.fromDegreesArray(newArray);
+		}
+		return result;
+	}
+	getTempPoint4(t, o, e) {
+		var $this = this;
+		var r, n, g, i, s = $this.mid(t, o),
+			a = $this.distance(s, e),
+			l = $this.getAngleOfThreePoints(t, s, e);
+		return l < Math.PI / 2 ? (n = a * Math.sin(l), g = a * Math.cos(l), i = $this.getThirdPoint(t, s, Math.PI / 2, n, !1), r = $this.getThirdPoint(s, i, Math.PI / 2, g, !0)) : l >= Math.PI / 2 && l < Math.PI ? (n = a * Math.sin(Math.PI - l), g = a * Math.cos(Math.PI - l), i = $this.getThirdPoint(t, s, Math.PI / 2, n, !1), r = $this.getThirdPoint(s, i, Math.PI / 2, g, !1)) : l >= Math.PI && l < 1.5 * Math.PI ? (n = a * Math.sin(l - Math.PI), g = a * Math.cos(l - Math.PI), i = $this.getThirdPoint(t, s, Math.PI / 2, n, !0), r = $this.getThirdPoint(s, i, Math.PI / 2, g, !0)) : (n = a * Math.sin(2 * Math.PI - l), g = a * Math.cos(2 * Math.PI - l), i = $this.getThirdPoint(t, s, Math.PI / 2, n, !0), r = $this.getThirdPoint(s, i, Math.PI / 2, g, !1)),
+			r
+	}
+
+	mid(t, o) {
+		return [(t[0] + o[0]) / 2, (t[1] + o[1]) / 2]
+	}
+
+	isClockWise(t, o, e) {
+		return (e[1] - t[1]) * (o[0] - t[0]) > (o[1] - t[1]) * (e[0] - t[0])
+	}
+
+	getArrowPoints(t, o, e, r) {
+		var $this = this;
+		var doubleArrowDefualParam = {
+			type: "doublearrow",
+			headHeightFactor: .25,
+			headWidthFactor: .3,
+			neckHeightFactor: .85,
+			fixPointCount: 4,
+			neckWidthFactor: .15
+		}
+		this.type = doubleArrowDefualParam.type,
+			this.headHeightFactor = doubleArrowDefualParam.headHeightFactor,
+			this.headWidthFactor = doubleArrowDefualParam.headWidthFactor,
+			this.neckHeightFactor = doubleArrowDefualParam.neckHeightFactor,
+			this.neckWidthFactor = doubleArrowDefualParam.neckWidthFactor;
+		var n = $this.mid(t, o),
+			g = $this.distance(n, e),
+			i = $this.getThirdPoint(e, n, 0, .3 * g, !0),
+			s = $this.getThirdPoint(e, n, 0, .5 * g, !0);
+		i = $this.getThirdPoint(n, i, Math.PI / 2, g / 5, r),
+			s = $this.getThirdPoint(n, s, Math.PI / 2, g / 4, r);
+		var a = [n, i, s, e],
+			l = $this.getArrowHeadPoints(a, this.headHeightFactor, this.headWidthFactor, this.neckHeightFactor, this.neckWidthFactor),
+			u = l[0],
+			c = l[4],
+			p = $this.distance(t, o) / $this.getBaseLength(a) / 2,
+			h = $this.getArrowBodyPoints(a, u, c, p),
+			d = h.length,
+			f = h.slice(0, d / 2),
+			E = h.slice(d / 2, d);
+		return f.push(u),
+			E.push(c),
+			f = f.reverse(),
+			f.push(o),
+			E = E.reverse(),
+			E.push(t),
+			f.reverse().concat(l, E)
+	}
+
+	getArrowHeadPoints(t, o, e) {
+		var $this = this;
+		var doubleArrowDefualParam = {
+			type: "doublearrow",
+			headHeightFactor: .25,
+			headWidthFactor: .3,
+			neckHeightFactor: .85,
+			fixPointCount: 4,
+			neckWidthFactor: .15
+		}
+		this.type = doubleArrowDefualParam.type,
+			this.headHeightFactor = doubleArrowDefualParam.headHeightFactor,
+			this.headWidthFactor = doubleArrowDefualParam.headWidthFactor,
+			this.neckHeightFactor = doubleArrowDefualParam.neckHeightFactor,
+			this.neckWidthFactor = doubleArrowDefualParam.neckWidthFactor;
+		var r = $this.getBaseLength(t),
+			n = r * this.headHeightFactor,
+			g = t[t.length - 1],
+			i = ($this.distance(o, e), n * this.headWidthFactor),
+			s = n * this.neckWidthFactor,
+			a = n * this.neckHeightFactor,
+			l = $this.getThirdPoint(t[t.length - 2], g, 0, n, !0),
+			u = $this.getThirdPoint(t[t.length - 2], g, 0, a, !0),
+			c = $this.getThirdPoint(g, l, Math.PI / 2, i, !1),
+			p = $this.getThirdPoint(g, l, Math.PI / 2, i, !0),
+			h = $this.getThirdPoint(g, u, Math.PI / 2, s, !1),
+			d = $this.getThirdPoint(g, u, Math.PI / 2, s, !0);
+		return [h, c, g, p, d];
+	}
+
+	getArrowBodyPoints(t, o, e, r) {
+		var $this = this;
+		for (var n = $this.wholeDistance(t), g = $this.getBaseLength(t), i = g * r, s = $this.distance(o, e), a = (i - s) / 2, l = 0, u = [], c = [], p = 1; p < t.length - 1; p++) {
+			var h = $this.getAngleOfThreePoints(t[p - 1], t[p], t[p + 1]) / 2;
+			l += $this.distance(t[p - 1], t[p]);
+			var d = (i / 2 - l / n * a) / Math.sin(h),
+				f = $this.getThirdPoint(t[p - 1], t[p], Math.PI - h, d, !0),
+				E = $this.getThirdPoint(t[p - 1], t[p], h, d, !1);
+			u.push(f), c.push(E)
+		}
+		return u.concat(c)
+	}
+
+	getBezierPoints(t) {
+		if (t.length <= 2) return t;
+		for (var o = [], e = t.length - 1, r = 0; 1 >= r; r += .01) {
+			for (var n = 0, y = 0, g = 0; e >= g; g++) {
+				var i = this.getBinomialFactor(e, g),
+					s = Math.pow(r, g),
+					a = Math.pow(1 - r, e - g);
+				n += i * s * a * t[g][0], y += i * s * a * t[g][1]
+			}
+			o.push([n, y])
+		}
+		return o.push(t[e]), o
+	}
+
+	getBaseLength(t) {
+		return Math.pow(this.wholeDistance(t), .99)
+	}
+
+	wholeDistance(t) {
+		for (var o = 0, e = 0; e < t.length - 1; e++) o += this.distance(t[e], t[e + 1]);
+		return o
+	}
+
+	getBinomialFactor(t, o) {
+		return this.getFactorial(t) / (this.getFactorial(o) * this.getFactorial(t - o))
+	}
+
+	getFactorial(t) {
+		if (1 >= t) return 1;
+		if (2 == t) return 2;
+		if (3 == t) return 6;
+		if (4 == t) return 24;
+		if (5 == t) return 120;
+		for (var o = 1, e = 1; t >= e; e++) o *= e;
+		return o
+	}
+
+	array2Dto1D(array) {
+		var newArray = [];
+		array.forEach(function(elt) {
+			newArray.push(elt[0]);
+			newArray.push(elt[1]);
+		});
+		return newArray;
+	}
+
+	distance(t, o) {
+		return Math.sqrt(Math.pow(t[0] - o[0], 2) + Math.pow(t[1] - o[1], 2))
+	}
+
+	getAngleOfThreePoints(t, o, e) {
+		var r = this.getAzimuth(o, t) - this.getAzimuth(o, e);
+		return 0 > r ? r + 2 * Math.PI : r
+	}
+
+	getAzimuth(t, o) {
+		var e, r = Math.asin(Math.abs(o[1] - t[1]) / this.distance(t, o));
+		return o[1] >= t[1] && o[0] >= t[0] ? e = r + Math.PI : o[1] >= t[1] && o[0] < t[0] ? e = 2 * Math.PI - r : o[1] < t[1] && o[0] < t[0] ? e = r : o[1] < t[1] && o[0] >= t[0] && (e = Math.PI - r), e
+	}
+
+	getThirdPoint(t, o, e, r, n) {
+		var g = this.getAzimuth(t, o),
+			i = n ? g + e : g - e,
+			s = r * Math.cos(i),
+			a = r * Math.sin(i);
+		return [o[0] + s, o[1] + a]
+	}
+
+}
+
+export default DrawPincerArrow

+ 138 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawPoint.js

@@ -0,0 +1,138 @@
+//一、点
+// DrawPoint
+/*
+绘制点
+ */
+class DrawPoint {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        // this.callback=arg.callback;
+        this._point = null;  //最后一个点
+        this._pointData = null;//点数据用于构造点
+        this._entities = []; //脏数据
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+ 
+    //返回最后活动点
+    get point() {
+        return this._point;
+    }
+ 
+    //加载点
+    addload(data) {
+        return this.createPoint(data);
+    }
+ 
+    //返回点数据用于加载点
+    getData() {
+        return this._pointData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data) {
+        let $this = this
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.cartesianToLatlng(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        $this._pointData = lnglatArr;
+        let point = lnglatArr[0]
+        return $this.Cesium.Cartesian3.fromDegrees(point[0],point[1])
+    }
+ 
+    //开始绘制
+    startCreate(drawType) {
+        this.drawType = drawType;
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if (!cartesian) return;
+            let latlon = $this.cartesianToLatlng(cartesian)
+            var point = $this.createPoint(latlon);
+            $this._pointData = cartesian;
+            $this._point = point;
+            // if(typeof $this.callback=="function"){
+            //     $this.callback(point);
+            // }
+            
+            $this.DrawEndEvent.raiseEvent($this._point, latlon, $this.drawType);
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+    }
+ 
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            Type:'DrawPoint',
+            Position:[cartesian],
+            position: $this.Cesium.Cartesian3.fromDegrees(cartesian[0],cartesian[1]),
+            id:cartesian.id || $this.objId,
+            billboard: {
+                image: "./static/poi2.png",
+                // scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, 0.4), //设置随图缩放距离和比例
+                // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), //设置可见距离 10000米可见
+                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+                // clampToGround: true
+            },
+        });
+        $this._entities.push(point); //加载脏数据
+        return point;
+    }
+
+    cartesianToLatlng(cartesian) {
+        let ellipsoid = this.viewer.scene.globe.ellipsoid
+        let cartographic = ellipsoid.cartesianToCartographic(cartesian);
+        let lat = Cesium.Math.toDegrees(cartographic.latitude);
+        let lng = Cesium.Math.toDegrees(cartographic.longitude);
+        return [lng, lat];
+    }
+ 
+    //销毁鼠标事件
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+ 
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this._entities.length; i++) {
+            this.viewer.entities.remove(this._entities[i]);
+        }
+        this._entities = [];
+        this._point = null;
+    }
+ 
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+}
+ 
+export default DrawPoint;

+ 229 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawPolygon.js

@@ -0,0 +1,229 @@
+//   六、多边形
+// DrawPolygon
+/*
+绘制面
+ */
+class DrawPolygon {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        // this.callback=arg.callback;
+        this._polygon = null;  //活动面
+        this._polygonLast = null;  //最后一个面
+        this._positions = []; //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_polygon = [];  //脏数据
+        this._polygonData = null; //用户构造面
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+
+    //返回最后活动面
+    get polygon() {
+        return this._polygonLast;
+    }
+
+    //返回面数据用于加载面
+    getData() {
+        return this._polygonData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data){
+        //计算面
+        let $this = this
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.cartesianToLatlng(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        $this._polygonData = lnglatArr;
+        return new $this.Cesium.PolygonHierarchy(data);
+    }
+
+    //加载面
+    addload(data) {
+        var $this = this;
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.LatlngTocartesian(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        return this.viewer.entities.add({
+            Type: 'DrawPolygon',
+            Position: data,
+            id:data.id || $this.objId,
+            polygon: {
+                hierarchy: new $this.Cesium.PolygonHierarchy(lnglatArr),
+                clampToGround: true,
+                show: true,
+                fill: true,
+                material: $this.Cesium.Color.RED.withAlpha(0.9),
+                width: 3,
+                outlineColor: $this.Cesium.Color.BLACK,
+                outlineWidth: 1,
+                outline: false
+            }
+        });
+    }
+
+    //开始绘制
+    startCreate(drawType) {
+        this.drawType = drawType;
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if ($this._positions.length == 0) {
+                $this._positions.push(cartesian.clone());
+            }
+            $this.createPoint(cartesian);
+            $this._positions.push(cartesian);
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制面
+            if ($this._positions.length < 1) return;
+            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+            if ($this._positions.length == 3) {
+                if (!$this.Cesium.defined($this._polygon)) {
+                    $this._polygon = $this.createPolygon();
+                }
+            }
+            $this._positions.pop();
+            $this._positions.push(cartesian);
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.setInputAction(function (evt) {
+            if (!$this._polygon) return;
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            $this._positions.pop();
+            // $this._positions.push(cartesian);
+            $this.createPoint(cartesian);
+            $this._polygonData = $this._positions.concat();
+            $this.viewer.entities.remove($this._positions); //移除
+            $this._positions = null;
+            $this._positions = [];
+            var lnglatArr = [];
+            for (var i = 0; i < $this._polygonData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this._polygonData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this._polygonData = lnglatArr;
+            var Polygon = $this.addload($this._polygonData);
+            $this._entities_polygon.push(Polygon);
+            $this._polygonLast = Polygon;
+            // if(typeof $this.callback=="function"){
+            //     $this.callback(Polygon);
+            // }
+            $this.clearPoint();
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+
+    //创建面
+    createPolygon() {
+        var $this = this;
+        var polygon = this.viewer.entities.add({
+            polygon: {
+                hierarchy: new $this.Cesium.CallbackProperty(function () {
+                    return new $this.Cesium.PolygonHierarchy($this._positions);
+                }, false),
+                clampToGround: true,
+                show: true,
+                fill: true,
+                material: $this.Cesium.Color.RED.withAlpha(0.5),
+                width: 3,
+                outlineColor: $this.Cesium.Color.BLACK,
+                outlineWidth: 1,
+                outline: false
+            }
+        });
+        $this._entities_polygon.push(polygon);
+        return polygon;
+    }
+
+    cartesianToLatlng(cartesian) {
+        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+        var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+        return [lng, lat];
+    }
+
+    LatlngTocartesian(latlng) {
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+        return cartesian3
+    }
+
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this._polygonLast, this._polygonData, this.drawType);
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        this._entities_point = [];  //脏数据
+    }
+
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this._entities_point.push(point);
+        return point;
+    }
+
+
+    //销毁事件
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        for (var i = 0; i < this._entities_polygon.length; i++) {
+            this.viewer.entities.remove(this._entities_polygon[i]);
+        }
+        this._polygon = null;  //活动面
+        this._polygonLast = null;  //最后一个面
+        this._positions = []; //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_polygon = [];  //脏数据
+        this._polygonData = null; //用户构造面
+    }
+
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+}
+
+export default DrawPolygon

+ 223 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawPolyline.js

@@ -0,0 +1,223 @@
+//二、折线
+// DrawPolyline
+/*
+绘制线
+ */
+class DrawPolyline {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        // this.callback=arg.callback;
+        this._polyline = null; //活动线
+        this._polylineLast = null; //最后一条线
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_line = [];  //脏数据
+        this._polylineData = null; //用于构造线数据
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+ 
+    //返回最后活动线
+    get line() {
+        return this._polylineLast;
+    }
+ 
+    //返回线数据用于加载线
+    getData() {
+        return this._polylineData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data){
+        //计算面
+        let $this = this
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.cartesianToLatlng(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        $this._polylineData = lnglatArr;
+        return data;
+    }
+ 
+    //加载线
+    addload(data) {
+        var $this = this;
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.LatlngTocartesian(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        var polyline = this.viewer.entities.add({
+            Type:'DrawPolyline',
+            Position:data,
+            id:data.id || $this.objId,
+            polyline: {
+                positions: lnglatArr,
+                show: true,
+                material: $this.Cesium.Color.RED,
+                width: 3,
+                clampToGround: true
+            }
+        });
+        return polyline;
+    }
+ 
+    //开始创建
+    startCreate(drawType) {
+        this.drawType = drawType;
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            //屏幕坐标转地形上坐标
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if ($this._positions.length == 0) {
+                $this._positions.push(cartesian.clone());
+            }
+            $this._positions.push(cartesian);
+            $this.createPoint(cartesian);// 绘制点
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制线
+            if ($this._positions.length < 1) return;
+            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+            if (!$this.Cesium.defined($this._polyline)) {
+                $this._polyline = $this.createPolyline();
+            }
+            if ($this._polyline) {
+                $this._positions.pop();
+                $this._positions.push(cartesian);
+            }
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.setInputAction(function (evt) {
+            if (!$this._polyline) return;
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            $this._positions.pop();
+            // $this._positions.push(cartesian);
+            $this.createPoint(cartesian);// 绘制点
+            $this._polylineData = $this._positions.concat();
+            $this.viewer.entities.remove($this._polyline); //移除
+            $this._polyline = null;
+            $this._positions = [];
+            var lnglatArr = [];
+            for (var i = 0; i < $this._polylineData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this._polylineData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this._polylineData = lnglatArr;
+            var line = $this.addload($this._polylineData); //加载线
+            $this._entities_line.push(line);
+            $this._polylineLast=line;
+            // if(typeof $this.callback=="function"){
+            //     $this.callback(line);
+            // }
+            $this.clearPoint();
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+ 
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this._entities_point.push(point);
+        return point;
+    }
+ 
+    //创建线
+    createPolyline() {
+        var $this = this;
+        var polyline = this.viewer.entities.add({
+            polyline: {
+                //使用cesium的peoperty
+                positions: new $this.Cesium.CallbackProperty(function () {
+                    return $this._positions
+                }, false),
+                show: true,
+                material: $this.Cesium.Color.RED,
+                width: 3,
+                clampToGround: true
+            }
+        });
+        $this._entities_line.push(polyline);
+        return polyline;
+    }
+
+    cartesianToLatlng(cartesian) {
+        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+        var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+        return [lng, lat];
+    }
+
+    LatlngTocartesian(latlng) {
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+        return cartesian3
+    }
+
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this._polylineLast , this._polylineData, this.drawType);
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        this._entities_point = [];  //脏数据
+    }
+ 
+    //销毁
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+ 
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        for (var i = 0; i < this._entities_line.length; i++) {
+            this.viewer.entities.remove(this._entities_line[i]);
+        }
+        this._polyline = null;
+        this._positions = [];
+        this._entities_point = [];  //脏数据
+        this._entities_line = [];  //脏数据
+        this._polylineData = null; //用于构造线数据
+        this._polylineLast=null;
+    }
+ 
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+}
+ 
+export default DrawPolyline

+ 289 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawRectFlag.js

@@ -0,0 +1,289 @@
+
+// DrawRectFlag
+/*
+绘制矩形旗帜旗帜
+ */
+class DrawRectFlag {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        this.identificationPoint = null; //标识点位
+        this.RectFlag = null; 
+        this.RectFlagLast = null; // 矩形旗帜数据
+        this.positions = [];  // 经纬度
+        this.entitiesPoint = [];   // 实体点位
+        this.entitiesRectFlag = [];  
+        this.RectFlagData = null; 
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+ 
+    //返回矩形旗帜数据
+    getData() {
+        return this.RectFlagData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data){
+        //计算面
+        let $this = this
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.cartesianToLatlng(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        let startPoint = lnglatArr[0];
+        // 取最后一个
+        let endPoint =lnglatArr[lnglatArr.length - 1]
+        let point0 = lnglatArr[0];
+        var point1 =[endPoint[0], startPoint[1]];
+        var point2 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        var point3 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        var point4 =[startPoint[0], endPoint[1]]
+        let componentspolygon = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point3,...point0,])
+        let componentspolyline = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point3,...point0,...point4])
+        let PolygonHierarchy = new $this.Cesium.PolygonHierarchy(componentspolygon)
+        $this.RectFlagData = lnglatArr;
+        console.log([PolygonHierarchy,componentspolyline])
+        return [PolygonHierarchy,componentspolyline];
+    }
+ 
+    //加载
+    addload(data) {
+        var $this = this;
+        if (data.length < 2) return;
+        let startPoint = data[0];
+        // 取最后一个
+        let endPoint =data[data.length - 1]
+        let point0 = data[0];
+        var point1 =[endPoint[0], startPoint[1]];
+        var point2 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        var point3 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        var point4 =[startPoint[0], endPoint[1]]
+        let componentspolygon = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point3,...point0,])
+        let componentspolyline = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point3,...point0,...point4])
+        var shape = this.viewer.entities.add({
+            Type:'DrawRectFlag',
+            Position:data,
+            id:data.id || $this.objId,
+            polygon: {
+                hierarchy: new $this.Cesium.PolygonHierarchy(componentspolygon),
+                extrudedHeight: 1,
+                material: $this.Cesium.Color.RED,
+            },
+            polyline: {
+                //使用cesium的peoperty
+                positions: componentspolyline,
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 5,
+                clampToGround: true
+            }
+        });
+        $this.entitiesRectFlag.push(shape);
+        return shape;
+    }
+ 
+    //开始创建
+    startCreate(drawType) {
+        this.drawType = drawType;
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            //屏幕坐标转地形上坐标
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if ($this.positions.length == 0) {
+                $this.positions.push(cartesian.clone());
+                $this.identificationPoint = $this.createPoint(cartesian);
+                $this.createPoint(cartesian);// 绘制点
+                $this.positions.push(cartesian);
+            }
+            // if ($this.positions.length == 2) {
+            //     $this.positions.push(cartesian);
+            // }
+            
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制线
+            if ($this.positions.length < 2) return;
+            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+            if (!$this.Cesium.defined($this.RectFlag)) {
+                $this.RectFlag = $this.createRectFlag();
+            }
+            $this.identificationPoint.position.setValue(cartesian);
+            if ($this.RectFlag) {
+                $this.positions.pop();
+                $this.positions.push(cartesian);
+            }
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.setInputAction(function (evt) {
+            if (!$this.RectFlag) return;
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            $this.positions.pop();
+            $this.positions.push(cartesian);
+            $this.createPoint(cartesian);// 绘制点
+            $this.RectFlagData = $this.positions.concat();
+            $this.viewer.entities.remove($this.RectFlag); //移除
+            $this.RectFlag = null;
+            $this.positions = [];
+            $this.identificationPoint.position.setValue(cartesian);
+            var lnglatArr = [];
+            for (var i = 0; i < $this.RectFlagData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this.RectFlagData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this.RectFlagData = lnglatArr;
+            var RectFlag = $this.addload([$this.RectFlagData[0],$this.RectFlagData[$this.RectFlagData.length -1 ]]); //加载
+            $this.entitiesRectFlag.push(RectFlag);
+            $this.RectFlagLast = RectFlag;
+            $this.clearPoint();
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+ 
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this.entitiesPoint.push(point);
+        return point;
+    }
+ 
+    //创建矩形旗帜
+    createRectFlag() {
+        console.log('232323')
+        var $this = this;
+        var polygon = this.viewer.entities.add({
+            polygon: {
+                hierarchy: new $this.Cesium.CallbackProperty(function () {
+                    if($this.positions.length < 2) return 
+                    let lonlat = [];
+                    let length = $this.positions.length
+                    for (let i=0; i<length; i++){
+                        lonlat.push($this.cartesianToLatlng($this.positions[i]))
+                    }
+                    let startPoint = lonlat[0]
+                    // 取最后一个
+                    let endPoint =lonlat[lonlat.length - 1]
+                    let point0 = lonlat[0];
+                    var point1 =[endPoint[0], startPoint[1]];
+                    var point2 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    var point3 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    var point4 =[startPoint[0], endPoint[1]]
+
+                    let components = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point3,...point0,])
+                    
+                    return new $this.Cesium.PolygonHierarchy(components);
+                }, false),
+                extrudedHeight: 1,
+                material: $this.Cesium.Color.RED,
+            },
+            polyline: {
+                //使用cesium的peoperty
+                positions: new $this.Cesium.CallbackProperty(function () {
+                    if($this.positions.length < 2) return 
+                    let lonlat = [];
+                    let length = $this.positions.length
+                    for (let i=0; i<length; i++){
+                        lonlat.push($this.cartesianToLatlng($this.positions[i]))
+                    }
+                    let startPoint = lonlat[0]
+                    // 取最后一个
+                    let endPoint =lonlat[lonlat.length - 1]
+                    let point0 = lonlat[0];
+                    var point1 =[endPoint[0], startPoint[1]];
+                    var point2 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    var point3 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    var point4 =[startPoint[0], endPoint[1]]
+
+                    let components = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point3,...point0,...point4])
+                    return components
+                }, false),
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 5,
+                clampToGround: true
+            }
+        });
+        $this.entitiesRectFlag.push(polygon);
+        return polygon;
+    }
+
+    cartesianToLatlng(cartesian) {
+        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+        var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+        return [lng, lat];
+    }
+
+    LatlngTocartesian(latlng) {
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+        return cartesian3
+    }
+
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this.RectFlagLast, [this.RectFlagData[0],this.RectFlagData[this.RectFlagData.length -1 ]], this.drawType);
+        for (var i = 0; i < this.entitiesPoint.length; i++) {
+            this.viewer.entities.remove(this.entitiesPoint[i]);
+        }
+        this.entitiesPoint = [];  //脏数据
+    }
+ 
+    //销毁
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+ 
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this.entitiesPoint.length; i++) {
+            this.viewer.entities.remove(this.entitiesPoint[i]);
+        }
+        for (var i = 0; i < this.entitiesRectFlag.length; i++) {
+            this.viewer.entities.remove(this.entitiesRectFlag[i]);
+        }
+        this.identificationPoint = null; //标识点位
+        this.RectFlag = null; 
+        this.RectFlagLast = null; // 矩形旗帜数据
+        this.positions = [];  // 经纬度
+        this.entitiesPoint = [];   // 实体点位
+        this.entitiesRectFlag = [];  
+        this.RectFlagData = null; 
+    }
+ 
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+}
+ 
+export default DrawRectFlag

+ 228 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawRectangle.js

@@ -0,0 +1,228 @@
+//  五、矩形
+// DrawRectangle
+/*
+绘制矩形
+ */
+class DrawRectangle {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        // this.callback=arg.callback;
+        this.floatingPoint = null;//标识点
+        this._rectangle = null; //活动矩形
+        this._rectangleLast = null; //最后一个矩形
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_rectangle = [];  //脏数据
+        this._rectangleData = null; //用于构造矩形数据
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+ 
+    //返回最后图形
+    get line() {
+        return this._rectangleLast;
+    }
+ 
+    //返回矩形数据
+    getData() {
+        return this._rectangleData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data){
+        //计算面
+        let $this = this
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.cartesianToLatlng(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        $this._rectangleData = lnglatArr;
+        return new $this.Cesium.Rectangle.fromCartesianArray(data);
+    }
+ 
+    //加载
+    addload(data) {
+        var $this = this;
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.LatlngTocartesian(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        var shape = this.viewer.entities.add({
+            Type:'DrawRectangle',
+            Position:data,
+            id:data.id || $this.objId,
+            rectangle: {
+                coordinates: $this.Cesium.Rectangle.fromCartesianArray(lnglatArr),
+                material: $this.Cesium.Color.RED.withAlpha(0.9)
+            }
+        });
+        $this._entities_rectangle.push(shape);
+        return shape;
+    }
+ 
+    //开始创建
+    startCreate(drawType) {
+        this.drawType = drawType;
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            //屏幕坐标转地形上坐标
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if ($this._positions.length == 0) {
+                $this._positions.push(cartesian.clone());
+                $this.floatingPoint = $this.createPoint(cartesian);
+                $this.createPoint(cartesian);// 绘制点
+                $this._positions.push(cartesian);
+            }
+            if ($this._positions.length == 2) {
+                $this._positions.push(cartesian);
+            }
+            
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制线
+            if ($this._positions.length < 3) return;
+            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+            if (!$this.Cesium.defined($this._rectangle)) {
+                $this._rectangle = $this.createRectangle();
+            }
+            $this.floatingPoint.position.setValue(cartesian);
+            if ($this._rectangle) {
+                $this._positions.pop();
+                $this._positions.push(cartesian);
+            }
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.setInputAction(function (evt) {
+            if (!$this._rectangle) return;
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            $this._positions.pop();
+            $this._positions.push(cartesian);
+            $this.createPoint(cartesian);// 绘制点
+            $this._rectangleData = $this._positions.concat();
+            $this.viewer.entities.remove($this._rectangle); //移除
+            $this._rectangle = null;
+            $this._positions = [];
+            $this.floatingPoint.position.setValue(cartesian);
+            var lnglatArr = [];
+            for (var i = 0; i < $this._rectangleData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this._rectangleData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this._rectangleData = lnglatArr;
+            var rectangle = $this.addload([$this._rectangleData[0],$this._rectangleData[$this._rectangleData.length -1 ]]); //加载
+            $this._entities_rectangle.push(rectangle);
+            $this._rectangleLast = rectangle;
+            // if(typeof $this.callback=="function"){
+            //     $this.callback(rectangle);
+            // }
+            $this.clearPoint();
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+ 
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this._entities_point.push(point);
+        return point;
+    }
+ 
+    //创建矩形
+    createRectangle() {
+        var $this = this;
+        var shape = this.viewer.entities.add({
+            name: "rectangle",
+            rectangle: {
+                coordinates: new $this.Cesium.CallbackProperty(function() {
+                    var obj = $this.Cesium.Rectangle.fromCartesianArray($this._positions);
+                    return obj;
+                }, false),
+                material: $this.Cesium.Color.RED.withAlpha(0.5)
+            }
+        });
+        $this._entities_rectangle.push(shape);
+        return shape;
+    }
+
+    cartesianToLatlng(cartesian) {
+        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+        var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+        return [lng, lat];
+    }
+
+    LatlngTocartesian(latlng) {
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+        return cartesian3
+    }
+
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this._rectangleLast, [this._rectangleData[0],this._rectangleData[this._rectangleData.length -1 ]], this.drawType);
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        this._entities_point = [];  //脏数据
+    }
+ 
+    //销毁
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+ 
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        for (var i = 0; i < this._entities_rectangle.length; i++) {
+            this.viewer.entities.remove(this._entities_rectangle[i]);
+        }
+        this.floatingPoint = null;//标识点
+        this._rectangle = null; //活动矩形
+        this._rectangleLast = null; //最后一个矩形
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_rectangle = [];  //脏数据
+        this._rectangleData = null; //用于构造矩形数据
+    }
+ 
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+}
+ 
+export default DrawRectangle

+ 327 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawSector.js

@@ -0,0 +1,327 @@
+// DrawSector
+/*
+九、绘制扇形
+ */
+class DrawSector {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        this.floatingPoint = null;//标识点
+        this._sector = null; //活动扇形
+        this._sectorLast = null; //最后一个扇形
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_sector = [];  //脏数据
+        this._sectorData = null; //用于构造扇形数据
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+
+    //返回扇形
+    get sector() {
+        return this._sectorLast;
+    }
+
+    //返回扇形数据用于加载扇形
+    getData() {
+        return this._sectorData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data){
+        let $this = this;
+        let pnts = data;
+        let center = $this.lonLatToMercator($this.cartesianToLatlng(pnts[0]));
+        let pnt2 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[1]));
+        let pnt3 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[2]));
+        var radius = $this.MathDistance(pnt2, center);
+        var startAngle = $this.getAzimuth(pnt2, center);
+        var endAngle = $this.getAzimuth(pnt3, center);
+        var pList = $this.getArcPoints(center, radius, startAngle, endAngle);
+        pList.push(pnts[0], pList[0]);
+        let arrow = [];
+        for (var i = 0; i < pList.length; i++) {
+            var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z);
+            arrow.push(cart3);
+        }
+        var lnglatArr = [];
+        for (var d = 0; d < data.length; d++){
+            lnglatArr.push($this.cartesianToLatlng(data[d]))
+        }
+        $this._sectorData = lnglatArr;
+        return new $this.Cesium.PolygonHierarchy(arrow)
+    }
+
+    //加载扇形
+    addload(data) {
+        var $this = this;
+        let pnts = data;
+        let center = $this.lonLatToMercator(pnts[0]);
+        let pnt2 = $this.lonLatToMercator(pnts[1]);
+        let pnt3 = $this.lonLatToMercator(pnts[2]);
+        var radius = $this.MathDistance(pnt2, center);
+        var startAngle = $this.getAzimuth(pnt2, center);
+        var endAngle = $this.getAzimuth(pnt3, center);
+        var pList = $this.getArcPoints(center, radius, startAngle, endAngle);
+        let pntsc = $this.Cesium.Cartesian3.fromDegrees(pnts[0][0], pnts[0][1])
+        pList.push(pntsc, pList[0]);
+        let arrow = [];
+        for (var i = 0; i < pList.length; i++) {
+            var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z);
+            arrow.push(cart3);
+        }
+        var arrowEntity = $this.viewer.entities.add({
+            Type: 'DrawSector',
+            Position: data,
+            id: data.id || $this.objId,
+            polygon: {
+                hierarchy: new $this.Cesium.PolygonHierarchy(arrow),
+                show: true,
+                fill: true,
+                clampToGround: true,
+                material: $this.Cesium.Color.AQUA.withAlpha(0.9)
+            }
+        });
+        return arrowEntity;
+    }
+
+    //开始创建
+    startCreate() {
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            //屏幕坐标转地形上坐标
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            // if($this._positions.length == 3) return
+            if ($this._positions.length < 3) {
+                $this.floatingPoint = $this.createPoint(cartesian);
+                $this._positions.push(cartesian);
+            }
+            if (!$this._sector) {
+                // $this.createPoint(cartesian);// 绘制点
+            }
+
+
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制面
+            if ($this._positions.length < 2) return;
+            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+            if ($this._positions.length == 2) {
+                $this._positions.push(cartesian);
+            }
+            if ($this._positions.length == 3) {
+                $this._positions.pop();
+                $this._positions.push(cartesian);
+                if (!$this.Cesium.defined($this._sector)) {
+                    $this._sector = $this.createsector();
+                }
+            }
+
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        this.handler.setInputAction(function (evt) {
+            if (!$this._sector) return;
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            $this._positions.pop();
+            $this._positions.push(cartesian);
+            $this._sectorData = $this._positions.concat();
+            $this.viewer.entities.remove($this._sector); //移除
+            $this._sector = null;
+            $this._positions = [];
+            $this.floatingPoint.position.setValue(cartesian);
+            var lnglatArr = [];
+            for (var i = 0; i < $this._sectorData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this._sectorData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this._sectorData = lnglatArr;
+            var sector = $this.addload(lnglatArr); //加载
+            $this._entities_sector.push(sector);
+            $this._sectorLast = sector;
+            $this.clearPoint();
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+
+    //创建直线扇形
+    createsector() {
+        // console.log(this._positions)
+        var $this = this;
+        var arrowEntity = $this.viewer.entities.add({
+            polygon: {
+                hierarchy: new $this.Cesium.CallbackProperty(
+                    function () {
+                        // if(this._positions.length < 3) return
+                        let pnts = $this._positions;
+                        let center = $this.lonLatToMercator($this.cartesianToLatlng(pnts[0]));
+                        let pnt2 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[1]));
+                        let pnt3 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[2]));
+                        var radius = $this.MathDistance(pnt2, center);
+                        var startAngle = $this.getAzimuth(pnt2, center);
+                        var endAngle = $this.getAzimuth(pnt3, center);
+                        var pList = $this.getArcPoints(center, radius, startAngle, endAngle);
+                        pList.push(pnts[0], pList[0]);
+                        let arrow = [];
+                        for (var i = 0; i < pList.length; i++) {
+                            var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z);
+                            arrow.push(cart3);
+                        }
+
+                        return new $this.Cesium.PolygonHierarchy(pList);
+
+                    }, false),
+                show: true,
+                fill: true,
+                clampToGround: true,
+                material: $this.Cesium.Color.AQUA.withAlpha(0.5)
+            }
+        }
+        )
+        $this._entities_sector.push(arrowEntity);
+        return arrowEntity
+    }
+
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this._entities_point.push(point);
+        return point;
+    }
+
+    cartesianToLatlng(cartesian) {
+        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+        var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+        return [lng, lat];
+    }
+    /**
+     * 经纬度坐标转墨卡托坐标
+     */
+    // 墨卡托坐标系:展开地球,赤道作为x轴,向东为x轴正方,本初子午线作为y轴,向北为y轴正方向。
+    // 数字20037508.34是地球赤道周长的一半:地球半径6378137米,赤道周长2*PI*r = 2 * 20037508.3427892,墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892]
+    lonLatToMercator(Latlng) {
+        var E = Latlng[0];
+        var N = Latlng[1];
+        var x = E * 20037508.34 / 180;
+        var y = Math.log(Math.tan((90 + N) * Math.PI / 360)) / (Math.PI / 180);
+        y = y * 20037508.34 / 180;
+        return [x, y]
+    }
+
+    WebMercator2lonLat(mercator) {
+        let x = mercator[0] / 20037508.34 * 180;
+        let ly = mercator[1] / 20037508.34 * 180;
+        let y = 180 / Math.PI * (2 * Math.atan(Math.exp(ly * Math.PI / 180)) - Math.PI / 2)
+        return [x, y];
+    }
+
+    //销毁
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this._sectorLast, this._sectorData);
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        this._entities_point = [];  //脏数据
+    }
+
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this._entities_point.length; i++) {
+            this.viewer.entities.remove(this._entities_point[i]);
+        }
+        for (var i = 0; i < this._entities_sector.length; i++) {
+            this.viewer.entities.remove(this._entities_sector[i]);
+        }
+        this.floatingPoint = null;//标识点
+        this._sector = null; //活动扇形
+        this._sectorLast = null; //最后一个扇形
+        this._positions = [];  //活动点
+        this._entities_point = [];  //脏数据
+        this._entities_sector = [];  //脏数据
+        this._sectorData = null; //用于构造扇形数据
+    }
+
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+
+    // 求取扇形坐标函数/
+    //扇形配置函数
+    MathDistance(pnt1, pnt2) {
+        return Math.sqrt(Math.pow(pnt1[0] - pnt2[0], 2) + Math.pow(pnt1[1] - pnt2[1], 2));
+    }
+
+    getAzimuth(startPoint, endPoint) {
+        var azimuth;
+        var angle = Math.asin(Math.abs(endPoint[1] - startPoint[1]) / this.MathDistance(startPoint, endPoint));
+
+        if (endPoint[1] >= startPoint[1] && endPoint[0] >= startPoint[0]) {
+            azimuth = angle + Math.PI;
+        } else if (endPoint[1] >= startPoint[1] && endPoint[0] < startPoint[0]) {
+            azimuth = Math.PI * 2 - angle;
+        } else if (endPoint[1] < startPoint[1] && endPoint[0] < startPoint[0]) {
+            azimuth = angle;
+        } else if (endPoint[1] < startPoint[1] && endPoint[0] >= startPoint[0]) {
+            azimuth = Math.PI - angle;
+        }
+
+        return azimuth;
+    }
+
+
+    getArcPoints(center, radius, startAngle, endAngle) {
+        var x = null,
+            y = null,
+            z = null,
+            pnts = [],
+            angleDiff = endAngle - startAngle;
+        angleDiff = angleDiff < 0 ? angleDiff + Math.PI * 2 : angleDiff;
+
+        for (var i = 0; i <= 100; i++) {
+            var angle = startAngle + angleDiff * i / 100;
+            x = center[0] + radius * Math.cos(angle);
+            y = center[1] + radius * Math.sin(angle);
+            let latlon = this.WebMercator2lonLat([x, y])
+            pnts.push(this.Cesium.Cartesian3.fromDegrees(latlon[0], latlon[1]));
+        }
+        return pnts;
+    }
+}
+
+export default DrawSector

+ 348 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawStraightArrow.js

@@ -0,0 +1,348 @@
+import {
+	createTooltip
+} from "../../../common/common.js";
+
+//    七、直线箭头
+// DrawStraightArrow
+/*
+绘制直线箭头
+ */
+class DrawStraightArrow {
+	constructor(arg) {
+		this.viewer = arg.viewer;
+		this.Cesium = arg.Cesium;
+		this.floatingPoint = null; //标识点
+		this._straightArrow = null; //活动箭头
+		this._straightArrowLast = null; //最后一个箭头
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_straightArrow = []; //脏数据
+		this._straightArrowData = null; //用于构造箭头数据
+		this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+		this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+
+		this._tooltip = createTooltip(this.viewer.container);
+
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+	}
+
+	//返回箭头
+	get straightArrow() {
+		return this._straightArrowLast;
+	}
+
+	//返回箭头数据用于加载箭头
+	getData() {
+		return this._straightArrowData;
+	}
+
+	// 修改编辑调用计算
+	computePosition(data) {
+		var $this = this;
+		var length = data.length;
+		var p1 = data[0];
+		var p2 = data[length - 1];
+		var firstPoint = $this.cartesianToLatlng(p1);
+		var endPoints = $this.cartesianToLatlng(p2);
+		var arrow = [];
+		var res = $this.fineArrow([firstPoint[0], firstPoint[1]], [endPoints[0], endPoints[1]]);
+		for (var i = 0; i < res.length; i++) {
+			var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
+			arrow.push(cart3);
+		}
+		$this._straightArrowData = [firstPoint, endPoints];
+		return new $this.Cesium.PolygonHierarchy(arrow);
+	}
+
+	//加载箭头
+	addload(data) {
+		var $this = this;
+		if (data.length < 2) {
+			return null;
+		}
+		var length = data.length;
+		var p1 = data[0];
+		var p2 = data[length - 1];
+		var arrow = [];
+		var res = $this.fineArrow([p1[0], p1[1]], [p2[0], p2[1]]);
+		for (var i = 0; i < res.length; i++) {
+			var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
+			arrow.push(cart3);
+		}
+		var arrowEntity = $this.viewer.entities.add({
+			Type: 'DrawStraightArrow',
+			Position: data,
+			id: data.id || $this.objId,
+			polygon: {
+				hierarchy: new $this.Cesium.PolygonHierarchy(arrow),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			}
+		});
+		return arrowEntity;
+	}
+
+	//开始创建
+	startCreate(drawType) {
+		this.drawType = drawType;
+		var $this = this;
+		this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+		this.handler.setInputAction(function(evt) { //单机开始绘制
+			//屏幕坐标转地形上坐标
+			var cartesian = $this.getCatesian3FromPX(evt.position);
+			if ($this._positions.length == 0) {
+				$this._positions.push(cartesian.clone());
+				$this.floatingPoint = $this.createPoint(cartesian);
+				$this._positions.push(cartesian);
+			}
+			if (!$this._straightArrow) {
+				$this.createPoint(cartesian); // 绘制点
+			} else {
+				$this._straightArrowData = $this._positions.concat();
+				$this.viewer.entities.remove($this._straightArrow); //移除
+				$this._straightArrow = null;
+				$this._positions = [];
+				$this.floatingPoint.position.setValue(cartesian);
+				var lnglatArr = [];
+				for (var i = 0; i < $this._straightArrowData.length; i++) {
+					var lnglat = $this.cartesianToLatlng($this._straightArrowData[i]);
+					lnglatArr.push(lnglat)
+				}
+				$this._straightArrowData = lnglatArr;
+				var straightArrow = $this.addload($this._straightArrowData); //加载
+				$this._entities_straightArrow.push(straightArrow);
+				$this._straightArrowLast = straightArrow;
+				$this.clearPoint();
+				$this.destroy();
+				
+				$this._tooltip.setVisible(false);
+			}
+
+		}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+		this.handler.setInputAction(function(evt) { //移动时绘制面
+			$this._tooltip.showAt(evt.endPosition, "点击开始绘制");
+
+			if ($this._positions.length < 2) return;
+			
+			$this._tooltip.showAt(evt.endPosition, "点击结束绘制");
+			
+			var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+			if (!$this.Cesium.defined($this._straightArrow)) {
+				$this._straightArrow = $this.createStraightArrow();
+			}
+			$this.floatingPoint.position.setValue(cartesian);
+			if ($this._straightArrow) {
+				$this._positions.pop();
+				$this._positions.push(cartesian);
+			}
+		}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+		// this.handler.setInputAction(function(evt) {
+		// 	if (!$this._straightArrow) return;
+		// 	var cartesian = $this.getCatesian3FromPX(evt.position);
+		// 	$this._positions.pop();
+		// 	$this._positions.push(cartesian);
+		// 	$this._straightArrowData = $this._positions.concat();
+		// 	$this.viewer.entities.remove($this._straightArrow); //移除
+		// 	$this._straightArrow = null;
+		// 	$this._positions = [];
+		// 	$this.floatingPoint.position.setValue(cartesian);
+		// 	var lnglatArr = [];
+		// 	for (var i = 0; i < $this._straightArrowData.length; i++) {
+		// 		var lnglat = $this.cartesianToLatlng($this._straightArrowData[i]);
+		// 		lnglatArr.push(lnglat)
+		// 	}
+		// 	$this._straightArrowData = lnglatArr;
+		// 	var straightArrow = $this.addload($this._straightArrowData); //加载
+		// 	$this._entities_straightArrow.push(straightArrow);
+		// 	$this._straightArrowLast = straightArrow;
+		// 	$this.clearPoint();
+		// 	$this.destroy()
+		// }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+	}
+
+	//创建直线箭头
+	createStraightArrow() {
+		var $this = this;
+		var arrowEntity = $this.viewer.entities.add({
+			polygon: {
+				hierarchy: new $this.Cesium.CallbackProperty(
+					function() {
+						// return new $this.Cesium.PolygonHierarchy($this._positions);
+						var length = $this._positions.length;
+						var p1 = $this._positions[0];
+						var p2 = $this._positions[length - 1];
+						var firstPoint = $this.cartesianToLatlng(p1);
+						var endPoints = $this.cartesianToLatlng(p2);
+						var arrow = [];
+						var res = $this.fineArrow([firstPoint[0], firstPoint[1]], [endPoints[0], endPoints[1]]);
+						for (var i = 0; i < res.length; i++) {
+							var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
+							arrow.push(cart3);
+						}
+						return new $this.Cesium.PolygonHierarchy(arrow);
+
+					}, false),
+				show: true,
+				fill: true,
+				clampToGround: true,
+				material: $this.polygonMaterial
+			}
+		})
+		$this._entities_straightArrow.push(arrowEntity);
+		return arrowEntity
+	}
+
+	//创建点
+	createPoint(cartesian) {
+		var $this = this;
+		var point = this.viewer.entities.add({
+			position: cartesian,
+			point: {
+				pixelSize: 10,
+				color: $this.Cesium.Color.RED,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			}
+		});
+		$this._entities_point.push(point);
+		return point;
+	}
+
+	cartesianToLatlng(cartesian) {
+		var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+		var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+		var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+		return [lng, lat];
+	}
+
+	//销毁
+	destroy() {
+		if (this.handler) {
+			this.handler.destroy();
+			this.handler = null;
+		}
+	}
+
+	clearPoint() {
+		this.DrawEndEvent.raiseEvent(this._straightArrowLast, this._straightArrowData, this.drawType);
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		this._entities_point = []; //脏数据
+	}
+
+	//清空实体对象
+	clear() {
+		for (var i = 0; i < this._entities_point.length; i++) {
+			this.viewer.entities.remove(this._entities_point[i]);
+		}
+		for (var i = 0; i < this._entities_straightArrow.length; i++) {
+			this.viewer.entities.remove(this._entities_straightArrow[i]);
+		}
+
+		this.floatingPoint = null; //标识点
+		this._straightArrow = null; //活动箭头
+		this._straightArrowLast = null; //最后一个箭头
+		this._positions = []; //活动点
+		this._entities_point = []; //脏数据
+		this._entities_straightArrow = []; //脏数据
+		this._straightArrowData = null; //用于构造箭头数据
+	}
+
+	getCatesian3FromPX(px) {
+		var cartesian;
+		var ray = this.viewer.camera.getPickRay(px);
+		if (!ray) return null;
+		cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+		return cartesian;
+	}
+
+	// 求取箭头坐标函数/
+	//箭头配置函数
+	fineArrowDefualParam() {
+		return {
+			tailWidthFactor: 0.15,
+			neckWidthFactor: 0.20,
+			headWidthFactor: 0.25,
+			headAngle: Math.PI / 8.5,
+			neckAngle: Math.PI / 13
+		}
+	}
+
+	fineArrow(tailPoint, headerPoint) {
+		var $this = this;
+		if ((tailPoint.length < 2) || (headerPoint.length < 2)) return;
+		//画箭头的函数
+		let tailWidthFactor = $this.fineArrowDefualParam().tailWidthFactor;
+		let neckWidthFactor = $this.fineArrowDefualParam().neckWidthFactor;
+		let headWidthFactor = $this.fineArrowDefualParam().headWidthFactor;
+		let headAngle = $this.fineArrowDefualParam().headAngle;
+		let neckAngle = $this.fineArrowDefualParam().neckAngle;
+		var o = [];
+		o[0] = tailPoint;
+		o[1] = headerPoint;
+		var e = o[0],
+			r = o[1],
+			n = $this.getBaseLength(o),
+			g = n * tailWidthFactor,
+			//尾部宽度因子
+			i = n * neckWidthFactor,
+			//脖子宽度银子
+			s = n * headWidthFactor,
+			//头部宽度因子
+			a = $this.getThirdPoint(r, e, Math.PI / 2, g, !0),
+			l = $this.getThirdPoint(r, e, Math.PI / 2, g, !1),
+			u = $this.getThirdPoint(e, r, headAngle, s, !1),
+			c = $this.getThirdPoint(e, r, headAngle, s, !0),
+			p = $this.getThirdPoint(e, r, neckAngle, i, !1),
+			h = $this.getThirdPoint(e, r, neckAngle, i, !0),
+			d = [];
+		d.push(a[0], a[1], p[0], p[1], u[0], u[1], r[0], r[1], c[0], c[1], h[0], h[1], l[0], l[1], e[0], e[1]);
+		return $this.Cesium.Cartesian3.fromDegreesArray(d);
+	}
+
+	getBaseLength(t) {
+		return Math.pow(this.wholeDistance(t), .99)
+	}
+
+	wholeDistance(t) {
+		for (var o = 0, e = 0; e < t.length - 1; e++) o += this.distance(t[e], t[e + 1]);
+		return o
+	}
+
+	distance(t, o) {
+		return Math.sqrt(Math.pow(t[0] - o[0], 2) + Math.pow(t[1] - o[1], 2))
+	}
+
+	getThirdPoint(t, o, e, r, n) {
+		var g = this.getAzimuth(t, o),
+			i = n ? g + e : g - e,
+			s = r * Math.cos(i),
+			a = r * Math.sin(i);
+		return [o[0] + s, o[1] + a]
+	}
+
+	getAzimuth(t, o) {
+		var e, r = Math.asin(Math.abs(o[1] - t[1]) / this.distance(t, o));
+		return o[1] >= t[1] && o[0] >= t[0] ? e = r + Math.PI : o[1] >= t[1] && o[0] < t[0] ? e = 2 * Math.PI - r : o[1] < t[1] && o[0] < t[0] ? e = r : o[1] < t[1] && o[0] >= t[0] && (e = Math.PI - r), e
+	}
+}
+
+export default DrawStraightArrow

+ 286 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/DrawTriangleFlag.js

@@ -0,0 +1,286 @@
+
+// DrawTriangleFlag
+/*
+绘制三角形旗帜
+ */
+class DrawTriangleFlag {
+    constructor(arg) {
+        this.viewer = arg.viewer;
+        this.Cesium = arg.Cesium;
+        this.identificationPoint = null; //标识点位
+        this.TriangleFlag = null; 
+        this.TriangleFlagLast = null; // 三角形旗帜数据
+        this.positions = [];  // 经纬度
+        this.entitiesPoint = [];   // 实体点位
+        this.entitiesTriangleFlag = [];  
+        this.TriangleFlagData = null; 
+        this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
+        this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 
+		
+		/* 通用参数集合 */
+		this._param = {
+			id: "DrawStraightArrow",
+			polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
+			outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
+			outlineWidth: 1, //边框宽度
+		}
+		
+		/* 创建面材质 */
+		this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
+		/* 创建线材质 */
+		// this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
+		// 	dashLength: 16,
+		// 	color: Cesium.Color.fromCssColorString(this._param.outlineColor)
+		// });
+		this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
+    }
+ 
+    //返回三角形旗帜数据
+    getData() {
+        return this.TriangleFlagData;
+    }
+
+    // 修改编辑调用计算
+    computePosition(data){
+        //计算面
+        let $this = this
+        var lnglatArr = [];
+        for (var i = 0; i < data.length; i++) {
+            var lnglat = $this.cartesianToLatlng(data[i]);
+            lnglatArr.push(lnglat)
+        }
+        let startPoint = lnglatArr[0];
+        // 取最后一个
+        let endPoint =lnglatArr[lnglatArr.length - 1]
+        let point0 = lnglatArr[0];
+        var point1 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        var point2 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        var point3 =[startPoint[0], endPoint[1]]
+        let componentspolygon = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point0])
+        let componentspolyline = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point0,...point3])
+        let PolygonHierarchy = new $this.Cesium.PolygonHierarchy(componentspolygon)
+        $this.TriangleFlagData = lnglatArr;
+        console.log([PolygonHierarchy,componentspolyline])
+        return [PolygonHierarchy,componentspolyline];
+    }
+ 
+    //加载
+    addload(data) {
+        var $this = this;
+        if (data.length < 2) return;
+        let startPoint = data[0];
+        // 取最后一个
+        let endPoint =data[data.length - 1]
+        let point0 = data[0];
+        var point1 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        var point2 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+        var point3 =[startPoint[0], endPoint[1]]
+        let componentspolygon = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point0])
+        let componentspolyline = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point0,...point3])
+        var shape = this.viewer.entities.add({
+            Type:'DrawTriangleFlag',
+            Position:data,
+            id:data.id || $this.objId,
+            polygon: {
+                hierarchy: new $this.Cesium.PolygonHierarchy(componentspolygon),
+                extrudedHeight: 1,
+                material: $this.Cesium.Color.RED,
+            },
+            polyline: {
+                //使用cesium的peoperty
+                positions: componentspolyline,
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 5,
+                clampToGround: true
+            }
+        });
+        $this.entitiesTriangleFlag.push(shape);
+        return shape;
+    }
+ 
+    //开始创建
+    startCreate(drawType) {
+        this.drawType = drawType;
+        var $this = this;
+        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
+        this.handler.setInputAction(function (evt) { //单机开始绘制
+            //屏幕坐标转地形上坐标
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            if ($this.positions.length == 0) {
+                $this.positions.push(cartesian.clone());
+                $this.identificationPoint = $this.createPoint(cartesian);
+                $this.createPoint(cartesian);// 绘制点
+                $this.positions.push(cartesian);
+            }
+            // if ($this.positions.length == 2) {
+            //     $this.positions.push(cartesian);
+            // }
+            
+        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (evt) { //移动时绘制线
+            if ($this.positions.length < 2) return;
+            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
+            if (!$this.Cesium.defined($this.TriangleFlag)) {
+                $this.TriangleFlag = $this.createTriangleFlag();
+            }
+            $this.identificationPoint.position.setValue(cartesian);
+            if ($this.TriangleFlag) {
+                $this.positions.pop();
+                $this.positions.push(cartesian);
+            }
+        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.setInputAction(function (evt) {
+            if (!$this.TriangleFlag) return;
+            var cartesian = $this.getCatesian3FromPX(evt.position);
+            $this.positions.pop();
+            $this.positions.push(cartesian);
+            $this.createPoint(cartesian);// 绘制点
+            $this.TriangleFlagData = $this.positions.concat();
+            $this.viewer.entities.remove($this.TriangleFlag); //移除
+            $this.TriangleFlag = null;
+            $this.positions = [];
+            $this.identificationPoint.position.setValue(cartesian);
+            var lnglatArr = [];
+            for (var i = 0; i < $this.TriangleFlagData.length; i++) {
+                var lnglat = $this.cartesianToLatlng($this.TriangleFlagData[i]);
+                lnglatArr.push(lnglat)
+            }
+            $this.TriangleFlagData = lnglatArr;
+            var TriangleFlag = $this.addload([$this.TriangleFlagData[0],$this.TriangleFlagData[$this.TriangleFlagData.length -1 ]]); //加载
+            $this.entitiesTriangleFlag.push(TriangleFlag);
+            $this.TriangleFlagLast = TriangleFlag;
+            $this.clearPoint();
+            $this.destroy()
+        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+    }
+ 
+    //创建点
+    createPoint(cartesian) {
+        var $this = this;
+        var point = this.viewer.entities.add({
+            position: cartesian,
+            point: {
+                pixelSize: 10,
+                color: $this.Cesium.Color.RED,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            }
+        });
+        $this.entitiesPoint.push(point);
+        return point;
+    }
+ 
+    //创建三角形旗帜
+    createTriangleFlag() {
+        console.log('232323')
+        var $this = this;
+        var polygon = this.viewer.entities.add({
+            polygon: {
+                hierarchy: new $this.Cesium.CallbackProperty(function () {
+                    if($this.positions.length < 2) return 
+                    let lonlat = [];
+                    let length = $this.positions.length
+                    for (let i=0; i<length; i++){
+                        lonlat.push($this.cartesianToLatlng($this.positions[i]))
+                    }
+                    let startPoint = lonlat[0]
+                    // 取最后一个
+                    let endPoint =lonlat[lonlat.length - 1]
+                    let point0 = lonlat[0];
+                    var point1 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    var point2 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    var point3 =[startPoint[0], endPoint[1]]
+
+                    let components = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point0])
+                    
+                    return new $this.Cesium.PolygonHierarchy(components);
+                }, false),
+                extrudedHeight: 1,
+                material: $this.Cesium.Color.RED,
+            },
+            polyline: {
+                //使用cesium的peoperty
+                positions: new $this.Cesium.CallbackProperty(function () {
+                    if($this.positions.length < 2) return 
+                    let lonlat = [];
+                    let length = $this.positions.length
+                    for (let i=0; i<length; i++){
+                        lonlat.push($this.cartesianToLatlng($this.positions[i]))
+                    }
+                    let startPoint = lonlat[0]
+                    // 取最后一个
+                    let endPoint =lonlat[lonlat.length - 1]
+                    let point0 = lonlat[0];
+                    var point1 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    var point2 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
+                    var point3 =[startPoint[0], endPoint[1]]
+
+                    let components = $this.Cesium.Cartesian3.fromDegreesArray([...point0, ...point1, ...point2, ...point0,...point3])
+                    return components
+                }, false),
+                show: true,
+                material: $this.Cesium.Color.YELLOW,
+                width: 5,
+                clampToGround: true
+            }
+        });
+        $this.entitiesTriangleFlag.push(polygon);
+        return polygon;
+    }
+
+    cartesianToLatlng(cartesian) {
+        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
+        var lat = this.Cesium.Math.toDegrees(latlng.latitude);
+        var lng = this.Cesium.Math.toDegrees(latlng.longitude);
+        return [lng, lat];
+    }
+
+    LatlngTocartesian(latlng) {
+        let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
+        return cartesian3
+    }
+
+    clearPoint() {
+        this.DrawEndEvent.raiseEvent(this.TriangleFlagLast, [this.TriangleFlagData[0],this.TriangleFlagData[this.TriangleFlagData.length -1 ]], this.drawType);
+        for (var i = 0; i < this.entitiesPoint.length; i++) {
+            this.viewer.entities.remove(this.entitiesPoint[i]);
+        }
+        this.entitiesPoint = [];  //脏数据
+    }
+ 
+    //销毁
+    destroy() {
+        if (this.handler) {
+            this.handler.destroy();
+            this.handler = null;
+        }
+    }
+ 
+    //清空实体对象
+    clear() {
+        for (var i = 0; i < this.entitiesPoint.length; i++) {
+            this.viewer.entities.remove(this.entitiesPoint[i]);
+        }
+        for (var i = 0; i < this.entitiesTriangleFlag.length; i++) {
+            this.viewer.entities.remove(this.entitiesTriangleFlag[i]);
+        }
+        this.identificationPoint = null; //标识点位
+        this.TriangleFlag = null; 
+        this.TriangleFlagLast = null; // 三角形旗帜数据
+        this.positions = [];  // 经纬度
+        this.entitiesPoint = [];   // 实体点位
+        this.entitiesTriangleFlag = [];  
+        this.TriangleFlagData = null; 
+    }
+ 
+    getCatesian3FromPX(px) {
+        var cartesian;
+        var ray = this.viewer.camera.getPickRay(px);
+        if (!ray) return null;
+        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
+        return cartesian;
+    }
+}
+ 
+export default DrawTriangleFlag
+

+ 47 - 0
src/jtMap3d/Widgets/DrawTools/MilitaryPlot/drawingMethod/index.js

@@ -0,0 +1,47 @@
+import DrawStraightArrow from './DrawStraightArrow';
+import DrawAttackArrow from './DrawAttackArrow';
+import DrawPincerArrow from './DrawPincerArrow';
+import DrawGatheringPlace from './DrawGatheringPlace';
+import DrawClosedCurve from './DrawClosedCurve';
+import DrawSector from './DrawSector';
+
+import DrawArc from './DrawArc';
+import DrawLune from './DrawLune';
+
+import DrawCurve from './DrawCurve';
+import DrawCurveFlag from './DrawCurveFlag';
+import DrawRectFlag from './DrawRectFlag';
+import DrawTriangleFlag from './DrawTriangleFlag';
+
+import DrawPoint from './DrawPoint';
+import DrawPolyline from './DrawPolyline';
+import DrawPolygon from './DrawPolygon';
+import DrawRectangle from './DrawRectangle';
+import DrawCircle from './DrawCircle';
+
+
+let MilitaryPlot = {
+	DrawStraightArrow, // 绘制直线箭头
+	DrawAttackArrow, //绘制攻击箭头
+	DrawPincerArrow, //绘制钳击箭头
+	DrawGatheringPlace, // 绘制集结地
+	DrawClosedCurve, //绘制闭合曲面
+
+	DrawSector, //绘制扇形
+
+	DrawArc, // 绘制弓形
+	DrawLune, // 绘制弓形面
+
+	DrawCurve, //绘制曲线
+	DrawCurveFlag, //绘制曲线旗帜
+	DrawRectFlag, //绘制矩形直角旗帜
+	DrawTriangleFlag, //绘制三角旗帜
+
+	DrawPoint, //绘制点
+	DrawPolyline, // 绘制线
+	DrawPolygon, // 多边形
+	DrawRectangle, // 绘制矩形
+	DrawCircle, //绘制圆
+}
+
+export default MilitaryPlot