Cesium剖面线分析

实现思路:
1、使用一条线段来进行剖面分析。
2、在开始点和结束点之间插值100个点。
3、把插值的点数据赋值到echart中展现出来
实现效果如下:
在这里插入图片描述
首先还是得把模型加载出来,这个就不多解释,可以参考我的另一篇添加3D模型

function addProfile(){
    
    
		// 具体事件的实现
		var ellipsoid = _this.viewer.scene.globe.ellipsoid
		var handler = new Cesium.ScreenSpaceEventHandler(_this.viewer.scene.canvas)
		var start, end
		var profile = {
    
    
			arrHB: [],
			arrPoint: [],
			ponits: [],
		}
		var draw = function (drawingMode) {
    
    
			var entityPolygon = null
			//淹没分析entity
			function createPoint(worldPosition) {
    
    
				var point = _this.viewer.entities.add({
    
    
					position: worldPosition,
					point: {
    
    
						pixelSize: 10,
						color: Cesium.Color.YELLOW,
						heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
					},
				})
				return point
			}

			var drawingMode = drawingMode
			function drawShape(positionData) {
    
    
				var shape
				if (drawingMode === 'line' && undefined != newProfile) {
    
    
					shape = _this.viewer.entities.add({
    
    
						polyline: {
    
    
							positions: positionData,
							clampToGround: true,
							arcType: Cesium.ArcType.RHUMB,
							material: Cesium.Color.GREEN,
							width: 3,
						},
					})
				} else if (drawingMode === 'polygon') {
    
    
					shape = _this.viewer.entities.add({
    
    
						polygon: {
    
    
							hierarchy: positionData,
							material: new Cesium.ColorMaterialProperty(
								Cesium.Color.LIGHTSKYBLUE.withAlpha(0.7)
							),
						},
					})
				}
				return shape
			}
			var activeShapePoints = []
			var activeShape
			var floatingPoint
			handler.setInputAction(function (event) {
    
    
				var earthPosition = _this.viewer.scene.pickPosition(event.position)
				if (Cesium.defined(earthPosition)) {
    
    
					if (activeShapePoints.length === 0) {
    
    
						start = earthPosition
						floatingPoint = createPoint(earthPosition)
						activeShapePoints.push(earthPosition)
						var dynamicPositions = new Cesium.CallbackProperty(function () {
    
    
							return activeShapePoints
						}, false)
						activeShape = drawShape(dynamicPositions)
					}
					activeShapePoints.push(earthPosition)
					createPoint(earthPosition)
				}
			}, Cesium.ScreenSpaceEventType.LEFT_CLICK)

			handler.setInputAction(function (event) {
    
    
				if (Cesium.defined(floatingPoint)) {
    
    
					var newPosition = _this.viewer.scene.pickPosition(event.endPosition)
					if (Cesium.defined(newPosition)) {
    
    
						floatingPoint.position.setValue(newPosition)
						activeShapePoints.pop()
						activeShapePoints.push(newPosition)
					}
				}
			}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

			function terminateShape() {
    
    
				activeShapePoints.pop()
				entityPolygon = drawShape(activeShapePoints)
				_this.viewer.entities.remove(floatingPoint)
				_this.viewer.entities.remove(activeShape)
				entityPolygon = null
				floatingPoint = undefined
				activeShape = undefined
				activeShapePoints = []
			}

			handler.setInputAction(function (event) {
    
    
				var length = activeShapePoints.length - 1
				end = activeShapePoints[length]
				profileAnalyse(start, end)//开始分析
				// setEchartsData(profile)//设置echart
				terminateShape()
				handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)//移除左键事件	
				handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)//移除移动事件	
				handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)//移除右键事件	
			}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
		}


		//剖面分析
		function profileAnalyse(start, end) {
    
    
			var scene = _this.viewer.scene;
			var startPoint = Cesium.Cartographic.fromCartesian(start)
			var endPoint = Cesium.Cartographic.fromCartesian(end)
			profile.ponits.push(start)
			profile.arrPoint.push(getDegrees(startPoint))
			profile.arrHB.push(startPoint.height)
			// 插值100个点,点越多模拟越精确,但是效率会低
			var count = 100;
			var arrHeight = []
			for (var i = 0; i < count; i++) {
    
    
				var cart = (Cesium.Cartesian3.lerp(
					start,
					end,
					i / count,
					new Cesium.Cartesian3()
				))
				arrHeight.push(cart)
			}
			//scene.clampToHeightMostDetailed获取模型样本高度,详情可查看cesium文档
			scene.clampToHeightMostDetailed(arrHeight).then(function (clampedCartesians) {
    
    
				for (var i = 0; i < count; i++) {
    
    
					profile.disc.push(distance(profile.ponits[i], Cesium.Cartographic.fromCartesian(clampedCartesians[i])))
					profile.ponits.push(clampedCartesians[i])
					profile.arrPoint.push(getDegrees(clampedCartesians[i]))
					profile.arrHB.push(Cesium.Cartographic.fromCartesian(clampedCartesians[i]).height)
				}
				profile.ponits.push(end)
				profile.arrPoint.push(getDegrees(endPoint))
				profile.arrHB.push(endPoint.height)
				setEchartsData(profile)
			})
		}

		//计算两点间的距离
		function distance(point1, point2) {
    
    
			/**根据经纬度计算出距离**/
			var geodesic = new Cesium.EllipsoidGeodesic()
			geodesic.setEndPoints(point1, point2)
			var s = geodesic.surfaceDistance
			//返回两点之间的距离
			s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2.height - point1.height, 2))
			return s
		}
		//世界坐标转换为经纬度
		function getDegrees(cart) {
    
    
			var cartographic = ellipsoid.cartesianToCartographic(cart)
			var lat = Cesium.Math.toDegrees(cartographic.latitude)
			var lng = Cesium.Math.toDegrees(cartographic.longitude)
			var alt = cartographic.height
			return {
    
     x: lng, y: lat, z: alt }
		}
		//经纬度保留两位小数
		function strFormat(str) {
    
    
			var strString = str.toString()
			var strs = strString.slice(0, strString.indexOf('.') + 3)
			return strs
		}

		//设置Echart数据
		function setEchartsData(e) {
    
    
			if (null != e && null != e.arrPoint && undefined != newProfile) {
    
    
				$('#sectionChars').show();
				var myChart = echarts.init(document.getElementById("echartsView1"), 'dark');
				var t = e.arrPoint,
					chartData = {
    
    
						grid: {
    
    
							left: 10,
							right: 10,
							bottom: 10,
							containLabel: !0,
						},
						tooltip: {
    
    
							trigger: 'axis',
							formatter: function (e) {
    
    
								var htmldiv = '';
								var r = t[e[0].dataIndex];
								return(
									htmldiv +=
									'所在位置:'+strFormat(r.x)+','+strFormat(r.y)+'<br/>'+							
									'高程值:'+haoutil.str.formatLength(e[0].value)+'<br/>'
									)
							},
						},
						xAxis:
						{
    
    
							name: '距离',
							type: 'category',
							boundaryGap: !1,
							axisLabel: {
    
    
								show: !1,
							},
							data: e.arrHB,
						},

						yAxis:
						{
    
    
							type: 'value',
							axisLabel: {
    
    
								rotate: 0,
								formatter: '{value} 米',
							},
						},

						series: [
							{
    
    
								name: '高程值',
								type: 'line',
								smooth: !0,
								symbol: 'none',
								sampling: 'average',
								itemStyle: {
    
    
									normal: {
    
    
										color: 'rgb(255, 70, 131)',
									},
								},
								areaStyle: {
    
    
									normal: {
    
    
										color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
											{
    
    
												offset: 0,
												color: 'rgb(255, 158, 68)',
											},
											{
    
    
												offset: 1,
												color: 'rgb(255, 70, 131)',
											},
										]),
									},
								},
								data: e.arrHB,
							},
						],
					}
				myChart.setOption(chartData)
			}
		}
		draw('line')
}

猜你喜欢

转载自blog.csdn.net/qq_44505797/article/details/122720382