Sfoglia il codice sorgente

增加OD线绘制及编辑(初步)

不会爬树的猴 2 anni fa
parent
commit
90a6cdb454

BIN
public/img/image_arrow.png


+ 20 - 11
src/components/CrMap/CrMap.vue

@@ -297,6 +297,15 @@ defineExpose({
 	},
 
 	/**
+	 * 绘制OD线
+	 */
+	onMouseDrawEditOdline: function() {
+		proxy.drawTools.draw(DrawTools.DrawType.OdLine, {
+			isEdit: true
+		});
+	},
+
+	/**
 	 * 更新墙属性
 	 * @param {JSON} params 参数配置项
 	 */
@@ -445,17 +454,17 @@ onMounted(() => {
 	});
 
 	/* 添加网格地图 */
-	proxy.CMapApi.addLayer({
-		layId: 'floatGHT',
-		layName: '浮动规划图',
-		layType: CrMap.LayerType.floatLayer,
-		isShow: true,
-		config: {
-			url: 'http://218.59.194.74:6080/arcgis/rest/services/LYLSQ_GHT_102100_202112/MapServer',
-			// url: 'http://218.59.194.74:6080/arcgis/rest/services/LYLSQ_YX_102100_202112/MapServer',
-			opacity: 0.7
-		}
-	});
+	// proxy.CMapApi.addLayer({
+	// 	layId: 'floatGHT',
+	// 	layName: '浮动规划图',
+	// 	layType: CrMap.LayerType.floatLayer,
+	// 	isShow: true,
+	// 	config: {
+	// 		url: 'http://218.59.194.74:6080/arcgis/rest/services/LYLSQ_GHT_102100_202112/MapServer',
+	// 		// url: 'http://218.59.194.74:6080/arcgis/rest/services/LYLSQ_YX_102100_202112/MapServer',
+	// 		opacity: 0.7
+	// 	}
+	// });
 
 	/* 进入中国位置 */
 	proxy.CMapApi.setMapRange({

+ 653 - 180
src/components/CrMap/DrawTools.js

@@ -1461,9 +1461,9 @@ Object.assign(DrawTools.prototype, {
 			this._drawEntity.polyline.material = this._lineMaterial;
 			this._drawEntity.polyline.width = this._param.lineWidth;
 		} else if (entityType === DrawTools.DrawType.House) {
-			/* 删除原来创�����的实体 */
+			/* 删除原来创�������的实体 */
 			this._removeEntityByObject(this._drawEntity);
-			/* �������������������������������������������������������������������������������建房屋的高度 */
+			/* �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������建房屋的高度 */
 			let height = parseFloat(this._sketchOutputPoints[0].height);
 			let houseHeight = height + 30;
 			/* 创建一个房屋实体 */
@@ -1800,6 +1800,185 @@ Object.assign(DrawTools.prototype, {
 		if (isEdit != undefined && isEdit === true) {
 			this._setEntityIsEdit(this._drawEntity);
 		}
+	},
+
+	/**
+	 * 计算OD线的中间点
+	 * @param {Cesium.Cartesian3} strPoint 起始点
+	 * @param {Cesium.Cartesian3} endPoint 终止点
+	 * @param {Number} height 最大高度
+	 * @param {Number} count 内插点数
+	 */
+	_calculateOdlinePositios: function(strPoint, endPoint, height, count) {
+		let pt1 = this._cartesian3ToGeo(strPoint);
+		let pt2 = this._cartesian3ToGeo(endPoint);
+		//方程 y=-(4h/L^2)*x^2+h h:顶点高度 L:横纵间距较大者
+		var h = height && height < 1000 ? height : 1000;
+		var L = Math.abs(pt1.longitude - pt2.longitude) > Math.abs(pt1.latitude - pt2.latitude) ?
+			Math.abs(pt1.longitude - pt2.longitude) : Math.abs(pt1.latitude - pt2.latitude);
+		var num = count && count > 50 ? count : 50;
+		var result = [];
+		var tempResult = []; //临时数组
+		var dlt = L / num;
+		var addHeight = pt1.height > pt2.height ? pt1.height : pt2.height;
+		var maxHeight = addHeight + h;
+		var minHeight1 = pt1.height;
+		var minHeight2 = pt2.height;
+		if (Math.abs(pt1.longitude - pt2.longitude) > Math.abs(pt1.latitude - pt2
+				.latitude)) { //以lon为基准
+			var delLat = (pt2.latitude - pt1.latitude) / num;
+			if (pt1.longitude - pt2.longitude > 0) {
+				dlt = -dlt;
+			}
+			for (var i = 1; i < num; i++) {
+				var tempH = h - Math.pow((-0.5 * L + Math.abs(dlt) * i), 2) * 4 * h / Math.pow(L, 2);
+				var lon = pt1.longitude + dlt * i;
+				var lat = pt1.latitude + delLat * i;
+				var alt = undefined;
+				if (Math.abs(dlt) * i == 0.5 * L) {
+					alt = maxHeight;
+				} else if (Math.abs(dlt) * i < 0.5 * L) {
+					//说明是抛物线左侧
+					alt = ((maxHeight - minHeight1) / h) * tempH + minHeight1;
+				} else {
+					//说明是抛物线右侧
+					alt = ((maxHeight - minHeight2) / h) * tempH + minHeight2;
+				}
+				tempResult.push([lon, lat, alt]);
+			}
+		} else { //以lat为基准
+			var delLon = (pt2.longitude - pt1.longitude) / num;
+			if (pt1.latitude - pt2.latitude > 0) {
+				dlt = -dlt;
+			}
+			for (var i = 1; i < num; i++) {
+				var tempH = h - Math.pow((-0.5 * L + Math.abs(dlt) * i), 2) * 4 * h / Math.pow(L, 2);
+				var lon = pt1.longitude + delLon * i;
+				var lat = pt1.latitude + dlt * i;
+				var alt = undefined;
+				if (Math.abs(dlt) * i == 0.5 * L) {
+					alt = maxHeight;
+				} else if (Math.abs(dlt) * i < 0.5 * L) {
+					//说明是抛物线左侧
+					alt = ((maxHeight - minHeight1) / h) * tempH + minHeight1;
+				} else {
+					//说明是抛物线右侧
+					alt = ((maxHeight - minHeight2) / h) * tempH + minHeight2;
+				}
+				tempResult.push([lon, lat, alt]);
+			}
+		}
+		/* 对结果进行处理 */
+		result.push([pt1.longitude, pt1.latitude, pt1.height]);
+		for (var i = 0; i < tempResult.length; i++) {
+			result.push(tempResult[i]);
+		}
+		result.push([pt2.longitude, pt2.latitude, pt2.height]);
+		/* 对结果进行转换 */
+		let results = [];
+		for (let i = 0; i < result.length; i++) {
+			results.push(Cesium.Cartesian3.fromDegrees(result[i][0], result[i][1], result[i][2]));
+		}
+		return results;
+	},
+
+	/**
+	 * 创建OD线
+	 * @param {Boolean} isFirst 是否第一次
+	 */
+	_createOdline: function(isFirst) {
+		/* 如果初次创建 创建一个父实体*/
+		if (isFirst !== undefined && isFirst === true) {
+			let fatherEntity = new Cesium.Entity({
+				name: this._sketchEntityName,
+			});
+			this._odlineFatherEntity = this._entities.add(fatherEntity);
+			/* 为父实体设置参数 保存该OD线集合的必要参数 */
+			this._odlineFatherEntity.setParams({
+				height: 1000,
+				count: 50,
+			})
+		}
+		let _self = this;
+		/* 创建OD线材质 */
+		let odLineMaterial = new WallMaterialProperty({
+			viewer: _self._viewer,
+			trailImage: '/img/image_arrow.png',
+			duration: 1500,
+			color: Cesium.Color.fromCssColorString('rgba(0, 255, 0, 0.7)'),
+			param: {
+				direction: 'horizontal',
+				count: 1,
+				order: '-',
+			},
+		});
+		/* 获取必要参数 */
+		let params = this._odlineFatherEntity.getParams();
+		/* 创建OD线 */
+		let entity = new Cesium.Entity({
+			name: _self._sketchEntityName,
+			parent: this._odlineFatherEntity,
+			polyline: {
+				show: true,
+				positions: new Cesium.CallbackProperty(function() {
+					let center = _self._sketchTempPoints[0];
+					let endPoint = _self._sketchTempPoints[_self._sketchTempPoints.length -
+						1];
+					let results = _self._calculateOdlinePositios(center, endPoint, parseInt(
+							params.height),
+						parseInt(params.count));
+					return results;
+				}, false),
+				material: odLineMaterial,
+				width: _self._param.moveLineWidth,
+				clampToGround: false, //由于是空间线禁止贴地或贴模型
+			}
+		})
+		/* 加入集合 */
+		this._drawEntity = this._entities.add(entity);
+	},
+
+	/**
+	 * 更新OD线
+	 * @param {Boolean} isLast 是否是最后一个
+	 * @param {Boolean} isEdit 是否为可编辑
+	 */
+	_updateOdline: function(isLast, isEdit) {
+		if (isLast !== undefined && isLast === true) {
+			if (isEdit !== undefined && isEdit === true) {
+				this._drawEntity.setEntityType(DrawTools.DrawType.OdLine);
+				this._setEntityIsEdit(this._drawEntity);
+			}
+		} else {
+			let params = this._drawEntity.parent.getParams();
+			let center = this._sketchTempPoints[0];
+			let endPoint = this._sketchTempPoints[this._sketchTempPoints.length -
+				1];
+			let results = this._calculateOdlinePositios(center, endPoint, parseInt(params.height),
+				parseInt(params.count));
+			this._drawEntity.polyline.positions = results;
+			this._drawEntity.setEntityType(DrawTools.DrawType.OdLine);
+			if (isEdit !== undefined && isEdit === true) {
+				this._drawEntity.setIsEdit(true);
+			}
+		}
+	},
+	/**
+	 * 生成GUID随机数
+	 */
+	_guid() {
+		function S4() {
+			return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+		}
+		return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
+	},
+
+	/**
+	 * 输出消息
+	 * @param {Object} res
+	 */
+	_console(...rest) {
+		console.log('===>>>', rest);
 	}
 })
 
@@ -2052,6 +2231,85 @@ Object.assign(DrawTools.prototype, {
 	},
 
 	/**
+	 * 绘制OD线工具
+	 * @param {Object} handler 事件句柄
+	 * @param {JSON} options 配置项
+	 * @param {Boolean} isEdit 是否可编辑 可选 默认可编辑
+	 * @param {Function} [options.onAdded(cPoints,gPoints)] 添加回调 可选
+	 * @param {Function} [options.onMoving(cPoint)] 移动回调 可选
+	 * @param {Function} [options.onUndo()] 撤销回调 可选 
+	 * @param {Function} [options.onComplete(cPoints,gPoints)] 完成回调 可选
+	 * @param {Function} [options.onError(message)] 错误回到 可选
+	 */
+	_sketchDrawOdline(handler, options) {
+		let _self = this;
+		/* 注册鼠标左键单击事件 */
+		this._registerLeftClickEvent(handler, function(event) {
+			/* 识别屏幕位置 */
+			let loc = _self._transfromFromScreenPoint(event.position);
+			if (!Cesium.defined(loc.sLocation)) return;
+			/* 绘制点 */
+			if (_self._isDrawPoint) {
+				_self._createPoint(loc.sLocation, _self._lineLabel);
+			}
+			/* 第一点击的时候绘制线 */
+			if (_self._sketchTempPoints.length === 0) {
+				_self._createOdline(true);
+				_self._sketchTempPoints.push(loc.sLocation.clone());
+			} else {
+				_self._updateOdline(false, options.isEdit);
+				_self._createOdline();
+			}
+			_self._sketchTempPoints.push(loc.sLocation);
+			/* 存储正式绘制点集合 */
+			_self._sketchPoints.push(loc.sLocation.clone());
+			/* 存储输出经纬度点集合 */
+			_self._sketchOutputPoints.push(loc.gLocation);
+			/* 监听输出 */
+			if (options.onAdded) options.onAdded(_self._sketchPoints, _self._sketchOutputPoints);
+		})
+		/* 注册鼠标移动事件 */
+		this._registerMouseMoveEvent(handler, function(event) {
+			/* 识别屏幕位置 */
+			let loc = _self._transfromFromScreenPoint(event.endPosition);
+			if (!Cesium.defined(loc.sLocation)) return;
+			if (_self._sketchTempPoints.length > 1) {
+				_self._sketchTempPoints.pop();
+				_self._sketchTempPoints.push(loc.sLocation);
+				/* 监听输出 */
+				if (options.onMoving) options.onMoving(loc.sLocation);
+			}
+		})
+		/* 注册鼠标左键双击事件 */
+		this._registerLeftDoubleClickEvent(handler, function(event) {
+			if (_self._sketchPoints.length < 2) {
+				if (options.onError) options.onError('绘制点少于2个,禁止结束绘制!');
+				return;
+			}
+			/* 绘制正式OD线 */
+			_self._removeEntityByObject(_self._drawEntity);
+			_self._updateOdline(true, options.isEdit);
+			/* 删除标记点 */
+			_self._removePointEntitys();
+			/* 干掉事件句柄 释放资源*/
+			_self._clearEvent(handler);
+			/* 监听输出 */
+			if (options.onComplete) options.onComplete(_self._sketchPoints, _self
+				._sketchOutputPoints);
+		})
+		/* 注册鼠标右键单击事件 */
+		this._registerRightClickEvent(handler, function(event) {
+			if (_self._sketchTempPoints.length > 2) {
+				/* 移除正式点最有一个元素 */
+				_self._sketchPoints.pop();
+				/* 移除临时点倒数第二个元素 */
+				_self._sketchTempPoints.splice(_self._sketchTempPoints.length - 2, 1);
+				if (options.onUndo) options.onUndo();
+			}
+		});
+	},
+
+	/**
 	 * 绘制贴地面工具
 	 * @param {Object} handler 事件句柄
 	 * @param {JSON} options 配置项
@@ -2451,6 +2709,9 @@ Object.assign(DrawTools.prototype, {
 			case DrawTools.DrawType.VideoWall:
 				_self._sketchDrawVideoWall(_self._drawEventHandler, options);
 				break;
+			case DrawTools.DrawType.OdLine:
+				_self._sketchDrawOdline(_self._drawEventHandler, options);
+				break;
 		}
 	},
 
@@ -2925,11 +3186,12 @@ Object.assign(DrawTools.prototype, {
 		let _self = this;
 		/* 设置实体要素可编辑 */
 		entity.setIsEdit(true);
+		this._console('当前编辑实体', entity);
 		/* 先撤销编辑 */
 		this._unActivateEdit();
 		/* 激活编辑 */
 		this._activateEdit(entity);
-		/* 注册一个事件 用于选择拾取和点击 */
+		/* 注册统一事件 用于单击拾取实体 */
 		let handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
 		this._registerLeftClickEvent(handler, function(event) {
 			let feature = _self._viewer.scene.pick(event.position);
@@ -3426,12 +3688,76 @@ Object.assign(DrawTools.prototype, {
 			console.log("===>>>", '该实体不可编辑');
 			return;
 		};
+		if (entityType === DrawTools.DrawType.OdLine) {
+			this._activeteOdlineEdit(editEntity);
+		} else {
+			this._activeteNormalEdit(editEntity);
+		}
+	},
+
+	/**
+	 * 激活编辑OD线实体
+	 * @param {Cesium.Entity} editEntity 编辑实体
+	 */
+	_activeteOdlineEdit: function(editEntity) {
+		let _self = this;
+		let entityType = editEntity.getEntityType();
+		/* 不可编辑对象 直接退出 */
+		if (entityType === undefined || entityType !== DrawTools.DrawType.OdLine) {
+			console.log("===>>>", '该实体不可编辑或该实体不是OD线类型');
+			return;
+		};
+		/* 获取父实体Id */
+		let faterEntityId = editEntity.parent.id;
+		/* 当前编辑OD线集合 */
+		this._editOdlineEntities = [];
+		/* 循环集合寻找符合条件的实体 */
+		for (let entity of this._entities.values) {
+			if (entity.parent !== undefined && entity.parent.id === faterEntityId) {
+				this._editOdlineEntities.push(entity);
+			}
+		}
+		/* 不存在可编辑的OD线 */
+		if (this._editOdlineEntities.length === 0) return;
+		for (let i = 0; i < this._editOdlineEntities.length; i++) {
+			let entity = this._editOdlineEntities[i];
+			let positions = entity.polyline.positions._value;
+			if (i === 0) {
+				this._createEditOdlineStartPoint(positions.splice(0, 1)[0], entity);
+				this._createEditOdlineEndPoint(positions.splice(-1)[0], entity);
+			} else {
+				this._createEditOdlineEndPoint(positions.splice(-1)[0], entity);
+			}
+		}
+		/* 创建事件句柄 */
+		if (this._sketchEditHandler === undefined) {
+			this._sketchEditHandler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
+		}
+		/* 注册鼠标左键按下事件 */
+		this._registerLeftDownEvent(this._sketchEditHandler, function(event) {
+			_self._eventEditMouseDown(event);
+		});
+		/* 注册鼠标左键移动事件 */
+		this._registerMouseMoveEvent(this._sketchEditHandler, function(event) {
+			_self._eventEditMouseMove(event);
+		});
+		/* 注册鼠标左键抬起事件 */
+		this._registerLeftUpEvent(this._sketchEditHandler, function(event) {
+			_self._eventEditMouseUp(event);
+		});
+	},
+
+	/**
+	 * 激活编辑单实体
+	 * @param {Cesium.Entity} editEntity 编辑实体
+	 */
+	_activeteNormalEdit: function(editEntity) {
 		let _self = this;
-		/* 设置实体类型 返回该实体用于绘制的点集合*/
-		console.log("===当前可编辑实体>>>", editEntity);
 		let positions = this._getEntityEditData(editEntity);
 		/* 删除所有临时绘制的点 */
 		this._removePointEntitys();
+		/* 获取编辑类型 */
+		let entityType = editEntity.getEntityType();
 		/* 赋值可编辑对象 */
 		this._editEntity = editEntity;
 		/* 创建节点和中心点 */
@@ -3466,196 +3792,286 @@ Object.assign(DrawTools.prototype, {
 		}
 		/* 注册鼠标左键按下事件 */
 		this._registerLeftDownEvent(this._sketchEditHandler, function(event) {
-			/* 拾取实体 */
-			let feature = _self._viewer.scene.pick(event.position);
-			console.log('===选中的节点>>>', feature)
-			/* 分类处理 */
-			if (feature != undefined && feature.id instanceof Cesium.Entity) {
-				/* 获取选择实体的样式 */
-				let featureType = feature.id.getEditType();
-				console.log("===>>>", featureType);
-				/* 说明当前移动的点是我们需要编辑的点 */
-				if (featureType === undefined) return;
-				/* 禁用场景的旋转移动功能 保留缩放功能 */
-				_self._viewer.scene.screenSpaceCameraController.enableRotate = false;
-				/* 位置信息 */
-				let entityPosition = feature.id.position._value;
-				/* 保存当前可编辑的实体 */
-				_self._editPointEntity = feature.id;
-				/* 设置鼠标样式为十字 */
-				_self._setMousePointerStyle();
-				/* 判断类型 是节点或中点 进行不同的操作 */
-				if (featureType.type === DrawTools.EditPointType.Node || featureType.type ===
-					DrawTools.EditPointType.Middle) {
-					/* 处理鼠标按下实体的属性变更回调 */
-					_self._entityCallbackPropertyByMouseDown();
-					/* 移除当前移动的点 */
-					_self._removeEntityByObject(_self._editPointEntity);
-					/* 删除高空点 */
-					if (_self._sketchEditEntitySpatialName != undefined) {
-						_self._removeEntityByName(_self._sketchEditEntitySpatialName);
-					}
-				} else if (featureType.type === DrawTools.EditPointType.Center) {
-					_self._entityCenterMouseDownEvent();
-				}
-				/* 根据节点类型不同进行特殊的处理 */
-				if (featureType.type === DrawTools.EditPointType.Middle) {
-					/* 如果选择的是中点 则插入节点 并记录当前的���引 */
-					let index = featureType.index;
-					_self._sketchEditPoints.splice(index, 0, entityPosition);
-					_self._sketchEditIndex = index;
-					/* 如果当前移动的中点为墙的中点,则需要进行特殊处理一下,主要为了修正高度 */
-					if (_self._sketchWallHeights != undefined && _self._sketchWallHeights.length >
-						0) {
-						/* 查询一下高度 */
-						let geoPoint = _self._cartesian3ToGeo(entityPosition);
-						let height = _self._queryHeightFromGeo(geoPoint.longitude, geoPoint
-							.latitude);
-						/* 墙的最小高度加入值 */
-						_self._sketchWallHeights.splice(index, 0, height);
-						/* 墙的最大高度需要加入值 */
-						let heightDifference = _self._sketchWallMaxHeights[0] - _self
-							._sketchWallHeights[0];
-						_self._sketchWallMaxHeights.splice(index, 0, height + heightDifference);
-					}
-					/* 设置提示标签 */
-					_self._tooltipInit('拖动中点,改变形状', event.position);
-				} else if (featureType.type === DrawTools.EditPointType.Node) {
-					/* 如果是节点 则直接记录索引 */
-					_self._sketchEditIndex = featureType.index;
-					/* 设置提示标签 */
-					_self._tooltipInit('拖动节点,改变形状', event.position);
-				} else if (featureType.type === DrawTools.EditPointType.Spatial) {
-					/* 如果是节点 则直接记录索引 */
-					_self._sketchEditIndex = featureType.index;
-					/* 设置提示标签 */
-					_self._tooltipInit('拖动节点,改变高度', event.position);
-				} else if (featureType.type === DrawTools.EditPointType.CoordinateAxis) {
-					/* 设置提示标签 */
-					_self._tooltipInit('拖动坐标轴,改变位置', event.position);
-				}
-			}
+			_self._eventEditMouseDown(event);
 		})
 		/* 注册鼠标移动事件 */
 		this._registerMouseMoveEvent(this._sketchEditHandler, function(event) {
-			if (_self._editPointEntity != undefined) {
-				let loc = _self._transfromFromScreenPoint(event.endPosition);
-				if (!Cesium.defined(loc.sLocation)) return;
-				_self._editPosition = loc.sLocation;
-				/* 获取当前可编辑点的类型 */
-				let editEntityType = _self._editPointEntity.getEditType();
-				if (editEntityType.type === DrawTools.EditPointType.Node) {
-					_self._sketchEditPoints[_self._sketchEditIndex] = loc.sLocation;
-					/* 获取当前编辑的实体的类型 */
-					let editEntityType = _self._editEntity.getEntityType();
-					if (editEntityType != DrawTools.DrawType.Rectangle &&
-						editEntityType != DrawTools.DrawType.Circle && editEntityType != DrawTools
-						.DrawType.DynamicCircle) {
-						/* 这里对面对象需要进特殊处理 保证第0号点和最后一个点是一致的 */
-						if ((editEntityType === DrawTools.DrawType.Polygon || editEntityType ===
-								DrawTools.DrawType.House) && _self
-							._sketchEditIndex === 0) {
-							_self._sketchEditPoints[_self._sketchEditPoints.length - 1] = loc
-								.sLocation;
-						} else if (editEntityType === DrawTools.DrawType.NormalWall ||
-							editEntityType === DrawTools.DrawType.DynamicWall || editEntityType ===
-							DrawTools.DrawType.TextWall) {
-							_self._sketchWallHeights[_self._sketchEditIndex] = loc.gLocation.height;
-						}
-						/* 移除所有中点 */
-						_self._removeEntityByName(_self._sketchEditEntityMiddleName);
-						/* 创建所有中点 */
-						if (editEntityType === DrawTools.DrawType.SpatialLine) {
-							_self._createEditMiddlePoint(_self._sketchEditPoints, true);
-						} else {
-							_self._createEditMiddlePoint(_self._sketchEditPoints);
-						}
-					}
-				} else if (editEntityType.type === DrawTools.EditPointType.Middle) {
-					_self._sketchEditPoints[_self._sketchEditIndex] = loc.sLocation;
-				} else if (editEntityType.type === DrawTools.EditPointType.Center) {
-					_self._entityCenterMouseMoveEvent(event);
-				} else if (editEntityType.type === DrawTools.EditPointType.Spatial) {
-					/* 当前移动的是空中点 */
-					let ellipsoid = _self._viewer.scene.globe.ellipsoid;
-					let cartesian = _self._viewer.camera.pickEllipsoid(event.endPosition,
-						ellipsoid);
-					let bottomPoint = _self._sketchEditPoints[_self._sketchEditIndex];
-					/* 计算高差 */
-					let heightDifference = cartesian.z - bottomPoint.z;
-					if (heightDifference > 0 && heightDifference < 500) {
-						for (let i = 0; i < _self._sketchWallHeights.length; i++) {
-							_self._sketchWallMaxHeights[i] = _self._sketchWallHeights[i] +
-								heightDifference;
-						}
-					}
-				}
-				/* 更改标签文字 */
-				_self._tooltipInit('抬起鼠标,完成更改', event.endPosition);
-			}
+			_self._eventEditMouseMove(event);
 		});
 		/* 注册鼠标抬起事件 */
 		this._registerLeftUpEvent(this._sketchEditHandler, function(event) {
-			if (_self._editPointEntity != undefined) {
-				/* 恢复所有鼠标默认事件 */
-				_self._viewer.scene.screenSpaceCameraController.enableRotate = true;
-				/* 移除标签 */
-				_self._tooltipRemove();
-				/* 恢复鼠标默认样式 */
-				_self._setMouseDefaultStyle();
-				/* 获取当前编辑的点类型 */
-				let editEntityPointType = _self._editPointEntity.getEditType().type;
-				if (editEntityPointType === DrawTools.EditPointType.CoordinateAxis) {
+			_self._eventEditMouseUp(event);
+		})
+	},
 
-				} else {
-					if (editEntityPointType === DrawTools.EditPointType.Node ||
-						editEntityPointType === DrawTools.EditPointType.Middle) {
-						/* 处理鼠标抬起实体的属性变更回调 */
-						_self._entityCallbackPropertyByMouseUp();
-					} else if (editEntityPointType === DrawTools.EditPointType.Center) {
-						_self._entityCenterMouseUpEvent(event);
+	/**
+	 * 编辑点鼠标抬起事件
+	 * @param {Object} event 事件
+	 */
+	_eventEditMouseDown: function(event) {
+		let _self = this;
+		/* 拾取实体 */
+		let feature = _self._viewer.scene.pick(event.position);
+		/* 分类处理 */
+		if (feature != undefined && feature.id instanceof Cesium.Entity) {
+			/* 获取选择实体的样式 */
+			let featureType = feature.id.getEditType();
+			/* 说明当前选中的实体 不是编辑点 */
+			if (featureType === undefined) return;
+			/* 禁用场景的旋转移动功能 保留缩放功能 */
+			_self._viewer.scene.screenSpaceCameraController.enableRotate = false;
+			/* 位置信息 */
+			let entityPosition = feature.id.position._value;
+			/* 保存当前可编辑的实体 */
+			_self._editPointEntity = feature.id;
+			/* 设置鼠标样式为十字 */
+			_self._setMousePointerStyle();
+			/* 判断类型 是节点或中点 进行不同的操作 */
+			if (featureType.type === DrawTools.EditPointType.Node || featureType.type ===
+				DrawTools.EditPointType.Middle) {
+				/* 处理鼠标按下实体的属性变更回调 */
+				_self._entityCallbackPropertyByMouseDown();
+				/* 移除当前移动的点 */
+				_self._removeEntityByObject(_self._editPointEntity);
+				/* 删除高空点 */
+				if (_self._sketchEditEntitySpatialName != undefined) {
+					_self._removeEntityByName(_self._sketchEditEntitySpatialName);
+				}
+			} else if (featureType.type === DrawTools.EditPointType.Center) {
+				_self._entityCenterMouseDownEvent();
+			} else if (featureType.type === DrawTools.EditPointType.OdlineEndNode) {
+				/* 删除当前移动点 */
+				_self._removeEntityByObject(_self._editPointEntity);
+				/* 设置当前编辑的实体 */
+				_self._editEntity = featureType.joinEntity;
+				/* 获取OD线的必要参数 */
+				let params = _self._editEntity.parent.getParams();
+				_self._sketchEditPoints = [];
+				let joinEntityPositions = _self._editEntity.polyline.positions._value;
+				_self._sketchEditPoints.push(joinEntityPositions.splice(0, 1)[0]);
+				_self._sketchEditPoints.push(joinEntityPositions.splice(-1)[0]);
+				_self._editEntity.polyline.positions = new Cesium.CallbackProperty(function() {
+					let positions = _self._calculateOdlinePositios(_self._sketchEditPoints[0], _self
+						._sketchEditPoints[1], parseInt(params.height), parseInt(params.count));
+					return positions;
+				}, false)
+			} else if (featureType.type === DrawTools.EditPointType.OdlineStrartNode) {
+				/* 删除当前移动点 */
+				_self._removeEntityByObject(_self._editPointEntity);
+				/* 设置当前编辑的实体 */
+				_self._editEntity = featureType.joinEntity;
+				/* 获取OD线的必要参数 */
+				let params = _self._editEntity.parent.getParams();
+				_self._sketchEditPoints = [];
+				let joinEntityPositions = _self._editEntity.polyline.positions._value;
+				_self._sketchEditPoints.push(joinEntityPositions.splice(0, 1)[0]);
+				for (let odEntity of _self._editOdlineEntities) {
+					let odEntityPositions = odEntity.polyline.positions._value;
+					let lastPosition = odEntityPositions.splice(-1)[0];
+					_self._sketchEditPoints.push(lastPosition.clone());
+					odEntity.polyline.positions = new Cesium.CallbackProperty(function() {
+						let positions = _self._calculateOdlinePositios(_self._sketchEditPoints[0],
+							lastPosition, parseInt(params.height), parseInt(params.count));
+						return positions;
+					}, false);
+				}
+			}
+			/* 根据节点类型不同进行特殊的处理 */
+			if (featureType.type === DrawTools.EditPointType.Middle) {
+				/* 如果选择的是中点 则插入节点 并记录当前的索引 */
+				let index = featureType.index;
+				_self._sketchEditPoints.splice(index, 0, entityPosition);
+				_self._sketchEditIndex = index;
+				/* 如果当前移动的中点为墙的中点,则需要进行特殊处理一下,主要为了修正高度 */
+				if (_self._sketchWallHeights != undefined && _self._sketchWallHeights.length >
+					0) {
+					/* 查询一下高度 */
+					let geoPoint = _self._cartesian3ToGeo(entityPosition);
+					let height = _self._queryHeightFromGeo(geoPoint.longitude, geoPoint
+						.latitude);
+					/* 墙的最小高度加入值 */
+					_self._sketchWallHeights.splice(index, 0, height);
+					/* 墙的最大高度需要加入值 */
+					let heightDifference = _self._sketchWallMaxHeights[0] - _self
+						._sketchWallHeights[0];
+					_self._sketchWallMaxHeights.splice(index, 0, height + heightDifference);
+				}
+				/* 设置提示标签 */
+				_self._tooltipInit('拖动中点,改变形状', event.position);
+			} else if (featureType.type === DrawTools.EditPointType.Node) {
+				/* 如果是节点 则直接记录索引 */
+				_self._sketchEditIndex = featureType.index;
+				/* 设置提示标签 */
+				_self._tooltipInit('拖动节点,改变形状', event.position);
+			} else if (featureType.type === DrawTools.EditPointType.Spatial) {
+				/* 如果是节点 则直接记录索引 */
+				_self._sketchEditIndex = featureType.index;
+				/* 设置提示标签 */
+				_self._tooltipInit('拖动节点,改变高度', event.position);
+			} else if (featureType.type === DrawTools.EditPointType.CoordinateAxis) {
+				/* 设置提示标签 */
+				_self._tooltipInit('拖动坐标轴,改变位置', event.position);
+			} else if (featureType.type === DrawTools.EditPointType.OdlineEndNode || featureType.type ===
+				DrawTools.EditPointType.OdlineStrartNode) {
+				/* 设置提示标签 */
+				_self._tooltipInit('拖动节点,改变OD线位置', event.position);
+			}
+		}
+	},
+
+	/**
+	 * 编辑点鼠标移动事件
+	 * @param {Object} event 事件
+	 */
+	_eventEditMouseMove: function(event) {
+		let _self = this;
+		if (_self._editPointEntity != undefined) {
+			let loc = _self._transfromFromScreenPoint(event.endPosition);
+			if (!Cesium.defined(loc.sLocation)) return;
+			_self._editPosition = loc.sLocation;
+			/* 获取当前可编辑点的类型 */
+			let editEntityType = _self._editPointEntity.getEditType();
+			if (editEntityType.type === DrawTools.EditPointType.Node) {
+				_self._sketchEditPoints[_self._sketchEditIndex] = loc.sLocation;
+				/* 获取当前编辑的实体的类型 */
+				let editEntityType = _self._editEntity.getEntityType();
+				if (editEntityType != DrawTools.DrawType.Rectangle &&
+					editEntityType != DrawTools.DrawType.Circle && editEntityType != DrawTools
+					.DrawType.DynamicCircle) {
+					/* 这里对面对象需要进特殊处理 保证第0号点和最后一个点是一致的 */
+					if ((editEntityType === DrawTools.DrawType.Polygon || editEntityType ===
+							DrawTools.DrawType.House) && _self
+						._sketchEditIndex === 0) {
+						_self._sketchEditPoints[_self._sketchEditPoints.length - 1] = loc
+							.sLocation;
+					} else if (editEntityType === DrawTools.DrawType.NormalWall ||
+						editEntityType === DrawTools.DrawType.DynamicWall || editEntityType ===
+						DrawTools.DrawType.TextWall) {
+						_self._sketchWallHeights[_self._sketchEditIndex] = loc.gLocation.height;
 					}
-					/* 删除节点、中点和中心点 */
-					_self._removeEntityByName(_self._sketchEditEntityNodeName);
+					/* 移除所有中点 */
 					_self._removeEntityByName(_self._sketchEditEntityMiddleName);
-					_self._removeEntityByName(_self._sketchEditEntityCenterName);
-					/* 创建节点、中点和中心点 */
-					if (entityType === DrawTools.DrawType.Circle || entityType === DrawTools
-						.DrawType
-						.DynamicCircle) {
-						/* 需要对点进行特殊处理 保证圆边界点始终在统一位置 */
-						let centerPosition = _self._editEntity.position._value;
-						let boundaryPosition = _self._calculateCircleBoundaryPoint(centerPosition,
-							_self
-							._sketchEllipseRadius);
-						_self._sketchEditPoints[0] = centerPosition;
-						_self._sketchEditPoints[1] = boundaryPosition;
-						_self._createEditNodePoint(_self._sketchEditPoints, 1);
-						_self._createEditCenterPoint(centerPosition);
+					/* 创建所有中点 */
+					if (editEntityType === DrawTools.DrawType.SpatialLine) {
+						_self._createEditMiddlePoint(_self._sketchEditPoints, true);
 					} else {
-						/* 创建节点 */
-						_self._createEditNodePoint(_self._sketchEditPoints);
-						/* 创建中心点 */
-						let centerPosition = _self._calculateCenterPosition(_self
-							._sketchEditPoints);
-						_self._createEditCenterPoint(centerPosition);
+						_self._createEditMiddlePoint(_self._sketchEditPoints);
 					}
-					/* 创建中点 */
-					if (entityType != DrawTools.DrawType.Rectangle &&
-						entityType != DrawTools.DrawType.Circle && entityType != DrawTools.DrawType
-						.DynamicCircle) {
-						if (entityType === DrawTools.DrawType.SpatialLine) {
-							_self._createEditMiddlePoint(_self._sketchEditPoints, true);
-						} else {
-							_self._createEditMiddlePoint(_self._sketchEditPoints);
-						}
+				}
+			} else if (editEntityType.type === DrawTools.EditPointType.Middle) {
+				_self._sketchEditPoints[_self._sketchEditIndex] = loc.sLocation;
+			} else if (editEntityType.type === DrawTools.EditPointType.Center) {
+				_self._entityCenterMouseMoveEvent(event);
+			} else if (editEntityType.type === DrawTools.EditPointType.Spatial) {
+				/* 当前移动的是空中点 */
+				let ellipsoid = _self._viewer.scene.globe.ellipsoid;
+				let cartesian = _self._viewer.camera.pickEllipsoid(event.endPosition,
+					ellipsoid);
+				let bottomPoint = _self._sketchEditPoints[_self._sketchEditIndex];
+				/* 计算高差 */
+				let heightDifference = cartesian.z - bottomPoint.z;
+				if (heightDifference > 0 && heightDifference < 500) {
+					for (let i = 0; i < _self._sketchWallHeights.length; i++) {
+						_self._sketchWallMaxHeights[i] = _self._sketchWallHeights[i] +
+							heightDifference;
+					}
+				}
+			} else if (editEntityType.type === DrawTools.EditPointType.OdlineEndNode) {
+				_self._sketchEditPoints[_self._sketchEditPoints.length - 1] = loc.sLocation;
+			} else if (editEntityType.type === DrawTools.EditPointType.OdlineStrartNode) {
+				_self._sketchEditPoints[0] = loc.sLocation;
+			}
+			/* 更改标签文字 */
+			_self._tooltipInit('抬起鼠标,完成更改', event.endPosition);
+		}
+	},
 
+	/**
+	 * 编辑点鼠标抬起事件
+	 * @param {Object} event 事件
+	 */
+	_eventEditMouseUp: function(event) {
+		let _self = this;
+		if (_self._editPointEntity != undefined) {
+			/* 恢复所有鼠标默认事件 */
+			_self._viewer.scene.screenSpaceCameraController.enableRotate = true;
+			/* 移除标签 */
+			_self._tooltipRemove();
+			/* 恢复鼠标默认样式 */
+			_self._setMouseDefaultStyle();
+			/* 获取当前编辑的点类型 */
+			let editEntityPointType = _self._editPointEntity.getEditType().type;
+			let entityType = _self._editEntity.getEntityType();
+			if (editEntityPointType === DrawTools.EditPointType.CoordinateAxis) {
+
+			} else if (editEntityPointType === DrawTools.EditPointType.OdlineEndNode) {
+				/* 获取OD线的必要参数 */
+				let params = _self._editEntity.parent.getParams();
+				/* 重置编辑实体的位置 */
+				let positions = _self._calculateOdlinePositios(_self._sketchEditPoints[0], _self
+					._sketchEditPoints[1], parseInt(params.height), parseInt(params.count));
+				_self._editEntity.polyline.positions = positions;
+				/* 创建OD线的终点 */
+				_self._createEditOdlineEndPoint(_self._sketchEditPoints[1], _self._editEntity);
+			} else if (editEntityPointType === DrawTools.EditPointType.OdlineStrartNode) {
+				/* 获取OD线的必要参数 */
+				let params = _self._editEntity.parent.getParams();
+				let index = 1;
+				for (let odEntity of _self._editOdlineEntities) {
+					let lastPosition = _self._sketchEditPoints[index++];
+					let positions = _self._calculateOdlinePositios(_self._sketchEditPoints[0],
+						lastPosition, parseInt(params.height), parseInt(params.count));
+					odEntity.polyline.positions = positions;
+				}
+				_self._createEditOdlineStartPoint(_self._sketchEditPoints[0], _self._editOdlineEntities[0]);
+			} else {
+				if (editEntityPointType === DrawTools.EditPointType.Node ||
+					editEntityPointType === DrawTools.EditPointType.Middle) {
+					/* 处理鼠标抬起实体的属性变更回调 */
+					_self._entityCallbackPropertyByMouseUp();
+				} else if (editEntityPointType === DrawTools.EditPointType.Center) {
+					_self._entityCenterMouseUpEvent(event);
+				}
+				/* 删除节点、中点和中心点 */
+				_self._removeEntityByName(_self._sketchEditEntityNodeName);
+				_self._removeEntityByName(_self._sketchEditEntityMiddleName);
+				_self._removeEntityByName(_self._sketchEditEntityCenterName);
+				/* 创建节点、中点和中心点 */
+				if (entityType === DrawTools.DrawType.Circle || entityType === DrawTools
+					.DrawType
+					.DynamicCircle) {
+					/* 需要对点进行特殊处理 保证圆边界点始终在统一位置 */
+					let centerPosition = _self._editEntity.position._value;
+					let boundaryPosition = _self._calculateCircleBoundaryPoint(centerPosition,
+						_self
+						._sketchEllipseRadius);
+					_self._sketchEditPoints[0] = centerPosition;
+					_self._sketchEditPoints[1] = boundaryPosition;
+					_self._createEditNodePoint(_self._sketchEditPoints, 1);
+					_self._createEditCenterPoint(centerPosition);
+				} else {
+					/* 创建节点 */
+					_self._createEditNodePoint(_self._sketchEditPoints);
+					/* 创建中心点 */
+					let centerPosition = _self._calculateCenterPosition(_self
+						._sketchEditPoints);
+					_self._createEditCenterPoint(centerPosition);
+				}
+				/* 创建中点 */
+				if (entityType != DrawTools.DrawType.Rectangle &&
+					entityType != DrawTools.DrawType.Circle && entityType != DrawTools.DrawType
+					.DynamicCircle) {
+					if (entityType === DrawTools.DrawType.SpatialLine) {
+						_self._createEditMiddlePoint(_self._sketchEditPoints, true);
+					} else {
+						_self._createEditMiddlePoint(_self._sketchEditPoints);
 					}
+
 				}
-				/* 清除选择的实体 */
-				_self._editPointEntity = undefined;
 			}
-		})
+			/* 清除选择的实体 */
+			_self._editPointEntity = undefined;
+		}
 	},
 
 	/**
@@ -4169,6 +4585,60 @@ Object.assign(DrawTools.prototype, {
 	},
 
 	/**
+	 * 创建可编辑的OD线编辑终点
+	 * @param {Cesium.Cartesian3} position 坐标
+	 * @param {Cesium.Entity} joinEntity 关联的实体 
+	 */
+	_createEditOdlineEndPoint(position, joinEntity) {
+		this._sketchEditEntityNodeName = "SketchEditEntityNode";
+		let _self = this;
+		/* 创建节点前 特殊处理一下 以保证创建的节点 高度是正确的 */
+		let geoPoint = this._cartesian3ToGeo(position);
+		/* 查询高度 */
+		let height = this._queryHeightFromGeo(geoPoint.longitude, geoPoint.latitude);
+		/* 创建新位置 */
+		let newPosition = Cesium.Cartesian3.fromDegrees(geoPoint.longitude, geoPoint.latitude, height);
+		/* 创建实体 */
+		_self._createEditPointEntity({
+			name: _self._sketchEditEntityNodeName,
+			position: position,
+			size: 12,
+			color: [0, 0, 255, 1.0],
+			editType: {
+				type: DrawTools.EditPointType.OdlineEndNode,
+				joinEntity: joinEntity,
+			},
+		});
+	},
+
+	/**
+	 * 创建可编辑的OD线编辑起点
+	 * @param {Cesium.Cartesian3} position 坐标
+	 * @param {Cesium.Entity} joinEntity 关联的实体 
+	 */
+	_createEditOdlineStartPoint(position, joinEntity) {
+		this._sketchEditEntityNodeName = "SketchEditEntityNode";
+		let _self = this;
+		/* 创建节点前 特殊处理一下 以保证创建的节点 高度是正确的 */
+		let geoPoint = this._cartesian3ToGeo(position);
+		/* 查询高度 */
+		let height = this._queryHeightFromGeo(geoPoint.longitude, geoPoint.latitude);
+		/* 创建新位置 */
+		let newPosition = Cesium.Cartesian3.fromDegrees(geoPoint.longitude, geoPoint.latitude, height);
+		/* 创建实体 */
+		_self._createEditPointEntity({
+			name: _self._sketchEditEntityNodeName,
+			position: position,
+			size: 12,
+			color: [0, 255, 0, 0.6],
+			editType: {
+				type: DrawTools.EditPointType.OdlineStrartNode,
+				joinEntity: joinEntity,
+			},
+		});
+	},
+
+	/**
 	 * 计算两个点的中点坐标
 	 * @param {Cesium.Cartesian3} position1 第一点
 	 * @param {Cesium.Cartesian3} position2 第二点
@@ -4330,6 +4800,7 @@ DrawTools.DrawType = Object.freeze({
 	DynamicPolyline: 'dynamicPolyline', //流动线
 	GrowPolyline: '发光线',
 	OultliePolyline: 'outlinePolyline', //描边线
+	OdLine: 'odLine', //OD线
 	Polygon: 'polygon', //贴地面
 	SpatialLine: 'spatialLine', //空间线
 	Circle: 'circle', //普通圆
@@ -4361,6 +4832,8 @@ DrawTools.EditPointType = Object.freeze({
 	Middle: 'middle', //中间点
 	Center: 'center', //中心点
 	CoordinateAxis: 'coordinateAxis', //坐标轴
+	OdlineStrartNode: 'odlineStartNode', //OD线起始点
+	OdlineEndNode: 'odlineEndNode', //OD线终点
 })
 
 /**

+ 9 - 0
src/pages/tab-cmap.vue

@@ -274,6 +274,12 @@ export default {
 			message: '绘制视频墙'
 		});
 		this.dynamicDrawTools.push({
+			iconName: 'app-icon app-icon-draw-video',
+			title: 'OD线',
+			id: 'odLine',
+			message: '绘制OD线'
+		});
+		this.dynamicDrawTools.push({
 			iconName: 'app-icon app-icon-map-clean',
 			title: '清除标绘',
 			id: 'clear',
@@ -410,6 +416,9 @@ export default {
 				case 'videoWall':
 					this.$refs['cmap'].onMouseDrawEditVideoWall();
 					break;
+				case 'odLine':
+					this.$refs['cmap'].onMouseDrawEditOdline();
+					break;
 				case 'clear':
 					this.$refs['cmap'].onClearDraw();
 					break;