基于cesium的三维城市建筑可视化系统(shp数据导入cesium的三种可行方法)
基于cesium的三維城市建筑可視化系統
- 1,快速搭建一個cesium的平臺環境
- 2.數據的格式及轉化。
- kml格式應該這樣加載:
- 3dtiles
- 第三種文件格式geojson
畢業快半個月了,一直想要把這次畢設所用到的cesium相關的內容記錄下來,雖然可能以后也用不到了,但還是記錄一下吧。由于過的時間已經有點長了,我盡量寫。
簡單介紹一下這次的基礎和目的吧,我拿到了一個西安市的.shp格式的二維建筑輪廓文件,老師希望我開發一個可以進行三維展示的可視化系統,要有簡單的統計功能,我最后做出來的功能包括根據高度改變顏色,鼠標左鍵右鍵中鍵點擊事件,統計分析,詳細信息展示等。
由于本人之前沒有接觸過cesium,所以在這幾個月里踩了很多坑,中間一度進行不下去,最后還是磕磕絆絆的做了出來。希望這篇文章可以盡量幫助新手入門。先放一點成果展示:
以及本項目的github:https://github.com/dewjiguang/cesium.git
下面介紹本項目中的所學,希望能幫到您。
1,快速搭建一個cesium的平臺環境
https://www.cnblogs.com/mazhenyu/p/6494748.html
上述搭建出一個可以運行的cesium地球就算成功了,但是需要注意的是(本人在這里卡住了好久,有個大坑)就是要加一個token,相當于一個個人認證吧,這個可以在cesium的官網進行申請,
官網地址:https://cesium.com/ion/signin
官網有一個很方便的功能就是可以上傳它規定的數據,將其轉化為3dtiles格式(cesium自己規定的一種格式),然后每次加載數據的時候通過下圖這個code在線加載自己的數據:
當然,自己的數據必須要用自己的token才可以訪問自己的數據。
如果不是自己的數據的話就無所謂了,要是嫌麻煩不想注冊的話你也可以用我的token:
Cesium.Ion.defaultAccessToken=‘eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3YzQ1YjI0NC05Nzg3LTQxOTQtYTBlMi1hNGMyMjVhYTJlODMiLCJpZCI6ODYyMCwic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU1MjM5MDU1MX0.6YczoUSHFcXfCuL5EAM7WWpld4Q5op-Lsc9HDYX1DgE’;
把上述這段加到body標簽里就可以啦。
這是我踩的第一個坑,卡了我快半個月,后來加了某cesium交流群問了群里的大佬才知道。所以學習這種較為冷門的新知識的時候要找一個組織共同學習。
2.數據的格式及轉化。
這是我遇到的一個難點,cesium支持的格式有很多,不同的格式呀有不同的加載方式,
kml格式應該這樣加載:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <!-- Tell IE to use the latest, best version. --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Make the application on mobile take up the full browser screen and disable user scaling. --> <meta name="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>Hello World!</title> <script src="./Cesium/Cesium.js"></script> <style> @import url(./Cesium/Widgets/widgets.css);html, body, #cesiumContainer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden; } </style> <div id="toolbar"></div> </head> <body><div id="cesiumContainer"></div><script><!--Cesium.BingMapsApi.defaultKey ='AvzM4FgDkpuZwkwP9DPDUwq15NUTJxHNyyUHGSXiA9JwAtAinnlPS31PvwB3hcWh';-->Cesium.Ion.defaultAccessToken='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3YzQ1YjI0NC05Nzg3LTQxOTQtYTBlMi1hNGMyMjVhYTJlODMiLCJpZCI6ODYyMCwic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU1MjM5MDU1MX0.6YczoUSHFcXfCuL5EAM7WWpld4Q5op-Lsc9HDYX1DgE';<!--var promise = Cesium.KmlDataSource.load('data.kml');--><!--viewer.dataSources.add(Cesium.KmlDataSource.load('bikeRide.kml',options));-->var viewer = new Cesium.Viewer('cesiumContainer');var options = {camera : viewer.scene.camera,canvas : viewer.scene.canvas};Sandcastle.addToolbarMenu([{text : 'gx KML extensions - Bike Ride',onselect : function() {viewer.dataSources.add(Cesium.KmlDataSource.load('/bikeRide.kml', options)).then(function(dataSource){viewer.clock.shouldAnimate = false;var rider = dataSource.entities.getById('tour');viewer.flyTo(rider).then(function(){viewer.trackedEntity = rider;viewer.selectedEntity = viewer.trackedEntity;viewer.clock.multiplier = 30;viewer.clock.shouldAnimate = true;});});}}], 'toolbar');Sandcastle.reset = function() {viewer.dataSources.removeAll();viewer.clock.clockRange = Cesium.ClockRange.UNBOUNDED;viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;};viewer.zoomTo(viewer.entities);</script></body> </html>上面這個kml就是我通過googleearth轉化得到的,這里提一下,我的原始數據是.shp數據,我走了好幾條數據轉化路線,這里就是成功的一條,下面簡單介紹一下googleearth將.shp轉化為kml(kmz)
打開谷歌地球,文件–>導入–》格式選擇.shp–》選中文件–》否
在臨時位置這里將圖層選中,得到一個二維平面圖層
編輯–》樣式模板–》新建樣式模板
將數據的高程字段設為高度字段,我這里floor就代表高度了,可以試著調一下高度或者縮放比例,
編輯–》樣式模板–》現有模板–》選中剛才建的模板–》確定,確定后結果就是這樣的
然后點保存,得到kml(kmz)文件。
(這里簡單提一下:最開始我和老師時使用arcgis的toolbox工具導出kml,但那樣其實很麻煩,首先arcgis比較難裝(破解教程超級麻煩),其次有可能裝好了后沒有quick導出功能(為了這個功能我還專門去淘寶找人幫我遠程裝軟件,還是兩次,每次20塊啊),裝好后轉化的步驟也很麻煩(arcgis導出具體可以看這里:http://www.studiosmuts.com/ceed3/arcmap_gis-to-3d/) 綜合來說還是谷歌地球這條路方便一些,而且kml本就是googleearth定義的,用它來導出也更放心一點)
上述是kml格式數據的轉化與加載,下面再介紹一下3dtiles格式的轉化與應用:
3dtiles
shp轉化3dtiles使用一個工具,是cesium官方提供的,功能很強大,需要下載,軟件的名字叫做cesiumlab
這里請讀者自行搜索下載
打開軟件后選擇中間的這個建筑物矢量處理,按照提示操作就可以得到3dtiles格式啦,詳細步驟可以看這里:https://blog.csdn.net/dyxcome/article/details/86532597
這里再說一下,這個cesiumlab是真的強大,官方出品必屬精品,他同時支持好幾種格式的轉化,但我們這里就只用了這一種功能。
這里提供一個網站:https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=3D%20Tiles%20Feature%20Styling.html
里面是官方提供的cesium沙盒,可以在線修改,也可以把代碼拷到本地運行,只不過有的時候進去會發現里面的demo跑出來都是黑的,具體什么原因我也不太清楚,可能看人品吧。這里面的絕大多數的數據加載都是加載的3dtiles,但是他沒有直接寫文件路徑和文件名,而是寫了個代號,比如說這個:
這里的5741其實就是cesium提供的在線加載的某個建筑數據,我們上述所說的個人數據里的code也是用這種方式的,但是如果我們要加載自己的數據要怎么寫呢?這里是我遇到的另一個問題,困擾了我好久。
這里說一下3dtiles的文件格式,他大概是這個樣子的:
一個文件夾下有好多個子文件夾,一集一個.json文件,所以我們加載的時候直接加載這個json就可以了
第三種文件格式geojson
cesium同時也支持Geojson文件格式(注意區別于普通的json),這種格式的好處是只有一個json文件,文件的格式很清晰,符合json的鍵值對對應的特點,這里使用這個在線轉化器得到Geojson:
https://mapshaper.org/
以及一個加載Geojson格式的例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <!-- Tell IE to use the latest, best version. --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Make the application on mobile take up the full browser screen and disable user scaling. --> <meta name="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>Hello World!</title> <script src="./Cesium/Cesium.js"></script><script src="js/echarts.min.js"></script> <style> @import url(./Cesium/Widgets/widgets.css);html, body, #cesiumContainer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden; } </style> <div id="toolbar"></div> </head> <body><div id="cesiumContainer"><div id="main" style="width: 600px;height:400px;position:absolute;top:50px;z-index:2"></div></div><script>Cesium.Ion.defaultAccessToken='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3YzQ1YjI0NC05Nzg3LTQxOTQtYTBlMi1hNGMyMjVhYTJlODMiLCJpZCI6ODYyMCwic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU1MjM5MDU1MX0.6YczoUSHFcXfCuL5EAM7WWpld4Q5op-Lsc9HDYX1DgE';var viewer = new Cesium.Viewer('cesiumContainer');var layers = viewer.imageryLayers;Cesium.Math.setRandomNumberSeed(0);var floor0_5=0;var floor6_10=0;var floor11_15=0;var floor16_20=0;var floor21_100=0;var promise =Cesium.GeoJsonDataSource.load('data/data.json');promise.then(function (dataSource) {//這是一個回調函數,異步執行,所以里面的東西還沒執行呢,外面就打印了viewer.dataSources.add(dataSource);//下面這些刪掉后高度顏色會變// console.log(JSON.stringify(dataSource.entities.values));var entities =dataSource.entities.values;var colorHash = {};for (var i = 0; i < entities.length;i++) { var entity = entities[i];//alert(entity.properties.Id+"--"+entity.properties.Floor);var name = entity.name;//name是一個id號,但不是建筑的id,因為一共有1729個 var color = colorHash[entity.properties.Floor]; if (!color) {color =Cesium.Color.fromRandom({alpha: 1.0 }); //colorHash[name] = color; } entity.polygon.material = color; entity.polygon.outline = false;entity.polygon.extrudedHeight =entity.properties.Floor*3;if(entity.properties.Floor._value<=5)floor0_5++;else if(entity.properties.Floor._value<=10)floor6_10++;else if(entity.properties.Floor._value<=15)floor6_10++;else if(entity.properties.Floor._value<=20)floor11_15++;else if(entity.properties.Floor._value<=25)floor16_20++;else floor21_100++;//console.log(entity.properties.Floor._value+"---"+floor6_10);}//上面console.log("ddd:"+floor6_10);var myChart = echarts.init(document.getElementById('main'));// 指定圖表的配置項和數據var option1 = {title: {text: '樓層高度統計'},tooltip: {},legend: {data:['樓層高度']},xAxis: {data: ["0-5","6-10","11-15","16-20","21-25","26-以上"]},yAxis: {},series: [{name: '樓層高度',type: 'bar',data: [floor0_5, floor6_10, floor11_15, floor16_20, floor21_100]}]};myChart.setOption(option1);});viewer.flyTo(promise);</script></body> </html>以上就是我這次畢設中探索出的三條使用shp數據轉化成cesium可用的數據并加載的技術路線。
最后再提供一點在這個過程中我搜集的一些資料吧。
官方api文檔:https://cesiumjs.org/Cesium/Build/Documentation/
一個學習cesium結構的很好的例子:https://www.jianshu.com/p/24ffa692aac3
一個實用的數據可視化工具(還支持地球顯示哦):https://echarts.baidu.com/examples/#chart-type-globe
cesium官方制作的一個高大上的例子:https://cesiumjs.org/NewYork/index.html?view=-74.00137290241591%2C40.71073017289542%2C888.4132973771704%2C18.955130605047422%2C-21.424922167642954%2C0.06394177048716491
以及一點建議:
1.建議不要用命令行的node server.js來啟動程序,因為那個也就能運行個helloworld了,每次改還要用記事本來打開,開發的話還是放到開發平臺上才舒服,我這里用eclipse來寫的,服務器用的tomcat,而且不要用eclipse自帶的瀏覽器來看結果,而是復制鏈接到谷歌瀏覽器上來看。
2.這就是一個純前端的東西,一個html就能顯示結果,我的這個是一個html做底板,上面嵌了幾個html,互相傳參。
3.上面提供的那個沙盒非常有用,demo都是從上面拷的,根據需求略作改變變成自己的。
最后,放一張圖片,這是我某次實在是卡主做不下去了,一氣之下給cesium創始團隊發的求助信,還挺佩服當時的自己的,以此紀念這次畢設吧。
10.31更新:最近偶然間發現了個三維建筑的網站,試了下他們的demo,簡直是太強大了,不僅能看能展示,還能第一人稱在建筑內部瀏覽,wasd控制方向,跟打游戲一樣,驚了,demo網址在這里
總結
以上是生活随笔為你收集整理的基于cesium的三维城市建筑可视化系统(shp数据导入cesium的三种可行方法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java毕业设计教程源码分享——简易网盘
- 下一篇: c语言个人日记本系统的设计,c语言程序课