| | |
| | | <div class="cesiumBotton"> |
| | | <div class="cesiumButtonGroup"> |
| | | <el-button id="groundPoi" @click="addGroundPoi()" type="primary">地面点</el-button> |
| | | <el-button id="groundPoi" @click="addGroundPoi()" type="primary">空中点</el-button> |
| | | <el-button id="groundPoi" @click="addGroundPoi()" type="primary">停留时间</el-button> |
| | | <!-- <el-button id="groundPoi" @click="addGroundPoi()" type="primary">停留时间</el-button> --> |
| | | <el-input v-model="mergeNumber" placeholder="请输入合并范围" type="number" style="width: 150px;"></el-input> |
| | | <el-button @click="mergePoint()" type="success">合并</el-button> |
| | | <el-button @click="renderData()" type="success">数据渲染</el-button> |
| | | <!-- <el-button @click="VisualCone()" type="success">生成视锥体</el-button> --> |
| | | |
| | | </div> |
| | | <div class="key-container"> |
| | | <div class="arrow-row"> |
| | | <div |
| | | class="arrow" |
| | | :class="{ active: activeKey === 'w' }" |
| | | >W</div> |
| | | </div> |
| | | <div class="key-row"> |
| | | <div |
| | | class="key" |
| | | :class="{ active: activeKey === 'a' }" |
| | | @mousedown="handleClick('a')" |
| | | >A</div> |
| | | <div |
| | | class="key" |
| | | :class="{ active: activeKey === 's' }" |
| | | @mousedown="handleClick('s')" |
| | | >S</div> |
| | | <div |
| | | class="key" |
| | | :class="{ active: activeKey === 'd' }" |
| | | @mousedown="handleClick('d')" |
| | | >D</div> |
| | | </div> |
| | | </div> |
| | | <div class="key-container"> |
| | | <div class="arrow-row"> |
| | | <div |
| | | class="arrow" |
| | | :class="{ active: activeKey === 'ArrowUp' }" |
| | | @mousedown="handleClick('ArrowUp')" |
| | | >↑</div> |
| | | </div> |
| | | <div class="key-row"> |
| | | <div |
| | | class="key" |
| | | :class="{ active: activeKey === 'ArrowLeft' }" |
| | | @mousedown="handleClick('ArrowLeft')" |
| | | >←</div> |
| | | <div |
| | | class="key" |
| | | :class="{ active: activeKey === 'ArrowDown' }" |
| | | @mousedown="handleClick('ArrowDown')" |
| | | >↓</div> |
| | | <div |
| | | class="key" |
| | | :class="{ active: activeKey === 'ArrowRight' }" |
| | | @mousedown="handleClick('ArrowRight')" |
| | | >→</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | let viewerM; |
| | | let viewerC; |
| | | let counter = 0; |
| | | let pois = [125.1541, 46.5542,0] |
| | | let globalon = 0 |
| | | let globalat = 0 |
| | | let pois = [globalon, globalat,0] |
| | | |
| | | // let pois = [0, 0,0] |
| | | let holdingPosition; |
| | | let rightKeyMove = false |
| | | // let pois = [125.1541, 46.5542,0] |
| | | let distance = 100; |
| | | export default { |
| | | props: { |
| | | towerUrl: { |
| | | type: String, |
| | | default() { |
| | | return '' |
| | | } |
| | | }, |
| | | }, |
| | | data(){ |
| | | return{ |
| | | moveSpeed: 1, |
| | |
| | | space: false, |
| | | }, |
| | | animationFrameId: null, |
| | | mergeNumber:null |
| | | mergeNumber:null, |
| | | activeKey: null, |
| | | timer: null, |
| | | handler: null, |
| | | frustumPrimitive: null, |
| | | selected: false, |
| | | } |
| | | }, |
| | | mounted(){ |
| | | console.log('111111111111111111') |
| | | this.initCesium(); |
| | | }, |
| | | beforeDestroy() { |
| | | counter = 0 |
| | | this.removeKeyboardEvents(); |
| | | if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId); |
| | | window.removeEventListener("keydown", this.handleKeydown); |
| | | if (viewerC) viewerC.destroy(); |
| | | }, |
| | | methods:{ |
| | | initCesium() { |
| | | viewerM = this.initViewer(this.$refs.cesiumContainer.id); |
| | | viewerC = this.initViewer(this.$refs.cesiumCamera.id); |
| | | window.viewerM = viewerM; |
| | | window.viewerC = viewerC; |
| | | // 💡 在这里继续调用 measure.js / camera.js / botton.js 等逻辑 |
| | | // 例如:window.registerMeasureTools(viewerM) |
| | | setTimeout(()=>{ |
| | |
| | | initViewer(cesiumId){ |
| | | //cesium全球30米分辨率地形资源token |
| | | let imageryProvider1 = new Cesium.TileMapServiceImageryProvider({ |
| | | // url: process.env.VUE_APP_BASE_GIS + "/daqing/dom-sea", |
| | | // url: process.env.VUE_APP_BASE_GIS + "/daqing/dom-sea", |
| | | url: `https://192.168.1.2:9999/daqing/dom-sea/`, |
| | | }); |
| | | let viewer = new Cesium.Viewer(cesiumId, { |
| | |
| | | navigationHelpButton: false, |
| | | navigationInstructionsInitiallyVisible: false, |
| | | imageryProvider: imageryProvider1, |
| | | // imageryProvider: false, |
| | | shadows: false, |
| | | animation: false, |
| | | infoBox: false, |
| | |
| | | fullscreenButton: false, |
| | | vrButton: false, |
| | | }); |
| | | window.viewer = viewer; |
| | | // 关闭天空盒效果 |
| | | // viewer.scene.skyAtmosphere = undefined; // 或者设置为 null |
| | | |
| | | // // 关闭光照效果 |
| | | // viewer.scene.globe.enableLighting = false; // 关闭光照效果 |
| | | |
| | | // viewer.imageryLayers.add(bdtvectoranoimagery); |
| | | viewer._cesiumWidget._creditContainer.style.display="none"; |
| | | return viewer; |
| | | |
| | | }, |
| | | loadModel(){ |
| | | const modelUrl = 'http://192.168.1.2:9001/model/tower.glb'; // GLB模型路径 |
| | | const modelUrl = this.towerUrl; // GLB模型路径 |
| | | // 沿原点坐标和地面点坐标方向上选取空中点的距离 |
| | | //初始化相机窗口视角参数 |
| | | cameraPostion = viewerM.camera.position |
| | |
| | | |
| | | // 设置视角,使其默认查看某个地理位置 |
| | | viewerM.scene.camera.setView({ |
| | | destination: Cesium.Cartesian3.fromDegrees(125.1511, 46.5542, 349.0), // 以经纬度设置位置(例如:大庆龙兴路) |
| | | destination: Cesium.Cartesian3.fromDegrees(globalon, globalat, 349.0), // 以经纬度设置位置(例如:大庆龙兴路) |
| | | // destination: Cesium.Cartesian3.fromDegrees(0.0005, 0.0017, 207.8), // 以经纬度设置位置(例如:大庆龙兴路) |
| | | orientation: { |
| | | heading: Cesium.Math.toRadians(86.94), // 方向 |
| | | pitch: Cesium.Math.toRadians(-30.22), // 俯角 |
| | | heading: Cesium.Math.toRadians(194.65), // 方向 |
| | | pitch: Cesium.Math.toRadians(-31.43), // 俯角 |
| | | roll: 0 |
| | | } |
| | | }); |
| | | |
| | | //创建模型 |
| | | const glbModelPoi = Cesium.Cartesian3.fromDegrees(pois[0], pois[1],pois[2]); |
| | | const heading = Cesium.Math.toRadians(10); |
| | | const heading = Cesium.Math.toRadians(0); |
| | | const pitch = Cesium.Math.toRadians(0); |
| | | const roll = Cesium.Math.toRadians(0); |
| | | const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); |
| | |
| | | orientation: orientations, |
| | | model: { |
| | | uri: url, |
| | | scale: 20, |
| | | shadows: Cesium.ShadowMode.DISABLED, |
| | | imageBasedLightingFactor: new Cesium.Cartesian2(1, 0.5) |
| | | } |
| | |
| | | // 存下回调以便销毁 |
| | | // this._preRenderCallback = () => this.syncViewer(); |
| | | viewerM.scene.preRender.addEventListener( this.syncViewer()); |
| | | window.addEventListener("keydown", this.handleKeydown); |
| | | }, |
| | | syncViewer(){ |
| | | console.log(viewerM.camera) |
| | |
| | | } |
| | | }, |
| | | addGroundPoi() { |
| | | console.log('1111111111111111') |
| | | console.log(new Cesium.ScreenSpaceEventHandler(viewerM.canvas)) |
| | | console.log(this) |
| | | let createPinHandler = new Cesium.ScreenSpaceEventHandler(viewerM.canvas); |
| | | let _this = this |
| | | createPinHandler.setInputAction(function (click) { |
| | |
| | | let lng = Cesium.Math.toDegrees(cartographic.longitude); |
| | | let lat = Cesium.Math.toDegrees(cartographic.latitude); |
| | | height = cartographic.height; |
| | | // camPosition = lng+','+lat+','+height; |
| | | console.log(lng+','+lat+','+height) |
| | | } |
| | | |
| | |
| | | const scalerNormalize = Cesium.Cartesian3.multiplyByScalar(normalize,distance,new Cesium.Cartesian3()); |
| | | const tagert = Cesium.Cartesian3.add(holdingPosition,scalerNormalize,new Cesium.Cartesian3()); |
| | | console.log(Cesium.Cartographic.fromCartesian(tagert)) |
| | | var airCartographic= Cesium.Cartographic.fromCartesian(tagert) |
| | | var airPointLongitude= Cesium.Math.toDegrees(airCartographic.longitude); |
| | | var airPointLatitude = Cesium.Math.toDegrees(airCartographic.latitude); |
| | | var airPointHeight = airCartographic.height; |
| | | _this.creatPin("aerialPoiId"+counter,tagert,`空${counter}`,Cesium.Color.RED,viewerM); |
| | | _this.updateCameraMovement(); |
| | | // console.log(direction) |
| | | // console.log(normalize ) |
| | | // console.log(longitude) |
| | | // console.log(latitude) |
| | | // console.log(pois) |
| | | // console.log(azimuthtwopoi(longitude,latitude,pois[0],pois[1])) |
| | | // let data = { |
| | | // id:(Date.now().toString(16) + Math.random().toString(16).slice(2, 10)).slice(0, 16), |
| | | // label:`地面点${counter}`, |
| | | // longitude:longitude, |
| | | // latitude:latitude, |
| | | // height:height, |
| | | // children:[ |
| | | // { |
| | | // id:(Date.now().toString(16) + Math.random().toString(16).slice(2, 10)).slice(0, 16), |
| | | // label:`空中点${counter}`, |
| | | // longitude:airPointLongitude, |
| | | // latitude:airPointLatitude, |
| | | // height:airPointHeight, |
| | | // } |
| | | // ] |
| | | // } |
| | | // _this.$emit('rightClickEnd',data) |
| | | //结束右键监听 |
| | | createPinHandler.destroy(); |
| | | //结束主图联动鹰眼监听 |
| | | viewerM.scene.preRender.removeEventListener(_this.syncViewer()); |
| | | // viewerM.scene.preRender.removeEventListener(this._preRenderCallback); |
| | | // if (this._preRenderCallback) { |
| | | // this.viewerM.scene.preRender.removeEventListener(this._preRenderCallback); |
| | | // this._preRenderCallback = null; |
| | | // } |
| | | //更新相机视角为空中点 |
| | | _this.changeCamera(tagert,_this.azimuthtwopoi(longitude,latitude,pois[0],pois[1])); |
| | | rightKeyMove = true |
| | | counter += 1; |
| | |
| | | }); |
| | | }, |
| | | registerKeyboardEvents() { |
| | | console.log('11111111111111111111111') |
| | | window.addEventListener("keydown", this.onKeyDown); |
| | | window.addEventListener("keyup", this.onKeyUp); |
| | | }, |
| | |
| | | case "1": |
| | | viewerC.scene.mode = Cesium.SceneMode.SCENE3D; |
| | | break; |
| | | // case "2": |
| | | // viewerC.scene.mode = Cesium.SceneMode.SCENE2D; |
| | | // break; |
| | | case "3": |
| | | viewerC.scene.mode = Cesium.SceneMode.COLUMBUS_VIEW; |
| | | break; |
| | |
| | | }, |
| | | onKeyUp(event) { |
| | | //键盘抬起进行更新左侧空中点pin |
| | | console.log(viewerM) |
| | | console.log(counter) |
| | | //获取右侧相机 |
| | | if(rightKeyMove){ |
| | | const camera = viewerC.camera; |
| | | console.log(camera) |
| | | const carto = Cesium.Cartographic.fromCartesian(camera.position); |
| | | console.log(carto) |
| | | //右侧相机视角转化为经纬度 |
| | | const lon = Cesium.Math.toDegrees(carto.longitude); |
| | | const lat = Cesium.Math.toDegrees(carto.latitude); |
| | | const height = carto.height; |
| | | const position = Cesium.Cartesian3.fromDegrees(lon, lat, height) |
| | | console.log(position) |
| | | let pinBuilder = new Cesium.PinBuilder(); |
| | | // const dest = this.calculateDestinationPoint(lon, lat, camera.heading, speed); |
| | | const groupEntity = viewerM.entities.getById("aerialPoiId"+(counter-1)); |
| | | //左侧地图同步更新pin空中点位置 |
| | | if (groupEntity == undefined) { |
| | |
| | | } |
| | | }, |
| | | updateCameraMovement() { |
| | | console.log('111111111111111111111111111111111111111111') |
| | | const camera = viewerC.camera; |
| | | // Adjust speed by modifiers |
| | | let currentSpeed = this.moveSpeed; |
| | |
| | | let rotSpeed = 1; |
| | | if (this.keyState.shift) rotSpeed *= this.speedMultiplier; |
| | | if (this.keyState.ctrl) rotSpeed *= this.slowMultiplier; |
| | | const multiplyByScalarrotateAmount = Cesium.Math.toRadians(0.5 * rotSpeed); |
| | | |
| | | // if (this.keyState.up) camera.lookUp(rotateAmount); |
| | | // if (this.keyState.down) camera.lookDown(rotateAmount); |
| | | // if (this.keyState.left) camera.lookLeft(rotateAmount); |
| | | // if (this.keyState.right) camera.lookRight(rotateAmount); |
| | | if (holdingPosition) { |
| | | // const groupPosition = groupEntity.position.getValue(Cesium.JulianDate.now()); |
| | | // console.log(groupPosition) |
| | | const distance = Cesium.Cartesian3.distance(holdingPosition, camera.position); |
| | | |
| | | const surroundSpeed = 0.005; //环绕速度,角度 |
| | | let cameraHeading = camera.heading; |
| | | let cameraPitch = camera.pitch; |
| | |
| | | if (this.keyState.right) camera.lookRight(rotateAmount); |
| | | } |
| | | this.resetRoll(); |
| | | |
| | | // Schedule next frame |
| | | this.animationFrameId = requestAnimationFrame(this.updateCameraMovement); |
| | | // this.animationFrameId = requestAnimationFrame(this.updateCameraMovement); |
| | | }, |
| | | calculateDestinationPoint(lon1, lat1, bearing, distance, radius = 6371000) { |
| | | const toRad = (d) => d * Math.PI / 180; |
| | |
| | | |
| | | return { lon: toDeg(lon2Norm), lat: toDeg(lat2Rad) }; |
| | | }, |
| | | |
| | | uavMoveForward(speed) { |
| | | console.log('11111' +speed) |
| | | const camera = viewerC.camera; |
| | | const carto = Cesium.Cartographic.fromCartesian(camera.position); |
| | | const lon = Cesium.Math.toDegrees(carto.longitude); |
| | |
| | | cammove_measure_point(){ |
| | | CesiumSurvey.cammeasureMovePoint(viewerM,'cammoveResultCon'); |
| | | }, |
| | | renderData(){ |
| | | this.$emit('renderData',viewerM) |
| | | }, |
| | | mergePoint(){ |
| | | let allEntities = viewerM.entities.values; // 所有实体对象组成的数组 |
| | | console.log(allEntities) |
| | | allEntities.forEach(entity => { |
| | | console.log('ID:', entity.id); |
| | | console.log('Position:', entity.position ? entity.position.getValue(Cesium.JulianDate.now()) : null); |
| | | console.log('Name:', entity.name); |
| | | console.log('Properties:', entity.properties); // 自定义属性 |
| | | }); |
| | | const grouped = {}; |
| | | //所有实体对象组成的数组转换成左侧树需要的格式 |
| | | allEntities.forEach(item => { |
| | |
| | | ] |
| | | }; |
| | | }); |
| | | console.log(result) |
| | | this.$emit('mergePoint',result,this.mergeNumber,viewerM) |
| | | }, |
| | | genId() { |
| | |
| | | latitude: Cesium.Math.toDegrees(cartographic.latitude), |
| | | height: cartographic.height |
| | | }; |
| | | } |
| | | }, |
| | | handleClick(key) { |
| | | this.triggerKey(key); |
| | | }, |
| | | triggerKey(key) { |
| | | this.activeKey = key; |
| | | clearTimeout(this.timer); |
| | | this.timer = setTimeout(() => { |
| | | this.activeKey = null; |
| | | }, 200); |
| | | |
| | | // 自定义动作触发 |
| | | console.log("Key triggered:", key); |
| | | // 这里可以发出事件或调用其它方法 |
| | | }, |
| | | handleKeydown(e) { |
| | | const key = e.key; |
| | | console.log(key) |
| | | const validKeys = ["a", "s", "d", "w",'q','e','ArrowUp','ArrowDown','ArrowLeft','ArrowRight','q','e']; |
| | | if (validKeys.includes(key)) { |
| | | this.triggerKey(key); |
| | | } |
| | | this.updateCameraMovement() |
| | | }, |
| | | VisualCone(){ |
| | | this.addFrustum(); |
| | | this.initDragHandler(); |
| | | }, |
| | | addFrustum() { |
| | | // 创建一个 PerspectiveFrustum |
| | | const frustum = new Cesium.PerspectiveFrustum({ |
| | | fov: Cesium.Math.PI_OVER_THREE, |
| | | aspectRatio: 1.0, |
| | | near: 1.0, |
| | | far: 500.0, |
| | | }); |
| | | |
| | | // 设置矩阵位置 |
| | | const position = Cesium.Cartesian3.fromDegrees(110.0, 30.0, 100.0); |
| | | const direction = Cesium.Cartesian3.normalize( |
| | | new Cesium.Cartesian3(1.0, 0.0, -1.0), |
| | | new Cesium.Cartesian3() |
| | | ); |
| | | const up = Cesium.Cartesian3.UNIT_Z; |
| | | const right = Cesium.Cartesian3.cross(direction, up, new Cesium.Cartesian3()); |
| | | const rotation = Cesium.Matrix3.setColumns( |
| | | new Cesium.Matrix3(), |
| | | right, |
| | | up, |
| | | Cesium.Cartesian3.negate(direction, new Cesium.Cartesian3()) |
| | | ); |
| | | |
| | | const modelMatrix = Cesium.Matrix4.fromRotationTranslation(rotation, position); |
| | | |
| | | this.frustumPrimitive = this.viewer.scene.primitives.add( |
| | | new Cesium.DebugCameraPrimitive({ |
| | | frustum, |
| | | modelMatrix, |
| | | color: Cesium.Color.LIME.withAlpha(0.5), |
| | | }) |
| | | ); |
| | | }, |
| | | |
| | | initDragHandler() { |
| | | const scene = viewerM.scene; |
| | | const canvas = scene.canvas; |
| | | this.handler = new Cesium.ScreenSpaceEventHandler(canvas); |
| | | |
| | | let isDragging = false; |
| | | let lastPosition = null; |
| | | |
| | | this.handler.setInputAction((movement) => { |
| | | const pickedObject = scene.pick(movement.position); |
| | | if (pickedObject && pickedObject.primitive === this.frustumPrimitive) { |
| | | this.selected = true; |
| | | isDragging = true; |
| | | lastPosition = movement.position; |
| | | } else { |
| | | this.selected = false; |
| | | } |
| | | }, Cesium.ScreenSpaceEventType.LEFT_DOWN); |
| | | |
| | | this.handler.setInputAction((movement) => { |
| | | if (isDragging && this.selected) { |
| | | const start = scene.pickPosition(lastPosition); |
| | | const end = scene.pickPosition(movement.endPosition); |
| | | if (start && end) { |
| | | const delta = Cesium.Cartesian3.subtract( |
| | | end, |
| | | start, |
| | | new Cesium.Cartesian3() |
| | | ); |
| | | const newMatrix = Cesium.Matrix4.multiplyByTranslation( |
| | | this.frustumPrimitive.modelMatrix, |
| | | delta, |
| | | new Cesium.Matrix4() |
| | | ); |
| | | this.frustumPrimitive.modelMatrix = newMatrix; |
| | | lastPosition = movement.endPosition; |
| | | } |
| | | } |
| | | }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); |
| | | |
| | | this.handler.setInputAction(() => { |
| | | isDragging = false; |
| | | lastPosition = null; |
| | | }, Cesium.ScreenSpaceEventType.LEFT_UP); |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | |
| | | .box_rb{width:10px;height:10px;position:absolute;border-bottom:2px solid #00d3e7;border-right:2px solid #00d3e7;right:0px;bottom:0px;} |
| | | .box_lb{width:10px;height:10px;position:absolute;border-bottom:2px solid #00d3e7;border-left:2px solid #00d3e7;left:0px;bottom:0px;} |
| | | </style> |
| | | |
| | | <style scoped> |
| | | .key-container { |
| | | display: inline-block; |
| | | background-color: rgba(0, 0, 0, 0.7); |
| | | padding: 8px 10px; |
| | | border-radius: 10px; |
| | | color: white; |
| | | font-family: sans-serif; |
| | | margin-top: 55px; |
| | | } |
| | | |
| | | .arrow-row{ |
| | | display: flex; |
| | | justify-content: center; |
| | | margin-bottom: 4px; |
| | | } |
| | | .key-row { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .arrow, |
| | | .key { |
| | | width: 30px; |
| | | height: 30px; |
| | | margin: 0 2px; |
| | | background-color: #333; |
| | | border-radius: 4px; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | font-weight: bold; |
| | | transition: background-color 0.2s; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .arrow.active, |
| | | .key.active { |
| | | background-color: #00aaff; |
| | | } |
| | | </style> |