/*
* @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>