import EventBus from './eventBus'
|
|
import { Cartesian3, Terrain, Viewer } from 'cesium'
|
|
import getBaseConfig from '@/buildConfig/config'
|
|
const {
|
imageryProvider_stand,
|
imageryProvider_standZh,
|
|
imageryProvider_tdt_img_w,
|
imageryProvider_tdt_cia_w
|
} = getBaseConfig()
|
|
const env = import.meta.env.VITE_APP_ENV || 'default'
|
|
import { addBlueFilter } from './common'
|
import * as Cesium from 'cesium'
|
|
let smallMpaCenterDistance = null
|
let curCameraHpr = null
|
|
let proHandler = null
|
let proController = null
|
let proMoveFlag = null
|
|
let handler = null
|
/**
|
* 公共的Cesium (蓝色,2d)
|
*/
|
|
// 封装的不用管
|
let cn = {
|
ri: function () {
|
return a
|
},
|
|
LS: function () {
|
return o
|
},
|
|
jL: function () {
|
return n
|
},
|
}
|
function a (e) {
|
return null != e
|
}
|
function o (e, t) {
|
return a(e) ? e : t
|
}
|
|
function n (e, t = !1) {
|
let { longitude: i, latitude: a, height: o } = e
|
return Cesium.Cartesian3.fromDegrees(i, a, t ? 0 : o)
|
}
|
|
export class PublicCesium {
|
|
constructor(options) {
|
this.handlerEvents = { handler: null }
|
this.viewer = null
|
this.init(options)
|
}
|
|
init (options) {
|
const that = this
|
const { dom, flatMode = true, terrain = false, mapFilter = true, layers } = options
|
Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
|
// 西南东北,默认显示中国
|
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
|
const viewerOptions = {
|
infoBox: false, // 禁用沙箱,解决控制台报错
|
animation: false, // 左下角的动画仪表盘
|
baseLayerPicker: false, // 右上角的图层选择按钮
|
geocoder: false, // 搜索框
|
homeButton: false, // home按钮
|
sceneModePicker: false, // 模式切换按钮
|
timeline: false, // 底部的时间轴
|
navigationHelpButton: false, // 右上角的帮助按钮,
|
selectionIndicator: false, // 是否显示选择指示器
|
baseLayer: false,
|
fullscreenButton: false,
|
}
|
|
this.viewer = new Viewer(options.dom, viewerOptions)
|
|
this.viewer.imageryLayers.removeAll()
|
this.viewer._cesiumWidget._creditContainer.style.display = 'none'
|
|
handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
|
|
if (flatMode) {
|
this.viewer.scene.screenSpaceCameraController.enableTilt = false
|
}
|
|
if (terrain) {
|
try {
|
Cesium.CesiumTerrainProvider.fromUrl(`${import.meta.env.VITE_APP_TERRAIN_URL}`, {
|
requestVertexNormals: true, // 启用地形法线增强立体感
|
requestWaterMask: true, // 启用水体遮罩效果
|
}).then(terrainProvider => {
|
this.viewer.terrainProvider = terrainProvider
|
})
|
} catch (error) {
|
console.error('地形加载失败:', error)
|
}
|
}
|
|
if (layers) {
|
layers.forEach(item => {
|
this.viewer.imageryLayers.addImageryProvider(item)
|
})
|
} else {
|
if (env === 'jiangwu') {
|
this.tcLayer = this.viewer.imageryLayers.addImageryProvider(imageryProvider_tdt_img_w)
|
this.zjLayer = this.viewer.imageryLayers.addImageryProvider(imageryProvider_tdt_cia_w)
|
} else {
|
this.tcLayer = this.viewer.imageryLayers.addImageryProvider(imageryProvider_stand)
|
this.zjLayer = this.viewer.imageryLayers.addImageryProvider(imageryProvider_standZh)
|
}
|
}
|
|
// if (mapFilter) {
|
// ;[this.tcLayer, this.zjLayer].forEach(item => {
|
// item.brightness = 0.6 // 亮度(默认值)
|
// item.contrast = 1.8 // 对比度(负值降低对比度)
|
// item.hue = 1 // 色相(弧度值,3.0可能导致紫色)
|
// item.saturation = 0 // 增加饱和度强化蓝色
|
// item.gamma = 0.3 // 伽马校正(小于1.0使颜色更鲜艳)
|
// })
|
|
// const filterOptions = { bInvertColor: true, bFilterColor: true, filterColor: '#4e70a6' }
|
// // 添加蓝色滤镜
|
// addBlueFilter(filterOptions, this.viewer)
|
// }
|
|
this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000
|
}
|
getViewer () {
|
return this.viewer
|
}
|
|
viewerDestroy () {
|
smallMpaCenterDistance = null
|
|
this.viewer && this.viewer.destroy()
|
this.viewer = null
|
}
|
addRightClickEvent (sid, cb) {
|
if (this.rightClickHandler) this.removeRightClickEvent()
|
|
this.rightClickHandler = new Cesium.ScreenSpaceEventHandler(this.viewer?.scene.canvas)
|
|
this.rightClickHandler.setInputAction(click => {
|
const pick = this.viewer?.scene.pick(click.position)
|
cb(click, pick, this.viewer)
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
}
|
|
// 移除鼠标右键事件
|
removeRightClickEvent () {
|
if (!this.rightClickHandler) return
|
this.rightClickHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
this.rightClickHandler = null
|
}
|
|
// 鼠标点击事件
|
addLeftClickEvent (sid, cb, eventKey = 'handler') {
|
if (this.handlerEvents.handler) this.removeLeftClickEvent()
|
if (this.handlerEvents[eventKey]) this.removeLeftClickEvent(eventKey)
|
|
this.handlerEvents[eventKey] = new Cesium.ScreenSpaceEventHandler(this.viewer?.scene.canvas)
|
this.handlerEvents[eventKey].setInputAction(click => {
|
const pick = this.viewer?.scene.pick(click.position)
|
|
if (pick && pick.primitive && pick.primitive?.customParams?.type === '3DTileset') {
|
return cb(click, pick, this.viewer, this.handlerEvents[eventKey])
|
}
|
|
if (pick && pick.id && (pick.id._id === sid || pick.id._id.includes(sid))) {
|
cb(click, pick, this.viewer, this.handlerEvents[eventKey])
|
}
|
|
if (sid === null) {
|
cb(click, pick, this.viewer, this.handlerEvents[eventKey])
|
}
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
}
|
|
// 移除鼠标点击事件
|
removeLeftClickEvent (eventKey = 'handler') {
|
if (this.handlerEvents[eventKey] == null) return
|
this.handlerEvents[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
this.handlerEvents[eventKey] = null
|
}
|
|
pointInitEvent (left_down, mouse_move, left_up) {
|
if (!this.pointEditHandler) {
|
this.pointEditHandler = new Cesium.ScreenSpaceEventHandler(this.viewer?.scene.canvas)
|
}
|
|
const events = {
|
left_down,
|
mouse_move,
|
left_up,
|
}
|
|
this.pointEditBindEvent(events)
|
this.pointEditBindEvent(events, Cesium.KeyboardEventModifier.CTRL)
|
this.pointEditBindEvent(events, Cesium.KeyboardEventModifier.ALT)
|
this.pointEditBindEvent(events, Cesium.KeyboardEventModifier.SHIFT)
|
this.pointEditBindEvent(events, Cesium.KeyboardEventModifier.META)
|
}
|
|
pointEditBindEvent (events, e) {
|
if (this.pointEditHandler) {
|
this.pointEditHandler.setInputAction(events.left_down(e), Cesium.ScreenSpaceEventType.LEFT_DOWN, e)
|
this.pointEditHandler.setInputAction(events.mouse_move(e), Cesium.ScreenSpaceEventType.MOUSE_MOVE, e)
|
this.pointEditHandler.setInputAction(events.left_up(e), Cesium.ScreenSpaceEventType.LEFT_UP, e)
|
}
|
}
|
|
pointUnInitEvent () {
|
this.pointEditUnBindEvent()
|
this.pointEditUnBindEvent(Cesium.KeyboardEventModifier.CTRL)
|
this.pointEditUnBindEvent(Cesium.KeyboardEventModifier.ALT)
|
this.pointEditUnBindEvent(Cesium.KeyboardEventModifier.SHIFT)
|
this.pointEditUnBindEvent(Cesium.KeyboardEventModifier.META)
|
|
this.pointEditHandler = null
|
}
|
|
pointEditUnBindEvent (e) {
|
this.pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN, e)
|
this.pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE, e)
|
this.pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP, e)
|
}
|
|
setCameraMove (e) {
|
this.setCameraAttribute(e)
|
}
|
|
setCameraAttribute (e) {
|
let t = {}
|
, i = !1
|
|
if (e.attitude) {
|
let { fov: n } = e.attitude
|
|
if ((0, cn.ri)(n) && this.viewer?.camera) {
|
this.viewer.camera.frustum = new Cesium.PerspectiveFrustum({
|
fov: Cesium.Math.toRadians(n),
|
aspectRatio: this.viewer?.canvas.clientWidth / this.viewer?.canvas.clientHeight,
|
near: .1
|
})
|
}
|
}
|
i && this.viewer?.camera.setView(t)
|
}
|
|
setView (options) {
|
const position = Cesium.Cartesian3.fromDegrees(
|
Number(options.longitude),
|
Number(options.latitude),
|
Number(options.height || 0),
|
)
|
const heading = Number(options.heading || 0)
|
this.viewer?.camera?.setView({
|
destination: position,
|
orientation: {
|
heading: Cesium.Math.toRadians(heading >= 0 ? heading : heading + 360), // 水平旋转(偏航角)
|
pitch: Cesium.Math.toRadians(Number(options.pitch || 0)), // 俯仰角(-90°表示俯视地心)
|
roll: 0.0 // 翻转角
|
}
|
})
|
|
this.getCameraCurPositionDistance()
|
}
|
|
getCameraCurPositionDistance () {
|
if (!this.viewer) return
|
|
// 获取相机位置
|
const position = this.viewer?.camera.positionCartographic
|
const cameraLongitude = Cesium.Math.toDegrees(position.longitude)
|
const cameraLatitude = Cesium.Math.toDegrees(position.latitude)
|
const cameraHeight = position.height
|
|
// 获取地图区域中心点位置
|
let mapCenterPx = {
|
x: this.viewer?.canvas.clientWidth / 2,
|
y: this.viewer?.canvas.clientHeight / 2
|
}
|
|
let centerInfo = this.getMouseInfo(mapCenterPx)
|
|
if (centerInfo.wgs84SurfacePosition) {
|
const {
|
lng,
|
lat,
|
alt
|
} = centerInfo.wgs84SurfacePosition
|
|
// 计算相机到中心点的距离
|
const cameraPosition = Cesium.Cartesian3.fromDegrees(cameraLongitude, cameraLatitude, cameraHeight)
|
const centerPoint = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
const distance = Cesium.Cartesian3.distance(cameraPosition, centerPoint)
|
|
smallMpaCenterDistance = distance
|
EventBus.emit('setCameraCurPositionDistance', distance)
|
} else {
|
const cameraPosition = this.viewer?.camera.position
|
const farDistance = this.viewer?.camera.frustum.far // 获取相机的远裁剪面距离
|
const distance = farDistance - Cesium.Cartesian3.magnitude(cameraPosition)
|
smallMpaCenterDistance = distance
|
EventBus.emit('setCameraCurPositionDistance', '')
|
}
|
}
|
|
getMouseInfo (position) {
|
let scene = this.viewer?.scene
|
let surfaceCartesian = undefined
|
let wgs84SurfacePosition = undefined
|
|
if (
|
scene.mode === Cesium.SceneMode.SCENE3D &&
|
!(this.viewer?.terrainProvider instanceof Cesium.EllipsoidTerrainProvider)
|
) {
|
let ray = scene.camera.getPickRay(position)
|
surfaceCartesian = scene.globe.pick(ray, scene)
|
} else {
|
surfaceCartesian = scene.camera.pickEllipsoid(
|
position,
|
Cesium.Ellipsoid.WGS84,
|
)
|
}
|
|
if (surfaceCartesian) {
|
let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(surfaceCartesian)
|
if (c) {
|
wgs84SurfacePosition = {
|
lng: Cesium.Math.toDegrees(c.longitude),
|
lat: Cesium.Math.toDegrees(c.latitude),
|
alt: c.height,
|
}
|
}
|
}
|
|
return {
|
wgs84SurfacePosition: wgs84SurfacePosition,
|
}
|
}
|
|
// 左键按下事件
|
pro_left_down (e) {
|
proMoveFlag = !0
|
}
|
|
// 左键抬起事件
|
pro_left_up (e) {
|
proMoveFlag = !1
|
}
|
|
// 鹰眼鼠标移动事件
|
pro_mouse_move (e) {
|
if (proMoveFlag) {
|
this.look3D(e.startPosition, e.endPosition)
|
|
const position = this.viewer.camera.positionCartographic
|
const lng = Cesium.Math.toDegrees(position.longitude).toFixed(4)
|
const lat = Cesium.Math.toDegrees(position.latitude).toFixed(4)
|
const alt = (position.height / 1000).toFixed(2) // 转换为千米
|
|
// 获取方向
|
const heading = Cesium.Math.toDegrees(this.viewer.camera.heading).toFixed(2)
|
const pitch = Cesium.Math.toDegrees(this.viewer.camera.pitch).toFixed(2)
|
const roll = Cesium.Math.toDegrees(this.viewer.camera.roll).toFixed(2)
|
|
curCameraHpr = {
|
heading,
|
pitch,
|
roll
|
}
|
|
let newHeading = ((heading + 180) % 360) - 180
|
EventBus.emit('PointAirLine-setRoamPoint', {
|
pitch: pitch,
|
heading: newHeading >= 0 ? newHeading - 180 : newHeading + 180
|
})
|
|
this.getCameraCurPositionDistance()
|
}
|
}
|
|
// 鹰眼地图相关事件
|
bindEvent () {
|
this.bindProLeftDown = this.pro_left_down.bind(this)
|
this.bindProLeftUp = this.pro_left_up.bind(this)
|
this.bindProLeftMove = this.pro_mouse_move.bind(this)
|
|
proHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
|
|
proController = this.viewer.scene.screenSpaceCameraController
|
|
proController.enableRotate = !1
|
proController.enableTilt = !1
|
proController.enableZoom = !1
|
proController.enableLook = !1
|
proController.enableTranslate = !1
|
proMoveFlag = false
|
|
handler.setInputAction(this.bindProLeftDown, Cesium.ScreenSpaceEventType.LEFT_DOWN)
|
handler.setInputAction(this.bindProLeftUp, Cesium.ScreenSpaceEventType.LEFT_UP)
|
handler.setInputAction(this.bindProLeftMove, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
}
|
|
unBindEvent = () => {
|
if (proHandler) {
|
handler.removeInputAction(this.bindProLeftDown, Cesium.ScreenSpaceEventType.LEFT_DOWN)
|
handler.removeInputAction(this.bindProLeftUp, Cesium.ScreenSpaceEventType.LEFT_UP)
|
handler.removeInputAction(this.bindProLeftMove, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
proController = null
|
proHandler = null
|
}
|
}
|
|
look3D (e, t, i = !1) {
|
let r = this.viewer.camera
|
, a = this.viewer.scene.globe.ellipsoid
|
, s = i ? -1 : 2
|
, o = a.geodeticSurfaceNormal(r.position)
|
r.look(o, this.getLookAngle(e, t, "x") * s),
|
this.lookVertical(-this.getLookAngle(e, t, "y") * s, o)
|
}
|
|
getLookAngle (e, t, i) {
|
let r, a
|
let s = e[i]
|
, o = t[i]
|
, n = new Cesium.Cartesian2("x" === i ? s : 0, "y" === i ? s : 0)
|
, l = new Cesium.Cartesian2("x" === i ? o : 0, "y" === i ? o : 0)
|
, c = this.viewer.camera.getPickRay(n)
|
, h = this.viewer.camera.getPickRay(l)
|
if (!c || !h)
|
return 0
|
this.viewer.camera.frustum instanceof Cesium.OrthographicFrustum ? (r = c.origin,
|
a = h.origin,
|
Cesium.Cartesian3.add(this.viewer.camera.direction, r, r),
|
Cesium.Cartesian3.add(this.viewer.camera.direction, a, a),
|
Cesium.Cartesian3.subtract(r, this.viewer.camera.position, r),
|
Cesium.Cartesian3.subtract(a, this.viewer.camera.position, a),
|
Cesium.Cartesian3.normalize(r, r),
|
Cesium.Cartesian3.normalize(a, a)) : (r = c.direction,
|
a = h.direction)
|
let d = Cesium.Cartesian3.dot(r, a)
|
, p = 0
|
return d < 1 && (p = Math.acos(d)),
|
s > o ? -p : p
|
}
|
|
lookVertical (e, t) {
|
let i = this.viewer.camera
|
, r = this.judgeParallelAndRecalculateAngle(-e, i.direction, t)
|
r && i.look(i.right, r)
|
}
|
|
sg (e, t) {
|
return Cesium.Cartesian3.equalsEpsilon(e, t, Cesium.Math.EPSILON2) ? 1 : Cesium.Cartesian3.equalsEpsilon(e, Cesium.Cartesian3.negate(t, new Cesium.Cartesian3), Cesium.Math.EPSILON2) ? -1 : 0
|
}
|
|
judgeParallelAndRecalculateAngle (e, t, i) {
|
let r = this.sg(t, i)
|
, a = e
|
if (1 === r && a < 0)
|
a = 0
|
else if (-1 === r && a > 0)
|
a = 0
|
else if (0 === r) {
|
let e = Cesium.Cartesian3.dot(t, i)
|
, r = Cesium.Math.acosClamped(-e)
|
a > 0 && a > r && (a = r - Cesium.Math.EPSILON4),
|
r = Cesium.Math.acosClamped(e),
|
a < 0 && -a > r && (a = -r + Cesium.Math.EPSILON4)
|
}
|
return a
|
}
|
|
// 添加entity
|
addCustomImageryProviderDataSource (imageryLayers) {
|
console.log(imageryLayers, this.viewer, '---1-')
|
|
return this.viewer?.imageryLayers.addImageryProvider(imageryLayers)
|
}
|
|
showCustomImageryProviderDataSource (imageryLayers, show) {
|
if (imageryLayers) {
|
imageryLayers.show = show
|
}
|
}
|
|
|
removeAllCustomImageryProviderDataSource (imageryLayers) {
|
if (imageryLayers) {
|
this.viewer?.imageryLayers.remove(imageryLayers)
|
}
|
}
|
}
|