Files
sdk4.0/src/YJEarth/index.js
2025-08-23 03:21:18 +08:00

527 lines
17 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* https://blog.csdn.net/qq_34205305/article/details/124862712
*/
import { keyboardMapRoamingInit } from '../Global/KeyBoard'
import { createCluster } from '../Global/cluster/cluster'
// import mouseRightMenu from '../Global/mouseRightMenu'
import { check } from '../BaseDialog/rule'
import { init_material } from '../Obj/Materail'
import AModelLoader from '../Obj/Base/LoadObjModel/AModelLoader'
import { setSvg } from '../Obj/Element/svg'
import Tools from '../Tools'
import { Proj } from '../Tools/proj'
import {
unRegLeftClickCallback,
unRegRightClickCallback,
unregMoveCallback
} from '../Global/ClickCallback'
import {
getCesiumIndexedDBMaxSize,
setCesiumIndexedDBMaxSize,
getCesiumManageIndexexDBState,
setCesiumManageIndexexDBState,
closeRotateAround,
closeViewFollow
} from '../Global/global'
import { syncSplitData, setActiveId } from '../Global/SplitScreen'
import { apiQueryGoodsList } from '../Tools/getGoodsList'
import YJColorPicker from "../Obj/Element/yj-color-picker";
// window.check = check
class YJEarth {
#_requestAnimationFrameEventId = undefined
/**
* @constructor
* @param div_id {string} 地球所在的dom id
* @param [options]
* @example new YJ.YJEarth("dom_id")
* */
constructor(div_id, options = {}) {
this.div_id = div_id
this.entityMap = new Map()
this._entityZIndex = 0
this.viewer = null
this.options = { ...options }
// apiQueryGoodsList()
// setCesiumIndexedDBMaxSize(getCesiumIndexedDBMaxSize())
setCesiumManageIndexexDBState(getCesiumManageIndexexDBState())
this.proj = new Proj()
this.clickTextDom = undefined
this.isLeftClick = false
this.init()
setSvg()
}
addIncetance(id, obj) {
this.entityMap.set(id + '', obj)
}
getIncetance(id) {
return this.entityMap.get(id + '')
}
removeIncetance(id) {
this.entityMap.delete(id)
unRegLeftClickCallback(this, id)
unRegRightClickCallback(this, id)
unregMoveCallback(this, id)
syncSplitData(this, id)
}
setDefaultView(options) {
if (options) {
this.viewer.CAMERA_DEFAULT_VIEW_RECTANGLE = {
destination: options.destination || {},
orientation: options.orientation || {}
}
closeRotateAround(this)
closeViewFollow(this)
this.viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
options.destination.lng,
options.destination.lat,
options.destination.alt
),
orientation: {
heading: Cesium.Math.toRadians(options.orientation.heading || 0),
pitch: Cesium.Math.toRadians(options.orientation.pitch || 0),
roll: Cesium.Math.toRadians(options.orientation.roll || 0)
},
duration: 0
})
} else {
this.viewer.CAMERA_DEFAULT_VIEW_RECTANGLE = undefined
//设置cesium的默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
//西边的经度
89.5,
//南边的纬度
10.4,
//东边的经度
110.4,
//北边的维度
61.2
)
// this.viewer.camera.flyHome()
this.viewer.camera.setView({
destination: Cesium.Camera.DEFAULT_VIEW_RECTANGLE
})
}
}
init() {
let cgs2000Ellipsolid = new Cesium.Ellipsoid(
6378137.0,
6378137.0,
6356752.31414035585
)
let cgs2000GeographicProj = new Cesium.GeographicProjection(
cgs2000Ellipsolid
)
let _this = this
this.options = {
imageryProvider: new Cesium.TileMapServiceImageryProvider({
url: Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')
}),
baseLayerPicker: false,
geocoder: false,
animation: false,
fullscreenButton: false,
navigationHelpButton: false,
// vrButton?: boolean;
homeButton: false,
infoBox: false,
sceneModePicker: false,
selectionIndicator: false,
timeline: false,
shouldAnimate: true,
mapProjection: cgs2000GeographicProj
}
if (Number(Cesium.VERSION.split('.')[1]) >= 107) {
this.options.baseLayer = Cesium.ImageryLayer.fromProviderAsync(
Cesium.TileMapServiceImageryProvider.fromUrl(
Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')
)
)
} else {
this.options.imageryProvider = new Cesium.TileMapServiceImageryProvider({
url: Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')
})
}
this.options.contextOptions = {
webgl: {
alpha: true,
depth: true,
stencil: true,
antialias: true,
premultipliedAlpha: true,
preserveDrawingBuffer: true,
failIfMajorPerformanceCaveat: true
},
requestWebgl2: true
}
Cesium.RequestScheduler.maximumRequests = 500
this.viewer = new Cesium.Viewer(this.div_id, this.options)
this.viewer.scene.imageryLayers._layers[0].notes = 'default-base-map'
this.viewer._shadows = this.viewer.shadows
this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 50000000
// 地球透明
this.viewer.scene.globe.translucency.enabled = true
// 天空盒
let tools = new Tools()
this.viewer.scene.skyBox = new Cesium.SkyBox({
sources: {
negativeX:
tools.getSourceRootPath() + '/img/skyBox/2/tycho2t3_80_mx.jpg',
negativeY:
tools.getSourceRootPath() + '/img/skyBox/2/tycho2t3_80_my.jpg',
negativeZ:
tools.getSourceRootPath() + '/img/skyBox/2/tycho2t3_80_mz.jpg',
positiveX:
tools.getSourceRootPath() + '/img/skyBox/2/tycho2t3_80_px.jpg',
positiveY:
tools.getSourceRootPath() + '/img/skyBox/2/tycho2t3_80_py.jpg',
positiveZ:
tools.getSourceRootPath() + '/img/skyBox/2/tycho2t3_80_pz.jpg'
}
})
init_material()
let fontData = [
{
name: '思源黑体',
value: 'SourceHanSansTi',
url: tools.getSourceRootPath() + '/custom/fonts/SourceHanSansCN-Medium.otf',
format: 'opentype'
},
{
name: '庞门正道标题体',
value: 'PMZDBTTi',
url: tools.getSourceRootPath() + '/custom/fonts/PangMenZhengDaoBiaoTiTi-1.ttf',
format: 'truetype'
},
{
name: '数黑体',
value: 'AlimamaShuHeiTi',
url: tools.getSourceRootPath() + '/custom/fonts/AlimamaShuHeiTi-Bold.ttf',
format: 'truetype'
}
]
for (let i = 0; i < fontData.length; i++) {
let font = new FontFace(
fontData[i].value,
`url('${fontData[i].url}') format('${fontData[i].format}')`,
)
font.load()
document.fonts.add(font);
}
document.fonts.ready.then(() => {
for (let [id, obj] of this.entityMap) {
if ('labelFontFamily' in obj) {
obj.labelFontFamily = obj.labelFontFamily
}
}
});
// const font = new FontFace(
// 'TencentSans W7CN',
// `url('${tools.getSourceRootPath()}/custom/fonts/TencentSans-W7-CN.woff2') format('woff2')`,
// );
// font.load()
this.setDefaultView()
//加载Cesium默认的地形数据。Bing在线地形影像--很慢可以指定mapStyle详见BingMapsStyle类
// var terrainProvider = Cesium.createWorldTerrain({
// requestWaterMask: true, // 请求水体效果所需要的海岸线数据
// requestVertexNormals: true, // 请求地形照明数据
// });
// this.viewer.terrainProvider = terrainProvider;
// this.viewer.camera.flyHome()
Cesium.Ion.defaultAccessToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhZmM5ODNkYy0yMTIzLTQxNzktOTE1Yy1mN2QxNmFkMjgyMTUiLCJpZCI6Mjk0NzIsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1OTIyMjkxMTJ9.9oYggi4kZgcapD2BkEGF8kG8tTuVkF33FdwxB2JKXeA'
this.viewer.scene.globe.depthTestAgainstTerrain = true
this.viewer.scene.screenSpaceCameraController.zoomEventTypes = [
Cesium.CameraEventType.WHEEL,
Cesium.CameraEventType.PINCH
]
this.viewer.scene.screenSpaceCameraController.tiltEventTypes = [
Cesium.CameraEventType.PINCH,
Cesium.CameraEventType.RIGHT_DRAG
]
// //视频融合 加载obj模型
// window.objLoader = new AModelLoader(this.viewer.scene.context)
//取消左键双击
this.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
)
/*禁止平移*/
// this.viewer.scene.screenSpaceCameraController.enableTranslate = false
// this.setSceneRotate(true)
if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
//判断是否支持图像渲染像素化处理
this.viewer.resolutionScale = window.devicePixelRatio
}
this.viewer.scene.fxaa = true
this.viewer.scene.postProcessStages.fxaa.enabled = true
this.viewer.scene.screenSpaceCameraController.enableCollisionDetection = true //true 禁止 false 允许
createCluster(this.viewer)
keyboardMapRoamingInit(this.viewer)
let a = Cesium.viewerCesiumNavigationMixin(this.viewer, {
// 修改重置视图的tooltip
resetTooltip: '重置视图',
// 修改放大按钮的tooltip
zoomInTitle: '缩小',
// 修改缩小按钮的tooltip
zoomOutTitle: '放大'
})
// 操作罗盘时关闭绕点旋转和轨迹运动的视角跟随
setTimeout(() => {
let compassOuterRingElm = document.getElementsByClassName('compass-outer-ring')[0]
let navigationControlsElm = document.getElementsByClassName('navigation-controls')[0]
compassOuterRingElm.addEventListener('mousedown', () => {
closeRotateAround(this)
closeViewFollow(this)
})
navigationControlsElm.addEventListener('mousedown', () => {
closeRotateAround(this)
closeViewFollow(this)
})
}, 0);
// this.viewer.dataSources.dataSourceMoved.addEventListener(()=>{
// syncDataSources()
// })
// this.viewer.dataSources.dataSourceRemoved.addEventListener(()=>{
// syncDataSources()
// })
// 开启鼠标右键菜单
// new mouseRightMenu(this, (e)=>{
// console.log(e)
// }).open()
// this.sdk.viewer.clock.onTick.addEventListener((clock) => {
// this.sdk.viewer.scene.light = new Cesium.DirectionalLight({
// direction: Cesium.Cartesian3.negate(this.sdk.viewer.scene.camera.position, new Cesium.Cartesian3()),
// intensity: 0.5
// })
// });
this.viewer.imageryLayers.layerAdded.addEventListener(() => {
for (let i = 0; i < this.viewer.imageryLayers._layers.length; i++) {
if (
this.viewer.imageryLayers._layers[i]._imageryProvider &&
this.viewer.imageryLayers._layers[i]._imageryProvider._type &&
(this.viewer.imageryLayers._layers[i]._imageryProvider._type ===
'flw' ||
this.viewer.imageryLayers._layers[i]._imageryProvider._type ===
'jww')
) {
this.viewer.imageryLayers.raiseToTop(
this.viewer.imageryLayers._layers[i]
)
}
}
})
// 开启地球阴影(可视域分析)
// this.viewer.scene.globe.shadows = Cesium.ShadowMode.ENABLED
// let tools = new Tools()
// tools.convertPxToRem(this)
// 更新光照
function updateLight() {
let intensity = 1
if (
_this.viewer &&
_this.viewer.scene.mode === 2
) {
intensity = 10
}
if (_this.viewer.shadows) {
_this.viewer.scene.light = new Cesium.SunLight()
} else {
if (_this.viewer.trackedEntity && _this.viewer.trackedEntity.position) {
intensity = 1
_this.viewer.scene.light = new Cesium.DirectionalLight({
direction: Cesium.Cartesian3.negate(
_this.viewer.trackedEntity.position._value,
new Cesium.Cartesian3(-1, -1, -1)
),
intensity: intensity
})
} else {
if (
_this.viewer &&
_this.viewer.scene.mode === 2
) {
intensity = 30
}
else {
intensity = 1
}
_this.viewer.scene.light = new Cesium.DirectionalLight({
direction: Cesium.Cartesian3.negate(
_this.viewer.scene.camera.position,
new Cesium.Cartesian3(-1, -1, -1)
),
intensity: intensity
})
}
}
}
animateUpdate()
function animateUpdate() {
_this.#_requestAnimationFrameEventId = requestAnimationFrame(
animateUpdate
)
updateLight()
TWEEN.update()
}
solveBug()
function solveBug() {
// 解决计算高度时多边形闪烁透视的bug原因不明
let pot1 = _this.viewer.entities.add(
new Cesium.Entity({
name: 'solve-bug',
position: { x: 0, y: 0, z: 0 },
billboard: {
scale: 0,
image: tools.getSourceRootPath() + '/img/point.png',
color: Cesium.Color.WHITE.withAlpha(0)
},
})
)
let pot2 = _this.viewer.entities.add(
new Cesium.Entity({
name: 'solve-bug',
position: { x: 0, y: 0, z: 100000000 },
billboard: {
scale: 0,
image: tools.getSourceRootPath() + '/img/point.png',
color: Cesium.Color.WHITE.withAlpha(0)
},
})
)
}
let ClickHandler = new Cesium.ScreenSpaceEventHandler(_this.viewer.canvas)
ClickHandler.setInputAction((movement) => {
let textList = document.getElementsByClassName('popup-textarea')
_this.isLeftClick = false
for (let i = textList.length - 1; i > -1; i--) {
let left = returnNumber(textList[i].style.left)
let top = returnNumber(textList[i].style.top)
let width = textList[i].clientWidth * 1
let height = textList[i].clientHeight * 1
let x = movement.position.x
let y = movement.position.y
if (x > left && x < left + width && y > top && y < top + height) {
if (_this.clickTextDom) {
_this.clickTextDom.style['pointer-events'] = 'none'
}
_this.clickTextDom = textList[i]
textList[i].style['pointer-events'] = 'all'
textList[i].querySelector('textarea').focus()
_this.isLeftClick = true
_this.entityMap.get(_this.clickTextDom.id).isClick(movement.position, _this.clickTextDom.id)
break;
}
}
let mousedown = undefined
let mousemove = undefined
let mouseup = undefined
let fun = undefined
let handler = undefined
if (_this.isLeftClick) {
let click = false
let layerX = 0
let layerY = 0
mousedown = function (e) {
layerX = e.layerX
layerY = e.layerY
click = true
}
mousemove = function (e) {
if (!click) {
return
}
let width = _this.clickTextDom.clientWidth * 1
let height = _this.clickTextDom.clientHeight * 1
let param = {
x: e.clientX - layerX + width / 2,
y: e.clientY - layerY + height,
}
_this.entityMap.get(_this.clickTextDom.id).setHandeler(param)
}
mouseup = function (e) {
if (!click) {
return
}
click = false
}
_this.clickTextDom.addEventListener('mousedown', mousedown);
document.addEventListener('mousemove', mousemove);
document.addEventListener('mouseup', mouseup);
}
// 点击其他地方取消
if (!_this.isLeftClick && _this.clickTextDom) {
_this.clickTextDom.removeEventListener('mousedown', mousedown);
document.removeEventListener('mousemove', mousemove);
document.removeEventListener('mouseup', mouseup);
_this.entityMap.get(_this.clickTextDom.id).getwords(_this.clickTextDom.getElementsByTagName('textarea')[0].value)
_this.clickTextDom.style['pointer-events'] = 'none'
_this.clickTextDom = undefined
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
// ClickHandler.setInputAction((movement) => {
// if (_this.clickTextDom) {
// _this.clickTextDom.style['pointer-events'] = 'none'
// _this.clickTextDom = undefined
// }
// }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
function returnNumber(str) {
let index = str.indexOf('px')
return Number(str.slice(0, index))
}
}
destroy() {
cancelAnimationFrame(this.#_requestAnimationFrameEventId)
for (let [id, obj] of this.entityMap) {
obj.remove()
}
if (this.viewer) {
if (this.viewer.entities) {
this.viewer.entities.removeAll()
}
this.viewer.destroy && this.viewer.destroy()
}
this.viewer = null
}
}
export default YJEarth