import { Cesium } from '../../namespace'
import { transformCartesianToWGS84 } from '../utils/Coordinate'
import { cloneDeep } from '../utils/Generate'
import {
flyToPos,
flyToItem,
flyToDegree,
zoomToItem,
getScale,
viewExtend,
flyToExtent,
} from '../utils/Navigation'
import AroundPoint from './AroundPoint'
import Roaming from './Roaming'
/**
* 导航主类
* @class
*/
class Navigation {
/**
* 构造函数
* @param {Object} viewer 地图场景对象
*/
constructor(viewer) {
this._viewer = viewer
this._homeCamera = {
position: new Cesium.Cartesian3(
-2453733.1395831853,
10818816.243349865,
7649756.401418009
),
hpr: { heading: 6.283185307179586, pitch: -1.5691401107287417, roll: 0 },
}
this.Roaming = new Roaming(this._viewer)
}
/**
* 获取/设置初始视角
* @type {CameraStatus}
*/
get homeCamera() {
return this._homeCamera
}
set homeCamera(cameraStatus) {
this._homeCamera = cloneDeep(cameraStatus)
}
/**
* 当前相机状态
* @readonly
* @type {CameraStatus}
*/
get cameraStatus() {
const { position, heading, pitch, roll } = this._viewer.camera
const degrees = transformCartesianToWGS84(position)
return {
degrees,
position,
hpr: {
heading,
pitch,
roll,
},
}
}
/**
* 获取比例尺,页面1px的距离,单位m
* @readonly
* @type {Number}
*
*/
get scale() {
return getScale(this._viewer)
}
/**
* 获取地图四至,最小和最大经纬度
* @readonly
* @type {ViewExtent}
*/
get viewExtent() {
return viewExtend(this._viewer)
}
/**
* 跳转到初始视角,即homeCamera参数
* @param {Number} [time=2.0] -(可选)跳转时间,以秒为单位,默认2秒
*/
homeView(time) {
this.flyToPos(this._homeCamera, time || 2)
}
/**
* 跳转到指定四至
* @param {Array<Number>} extent 四至范围,格式:[west,south,east,north],单位经纬度
* @param {Number} [time=2.0] 跳转时间,单位s,默认2秒
* @param {Function} [callback=null] 回调函数,可以在其中写入跳转完成后执行方法
*/
flyToExtent(extent, time, callback) {
flyToExtent(this._viewer, extent, time, callback)
}
/**
* 跳转到指定视角
* @param {ViewStatus} viewStatus 待跳转视角对象
* @param {Number} [time=2.0] 跳转时间,单位秒(s),默认2秒
* @param {Boolean} [degree=false] 传参类型,欧拉角是否位经纬度。
* 若degree=false,则{@link ViewStatus}的position为笛卡尔坐标,欧拉角单位为弧度;
* 若degree=true,则{@link ViewStatus}的position为WGS84坐标,欧拉角单位为度
* @param {Function} [callback=null] 回调函数,可以在其中写入跳转完成后执行方法
*/
flyToPos(viewStatus, time, degree = false, callback) {
const { position, hpr } = viewStatus
const bool = typeof time === 'number'
flyToPos(this._viewer, position, hpr, bool ? time : 2, degree, callback)
}
/**
* 定位到指定视角,仅限笛卡尔坐标和弧度参数
* @param {ViewStatus} cameraStatus
*/
zoomToPos(cameraStatus) {
this.flyToPos(cameraStatus, 0)
}
/**
* 跳转到指定对象
* @param {Object} item - 待跳转对象,理论支持界面加载的所有对象
*/
flyToItem(item) {
flyToItem(this._viewer, item)
}
/**
* 定位到指定对象
* @param {Object} item - 待定位对象,理论支持界面加载的所有对象
*/
zoomToItem(item) {
zoomToItem(this._viewer, item)
}
/**
* 跳转到指定坐标
* @param {DegreePosZ} pos 待跳转坐标,WGS84坐标
* @param {Number} [time=2.0] 跳转时间,默认2秒
* @param {Function} [callback=null] 回调函数,可以在其中写入跳转完成后执行方法
*/
flyToDegree(pos, time, callback) {
const { x, y, z } = pos
const bool = typeof time === 'number'
flyToDegree(this._viewer, x, y, z, bool ? time : 2, callback)
}
/**
* 定位到指定坐标
* @param {DegreePosZ} pos 待跳转坐标,WGS84坐标
* @param {Function} [callback=null] 回调函数,可以在其中写入跳转完成后执行方法
*/
zoomToDegree(pos, callback) {
this.flyToDegree(pos, 0, callback)
}
/**
* 绕点旋转
* @param {DegreePosZ} pos - 位置点,WGS84坐标
* @param {Number} angle 观察角度,-90为垂直正视,建议值区间[-30,-40]
* @param {Number} amount 旋转360度所需要时间,单位:秒(s)
* @param {Number} distance 点距离相机距离,单位:米(m)
* @returns {AroundPoint} 绕点旋转对象
*/
aroundPoint(pos, angle, time, distance) {
const { x, y, z } = pos
let aroundPoint = new AroundPoint(
this._viewer,
Cesium.Cartesian3.fromDegrees(x, y, z),
angle,
time,
distance
)
return aroundPoint
}
}
export default Navigation