原理介绍:
1.监听鼠标单击事件,获取点击屏幕位置e.position,综合弹出框宽高,动态设置弹出框位置。
bubble.style.left = e.position.x-70+"px";
var divheight = bubble.offsetHeight;
var divy = e.position.y - divheight -50;
2.添加entity的描述时,绑定弹出框table
3.监听帧渲染结束事件,获取实时位置,动态改变弹出框 viewer.scene.postRender.addEventListener(function (e) {});
添加的_cartesian转屏幕坐标,实时改变
_pm_position_2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, _cartesian);
以下是代码:(基于supermap的demo改写的,加载数据路径可能不同)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>动态气泡</title>
<link href="../Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<link href="css/pretty.css" rel="stylesheet">
<script src="js/jquery.min.js"></script>
<script src="js/slider.js"></script>
<script src="js/config.js"></script>
<script type="text/javascript" src="js/require.min.js" data-main="js/main"></script>
</head>
<body>
<div id="cesiumContainer"></div>
<div id="bubble1" class="bubble" style="top:0;left:82%;display:block;width: 400px;visibility: hidden;"><!--class="bubble"-->
<div id="tools" style="text-align : right">
<span style="color: rgb(95, 74, 121);padding: 5px;position: absolute;left: 10px;top: 4px;">对象属性</span>
<span class="fui-export" id="bubblePosition" style="color: darkgrey; padding:5px" title="停靠"></span>
<span class="fui-cross" title="关闭" id="close" style="color: darkgrey;padding:5px"></span>
</div>
<div style="overflow-y:scroll;height:190px" id="tableContainer"><table id="tab">test</table></div>
</div>
<script>
/**
* 动态添加气泡窗口
*/
function onload(Cesium) {
var viewer = new Cesium.Viewer('cesiumContainer', {
//infoBox: false, //点击要素之后显示的信息,默认true
});
var scene = viewer.scene;
var globe = viewer.scene.globe;
viewer.scene.undergroundMode = true; //设置开启地下场景
viewer.scene.screenSpaceCameraController.minimumZoomDistance = -1000;//设置相机最小缩放距离,距离地表-1000米
viewer.scene.terrainProvider.isCreateSkirt = false; // 关闭裙边
viewer._cesiumWidget._creditContainer.style.display = "none";//隐藏logo
//加载本地osgb数据
var promise_underground = scene.open('http://www.supermapol.com/realspace/services/3D-pipe/rest/realspace');
//promise.then方式加载数据
promise_underground.then(function (layers) {
//var overGroundLayer = scene.layers.find('Config');//
});
/***加载二维地图
*/
viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({
url: 'https://dev.virtualearth.net',
mapStyle: Cesium.BingMapsStyle.AERIAL,
key: URL_CONFIG.BING_MAP_KEY
}));
//设置相机视角
scene.camera.setView({
//destination: new Cesium.Cartesian3(-2654051.707084536, 3570921.9596162816, 4570167.290651748),
destination: new Cesium.Cartesian3.fromDegrees(126.62239531477519, 45.76877337892773, 100),
orientation: {
heading: 6.255714027185674,
pitch: -0.3054587954655701,
roll: 6.283090080629748
}
});
//添加三维气泡点
viewer.entities.add({
id: 'point1',
position: Cesium.Cartesian3.fromDegrees(126.62286665737508, 45.768049657165975, 10 + 0.5),
billboard: {
image: 'images/location4.png',
width: 30,
height: 40,
},
description: "chufa\ndata:this is data.",
label: {
//text: "llll11",
//backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8)
}
});
/*
气泡
*/
var table = document.getElementById("tableContainer");
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
var _position, _pm_position, _cartesian;
var camera = viewer.scene.camera;
handler.setInputAction(function (e) {
//viewer.infoBox = infoboxContainer;
$("#bubble1").show();
viewer.entities.removeAll();
var position = scene.pickPosition(e.position); //单击位置
var positionObj = scene.pick(e.position);//选中的对象
//将笛卡尔坐标转化为经纬度坐标
var cartographic = Cesium.Cartographic.fromCartesian(position);
var longitude = Cesium.Math.toDegrees(cartographic.longitude);
var latitude = Cesium.Math.toDegrees(cartographic.latitude);
var height = cartographic.height;
var cartesian = scene.globe.pick(camera.getPickRay(e.position), scene);
var cartographic = scene.globe.ellipsoid.cartesianToCartographic(cartesian);
var picks = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, cartesian);
var bubble = document.getElementById("bubble1");
//设置弹出框位置
bubble.style.left = e.position.x-70+"px";
var divheight = bubble.offsetHeight;
var divy = e.position.y - divheight -50;//50px为.bubble:after--20x50
bubble.style.top = divy + "px";
bubble.style.visibility = "visible"; //visibility: "hidden"
_position = e.position;
_cartesian = cartesian;
_pm_position = { x: picks.x, y: picks.y }
//viewer.selectedEntity = entity;
//在点击位置添加对应点
viewer.entities.add(new Cesium.Entity({
name: "位置信息",
billboard: {
image: 'images/location4.png',
width: 30,
height: 40,
},
position: Cesium.Cartesian3.fromDegrees(longitude, latitude, height + 0.5),
description: createDescription(Cesium, table, [longitude, latitude, height])
}));
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
$("#close").click(function () {
$("#bubble1").hide();
});
//创建描述位置的对话框
function createDescription(Cesium,table, properties) {
var simpleStyleIdentifiers = ['经度', '纬度', '高度'];
var html = '';
for (var key in properties) {
if (properties.hasOwnProperty(key)) {
if (simpleStyleIdentifiers.indexOf(key) !== -1) {
continue;
}
var value = properties[key];
if (Cesium.defined(value) && value !== '') {
html += '<tr><td>' + simpleStyleIdentifiers[key] + '</td><td>' + value + '</td></tr>';
}
}
}
if (html.length > 0) {
html = '<table class="zebra"><tbody>' + html + '</tbody></table>';
}
table.innerHTML = html;
}
/***
* 弹出框随漫游移动
*/
var _pm_position_2;
//每帧渲染结束监听
viewer.scene.postRender.addEventListener(function (e) {
if (_pm_position != _pm_position_2) {
_pm_position_2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, _cartesian);
var popw = document.getElementById("bubble1").offsetWidth;
var poph = document.getElementById("bubble1").offsetHeight;
var trackPopUpContent_ = window.document.getElementById("bubble1");
//trackPopUpContent_.style.visibility = "visible";
trackPopUpContent_.style.left = _pm_position_2.x-70+"px";
trackPopUpContent_.style.top = _pm_position_2.y - (poph + 50) + "px";
}
});
}
</script>
</body>
</html>