第一步正常建viewer,需要注意的是官網例子屬性值比較老,最新版本的屬性值有所差異,全copy官網會無法運行,提示函式未定義,
第一處差異
官網:
1 const viewer = new Cesium.Viewer("cesiumContainer", { 2 terrain: Cesium.Terrain.fromWorldTerrain({ 3 requestWaterMask: true, 4 requestVertexNormals: true, 5 }), 6 });
實際代碼:
const viewer = new Cesium.Viewer("cesiumContainer", { terrainProvider: Cesium.createWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }), });
Cesium.createWorldTerrain //為 Cesium World Terrain 創建一個 CesiumTerrainProvider 實體
第二處差異
官方{ text: "CesiumTerrainProvider - Cesium World Terrain", onselect: function () { viewer.scene.setTerrain( Cesium.Terrain.fromWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }) ); viewer.scene.globe.enableLighting = true; },
實際代碼
{ text: "CesiumTerrainProvider - Cesium World Terrain", onselect: function () { viewer.terrainProvider = Cesium.createWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }); viewer.scene.globe.enableLighting = true; }, },
后續幾個都是如此,直接替換
第三處代碼差異
官網代碼{ text: "VRTheWorldTerrainProvider", onselect: function () { viewer.scene.setTerrain( new Cesium.Terrain( Cesium.VRTheWorldTerrainProvider.fromUrl( "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", { credit: "Terrain data courtesy VT M?K", } ) ) ); },
實際代碼
{ text: "VRTheWorldTerrainProvider", onselect: function () { viewer.terrainProvider = Cesium.createWorldTerrain( Cesium.VRTheWorldTerrainProvider({ url: "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", credit: "Terrain data courtesy VT M?K", }) ); }, },
完整代碼
Cesium.Ion.defaultAccessToken = token; const viewer = new Cesium.Viewer("cesiumContainer", { terrainProvider: Cesium.createWorldTerrain({ //為 Cesium World Terrain 創建一個 CesiumTerrainProvider 實體 requestWaterMask: true, //指示客戶端是否應從服務器請求每個瓷磚水面具(如果可用), requestVertexNormals: true, //指示客戶端是否應從服務器請求額外的照明資訊(如果可用), }), }); viewer.scene.globe.enableLighting = true; //啟用使用場景光源照亮地球, const ellipsoidProvider = new Cesium.EllipsoidTerrainProvider(); //一個非常簡單的 TerrainProvider ,它通過對橢球面進行鑲嵌來生成幾何圖形, const customHeightmapWidth = 32; const customheightmapHeight = 32; const customHeightmapProvider = new Cesium.CustomHeightmapTerrainProvider( //從回呼函式獲取高度值的簡單 TerrainProvider , //它可以用于程式生成的地形或作為一種加載自定義高度圖資料的方式, //而無需創建 TerrainProvider 的子類, //有一些限制,例如沒有水面具、沒有頂點法線和沒有可用性, //所以一個成熟的 TerrainProvider 子類更適合這些更復雜的用例, { width: customHeightmapWidth, height: customheightmapHeight, callback: function (x, y, level) { const width = customHeightmapWidth; const height = customheightmapHeight; const buffer = new Float32Array(width * height); for (let yy = 0; yy < height; yy++) { for (let xx = 0; xx < width; xx++) { const u = (x + xx / (width - 1)) / Math.pow(2, level); const v = (y + yy / (height - 1)) / Math.pow(2, level); const heightValue = 4000 * (Math.sin(8000 * v) * 0.5 + 0.5); const index = yy * width + xx; buffer[index] = heightValue; } } return buffer; }, } ); Sandcastle.addToolbarMenu( [ { text: "CesiumTerrainProvider - Cesium World Terrain", onselect: function () { viewer.terrainProvider = Cesium.createWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }); viewer.scene.globe.enableLighting = true; }, }, { text: "CesiumTerrainProvider - Cesium World Terrain - no effects", onselect: function () { viewer.terrainProvider = new Cesium.createWorldTerrain(); }, }, { text: "CesiumTerrainProvider - Cesium World Terrain w/ Lighting", onselect: function () { viewer.terrainProvider = Cesium.createWorldTerrain({ requestVertexNormals: true, }); viewer.scene.globe.enableLighting = true; }, }, { text: "CesiumTerrainProvider - Cesium World Terrain w/ Water", onselect: function () { viewer.terrainProvider = Cesium.createWorldTerrain({ requestWaterMask: true, }); }, }, { text: "EllipsoidTerrainProvider", onselect: function () { viewer.terrainProvider = ellipsoidProvider; }, }, { text: "CustomHeightmapTerrainProvider", onselect: function () { viewer.terrainProvider = customHeightmapProvider; }, }, { text: "VRTheWorldTerrainProvider", onselect: function () { viewer.terrainProvider = Cesium.createWorldTerrain( Cesium.VRTheWorldTerrainProvider({ url: "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", credit: "Terrain data courtesy VT M?K", // 資料源的功勞,顯示在畫布上, }) ); }, }, { text: "ArcGISTerrainProvider", onselect: function () { viewer.terrainProvider = Cesium.createWorldTerrain( Cesium.ArcGISTiledElevationTerrainProvider({ url: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer", }) ); }, }, ], "terrainMenu" ); Sandcastle.addDefaultToolbarMenu( [ { text: "Mount Everest", onselect: function () { const target = new Cesium.Cartesian3( 300770.50872389384, 5634912.131394585, 2978152.2865545116 ); const offset = new Cesium.Cartesian3( 6344.974098678562, -793.3419798081741, 2499.9508860763162 ); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform( Cesium.Matrix4.IDENTITY //transform Matrix4 定義參考系的變換矩陣, ); //使用目標和變換矩陣設定相機位置和方向, //偏移量可以是笛卡爾坐標或航向/間距/范圍, //如果偏移量是笛卡爾坐標,則它是從由變換矩陣定義的參考系中心的偏移量, //如果偏移量是航向/俯仰/范圍,則航向和俯仰角在由變換矩陣定義的參考系中定義, //航向是從 y 軸到 x 軸增加的角度, //俯仰是從 xy 平面的旋轉,正俯仰角在平面下方, //負俯仰角在平面上方,范圍是到中心的距離, //在 2D 中,必須有自上而下的視圖,相機將放置在參考框架的中心上方, //目標上方的高度將是偏移量的大小,航向將根據偏移量確定, //如果無法根據偏移量確定航向,則航向將為北, }, }, { text: "Half Dome", onselect: function () { const target = new Cesium.Cartesian3( -2489625.0836225147, -4393941.44443024, 3882535.9454173897 ); const offset = new Cesium.Cartesian3( -6857.40902037546, 412.3284835694358, 2147.5545426812023 ); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }, }, { text: "San Francisco Bay", onselect: function () { const target = new Cesium.Cartesian3( -2708814.85583248, -4254159.450845907, 3891403.9457429945 ); const offset = new Cesium.Cartesian3( 70642.66030209465, -31661.517948317807, 35505.179997143336 ); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }, }, ], "zoomButtons" ); let terrainSamplePositions; function sampleTerrainSuccess(terrainSamplePositions) { const ellipsoid = Cesium.Ellipsoid.WGS84; //初始化為 WGS84 標準的 Ellipsoid 實體, viewer.scene.globe.depthTestAgainstTerrain = true; //如果廣告牌、折線、標簽等圖元應針對地形表面進行深度測驗,則為 true; //如果此類圖元應始侄訓制在地形頂部,除非它們位于地球的另一側,則為 false, //針對地形進行深度測驗圖元的缺點是, //輕微的數值噪聲或地形細節級別的切換有時會使應該在表面上的圖元在其下方消失, viewer.entities.suspendEvents(); //防止引發 EntityCollection#collectionChanged 事件, //直到對 EntityCollection#resumeEvents 進行相應的呼叫, //此時將引發涵蓋所有暫停操作的單個事件, //這允許有效地添加和洗掉許多專案, //只要有對 EntityCollection#resumeEvents 的相應呼叫,就可以安全地多次呼叫此函式, viewer.entities.removeAll(); // 從集合中移除所有物體, for (let i = 0; i < terrainSamplePositions.length; ++i) { const position = terrainSamplePositions[i]; viewer.entities.add({ name: position.height.toFixed(1), //toFixed 固定小數位 position: ellipsoid.cartographicToCartesian(position), //將提供的制圖轉換為笛卡爾表示, billboard: { //描述位于包含 Entity 位置的二維圖示, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //原點相對于物件的垂直位置,例如 Billboard 或 Label ,例如, //將垂直原點設定為 TOP 或 BOTTOM 將在錨點位置上方或下方(在螢屏空間中)顯示廣告牌 scale: 0.7, // 一個數字屬性,指定應用于影像大小的比例, image: "../../images/facility.gif", //一個屬性,指定用于廣告牌的影像、URI 或畫布, }, label: { //描述位于包含 Entity 位置的二維標簽 text: position.height.toFixed(1), // 指定文本的屬性,支持顯式換行符 '', font: "10pt monospace", horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //原點相對于物件的水平位置,例如 Billboard 或 Label , //例如,將水平原點設定為 LEFT 或 RIGHT 將在錨點位置的左側或右側(在螢屏空間中)顯示廣告牌, pixelOffset: new Cesium.Cartesian2(0, -14), // 指定像素偏移的 Cartesian2 屬性 fillColor: Cesium.Color.BLACK, //填充 outlineColor: Cesium.Color.BLACK, //輪廓 showBackground: true, //一個布爾屬性,指定標簽背后背景的可見性, backgroundColor: new Cesium.Color(0.9, 0.9, 0.9, 0.7), backgroundPadding: new Cesium.Cartesian2(4, 3), // 一個 Cartesian2 屬性,以像素為單位指定水平和垂直背景填充, }, }); } viewer.entities.resumeEvents(); //添加或洗掉專案時立即恢復引發 EntityCollection#collectionChanged 事件, //在事件掛起期間所做的任何修改都將在呼叫此函式時作為單個事件觸發, //此函式是參考計數的,只要有對 EntityCollection#resumeEvents 的相應呼叫,就可以安全地多次呼叫該函式, } function createGrid(rectangleHalfSize) { //矩形一半大小 const gridWidth = 41; const gridHeight = 41; const everestLatitude = Cesium.Math.toRadians(27.988257); //將度數轉換為弧度 const everestLongitude = Cesium.Math.toRadians(86.925145); //everest 最高 const e = new Cesium.Rectangle( everestLongitude - rectangleHalfSize, everestLatitude - rectangleHalfSize, everestLongitude + rectangleHalfSize, everestLatitude + rectangleHalfSize ); const terrainSamplePositions = []; for (let y = 0; y < gridHeight; ++y) { for (let x = 0; x < gridWidth; ++x) { const longitude = Cesium.Math.lerp( e.west, e.east, x / (gridWidth - 1) ); //計算兩個值的線性插值, const latitude = Cesium.Math.lerp( e.south, e.north, y / (gridHeight - 1) ); const position = new Cesium.Cartographic(longitude, latitude); //由經度、緯度和高度定義的位置, terrainSamplePositions.push(position); } } return terrainSamplePositions; } Sandcastle.addToggleButton( "Enable Lighting", viewer.scene.globe.enableLighting, function (checked) { viewer.scene.globe.enableLighting = checked; } ); Sandcastle.addToggleButton( "Enable fog", viewer.scene.fog.enabled, function (checked) { viewer.scene.fog.enabled = checked; } ); Sandcastle.addToolbarButton( "Sample Everest Terrain at Level 9", function () { const terrainSamplePositions = createGrid(0.005); Promise.resolve( Cesium.sampleTerrain( //通過向地形提供者請求切片、采樣和插值,啟動對 Cartographic 位置陣列的地形高度查詢, //插值匹配用于在指定級別渲染地形的三角形,查詢是異步發生的,所以這個函式回傳一個在查詢完成時解決的 Promise, //每個點的高度都在原地修改,如果由于該位置的指定級別沒有可用的地形資料而無法確定高度,或者發生其他錯誤,則將高度設定為未定義, //作為典型的 Cartographic 型別,提供的高度是參考橢球體上方的高度(例如 Ellipsoid.WGS84 ),而不是高于平均海平面的高度, //換句話說,如果在海洋中采樣,它不一定是 0.0,此函式需要地形細節級別作為輸入, //如果您需要盡可能精確地獲取地形高度(即最大細節級別),請使用 sampleTerrainMostDetailed , viewer.terrainProvider, 9, terrainSamplePositions //terrainProvider TerrainProvider 從中查詢高度的地形提供者, //level Number 用于查詢地形高度的地形細節層次, //positions Array.< Cartographic > 使用地形高度更新的位置, ) ).then(sampleTerrainSuccess); const target = new Cesium.Cartesian3( 300770.50872389384, 5634912.131394585, 2978152.2865545116 ); const offset = new Cesium.Cartesian3( 6344.974098678562, -793.3419798081741, 2499.9508860763162 ); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }, "sampleButtons" ); Sandcastle.addToolbarButton( "Sample Most Detailed Everest Terrain", function () { if (!Cesium.defined(viewer.terrainProvider.availability)) { window.alert( "sampleTerrainMostDetailed is not supported for the selected terrain provider" ); return; } const terrainSamplePositions = createGrid(0.0005); Promise.resolve( Cesium.sampleTerrainMostDetailed( viewer.terrainProvider, terrainSamplePositions ) //在地形資料集的最大可用切片級別啟動 sampleTerrain() 請求, ).then(sampleTerrainSuccess); const target = new Cesium.Cartesian3( 300770.50872389384, 5634912.131394585, 2978152.2865545116 ); const offset = new Cesium.Cartesian3( 6344.974098678562, -793.3419798081741, 2499.9508860763162 ); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }, "sampleButtons" );
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/549441.html
標籤:GIS
