# 点位显示
export default {
...
mounted () {
this.init()
this.loadPoints()
},
// Vue方法定义
methods: {
// 地图初始化
init() {
...
},
// 模拟点位数据
loadPoints() {
// 用模拟数据测试
this.pointInfo = [
{
id: '392f7fbb-ae25-4eef-ac43-58fd91148d1f',
latitude: '31.87532',
longitude: '120.55538',
psName: '有限公司1',
},
{
id: '0278a88c-b4f4-4d64-9ccb-65831b3fb19d',
latitude: '31.991057',
longitude: '120.700713',
psName: '有限公司2',
},
{
id: '248f6853-2ced-4aa6-b679-ea6422a5f3ac',
latitude: '31.94181',
longitude: '120.51517',
psName: '有限公司3',
},
{
id: 'F8DADA95-A438-49E1-B263-63AE3BD7DAC4',
latitude: '31.97416',
longitude: '120.56132',
psName: '有限公司4',
},
{
id: '9402a911-78c5-466a-9162-d5b04d0e48f0',
latitude: '31.91604',
longitude: '120.57771',
psName: '有限公司5',
},
{
id: 'EB392DD3-6998-437F-8DCB-F805AD4DB340',
latitude: '31.88727',
longitude: '120.48887',
psName: '有限公司6',
},
]
this.addMarker()
},
// cesium 加载点位
addMarker() {
const Cesium = this.cesium
// 清除上一次加载的点位
this.viewer.entities.removeAll()
// foreach循环加载点位
this.pointInfo.forEach((pointObj) => {
this.viewer.entities.add({
name: pointObj.psName,
code: pointObj.id,
id: pointObj.id,
position: Cesium.Cartesian3.fromDegrees(pointObj.longitude * 1, pointObj.latitude * 1),
// 点
// point: {
// pixelSize: 5,
// color: Cesium.Color.RED,
// outlineColor: Cesium.Color.WHITE,
// outlineWidth: 2,
// },
// 文字标签
label: {
// show: false,
text: pointObj.psName,
font: "12px monospace",
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
fillColor: Cesium.Color.fromCssColorString("rgb(11, 255, 244)"),
outlineWidth: 4,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直方向以底部来计算标签的位置
pixelOffset: new Cesium.Cartesian2(0, -20), // 偏移量
},
// 图标
billboard: {
image: require("@/assets/logo.png"),
width: 18,
height: 24,
},
})
})
},
}
}
这里用到啦API中的viewer (opens new window)中entities.removeAll() (opens new window)和entities.add() (opens new window)
# 点击坐标弹框显示
引入弹框组件
// 地图组件
<template>
<div class="map-box">
<div id="cesiumContainer"></div>
<!-- 地图弹框 -->
<div class="dynamic-layer" id="one">
<div class="line"></div>
<div class="main">
<cesiumPopup :pointInfo="popData" ref="popUp" />
<!-- 下方箭头 -->
<div class="tooltip-arrow"></div>
</div>
</div>
</div>
</template>
// 弹框组件
<template>
<div>
我是弹框
</div>
</template>
<script>
export default {
name: '',
props:['pointInfo'],
// Vue方法定义
methods: {
defalutSetting() {},
}
}
</script>
用到啦jQuery 需要
npm i jQuery
安装挂载到main.js中
import $ from 'jquery';
Vue.prototype.$ = $;
给地图绑定点击事件,使弹框元素出现
init(){
...
// 给全图绑定事件
const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
handler.setInputAction((click)=>{
// 屏幕坐标 转 世界坐标
const cartesian = this.viewer.camera.pickEllipsoid(click.position,this.viewer.scene.globe.ellipsoid)
// 世界坐标 转 地理坐标
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
// 保留5位数以十进制方式显示
const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5)
const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5)
console.log("🚀 ~ file: No01-init.vue ~ line 76 ~ handler.setInputAction ~ lat lon",lon,lat)
// 获取地图上的点位实体(entity)坐标
const pick = this.viewer.scene.pick(click.position);
console.log("🚀 ~ file: No01-init.vue ~ line 92 ~ handler.setInputAction ~ pick", pick)
// 如果pick不是undefined 那么他就是点位
if(pick&&pick.id){
const data = {
layerId: "layer1", // 英文,且唯一,内部entity会用得到
lon: lon,
lat: lat,
element: "#one", // 弹框的唯一id
boxHeightMax: 0, // 中间立方体的最大高度
};
this.$("#one").css("z-index", 9990);
this.showDynamicLayer(this.viewer, data, () => { // 回调函数 改变弹窗的内容;
this.popData.title = pick.id.name;
this.popData.pointId = pick.id.id;
});
// 调用弹框的默认方法
this.$refs.popUp.defalutSetting();
// 点位地图定位
this.locationToCenter(lon, lat);
} else {
// 移除弹框
if (document.querySelector("#one")) {
this.removeDynamicLayer(this.viewer, { element: "#one" });
this.$("#one").css("z-index", -1);
}
}
},Cesium.ScreenSpaceEventType.LEFT_CLICK) //函数方法 单击
},
// 创建一个动态实体弹窗
showDynamicLayer(viewer, data, callback) {
/* 弹窗的dom操作--默认必须*/
this.$(data.element).css({ opacity: 0 }); // 使用hide()或者display是不行的 因为cesium是用pre定时重绘的div导致 left top display 会一直重绘
this.$(".dynamic-layer .line").css({ width: 0 });
this.$(data.element).find(".main").hide(0);
/* 弹窗的dom操作--针对性操作*/
callback();
// 添加div弹窗
const lon = data.lon * 1, lat = data.lat * 1;
// data.boxHeightMax为undef也没事
var divPosition = this.cesium.Cartesian3.fromDegrees(lon, lat, data.boxHeightMax);
this.$("#one").css({ opacity: 1 });
this.$("#one").find(".line").animate({
width: 50 // 线的宽度
}, 500, () => {
this.$("#one").find(".main").fadeIn(500);
});
// 当为true的时候,表示当element在地球背面会自动隐藏。默认为false,置为false,不会这样。但至少减轻判断计算压力
this.creatHtmlElement(viewer, data.element, divPosition, [10, -0], true);
},
// 创建一个 htmlElement元素 并且,其在earth背后会自动隐藏
creatHtmlElement(viewer, element, position, arr, flog) {
const Cesium = this.cesium;
var ele = document.querySelector(element);
var scratch = new Cesium.Cartesian2(); // cesium二维笛卡尔 笛卡尔二维坐标系就是我们熟知的而二维坐标系;三维也如此
var scene = viewer.scene, camera = viewer.camera;
scene.preRender.addEventListener(() => {
var canvasPosition = scene.cartesianToCanvasCoordinates(position, scratch); // cartesianToCanvasCoordinates 笛卡尔坐标(3维度)到画布坐标
if (Cesium.defined(canvasPosition)) {
ele.style.left = (canvasPosition.x + arr[0] - 534/2 - 15 + 5) + 'px';
ele.style.top = (canvasPosition.y + arr[1] - 30 - 22) + 'px';
/* 此处进行判断**/// var px_position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, cartesian)
if (flog && flog == true) {
var e = position, i = camera.position, n = scene.globe.ellipsoid.cartesianToCartographic(i).height
if (!(n += 1 * scene.globe.ellipsoid.maximumRadius, Cesium.Cartesian3.distance(i, e) > n)) {
// $(element).show()
ele.style.display = "block";
} else {
ele.style.display = "none";
// $(element).hide()
}
}
}
});
},
// 移除动态弹窗 为了方便 这里的移除 是真的移除,因此 到时是需要重建弹窗的doom的
removeDynamicLayer(viewer, data) {
document.querySelector(data.element).style.opacity = 0;
},
# 定位中心点在地图中间
init(){
...
// 给全图绑定事件
const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
handler.setInputAction((click)=>{
// 点位地图定位
this.locationToCenter(lon, lat);
},Cesium.ScreenSpaceEventType.LEFT_CLICK)
...
},
// 点位定位到地图中心
locationToCenter(lon, lat) {
const Cesium = this.cesium;
const pointLocation = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(lon * 1, lat * 1, 100), 15000); // 120.55538, 31.87532
this.viewer.camera.flyToBoundingSphere(pointLocation);
},