好久没写东西了,刚刚前段时间有个业务需求是要用到cesium,百度了很多文章,总算实现了想要的效果,先记录了一下,以备后用。
先上图:
如上图所示,就是需要实现的效果。
一、下载cesium
这一点就不多说了,这里给出下载链接:cesium。
二、关于ysc
ysc其实我也不太熟悉,但它却是是一个不错的东西,因为我需要的效果刚好在这里面有例子,只不过我改造了一下(其实就是加了点鼠标事件代码)。
ysc网站
三、开始
首先需要引入一些必要的js文件,如下
<script type="text/javascript" src="Build/Cesium/Cesium.js"></script>
<script type="text/javascript" src="ysc/ysc.js"></script>
<script type="text/javascript" src="echart/echarts.min.js"></script>
对了,这里用到了echarts,因为地图上的色块就是用echarts做的。
一些必要的样式:
<style type="text/css">
@import url(Build/Cesium/Widgets/widgets.css);
body{
position: relative;
}
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
}
#cesiumContainer,#bubble1{
position: absolute;
}
.bubble{
background-color: rgba(0,0,0,.3);
top:0;left:82%;
display:flex;
flex-direction: column;
width: auto;
padding: 10px;
visibility: hidden;
border-radius: 4px;
}
#tableContainer{
display:flex;
flex-direction: column;
height:auto
}
</style>
接下来就是“干货”了!
- cesium的基础配置
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzMWU5ZmI1Ny0wNTkwLTRmYjktYjdhMy03MWFhYTQ5ODgzYjgiLCJpZCI6MTI4MDYsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1NjE5Njc4ODZ9.zsl7Ko6RFIvpvphyPMcCzqlMbNOw4ipOXOfkFMKsKTw';
var data = [];//这里是需要展示数据,就不在这里给出了
var scene = viewer.scene;
//隐藏版本信息
viewer._cesiumWidget._creditContainer.style.display="none";
var promise = Cesium.GeoJsonDataSource.load('chongqing2.json');
promise.then(function(dataSource){
viewer.dataSources.add(dataSource);
var entities = dataSource.entities.values;
var colorHash = {};
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
var name = entity.name;
var color = colorHash[name];
if (!color) {
color = Cesium.Color.fromRandom({
alpha:0.5
});
colorHash[name] = color;
}
entity.polygon.material = color;
entity.polygon.outline = false;
entity.polygon.extrudedHeight = Math.random()*10000.0;
for (var j = 0; j < data.length; j++) {
if (name == data[j]['name']) {
entity.data = data[j];
}
}
}
});
option = {
title: {
text: '',
subtext: '',
left: 'center'
},
GLMap: {},
tooltip: {
trigger: 'item',
formatter : function(params) {
var result = '';
result += '<span style="font-size:16px;font-weight:bold;">'+ params.name +'</span><br/>';
result += '林业用地:' + params.data.land + "万公顷" + '<br/>';
result += '森林面积:' + params.data.area + "万公顷" + '<br/>';
result += '森林覆盖率:' + params.data.coverage + "%" + '<br/>';
result += '活力木蓄积:' + params.data.accumulate + "万立方米" + '<br/>';
result += '森林公园:' + params.data.park + "个" + '<br/>';
result += '自然保护区:' + params.data.reserve + "个";
return result;
}
},
series: [
{
name: '重庆市地图',
type: 'map',
mapType: '重庆', // 自定义扩展图表类型
itemStyle:{
normal:{borderColor: 'white',label:{show:false}},
emphasis:{label:{show:true}}
},
}
]
}
以上就是基础的一些设置。
关键代码在这里:
ysc.echartsCombineCesium(viewer,option);
上面的代码的作用就是将cesium和echarts结合起来。
下面是真正的应用,也就是鼠标移动到目标区域后,弹出一个信息框,就是刚开始的效果图。
我也不细说了,直接上代码
ysc.mouseMove(viewer,function(e,obj){
if (obj == undefined) {
$("#bubble1").hide();
viewer.entities.removeAll();
return;
}
$("#bubble1").show();
viewer.entities.removeAll();
var position = scene.pickPosition(e.endPosition); //单击位置
var positionObj = scene.pick(e.endPosition);//选中的对象
//将笛卡尔坐标转化为经纬度坐标
var cartographic = Cesium.Cartographic.fromCartesian(positionObj);
var longitude = Cesium.Math.toDegrees(cartographic.longitude);
var latitude = Cesium.Math.toDegrees(cartographic.latitude);
var height = cartographic.height;
//这一块就是信息框上展示的数据
var name = obj.id.data.name;
var land = obj.id.data.land;
var area = obj.id.data.area;
var coverage = obj.id.data.coverage;
var accumulate = obj.id.data.accumulate;
var park = obj.id.data.park;
var reserve = obj.id.data.reserve;
//这的大致作用是计算信息框的位置
var cartesian = scene.globe.pick(camera.getPickRay(e.endPosition), scene);
var cartographic = scene.globe.ellipsoid.cartesianToCartographic(cartesian);
var picks = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, cartesian);
var bubble = document.getElementById("bubble1");
//设置弹出框位置
bubble.style.left = e.endPosition.x-70+"px";
var divheight = bubble.offsetHeight;
var divy = e.endPosition.y - divheight -50;//50px为.bubble:after--20x50
bubble.style.top = divy + "px";
bubble.style.visibility = "visible"; //visibility: "hidden"
_position = e.endPosition;
_cartesian = cartesian;
_pm_position = { x: picks.x, y: picks.y }
//渲染处信息框
var en = viewer.entities.add(new Cesium.Entity({
id:obj.id._id,
name: "位置信息",
billboard: {
image: 'images/location4.png',
width: 30,
height: 40,
},
description: createDescription(Cesium, table,name, [land, area,coverage,accumulate,park,reserve])
}));
});
信息框出来后还要随着鼠标的移动跟着移动,代码如下:
/***
* 弹出框随漫游移动
*/
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";
}
});
viewer.flyTo(promise);
viewer.camera.setView({
destination : Cesium.Cartesian3.fromDegrees(117.16, 32.71, 15000000.0)
});
好了,记录到此算是结束了,写得不好,只怪当初语文没学好o(╥﹏╥)o