基于Cesium开源框架的3D展示(包含加载三维以及地图的一些基本操作)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
3D展示效果 geojson格式數據展示白駒過隙,時光如梭,又到一年年尾。回想一年的工作,感覺做了很多,又感覺什么都沒做成。so,在此回顧一下今年經歷過的那些個不一定有頭,不一定有尾的項目經歷。今天講講Cesium。
我是個隨性的人,想到哪里講到哪里,但是邏輯還是很清晰的,細節即是如此。
Cesium是一個很強大的3D框架,很多大公司的底層框架都基于此。so自己實踐做了一些實驗,對Cesium做了比較詳細的了解,并簡單實現了測面、測距、加載各種格式的數據(.geojson 3Dtile .kml .czml等格式)。廢話不多說,具體了解一下。
首先是Cesium開發包的引入,直接在Cesium的官網上下載就好了,然后新建的項目在項目的Apps里面存放即可。
頭部導入.js類
<!-- script部分 --><script src="../../../Build/Cesium/Cesium.js"></script>初始化Cesium界面
var viewer = new Cesium.Viewer('map_container', {animation: false,baseLayerPicker: false,geocoder: true,timeline: false,sceneModePicker: true,navigationHelpButton: false,infoBox: true,fullscreenButton:false,vrButton:true,homeButton:false,selectionIndicator : false,//是否顯示選取指示器組件});viewer._cesiumWidget._creditContainer.style.display = "none"; //去掉左下角那個不可愛的圖標// viewer.extend(Cesium.viewerCesiumInspectorMixin); //那些個特效viewer.camera.setView({destination:Cesium.Cartesian3.fromDegrees(111.07, 39.05, 20000000),orientation:{heading : Cesium.Math.toRadians(0),pitch : Cesium.Math.toRadians(-90),roll : Cesium.Math.toRadians(0) //heading、pitch和roll就是鏡頭相對于xyz軸的角度,比如pitch為-90°而另外兩個為0時,就是90°向下俯視地球。}});new操作的時候,后面{}里面的item都是可選的,改成true or false都可以,都是些特效類,玩膩了,除了必要的,都不要了,例如baselayerPicker底圖選擇器,里面包含多種數據源(google的啦,bingMap)
加載底圖(天地圖的,找了好久才找到)
var layerone = viewer.scene.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({url: "http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles",layer: "tdtImgBasicLayer",style: "default",format: "image/jpeg",tileMatrixSetID: "GoogleMapsCompatible",show: false}));//衛星影像 // layerone.alpha = 0.3; // layerone.brightness = 2.0;var layertwo = viewer.scene.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({url: "http://t0.tianditu.com/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles",layer: "tdtImgAnnoLayer",style: "default",format: "image/jpeg",tileMatrixSetID: "GoogleMapsCompatible",show: false}));//注記圖層加載數據,不具體去分開了,因為我自己代碼就是寫在一起的,來個大集合,.geojson、.KML、tileset.json(3Dtile數據)
3Dtile是什么格式?該知道的總會知道,Cesium加載3Dtile
var URL_MODEL = "/officalCesium/Apps/baseData/";$('#upLoadFile').change(function () {var file = $('#upLoadFile').get(0).files[0];var filename = file.name;var t = filename.lastIndexOf(".");var s = filename.substring(t+1,filename.length).toUpperCase();var dataType = document.getElementById("typeInput");var value = dataType.options[dataType.selectedIndex].value.toUpperCase();$('#addLayerModal').modal('hide'); //隱藏對話框if(s == value){if(value == "GEOJSON"){var filepath = URL_MODEL+filename;var geosonView = viewer.dataSources.add(Cesium.GeoJsonDataSource.load(filepath,{stroke: Cesium.Color.YELLOW, //設置為TRANSPARENT的時候,透明fill: Cesium.Color.YELLOW,strokeWidth: 5,markerSymbol: '?',}));viewer.flyTo(geosonView); // alert(filepath+"");}else if (value == "JSON" && filename.toUpperCase() == "TILESET.JSON"){var filepath = URL_MODEL+filename;var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({url: filepath, //數據路徑maximumScreenSpaceError: 2,//默認16,最大屏幕空間錯誤//maximumNumberOfLoadedTiles: 1000,maximumMemoryUsage:1024//默認512,內存MB的最大數量}));viewer.flyTo(tileset); // alert(filepath+"");}else if(value == "KML"){var filepath = URL_MODEL+filename;var kml_view = Cesium.KmlDataSource.load(filepath);viewer.flyTo(kml_view); // alert(filepath+"");}else if(value == "CZML"){var filepath = URL_MODEL+filename;var dataRecourse = new Cesium.CzmlDataSource(filepath);dataRecourse.load();viewer.dataSources.add(dataRecourse);viewer.flyTo(data_resouce);}}else {alert("上傳失敗,不是."+value+"類型的文件");}});飛行、復位等實用工具如下:
//飛行到某個點function dingwei(lon,lat,height){viewer.camera.flyTo({destination : Cesium.Cartesian3.fromDegrees(lon,lat,height), // 設置位置orientation: {heading : Cesium.Math.toRadians(20.0), // 方向pitch : Cesium.Math.toRadians(-90.0),// 傾斜角度roll : 0},duration:5, // 設置飛行持續時間,默認會根據距離來計算complete: function () {// 到達位置后執行的回調函數console.log('到達目的地');},cancle: function () {// 如果取消飛行則會調用此函數console.log('飛行取消')},pitchAdjustHeight: -90, // 如果攝像機飛越高于該值,則調整俯仰俯仰的俯仰角度,并將地球保持在視口中。maximumHeight:500, // 相機最大飛行高度flyOverLongitude: 100, // 如果到達目的地有2種方式,設置具體值后會強制選擇方向飛過這個經度});}//復位地圖function clearMap(){ // dingwei(115.446105254,22.771558650,2000);viewer.flyTo(tileset);clearAllPan();}//清空地圖function clearAll(){clearAllPan();}然后就是測距測面,測量分兩種吧,一直貼地的,一種是3D的那種,貼地量算沒問題,3D的我寫的代碼還是有問題。
//* 測距測面 */var scene = viewer.scene;var canvas = viewer.canvas;var clock = viewer.clock;var camera = viewer.scene.camera;//布爾型變量var isPoint = false;var isPolyline = false;var isPolygon_line = false;//是否開始繪制標識var isStartDraw = false;var isclear = false;var points = viewer.entities.add(new Cesium.Entity());var polylines = viewer.entities.add(new Cesium.Entity());var Polygons_Line = viewer.entities.add(new Cesium.Entity());//畫多邊形過程中展示的線最后要移除或者不顯示var Polygon_Lines_remove = viewer.entities.add(new Cesium.Entity());var ellipsoid = scene.globe.ellipsoid;canvas.onclick = function () {canvas.focus();};var handler = new Cesium.ScreenSpaceEventHandler(canvas);viewer.zoomTo(viewer.entities);defaultZoomAmount_ = 3000000.0;var lastPointLon = -999.0;var lastPointLat = -999.0;var firstPointLon = -999.0;var firstPointLat = -999.0;var measurePointsArray=new Array();measurePointsArray.splice(0,measurePointsArray.length);var endCartographic = new Cesium.Cartographic();var geodesic = new Cesium.EllipsoidGeodesic();var PolygonPointArray_line = null;var PolygonPointArray_fill = null;//鼠標移動時的那條線var moveLine_first = viewer.entities.add({id: "moveLine_first",name: 'line on the surface',polyline: {show: false,width: 2,material: Cesium.Color.WHITE}});var moveLine_second = viewer.entities.add({id: "moveLine_second",name: 'line on the surface',polyline: {show: false,width: 2,material: Cesium.Color.WHITE}});/* handler.setInputAction(function(){},Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);*///鼠標移動時做的操作handler.setInputAction(function (movement) {//捕獲橢球體,將笛卡爾二維平面坐標轉為橢球體的笛卡爾三維坐標,返回球體表面的點var cartesian=viewer.camera.pickEllipsoid(movement.endPosition, ellipsoid);if(cartesian) {//將笛卡爾三維坐標轉為地圖坐標(弧度)var cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);//將地圖坐標(弧度)轉為十進制的度數var lat_String = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4);var log_String = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4);var alti_String = (viewer.camera.positionCartographic.height / 1000).toFixed(2);longitude_show.innerHTML = log_String;latitude_show.innerHTML = lat_String;altitude_show.innerHTML = alti_String;}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);function clearAllPan() {viewer.entities.removeAll();isStartDraw = false;isclear = true;document.body.style.cursor = "pointer";document.getElementById("map_container").style.cursor = "pointer";handler.setInputAction(function(){},Cesium.ScreenSpaceEventType.LEFT_CLICK);}var QQ=0;function clearAllPan1(id) {if(id!=undefined){var tempmark = viewer.entities.getById(id);viewer.entities.remove(tempmark);}QQ=1;}//雙擊停止加線面function shuangji(){isPolyline = false;isPolygon_line = false;isPolygon_fill = false;isStartDraw = false;}//加點function addPoint() {isPoint = true;isPolyline = false;isPolygon_line = false;isPolygon_fill = false;isStartDraw = false;QQ=0;}//加線function measureLength() {var select_measure = document.getElementById("selOpt");var value_measure = select_measure.options[select_measure.selectedIndex].value;if(value_measure == 2){isPoint = false;isPolyline = true;isPolygon_line = false;isPolygon_fill = false;isStartDraw = false;QQ=0;document.body.style.cursor = "url(resource/pic/icons/magnifier3.cur) 12 12,crosshair";document.getElementById("map_container").style.cursor = "url(resource/pic/icons/magnifier3.cur) 12 12,crosshair";addOnClickListener();}}function addOnClickListener(){handler.setInputAction(function(){},Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);//鼠標移動時做的操作handler.setInputAction(function (movement) {if (isPolyline || isPolygon_line ) {var cartesian = viewer.camera.pickEllipsoid(movement.endPosition, scene.globe.ellipsoid);if (cartesian && isStartDraw) {//做清除工作把全局變量moveLine清除掉了 ,需要重新加到entities上 否則顯示不正常if (isclear) {viewer.entities.add(moveLine_first);viewer.entities.add(moveLine_second);isclear = false;}var cartographic = Cesium.Cartographic.fromCartesian(cartesian);var curMovementLon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(12);var curMovementLat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(12);viewer.entities.getById("moveLine_first").polyline.positions = Cesium.Cartesian3.fromDegreesArray([lastPointLon, lastPointLat ,curMovementLon,curMovementLat]);//修改屬性viewer.entities.getById("moveLine_first").polyline.show = true;if (PolygonPointArray_line != null) {if (PolygonPointArray_line.length >= 3) {viewer.entities.getById("moveLine_second").polyline.positions = Cesium.Cartesian3.fromDegreesArray([curMovementLon, curMovementLat, firstPointLon, firstPointLat]);//修改屬性viewer.entities.getById("moveLine_second").polyline.show = true;}}}}//捕獲橢球體,將笛卡爾二維平面坐標轉為橢球體的笛卡爾三維坐標,返回球體表面的點var cartesian=viewer.camera.pickEllipsoid(movement.endPosition, ellipsoid);if(cartesian){//將笛卡爾三維坐標轉為地圖坐標(弧度)var cartographic=viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);//將地圖坐標(弧度)轉為十進制的度數var lat_String=Cesium.Math.toDegrees(cartographic.latitude).toFixed(4);var log_String=Cesium.Math.toDegrees(cartographic.longitude).toFixed(4);var alti_String=(viewer.camera.positionCartographic.height/1000).toFixed(2);longitude_show.innerHTML=log_String;latitude_show.innerHTML=lat_String;altitude_show.innerHTML=alti_String;}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);//鼠標左擊做的操作handler.setInputAction(function (click) {if(QQ==1){var pickedObject = viewer.scene.pick(click.position);if (Cesium.defined(pickedObject) && (pickedObject.id != undefined)) {actEntity = pickedObject.id;clearAllPan1(actEntity._id);}}if (isPoint || isPolyline || isPolygon_line ) {var cartesian = viewer.camera.pickEllipsoid(click.position, scene.globe.ellipsoid);if (cartesian) {var cartographic = Cesium.Cartographic.fromCartesian(cartesian);var currentClickLon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(12);var currentClickLat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(12);/* var currentClickHeight = cartographic.height;console.log(currentClickHeight); */if (!isStartDraw) {viewer.entities.add({position: cartesian,point: {parent: points,pixelSize: 5,color: Cesium.Color.YELLOW}});firstPointLon = currentClickLon;firstPointLat = currentClickLat;PolygonPointArray_line = null;PolygonPointArray_fill = null;measurePointsArray.splice(0,measurePointsArray.length); // var startCartographic = Cesium.Cartographic.fromDegrees(firstPointLon, firstPointLat);measurePointsArray.push(cartographic);isStartDraw = true;} else {if (isPoint) {viewer.entities.add({position: cartesian,point: {parent: points,pixelSize: 5,color: Cesium.Color.YELLOW}});}if (isPolyline || isPolygon_line ){// endCartographic = Cesium.Cartographic.fromDegrees(currentClickLon, currentClickLat,currentClickHigh);endCartographic = Cesium.Cartographic.fromDegrees(currentClickLon, currentClickLat);console.log(endCartographic);measurePointsArray.push(endCartographic);var arrLength=measurePointsArray.length;var tmpDis=0;var sumDis=0;for(var i=1;i<arrLength;i++){geodesic.setEndPoints(measurePointsArray[i-1], measurePointsArray[i]);tmpDis=Math.round(geodesic.surfaceDistance);sumDis=sumDis+tmpDis;}if(sumDis>1000){var polylineDis= (sumDis / 1000).toFixed(1) + " km";}else{var polylineDis= sumDis + " m";}// console.log(dis);viewer.entities.add({parent: polylines,polyline: {// positions: Cesium.Cartesian3.fromDegreesArray([lastPointLon, lastPointLat,lastPointHigh, currentClickLon, currentClickLat,currentClickHigh]),positions: Cesium.Cartesian3.fromDegreesArray([lastPointLon, lastPointLat, currentClickLon, currentClickLat]),width: 2,material: Cesium.Color.RED},label: {text: polylineDis.toString(),font: '20px SimHei ',Width: 10,style: Cesium.LabelStyle.FILL_AND_OUTLINE,fillColor: Cesium.Color.YELLOW,outlineColor : Cesium.Color.GRAY,outlineWidth :5,horizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM},/* label : {// This callback updates the length to print each frame.text: polylineDis.toString(),font : '25px',pixelOffset : new Cesium.Cartesian2(1, 20)},*/ // position: Cesium.Cartesian3.fromDegrees(currentClickLon, currentClickLat,currentClickHigh)position: Cesium.Cartesian3.fromDegrees(currentClickLon, currentClickLat)});viewer.entities.getById("moveLine_first").polyline.show = false;viewer.entities.getById("moveLine_second").polyline.show = false;}}//記錄鼠標點擊的當前位置 作為下一次畫線的起始點位置lastPointLon = currentClickLon;lastPointLat = currentClickLat; // lastPointHigh = currentClickHigh;if (isPolygon_line) {if (PolygonPointArray_line == null)PolygonPointArray_line = new Array();PolygonPointArray_line.push(currentClickLon);PolygonPointArray_line.push(currentClickLat); // PolygonPointArray_line.push(currentClickHigh);}}}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);//鼠標雙擊時做的操作handler.setInputAction(function (click){if (isPolyline || isPolygon_line ){var cartesian = viewer.camera.pickEllipsoid(click.position, scene.globe.ellipsoid);if (cartesian && isStartDraw){var cartographic = Cesium.Cartographic.fromCartesian(cartesian);var endPointLon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(12);var endPointLat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(12);var endPointHigh = Cesium.Math.toDegrees(cartographic.height).toFixed(12);measurePointsArray.push(cartographic);var arrLength=measurePointsArray.length;var tmpDis=0;var sumDis=0;for(var i=1;i<arrLength;i++){geodesic.setEndPoints(measurePointsArray[i-1], measurePointsArray[i]);tmpDis=Math.round(geodesic.surfaceDistance);sumDis=sumDis+tmpDis;}//考慮多邊形最后顯示距離geodesic.setEndPoints(measurePointsArray[0], measurePointsArray[arrLength-1]);tmpDis=Math.round(geodesic.surfaceDistance);sumDis1=sumDis+tmpDis;if(sumDis>1000){var polylineDis= (sumDis / 1000).toFixed(1) + " km";var polygonDis = (sumDis1 / 1000).toFixed(1) + " km";}else{var polylineDis= (sumDis) + " m";var polygonDis = (sumDis1) + " m";}if (isPolyline || isPolygon_line ){//畫末線段viewer.entities.add({name: 'line on the surface',parent: polylines,polyline: {positions: Cesium.Cartesian3.fromDegreesArray([lastPointLon, lastPointLat, endPointLon, endPointLat]),width: 5,material: Cesium.Color.RED},label: {text: polylineDis.toString(),font: '20px SimHei ',Width: 10,style: Cesium.LabelStyle.FILL_AND_OUTLINE,fillColor: Cesium.Color.YELLOW,outlineColor : Cesium.Color.GRAY,outlineWidth :5,horizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM},/*label : {// This callback updates the length to print each frame.text: polylineDis.toString(),font : '25px',pixelOffset : new Cesium.Cartesian2(1, 20)},*/position: Cesium.Cartesian3.fromDegrees(endPointLon, endPointLat)});if ( isPolygon_line ){viewer.entities.add({name: 'line on the surface',parent: polylines,polyline: {positions: Cesium.Cartesian3.fromDegreesArray([endPointLon, endPointLat, firstPointLon, firstPointLat]),width: 5,material: Cesium.Color.RED}});viewer.entities.getById("moveLine_second").polyline.show = false;}viewer.entities.getById("moveLine_first").polyline.show = false;}//畫多邊形 不帶填充if (isPolygon_line){if (PolygonPointArray_line != null) {PolygonPointArray_line.push(endPointLon);PolygonPointArray_line.push(endPointLat);}//當多邊形數組中點的個數大于等于3時添加多邊形if (PolygonPointArray_line.length >= 3) {viewer.entities.add({name: 'polygon on surface',polygon: {hierarchy: Cesium.Cartesian3.fromDegreesArray(PolygonPointArray_line),material: Cesium.Color.RED,fill: false, //不顯示填充outline: true,outlineWidth: 5.0,outlineColor: Cesium.Color.RED},label: {text: polygonDis.toString(),font: '20px SimHei ',Width: 10,style: Cesium.LabelStyle.FILL_AND_OUTLINE,fillColor: Cesium.Color.YELLOW,outlineColor : Cesium.Color.GRAY,outlineWidth :5,horizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM},/* label : {// This callback updates the length to print each frame.text: polygonDis.toString(),font : '25px',pixelOffset : new Cesium.Cartesian2(1, 1)},*/position: Cesium.Cartesian3.fromDegrees(firstPointLon, firstPointLat)});}PolygonPointArray_line = null;viewer.entities.getById("moveLine_first").polyline.show = false;viewer.entities.getById("moveLine_second").polyline.show = false;}isStartDraw = false;}}}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);}//加多邊形不帶填充function measureArea() {var select_measure = document.getElementById("selOpt");var value_measure = select_measure.options[select_measure.selectedIndex].value;if(value_measure == 2){isPoint = false;isPolyline = false;isPolygon_line = true;isPolygon_fill = false;isStartDraw = false;QQ=0;document.body.style.cursor = "url(resource/pic/icons/magnifier3.cur) 12 12,crosshair";document.getElementById("map_container").style.cursor = "url(resource/pic/icons/magnifier3.cur) 12 12,crosshair";addOnClickListener();}}唔,大概主要功能就是這些了。給自己備忘,代碼包我就不傳了,如果有問題或者想了解更多的童鞋可以私信或者微我 ^V^
GeoJson格式的國界線數據展示?
測量Life is like a box of chocolate,you never know what you're gonna get next.
?
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的基于Cesium开源框架的3D展示(包含加载三维以及地图的一些基本操作)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 决定系数 均方误差mse_误差分析计算公
- 下一篇: opencv-自定义色带产生类似jet的