/* * @Author: 蘋果園dog * @Date: 2020-10-31 21:50:33 * @LastEditTime: 2020-11-05 23:06:14 * @LastEditors: Please set LastEditors * @Description: Cesium 的各種定位方法匯總,只列出項目中經常使用的,如果不夠靈活,可直接調用Cesium官方API,也很方便。 * Cesium的定位從效果上包含兩種:直接定位、飛行定位。在方法封裝上,本狗姑且將直接定位分類為zoomTo系列,飛行定位分類flyTo。 * 定位的對象上包括:坐標點、矩形范圍、entities、3dtiles、gltf、kml、geojson、影像、地形、geometry * Cesium的定位主要是使用Camera對象和Viewer對象,Viewer的定位zoomTo,flyTo等方法是較高級別的函數,可以定位到Entity、3dtiles、DataSource等添加到三維球上顯示的實體, * Viewer的定位方法內部都是調用Camera的相關定位方法,針對不同的定位對象,通過一些列計算得出傳入實體的合適定位范圍和攝像機視角,然后定位,使用起來很方便。 * Camera的flyTo、flyToBoundingSphere、lookat、setView等方法是較低級別函數,通過定位坐標和角度參數的傳入,精細化控制定位視角,靈活。 * @FilePath: \web\cesiumS\cesium\cesium\mytest\朝花夕拾\定位\cesiumLocateUtil.js */ var cesiumLocateUtil = { zoomTo: { }, flyTo: { /** * @description: 飛行定位到一個笛卡爾空間直角坐標點位置 * @param {Cartesian3} destination 目標點 Cartesian3 * @param {Number} heading 默認=0.0 偏航角 正北,由正北向東偏向為正 * @param {*} pitch =-90 俯仰角 垂直向下, ENU局部坐標系中XY平面的旋轉角度,平面下為負,上為正, * @param {*} range =0.0 距目標點距離 * @param {*} duration =3 持續時間 * @param {*} callBack =null 回調函數,定位完成后執行 */ flyToPoint: function (destination, heading = 0.0, pitch = -90, range = 0.0, duration = 3, callBack = null) { if (!viewer) { console.log('三維球未初始化!'); return; } if (!destination) { console.log('定位目標點不對!'); return; } var boundingSphere = new Cesium.BoundingSphere(destination, 0.0); viewer.camera.flyToBoundingSphere(boundingSphere, { duration: duration, maximumHeight: undefined, complete: function () { if (callBack) { callBack(); }else{ console.log('定位失敗!'); } }, cancel: function () { console.log('定位取消!'); }, offset: { heading: Cesium.Math.toRadians(heading), pitch: Cesium.Math.toRadians(pitch), range: range }, }); }, /** * @description: 飛行定位到一個矩形 * @param {Array.<Cartesian3>} cartesians 笛卡爾坐標數組 Array.<Cartesian3> * @param {Number} heading =0.0 偏航角 正北,由正北向東偏向為正 * @param {*} pitch =-90 俯仰角 =-90 ENU局部坐標系,XY平面的旋轉角度,平面下為負,上為正, * @param {*} scale =1.0 范圍縮放倍率 * @param {*} duration =3 持續時間 * @param {*} callBack =null 回調函數,定位完成后執行 * @return {*} */ flyToRectangle: function (cartesians, heading = 0.0, pitch = -90, scale = 1.0, duration = 3, callBack = null) { if (!viewer) { console.log('三維球未初始化!'); return; } if (!Array.isArray(cartesians)) { console.log('定位范圍不對!'); return; } if(scale<0.1){ scale=1.0; } var rec = Cesium.Rectangle.fromCartesianArray(cartesians); var boundingSphere = Cesium.BoundingSphere.fromRectangle3D(rec); boundingSphere.radius=boundingSphere.radius*scale; viewer.camera.flyToBoundingSphere(boundingSphere, { duration: duration, maximumHeight: undefined, complete: function () { if (callBack) { callBack(); }else{ console.log('定位失敗!'); } }, cancel: function () { console.log('定位取消!'); }, offset: { heading: Cesium.Math.toRadians(heading), pitch: Cesium.Math.toRadians(pitch), range: 0.0 } }); }, flyToEntity(entity,){ } } }
測試
<!-- * @Author: 蘋果園dog * @Date: 2020-10-31 21:48:16 * @LastEditTime: 2020-11-02 22:48:03 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: \web\cesiumS\cesium\cesium\mytest\朝花夕拾\定位\定位.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>朝花夕拾——定位</title> <script src="../../../Build/CesiumUnminified/Cesium.js"></script> <script src="../../cesiumCommon.js"></script> <script src="../../cesiumUtil.js"></script> <script src="../../jquery.min.js"></script> <script src="../../cesiumCoordUtil.js"></script> <script src="../../cesium3dTilesUtil.js"></script> <script src="./cesiumLocateUtil.js"></script> <style> @import url(../../../Build/CesiumUnminified/Widgets/widgets.css); html, body, #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } #trailer { position: absolute; bottom: 75px; right: 0; width: 320px; height: 180px; } #testtool { position: absolute; top: 75px; left: 100px; } button { margin-right: 30px; } </style> </head> <body> <div id="cesiumContainer" class="fullSize"></div> <div id="loadingOverlay"> <h1>Loading...</h1> </div> <div id="testtool" style="background: gray;"> <button onclick="flyToPoint()"> flyToPoint </button> <button onclick="flyToRectangle()"> flyToRectangle </button> </div> <script> var viewer = init3D("cesiumContainer"); var scene = viewer.scene; var center = Cesium.Cartesian3.fromDegrees(116, 39, 0); var center2 = Cesium.Cartesian3.fromDegrees(116.5, 39.3, 0); var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center); var referenceFramePrimitive = scene.primitives.add( new Cesium.DebugModelMatrixPrimitive({ modelMatrix: transform, length: 100000.0, }) ); function flyToPoint() { removeAll(); cesiumLocateUtil.flyTo.flyToPoint(center, 30, -45, 5000, 3, function () { alert('定位成功!'); }) } function flyToRectangle() { removeAll(); var redRectangle = viewer.entities.add({ name: "Red translucent rectangle", rectangle: { coordinates: Cesium.Rectangle.fromCartesianArray([center, center2]), material: Cesium.Color.RED.withAlpha(0.5), }, }); cesiumLocateUtil.flyTo.flyToRectangle([center, center2], 0, -45, 3, 2, function () { alert('定位成功!'); }) } function removeAll(){ viewer.entities.removeAll(); } </script> </body> </html>