三維地球Cesium.js的研究

好久沒寫東西了,剛剛前段時間有個業務需求是要用到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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章