cesium三維開發全過程記錄


以下是我以前學習cesium三維開發全過程記錄

環境准備

1.Supermap iServer9.1.2a win64 

2.基於supermap SuperMap_iClient3D_10i_for_WebGL_CN.zip

3.Supermap 10i 的iDesktop  supermap-idesktop-10.0.0-39781-win32-bin-zip-chs

官網下載好了。

注意許可問題,可以在線申請試用許可(下載兩個文件),三個月。iServer和iDesktop都需要,在bin的同級文件下有許可的文件夾,可以打開可執行文件進行許可導入(注意選擇許可文件類型)、更新。

 

iServer啟動停止在startup.bat  shutup.bat

idesktop三維場景不支持微軟的遠程桌面,遠程時會直接崩掉。問了客服,可以使用如anyDesk, TV這種互聯網遠程工作。

 

基於webgl三維展示主要考慮客戶端瀏覽器端的顯卡能力、顯存配置。客戶有一台老機器,顯示效果卡頓得慘不忍睹。 

iClient for WebGL的配置

iServer和desktop正常運行之后,解壓SuperMap_iClient3D_10i_for_WebGL_CN.zip所有文件到iServer的webapps目錄下,如

 

 

 

 

 

 

然后在瀏覽器中測試這個地址,正常顯示就可以了。

http://localhost:8090/WebGL/examples/examples.html#layer

這是自帶的示例。

http://localhost:8090/WebGL/Build/Documentation/index.html

這是自帶的api幫助

 

由於iclient for webgl 是基於cesium的封裝,所以這里很多API和cesium超級像,而且就是一致的,里面的使用方法也一樣。

所以本質上就是學習cesium開發。

Cesium開發的資源

Cesium官網,https://cesium.com/cesiumjs/,這里可以下載cesiumJs 1.64

由於超圖已經封裝好了,不必下載(不用iserver, 改用node.js就需要下載了)

Cesium中文網 http://cesium.xin/

躍焱邵隼 的個人示例:

https://www.wellyyss.cn/ysCesium/views/main.html

 

數據准備

1。地圖

二維:行政區,地籍區,子區、道路,河流,

三維:樓幢按高度拉伸

 

由於客戶希望實現科技感的效果,最終采用了夜景深色的方案

如阿里的

 

 

 

先是在desktop里拉抻幢數據,高度是采用層數*3的數值

桌面里新建工作空間,新建數據源,超圖支持建議我們使用udb文件類型的,而不是udbx,不明原因。

 

加載數據源,把准備好的shp文件全部導入進去。

轉換坐標。由於三維場景發布之后是經緯度坐標,而客戶提供的是2000投影坐標,生成二維的圖切片之后也是2000的,不能動態投影上去,所以制作二維底圖的時候要先做坐標轉換。沒有橢球體的變換,直接轉就可以

 

 

 

一個一個層轉換,轉存到另一個數據源里。

然后開始制圖。

 

建二維地圖,把區、路、河的數據拖進去,配色,制作成深色效果,如:

 

 

 

 

 切片。

地圖上右鍵就可以:

 

 

 

同樣,可以將切好的圖加載到地圖里。

數據源右鍵à加載文件型à找到切片目錄,加載.sci文件就可以

然后再添加到地圖中。

 

 

 

建三維球面場景(要用球面,不然二維的圖疊不上去)

先使用樓幢數據拉伸白模。

將zrz樓幢的數據拖到三維場景中,然后在三維地理設計菜單里規則建模里,拉伸

 

 

 

 

 

 

 生成白模之后可以在場景圖層中,菜單風格設置里調整顏色、透明度:

 

 

 

把二維的圖也疊加進來看看是不是重合

 

 

 

最后發布三維切片。

 

 

  

要選擇s3m的,其他可以默認。

 

發布地圖服務:

二維要選擇ugcv5瓦片,再選擇切片目錄的sci文件

 

 

 

 

 

  

使用這個層級的路徑就好:

  

三維

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2。圖片

如天空盒子

代碼

 

 

 

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="utf-8">
  5     <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  6     <meta name="viewport"
  7           content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
  8     <title>沿線飛行</title>
  9     <link href="../Build/Cesium/Widgets/widgets.css" rel="stylesheet">
 10     <link href="./css/bootstrap.min.css" rel="stylesheet">
 11     <link href="./css/pretty.css" rel="stylesheet">
 12     <script src="./js/jquery.min.js"></script>
 13     <script src="./js/bootstrap.min.js"></script>
 14     <script src="./js/bootstrap-select.min.js"></script>
 15     <script src="./js/config.js"></script>
 16     <script type="text/javascript" src="./js/require.min.js" data-main="js/main"></script>
 17     <style>
 18         #play {
 19             content: url(./images/play.png);
 20             height: 30px;
 21             padding: 5px;
 22         }
 23 
 24         #pause {
 25             content: url(./images/pause.png);
 26             height: 30px;
 27             padding: 5px;
 28         }
 29 
 30         #stop {
 31             content: url(./images/stop.png);
 32             height: 30px;
 33             padding: 5px;
 34         }
 35 
 36         .bootstrap-select {
 37             width: 150px;
 38         }
 39     </style>
 40 </head>
 41 <body>
 42 <div id="cesiumContainer"></div>
 43 
 44 <script>
 45 
 46     var flyManager;
 47     var regCenterArr = [[118.872007133102,32.5654461621505],[118.8721859694,32.5681986643736]];
 48     var currentSkyBox, defaultSkyBox, qingtianSkyBox, wanxiaSkyBox, lantianSkyBox;
 49 
 50     function onload(Cesium) {
 51         
 52         var viewer = new Cesium.Viewer('cesiumContainer');
 53         // var terrainProvider= new Cesium.CesiumTerrainProvider({
 54         //     url : 'http://localhost:8090/WebGL/terrain_tiles' 
 55         // });
 56         // var viewer = new Cesium.Viewer('cesiumContainer', {
 57         //     terrainProvider: terrainProvider
 58         // });
 59         // var viewer = new Cesium.Viewer('cesiumContainer');
 60 
 61         viewer.imageryLayers.addImageryProvider(new Cesium.SuperMapImageryProvider({
 62                 url:'http://localhost:8090/iserver/services/map-ugcv5-D21C/rest/maps/D21C'                
 63         }));
 64 
 65         var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
 66         handler.setInputAction(function (movement) {
 67             var pick = viewer.scene.pick(movement.position);
 68             if (Cesium.defined(pick)) {
 69                 console.log(pick);
 70             }
 71         }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
 72 
 73         var scene = viewer.scene;
 74         scene.globe.depthTestAgainstTerrain = false;
 75 
 76         var camera = scene.camera;
 77         //添加S3M圖層服務
 78         //var promise = scene.open('http://localhost:8090/iserver/services/3D-test2/rest/realspace');
 79         var promise = scene.open('http://localhost:8090/iserver/services/3D-LinearExtrudeResult_2-test1/rest/realspace');
 80         promise.then(function (layers) {
 81             camera.setView({
 82                 destination: Cesium.Cartesian3.fromDegrees(118.873391561571 ,32.5519730104681 , 800.0),
 83                 orientation: {
 84                     heading : Cesium.Math.toRadians(0.0),
 85                         pitch : Cesium.Math.toRadians(-23),
 86                         roll : 0
 87                 }
 88             });
 89 
 90 
 91             console.log(layers);
 92             //layers[1].setObjsColor(885, Cesium.Color.YELLOW);
 93 
 94 //設置不同顏色的,沒有作用。
 95             promise.style = new Cesium.Cesium3DTileStyle({
 96                 color: {
 97                     conditions: [
 98                         ['${zcs} >= 8', 'rgba(45, 0, 75, 0.5)'],
 99                         ['${zcs} >= 7', 'rgb(102, 71, 151)'],
100                         ['${zcs} >= 6', 'rgb(170, 162, 204)'],
101                         ['${zcs} >= 5', 'rgb(224, 226, 238)'],
102                         ['${zcs} >= 4', 'rgb(252, 230, 200)'],
103                         ['${zcs} >= 3', 'rgb(248, 176, 87)'],
104                         ['${zcs} >= 2', 'rgb(198, 106, 11)'],
105                         ['true', 'rgb(127, 59, 8)']
106                     ]
107                 }
108             });
109 
110             //天空盒子
111             qingtianSkyBox = new Cesium.SkyBox({
112                 nearGround: true,
113                 sources: {
114                     positiveX : './images/天空盒素材/晴天/Right.jpg',
115                     negativeX : './images/天空盒素材/晴天/Left.jpg',
116                     positiveY : './images/天空盒素材/晴天/Front.jpg',
117                     negativeY : './images/天空盒素材/晴天/Back.jpg',
118                     positiveZ : './images/天空盒素材/晴天/Up.jpg',
119                     negativeZ : './images/天空盒素材/晴天/Down.jpg'
120                 }
121             });
122             wanxiaSkyBox = new Cesium.SkyBox({
123                 nearGround: true,
124                 sources: {
125                     positiveX : './images/天空盒素材/晚霞/Right.jpg',
126                     negativeX : './images/天空盒素材/晚霞/Left.jpg',
127                     positiveY : './images/天空盒素材/晚霞/Front.jpg',
128                     negativeY : './images/天空盒素材/晚霞/Back.jpg',
129                     positiveZ : './images/天空盒素材/晚霞/Up.jpg',
130                     negativeZ : './images/天空盒素材/晚霞/Down.jpg'
131                 }
132             });
133             lantianSkyBox = new Cesium.SkyBox({
134                 nearGround: true,
135                 sources: {
136                     positiveX : './images/天空盒素材/藍天/Right.jpg',
137                     negativeX : './images/天空盒素材/藍天/Left.jpg',
138                     positiveY : './images/天空盒素材/藍天/Front.jpg',
139                     negativeY : './images/天空盒素材/藍天/Back.jpg',
140                     positiveZ : './images/天空盒素材/藍天/Up.jpg',
141                     negativeZ : './images/天空盒素材/藍天/Down.jpg'
142                 }
143             });
144 
145             // defaultSkyBox = viewer.scene.skyBox;
146             // //天空盒效果切換
147             // currentSkyBox = wanxiaSkyBox;
148             // scene.skyBox = currentSkyBox;
149             // scene.postRender.addEventListener(function() {
150             //     var cameraHeight = scene.camera.positionCartographic.height;
151             //     var toggleHeight = 23e4;
152             //     if(cameraHeight < toggleHeight && Cesium.defined(currentSkyBox)) {
153             //         scene.skyBox = currentSkyBox;
154             //         scene.skyAtmosphere.show = false;
155             //     } else {
156             //         scene.skyBox = defaultSkyBox;
157             //         scene.skyAtmosphere.show = true;
158             //     }
159             // });
160 
161    
162 
163             //加載飛行路線管理
164             var routes = new Cesium.RouteCollection(viewer.entities);
165             var fpfUrl = 'fly333.fpf';
166             routes.fromFile(fpfUrl);
167             var flyManager = new Cesium.FlyManager({
168                 scene: scene,
169                 routes: routes
170             });
171             //注冊站點到達事件
172             flyManager.stopArrived.addEventListener(function (routeStop) {
173                 routeStop.waitTime = 0; // 在每個站點處停留1s
174                 var route = flyManager.currentRoute;
175                 // var stop = route.get(index);  // flyManager.currentStopIndex = index;  // flyManager.viewToStop(stop);
176                 //console.log(routeStop._index);
177                 switch(routeStop._index){
178                     case 1:
179                         load_certs_bubbles();
180                         break;
181                     case 2:
182                         // var entity2 = viewer.entities.getById(885);
183                         // console.log(entity2);                        
184                         //entity2.model.color = Cesium.Color.YELLOW;//修改模型顏色
185 
186                         load_big_reg_bullitin({id:'pos1',lon:118.872007133102,lat:32.5654461621505,height:50,name:'南京市大光路不動產登記中心'});
187 
188                         viewer.entities.removeById('111');
189                         addCircleRipple(viewer,{ //默認只繪制兩個圓圈疊加 如遇繪制多個,請自行源碼內添加。
190                             id:"111",
191                             lon:118.872007133102,
192                             lat:32.5654461621505,
193                             height:0,
194                             maxR:150,
195                             minR:0,//最好為0
196                             deviationR:1,//差值 差值也大 速度越快
197                             eachInterval:1000,//兩個圈的時間間隔
198                             imageUrl:'./images/環狀掃描紋理2.png'
199                         });
200                         break;
201                     case 9:
202                         load_big_reg_bullitin({id:'pos1',lon:118.8721859694,lat:32.5681986643736,height:50,name:'華僑路不動產登記中心'});
203                         viewer.entities.removeById('211');
204                         addCircleRipple(viewer,{ 
205                             id:"211",
206                             lon:118.8721859694,
207                             lat:32.5681986643736,
208                             height:0,
209                             maxR:150,
210                             minR:0,
211                             deviationR:1,
212                             eachInterval:1000,
213                             imageUrl:'./images/環狀掃描紋理2.png'
214                         });
215                     break;
216                 }
217                 
218             });
219 
220             flyManager.readyPromise.then(function () { // 飛行路線就緒
221                 var currentRoute = flyManager.currentRoute;
222                 currentRoute.isLineVisible = false;
223                 currentRoute.isStopVisible = false;
224                 //播放飛行
225                 flyManager && flyManager.play();
226             });
227         });
228 
229 
230         var load_big_reg_bullitin  =function(data){
231             var entity_big = viewer.entities.add({
232                 position: Cesium.Cartesian3.fromDegrees(data.lon, data.lat, data.height),//118.872007133102 ,32.5654461621505,40),
233                 // billboard: {
234                 //     image: 'images/loading.gif',
235                 //     width: 12,
236                 //     height: 40,
237                 // },
238                 label : {
239                     text : data.name,//'南京市大光路不動產登記中心',
240                     font : '18pt 宋體',    //字體樣式
241                     fillColor:Cesium.Color.BLUE,        //字體顏色
242                     backgroundColor:Cesium.Color.WHITE,    //背景顏色
243                     showBackground:true,                //是否顯示背景顏色
244                     style: Cesium.LabelStyle.OUTLINE,        //label樣式
245                     outlineWidth : 2,                    
246                     verticalOrigin : Cesium.VerticalOrigin.CENTER,//垂直位置
247                     horizontalOrigin :Cesium.HorizontalOrigin.LEFT,//水平位置
248                     pixelOffset:new Cesium.Cartesian2(10,0)            //偏移
249                 }
250             });
251 
252             viewer.entities.add({
253                 name:"",
254                 polyline: {
255                     positions: Cesium.Cartesian3.fromDegreesArrayHeights([
256                         data.lon,data.lat,40,
257                         data.lon,data.lat, 50,]
258                     ),
259                     width: 4,
260                     material : new Cesium.PolylineGlowMaterialProperty({ //發光線
261                         glowPower : 0.1,
262                         color : Cesium.Color.WHITE
263                     })
264                 }
265             });
266             viewer.entities.add({
267                 position : Cesium.Cartesian3.fromDegrees(data.lon,data.lat,50),
268                 point : {
269                     pixelSize : 10,
270                     color : Cesium.Color.WHITE
271                 }
272             });
273 
274         };
275 
276         //隨機加載氣泡效果
277         var load_certs_bubbles = function(){
278             $.get('data2.json', function(Json){
279                 // console.log(Json.data);
280                 var arr = [];
281                 for(var i in Json.data){
282                     arr.push(Json.data[i]);
283                 }
284                 // console.log(arr.length);
285                 var j = 0;
286                 var interval =setInterval(function () {
287                     var id=(j+"x").toString();
288                     entity_label(arr[j].lon, arr[j].lat, 20,arr[j].JZWMC,id );
289                     j++
290                     if (j >= arr.length) {
291                         clearInterval(interval);
292                     }
293                 }, GetRandomNum(500, 1500));
294                 //remove
295                 var i=0;
296                 var interval2 =setInterval(function () {
297                     //console.log(i+"out");
298                     const labelEntity = viewer.entities.getById((i+"x").toString() );
299                     viewer.entities.remove(labelEntity);
300                     i++
301                     if (i >= arr.length) {
302                         clearInterval(interval2);
303                     }
304                 }, GetRandomNum(500, 4000));
305 
306             });
307 
308             var entity_label= function(lon,lat,height,jzwmc,value){
309                 var entity_label = viewer.entities.add({
310                     id: value,
311                     position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
312                     // point: {
313                     //     color: Cesium.Color.RED,    //點位顏色
314                     //     pixelSize: 0                //像素點大小
315                     // },
316                     billboard: {
317                         image: 'images/location4.png',
318                         width: 12,
319                         height: 14,
320                     },
321                     label: {
322                         text: jzwmc,
323                         font: '9pt Source Han Sans CN',    //字體樣式
324                         fillColor: Cesium.Color.BLACK ,        //字體顏色
325                         backgroundColor: Cesium.Color.ALICEBLUE,    //背景顏色
326                         showBackground: true,                //是否顯示背景顏色
327                         style: Cesium.LabelStyle.FILL,        //label樣式
328                         outlineWidth: 2,
329                         verticalOrigin: Cesium.VerticalOrigin.CENTER,//垂直位置
330                         horizontalOrigin: Cesium.HorizontalOrigin.LEFT,//水平位置
331                         pixelOffset: new Cesium.Cartesian2(10, 0)            //偏移
332                     }
333                 });
334 //                 //添加尾跡線
335 //                 var pos= regCenterArr[Math.round(Math.random()*(regCenterArr.length-1))];
336 //                 viewer.entities.add({
337 //                     description: 'trail-line',
338 //                     name: 'test',
339 //                     polyline: {
340 //                         width: 1, //positions: Cesium.Cartesian3.fromDegreesArray([118.872007133102 ,32.5654461621505, lon, lat]),
341 //                         positions: Cesium.Cartesian3.fromDegreesArray([pos[0] ,pos[1], lon, lat]),
342 //                         material: new Cesium.PolylineTrailMaterialProperty({ // 尾跡線材質
343 //                             color: Cesium.Color.fromCssColorString("rgba(118, 233, 241, 1.0)"),
344 //                             trailLength : 0.2,
345 //                             period : 5.0
346 //                         })
347 //                     }
348 //                 });
349             };
350             var GetRandomNum = function(Min,Max){  
351                 var Range = Max - Min;  
352                 var Rand = Math.random();  
353                 return(Min + Math.round(Rand * Range));  
354             }  
355         }
356 
357         /**
358         *兩個圓擴散紋理
359         * */
360         function addCircleRipple(viewer,data){
361             var r1=data.minR,r2=data.minR;
362 
363             function changeR1() { //這是callback,參數不能內傳
364                 r1=r1+data.deviationR;
365                 if(r1>=data.maxR){
366                     r1=data.minR;
367                 }
368                 return r1;
369             }
370             function changeR2() {
371                 r2=r2+data.deviationR;
372                 if(r2>=data.maxR){
373                     r2=data.minR;
374                 }
375                 return r2;
376             }
377             viewer.entities.add({
378                 id:data.id,
379                 name:"",
380                 position:Cesium.Cartesian3.fromDegrees(data.lon,data.lat,data.height),
381                 ellipse : {
382                     semiMinorAxis :new Cesium.CallbackProperty(changeR1,false),
383                     semiMajorAxis :new Cesium.CallbackProperty(changeR2,false),
384                     height:data.height,
385                     material:new Cesium.ImageMaterialProperty({
386                         image:data.imageUrl,
387                         repeat:new Cesium.Cartesian2(1.0, 1.0),
388                         transparent:true,
389                         color:new Cesium.CallbackProperty(function () {
390                         var alp=1-r1/data.maxR;
391                             return Cesium.Color.WHITE.withAlpha(alp)  //entity的顏色透明 並不影響材質,並且 entity也會透明哦
392                         },false)
393                     })
394                 }
395             });
396             setTimeout(function () {
397                 viewer.entities.add({
398                     name:"",
399                     position:Cesium.Cartesian3.fromDegrees(data.lon,data.lat,data.height),
400                     ellipse : {
401                         semiMinorAxis :new Cesium.CallbackProperty(changeR1,false),
402                         semiMajorAxis :new Cesium.CallbackProperty(changeR2,false),
403                         height:data.height,
404                         material:new Cesium.ImageMaterialProperty({
405                             image:data.imageUrl,
406                             repeat:new Cesium.Cartesian2(1.0, 1.0),
407                             transparent:true,
408                             color:new Cesium.CallbackProperty(function () {
409                                 var alp=1;
410                                 alp=1-r2/data.maxR;
411                                 return Cesium.Color.WHITE.withAlpha(alp)
412                             },false)
413                         })
414                     }
415                 });
416             },data.eachInterval)
417         }
418 
419     }
420 </script>
421 </body>
422 </html>
View Code

發布

再重新部署一套iServer就可以了。把寫好的html文件。Data.Json, fly飛行路線文件按原文件存放就可以了。

 http://localhost:8090/WebGL/examples/test1.html

 

 

 QQ 276605216

2019.12.18

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM