/** * 路径漫游 */ (function (window) { 'use strict'; function define_CesiumRoam() { //Main object var CesiumRoam = {}; CesiumRoam.lines = "114.53836273034896,38.00039331211704,153.00913091160308,114.53675083313561,37.99913904663243,148.8441307249287,114.53693864410401,37.99726980815997,149.97794017557146,114.5388775477768,37.99617034897775,150.0931846567538,114.54151503045546,37.99624273198715,152.76414965599372,114.54306394123357,37.99746809717264,153.64383252744818,114.54278976236779,37.99915136617812,151.8990943270027,114.5405325034151,38.00028459715921,153.81891784625202,114.53856752601202,38.000386426715586,152.02134046421168"; CesiumRoam.options; CesiumRoam.view={}; var roamStart, roamStop; function ComputeRoamingLineProperty(viewer, Lines, time, isRe) { var property = new Cesium.SampledPositionProperty(); var lineLength = Lines.length; var tempTime = time - time % lineLength; var increment = tempTime / lineLength; roamStart = Cesium.JulianDate.now(); roamStop = Cesium.JulianDate.addSeconds(roamStart, tempTime, new Cesium.JulianDate()); viewer.clock.startTime = roamStart.clone(); viewer.clock.stopTime = roamStop.clone(); viewer.clock.currentTime = roamStart.clone(); viewer.clock.clockRange = isRe ? Cesium.ClockRange.LOOP_STOP : Cesium.ClockRange.CLAMPED; // Loop at the end viewer.clock.multiplier = 10; viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER; for (var i = 0; i < lineLength; i++) { var timesample = Cesium.JulianDate.addSeconds(roamStart, i * increment, new Cesium.JulianDate()); var position = Lines[i]; property.addSample(timesample, position); } return property; } /** * @param {*} position computeRoamingLineProperty计算的属性 * @param {*} start 开始时间节点 * @param {*} stop 结束时间节点 * @param {*} isPathShow path路径是否显示 * @memberof Roaming */ var roamEntity; CesiumRoam.initRoaming = function (options) { this.EndRoaming(options.viewer); this.options = options; var lineArrtemp = options.lines === null ? this.lines.split(',') : options.lines.split(','); var lineArr = []; for (var i = 0; i < lineArrtemp.length; i = i + 3) { var linepoint = Cesium.Cartesian3.fromDegrees(Number(lineArrtemp[i]), Number(lineArrtemp[i + 1]), Number(lineArrtemp[i + 2])); lineArr.push(linepoint); } var roamproperty = ComputeRoamingLineProperty(options.viewer, lineArr, options.speed, options.isRe); roamEntity = options.viewer.entities.add({ availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: roamStart, stop: roamStop })]), position: roamproperty,// 位置 orientation: new Cesium.VelocityOrientationProperty(roamproperty),// 计算朝向 // 加载模型 model: { uri: options.modeluri,// 模型路径 minimumPixelSize: 32,// 模型最小刻度 maximumSize: 128, maximumScale: 200,// 设置模型最大放大大小 show: options.roamIsmodelshow,// 模型是否可见 silhouetteColor: Cesium.Color.WHITE,// 模型轮廓颜色 color: options.roamIsmodelshow ? null : Cesium.Color.fromAlpha(Cesium.Color.RED, 0.1),// 模型颜色 ,这里可以设置颜色的变化 debugWireframe: false,// 仅用于调试,显示模型绘制时的线框 debugShowBoundingVolume: false,// 仅用于调试。显示模型绘制时的边界球。 scale: options.scale, heightReference: options.ontheground == true ? Cesium.HeightReference.CLAMP_TO_GROUND : Cesium.HeightReference.NONE, runAnimations: true // 是否运行模型中的动画效果 }, path: { resolution: 1, material: new Cesium.PolylineGlowMaterialProperty({ glowPower: 0.1, color: Cesium.Color.YELLOW, }), heightReference: options.ontheground == true ? Cesium.HeightReference.CLAMP_TO_GROUND : Cesium.HeightReference.NONE, width: 10, show: options.isPathShow, } }); if (options.type == '平滑线') { roamEntity.position.setInterpolationOptions({ // 点插值 interpolationDegree: 5, interpolationAlgorithm: Cesium.LagrangePolynomialApproximation }); } options.viewer.clock.multiplier = 0; options.viewer.flyTo(roamEntity).then(function () { options.viewer.trackedEntity = roamEntity; options.viewer.clock.multiplier = 10; }); } CesiumRoam.ChangeRoamingSetting = function (options) { switch (options.viewModel) { case 1: { options.viewer.trackedEntity = undefined; this.lockCamera(false); break; } case 2: { options.viewer.trackedEntity = roamEntity; this.lockCamera(false); break; } case 3: { options.viewer.trackedEntity = roamEntity; this.view.pitch = -20; this.lockCamera(true); break; } case 4: { options.viewer.trackedEntity = roamEntity; this.view.pitch = -89; this.lockCamera(true); break; } } this.ChangeRoamingSpeed(options.viewer, options.speed); } CesiumRoam.lockCamera = function (islock) { // 停止监听屏幕绘制事件(停止相机变化) if(this.handler){ this.handler(); this.handler = null; // 解锁相机视角 viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); } if (islock) { this.addSceneEvent((time) => { this.getRoamingPosition(time); }); } } CesiumRoam.addSceneEvent = function (callback) { // addEventListener() → Event.RemoveCallback // 监听之前先销毁 if (this.handler instanceof Function) { this.handler(); this.handler = null; } this.handler = this.options.viewer.scene.preRender.addEventListener((scene, time) => { callback(time); }); } CesiumRoam.getRoamingPosition = function (time) { if (roamEntity) { const position = roamEntity.position.getValue(time); this.setCameraPosition(position, this.view || {}); } } CesiumRoam.cartesian3ToWGS84 = function (point) { const cartographic = Cesium.Cartographic.fromCartesian(point); const lat = Cesium.Math.toDegrees(cartographic.latitude); const lng = Cesium.Math.toDegrees(cartographic.longitude); const alt = cartographic.height; return { longitude: lng, latitude: lat, height: alt, }; } CesiumRoam.bearing = function (startLat, startLng, destLat, destLng) { startLat = Cesium.Math.toRadians(startLat); startLng = Cesium.Math.toRadians(startLng); destLat = Cesium.Math.toRadians(destLat); destLng = Cesium.Math.toRadians(destLng); const y = Math.sin(destLng - startLng) * Math.cos(destLat); const x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng); const brng = Math.atan2(y, x); const brngDgr = Cesium.Math.toDegrees(brng); return (brngDgr + 360) % 360; } CesiumRoam.setCameraPosition = function (position, options) { if (position) { // 最新传进来的坐标(后一个位置) this.position2 = this.cartesian3ToWGS84(position); let heading = 0; // 前一个位置点位 if (this.position1) { // 计算前一个点位与第二个点位的偏航角 heading = this.bearing(this.position1.latitude, this.position1.longitude, this.position2.latitude, this.position2.longitude); } this.position1 = this.cartesian3ToWGS84(position); if (position) { const dynamicHeading = Cesium.Math.toRadians(heading); const pitch = Cesium.Math.toRadians(options.pitch || -20.0); const range = options.range || 300.0; this.options.viewer.camera.lookAt(position, new Cesium.HeadingPitchRange(dynamicHeading, pitch, range)); } } } CesiumRoam.firstpersonCamera = function () { let center = roamEntity.position.getValue( this.options.viewer.clock.currentTime ); let orientation = roamEntity.orientation.getValue( this.options.viewer.clock.currentTime ); let transform = Cesium.Transforms.eastNorthUpToFixedFrame(center); transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromQuaternion(orientation), center); this.options.viewer.camera.lookAtTransform(transform, new Cesium.Cartesian3(-100, 0, 50)); // this.options.viewer.scene._screenSpaceCameraController.enableRotate = false; // this.options.viewer.scene._screenSpaceCameraController.enableTranslate = false; // this.options.viewer.scene._screenSpaceCameraController.enableZoom = false; // this.options.viewer.scene._screenSpaceCameraController.enableTilt = false; // this.options.viewer.scene._screenSpaceCameraController.enableLook = false; // this.options.viewer.clock.shouldAnimate = true; } CesiumRoam.overlookCamera = function () { let center = roamEntity.position.getValue( this.options.viewer.clock.currentTime ); let orientation = roamEntity.orientation.getValue( this.options.viewer.clock.currentTime ); let transform = Cesium.Transforms.eastNorthUpToFixedFrame(center); transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromQuaternion(orientation), center); this.options.viewer.camera.lookAtTransform(transform, new Cesium.Cartesian3(-50, 0, 250)); } /** *漫游的暂停和继续 * * @param {*} state bool类型 false为暂停,ture为继续 * @memberof Roaming */ CesiumRoam.PauseOrContinue = function (viewer, state) { if (state) { // 继续播放 if (!this.handler && this.entity) { this.addSceneEvent((time) => { this.getRoamingPosition(time); }); } } else if (this.handler) { // 停止监听屏幕绘制事件(停止相机变化) this.handler(); this.handler = null; // 解锁相机视角 viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); } viewer.clock.shouldAnimate = state; } /** *改变飞行的速度 * * @param {*} value 整数类型 * @memberof Roaming */ CesiumRoam.ChangeRoamingSpeed = function (viewer, value) { viewer.clock.multiplier = value; } /** *取消漫游 * @memberof Roaming */ CesiumRoam.EndRoaming = function (viewer) { if (roamEntity !== undefined) { if (this.handler instanceof Function) { this.handler(); this.handler = null; } // 清空实体 viewer.entities.remove(roamEntity); // 解锁相机视角 viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); roamEntity = null; } } var roamDrawMarkArr = []; var roamHandler; //绘制漫游路径 CesiumRoam.drawRoamDraw = function (options) { roamHandler = roamHandler && roamHandler.destroy(); if ((options.viewer.entities.getById('dynamicRoamGroundEntity') !== undefined)) { options.viewer.entities.removeById('dynamicRoamGroundEntity'); } if ((options.viewer.entities.getById('measureRoamGroundEntity') !== undefined)) { options.viewer.entities.removeById('measureRoamGroundEntity'); } for (var i = 0; i < roamDrawMarkArr.length; i++) { options.viewer.entities.remove(roamDrawMarkArr[i]); } roamDrawMarkArr = []; var isFirst = true;//是否为第一个点 var previousPosition;//前一个点的坐标 var currentPosition;//当前点坐标 var dynamicPositions = []; var dynamicRoamGroundEntity = options.viewer.entities.add({ id: 'dynamicRoamGroundEntity', polyline: { clampToGround: true, width: 3, material: options.pointcolor, } }); dynamicRoamGroundEntity.polyline.positions = new Cesium.CallbackProperty(function () { return dynamicPositions; }, false); //已输入的线段的entity var measureLinePositonsArray = [];//存储已量测的线段的折点 var measureRoamGroundEntity = options.viewer.entities.add({ id: 'measureRoamGroundEntity', polyline: { clampToGround: true, width: 3, material: options.polylinecolor, } }); measureRoamGroundEntity.polyline.positions = new Cesium.CallbackProperty(function () { return measureLinePositonsArray; }, false); //节点添加标签 function addPin(carPoi) { roamDrawMarkArr.push(options.viewer.entities.add({ position: carPoi, point: { pixelSize: 8, color: options.pointcolor, disableDepthTestDistance: Number.POSITIVE_INFINITY, outlineWidth: 3, outlineColor: options.polylinecolor }, })); } function popPin() { options.viewer.entities.remove(roamDrawMarkArr[roamDrawMarkArr.length - 1]); measureLinePositonsArray.pop(); roamDrawMarkArr.pop(); if (measureLinePositonsArray.length > 0) { previousPosition = measureLinePositonsArray[measureLinePositonsArray.length - 1]; dynamicPositions = [previousPosition, currentPosition]; } else { previousPosition = undefined; isFirst = true; dynamicPositions = []; } } roamHandler = new Cesium.ScreenSpaceEventHandler(options.viewer.scene.canvas); roamHandler.setInputAction(function (movement) { if (isFirst) { previousPosition = options.viewer.scene.pickPosition(movement.position); var cartographic = Cesium.Cartographic.fromCartesian(previousPosition); var height = cartographic.height;//模型高度 if (Number(height) < 0) { var ray = options.viewer.camera.getPickRay(movement.position); previousPosition = options.viewer.scene.globe.pick(ray, options.viewer.scene); } if (previousPosition && previousPosition.x) { var tmp1 = previousPosition.clone(); measureLinePositonsArray.push(tmp1); isFirst = false; addPin(tmp1); } } else { currentPosition = options.viewer.scene.pickPosition(movement.position); var cartographic = Cesium.Cartographic.fromCartesian(currentPosition); var height = cartographic.height;//模型高度 if (Number(height) < 0) { var ray = options.viewer.camera.getPickRay(movement.position); currentPosition = options.viewer.scene.globe.pick(ray, options.viewer.scene); } if (currentPosition && currentPosition.x) { if (Math.abs(previousPosition.x - currentPosition.x) > 0.000001 || Math.abs(previousPosition.y - currentPosition.y) > 0.000001) { var tmp2 = currentPosition.clone(); measureLinePositonsArray.push(tmp2); previousPosition = currentPosition.clone(); dynamicPositions = [previousPosition, currentPosition]; addPin(tmp2); } } } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); roamHandler.setInputAction(function (movement) { if (!isFirst) { //获取当前点的坐标 currentPosition = options.viewer.scene.pickPosition(movement.endPosition); var cartographic = Cesium.Cartographic.fromCartesian(currentPosition); var height = cartographic.height;//模型高度 if (Number(height) < 0) { var ray = options.viewer.camera.getPickRay(movement.endPosition); currentPosition = options.viewer.scene.globe.pick(ray, options.viewer.scene); } if (currentPosition) { dynamicPositions = [previousPosition, currentPosition]; } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); roamHandler.setInputAction(function () { if (!isFirst) { popPin(); } }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); roamHandler.setInputAction(function () { if (!isFirst) { roamHandler = roamHandler && roamHandler.destroy(); options.viewer.entities.remove(dynamicRoamGroundEntity); if (roamDrawMarkArr.length < 2) { popPin(); options.viewer.entities.remove(measureRoamGroundEntity); } else { let tempPointsStr = ''; for (var i = 0; i < measureLinePositonsArray.length; i++) { var cartographic = Cesium.Cartographic.fromCartesian(measureLinePositonsArray[i]); var longitudeString = Cesium.Math.toDegrees(cartographic.longitude); var latitudeString = Cesium.Math.toDegrees(cartographic.latitude); var heightString = cartographic.height + options.roamHeight; tempPointsStr += longitudeString + "," + latitudeString + "," + heightString + ","; } CesiumRoam.drawLines = tempPointsStr.substring(0, tempPointsStr.length - 1); } for (let i in roamDrawMarkArr) { options.viewer.entities.remove(roamDrawMarkArr[i]); } } }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); } //显示漫游路径 CesiumRoam.showRoamLine = function (options) { roamDrawMarkArr = []; CesiumRoam.drawLines = JSON.parse(JSON.stringify(options.lines)); let lineArrtemp = options.lines.split(','); var measureLinePositonsArray = [];//存储已量测的线段的折点 for (var i = 0; i < lineArrtemp.length; i = i + 3) { var linepoint = Cesium.Cartesian3.fromDegrees(Number(lineArrtemp[i]), Number(lineArrtemp[i + 1]), Number(lineArrtemp[i + 2])); var cartographic = Cesium.Cartographic.fromCartesian(linepoint); var height = cartographic.height;//模型高度 if (Number(height) < 0) { var ray = options.viewer.camera.getPickRay(movement.position); linepoint = options.viewer.scene.globe.pick(ray, options.viewer.scene); } measureLinePositonsArray.push(linepoint); addPin(linepoint); } var measureRoamGroundEntity = options.viewer.entities.add({ id: 'measureRoamGroundEntity', polyline: { positions: measureLinePositonsArray, clampToGround: false, width: 3, material: options.polylinecolor, } }); viewer.flyTo(measureRoamGroundEntity); function addPin(carPoi) { roamDrawMarkArr.push(options.viewer.entities.add({ position: carPoi, point: { pixelSize: 10, color: options.pointcolor, disableDepthTestDistance: 5000000, outlineWidth: 2, outlineColor: Cesium.Color.WHITE.withAlpha(1) }, })); } } CesiumRoam.drawRoamClean = function (options) { roamHandler = roamHandler && roamHandler.destroy(); if ((options.viewer.entities.getById('dynamicRoamGroundEntity') !== undefined)) { options.viewer.entities.removeById('dynamicRoamGroundEntity'); } if ((options.viewer.entities.getById('measureRoamGroundEntity') !== undefined)) { options.viewer.entities.removeById('measureRoamGroundEntity'); } for (var i = 0; i < roamDrawMarkArr.length; i++) { options.viewer.entities.remove(roamDrawMarkArr[i]); } CesiumRoam.drawLines = undefined; } return CesiumRoam; } if (typeof (CesiumRoam) === 'undefined') { window.CesiumRoam = define_CesiumRoam(); } else { console.log("CesiumRoam already defined."); } })(window);