一、父组件代码
<template>
<div class="map">
<div class=treeBox>
<el-tree
:data="treeData"
:props="defaultProps"
draggable
highlight-current
:allow-drop="allowDrop"
:allow-drag="allowDrag"
@node-drag-start="handleDragStart">
</el-tree>
</div>
<div id="mapBox">
<!-- middle-地图 -->
<Cesium
@drop.native="drop"
@dragenter.native.prevent
@dragover.native.prevent
ref="cesiumRef"></Cesium>
</div>
</div>
</template>
<script>
import Cesium from './Cesium'
export default {
name: "",
components: {
Cesium,
},
props: {},
data() {
return {
// tree数据
treeData:[
{
label:'飞机模型',
value:1,
path:'模型路径'
}
]
defaultProps:{
children:"children",
label:"label",
value:"value"
}
// 模型路径
modelPath:null,
};
},
computed: {},
created() {},
mounted() {},
methods: {
// -----------------------<<地图>>----------------------
// 开始拖拽
handleDragStart(node, ev) {
this.modelPath = node.path
},
// 拖拽结束
drop(e) {
let toLeft = null, // cesium元素距离左边距离
toTop = null, // cesium元素距离顶部距离
x = null, // cesium元素屏幕坐标x轴位置
y = null; // cesium元素屏幕坐标y轴位置
// 获取cesium元素距离左边位置
toLeft = document.getElementById("mapBox").getBoundingClientRect().left;
// 获取cesium元素距离顶部位置
toTop = document.getElementById("mapBox").getBoundingClientRect().top;
// 计算地图屏幕坐标
// 计算cesium元素屏幕坐标x轴位置
x = e.clientX - toLeft;
// 计算cesium元素屏幕坐标y轴位置
y = e.clientY - toTop;
//创建模型
this.$refs.cesiumRef.addModel(this.modelPath, {x,y,});
},
// 是否允许拖拽
allowDrag(draggingNode) {
if (draggingNode.childNodes && draggingNode.childNodes.length !== 0) {
return false;
} else {
return true;
}
},
// 是否允许放置
allowDrop(draggingNode, dropNode, type) {
return false;
},
},
};
</script>
<style lang="less" scoped>
.map{
width:100%;
height:100vh;
.treeBox{
width:20%;
height:100%;
}
.mapBox{
widht:80%;
height:100%;
}
}
</style>
二、Cesium组件代码
<template>
<div id="cesiumContainer">
</div>
</template>
<script>
export default {
name: "Cesium",
components: {},
data() {
return {
// ----------------------<<地图>>----------------------
// cesium相机初始位置
ps: {
lon: 104.06,
lat: 30.67,
alt: 10000,
},
modelId:1,
};
},
mounted() {
this.initMap();
},
methods: {
// ---------------------<<地图>>---------------------
// 初始化地图
initMap() {
// 配置在线地图token
Cesium.Ion.defaultAccessToken = "map-Key"
//在线地图
imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
url: "在线地图地址",
});
window.viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false, //右上角搜索
homeButton: false, //右上角home
sceneModePicker: false, //右上角2D/3D切换
baseLayerPicker: false, //右上角地形
navigationHelpButton: false, //右上角帮助
animation: false, //左下角圆盘动画控件
timeline: true, //底部时间轴
fullscreenButton: false, //右下角全屏控件
vrButton: false, //如果设置为true,将创建VRButton小部件。
scene3DOnly: false, // 每个几何实例仅以3D渲染以节省GPU内存
infoBox: false, //隐藏点击要素后的提示信息
imageryProvider: imageryProvider, //地图地址
});
// 隐藏左下角商标信息
viewer._cesiumWidget._creditContainer.style.display = "none";
// 隐藏底部时间轴
viewer.timeline.container.style.display = "none";
viewer.scene.globe.depthTestAgainstTerrain = true; //开启深度检测
// 相机初始位置
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(
this.ps.lon,
this.ps.lat,
this.ps.alt
),
// 方向,俯视和仰视的视角
orientation: {
heading: Cesium.Math.toRadians(0), //坐标系旋转0度
pitch: Cesium.Math.toRadians(-90), //设置俯仰角度为-15度
},
});
},
addModel(path, ps) {
// 鼠标位置转换为二维笛卡尔坐标
const twoCoordinate = new Cesium.Cartesian2(ps.x, ps.y);
// 获取鼠标位置的对应椭球面位置
const wordCoordinate = viewer.scene.camera.pickEllipsoid(
twoCoordinate,
viewer.scene.globe.ellipsoid
);
// 笛卡尔坐标转弧度
let cartographic = Cesium.Cartographic.fromCartesian(
wordCoordinate,
viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
// Cesium.Math.toDegrees 将弧度转换成经纬度
let lng = Cesium.Math.toDegrees(cartographic.longitude);
let lat = Cesium.Math.toDegrees(cartographic.latitude);
let alt = 1000;
// 转换笛卡尔空间直角坐标
let position = new Cesium.Cartesian3.fromDegrees(lng, lat, alt);
//模型朝向
const heading = Cesium.Math.toRadians(0);
const pitch = 0;
const roll = 0;
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);
const entity = viewer.entities.add({
id:"plane" + this.modelId,
position: position, //模型位置,高度
orientation: orientation,
model: {
uri: path, //模型文件
minimumPixelSize: 100, //模型最小像素大小
maximumScale: 1000, //模型最大像素大小
},
});
// 同一场景modelId自增
this.modelId++;
// 定位到模型
// viewer.trackedEntity = entity;
},
},
};
</script>
<style lang="less" scoped>
#cesiumContainer {
width: 100%;
height: 100%;
position: relative;
}
</style>
123
三、Cesiun模型拖拽
已添加到地图的模型拖拽功能
// 注册鼠标事件-模型拖拽
setMouseEvent() {
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// *****注册鼠标左键按下事件*****
handler.setInputAction((event) => {
let pick = viewer.scene.pick(event.position);
// 如果点击空白区域
if (!Cesium.defined(pick)) {
return;
}
// 将相机锁定,不然后续移动实体时相机也会动
// 左键拖拽锁定视角
// viewer.scene.screenSpaceCameraController.enableRotate = false;
// 右键拖拽锁定视角
viewer.scene.screenSpaceCameraController.enableZoom = false;
//设置选中时的颜色
pick.id.model.color = Cesium.Color.fromAlpha(Cesium.Color.TOMATO, 0.5);
// *****注册鼠标移动事件*****
viewer.screenSpaceEventHandler.setInputAction((arg) => {
// arg有startPosition与endPosition两个属性,即移动前后的位置信息:Cartesian2对象
const position = arg.endPosition;
const cartesian = viewer.scene.globe.pick(
viewer.camera.getPickRay(position),
viewer.scene
);
//将Cartesian2转为Cartesian3
pick.id.position._value = cartesian;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// *****注册鼠标抬起事件*****
viewer.screenSpaceEventHandler.setInputAction(({ position }) => {
// 取消相机锁定
viewer.scene.screenSpaceCameraController.enableRotate = true;
pick.id.model.color = null; //设置颜色
// *****解除viewer的MOUSE_MOVE事件监听器*****
viewer.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.MOUSE_MOVE
);
// 解除相机锁定
viewer.scene.screenSpaceCameraController.enableZoom = true;
}, Cesium.ScreenSpaceEventType.RIGHT_UP);
}, Cesium.ScreenSpaceEventType.RIGHT_DOWN);
},