import * as Cesium from 'cesium'
|
import AmapMercatorTilingScheme from './cesium/AmapMercatorTilingScheme/index'
|
import store from '@/store'
|
import { Terrain } from 'cesium'
|
import { addBlueFilter } from '@/utils/cesium/common'
|
|
// 定义全局的viewer变量防止重复生成
|
let viewer = null
|
let globalBaseMapLayers = []
|
|
window.globalCesium = Cesium
|
window.$viewer = null
|
|
let customEntityDataSources = {}
|
|
let customMapLayer = {}
|
let handlerEvents = {
|
handler: null,
|
}
|
let TDT_Token = import.meta.env.VITE_APP_TDT_TOKEN
|
|
export default function cesiumOperation () {
|
// 天地图地图
|
const TDT_IMG_C =
|
'https://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
|
'&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
|
'&style=default&format=tiles&tk=' +
|
TDT_Token
|
// 天地图注记
|
const TDT_ZJ =
|
'https://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
|
'&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
|
'&style=default&format=tiles&tk=' +
|
TDT_Token
|
// 标准地图注记
|
const TID_STAND =
|
'https://{s}.tianditu.gov.cn/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0' +
|
'&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
|
'&style=default&format=tiles&tk=' +
|
TDT_Token
|
// 天地图图层变量
|
const imageryProvider_tdt = new Cesium.WebMapTileServiceImageryProvider({
|
url: TDT_IMG_C,
|
layer: 'tdtImg_c',
|
style: 'default',
|
format: 'tiles',
|
tileMatrixSetID: 'c',
|
subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
|
tilingScheme: new Cesium.GeographicTilingScheme(),
|
tileMatrixLabels: [
|
'1',
|
'2',
|
'3',
|
'4',
|
'5',
|
'6',
|
'7',
|
'8',
|
'9',
|
'10',
|
'11',
|
'12',
|
'13',
|
'14',
|
'15',
|
'16',
|
'17',
|
'18',
|
'19',
|
],
|
maximumLevel: 17,
|
})
|
// 标准地图图层变量
|
const imageryProvider_stand = new Cesium.UrlTemplateImageryProvider({
|
url: 'https://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
// format: 'image/jpeg',
|
// show: true,
|
maximumLevel: 18,
|
credit: 'stand_tc',
|
})
|
// 标准地图图层注解
|
const imageryProvider_standZh = new Cesium.UrlTemplateImageryProvider({
|
url: 'https://t{s}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
maximumLevel: 18,
|
credit: 'stand_zj',
|
})
|
// 天地图中文注记加载
|
const annotation = new Cesium.WebMapTileServiceImageryProvider({
|
url: TDT_ZJ,
|
layer: 'tdtZwImg_c',
|
style: 'default',
|
format: 'tiles',
|
tileMatrixSetID: 'c',
|
subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
|
tilingScheme: new Cesium.GeographicTilingScheme(),
|
tileMatrixLabels: [
|
'1',
|
'2',
|
'3',
|
'4',
|
'5',
|
'6',
|
'7',
|
'8',
|
'9',
|
'10',
|
'11',
|
'12',
|
'13',
|
'14',
|
'15',
|
'16',
|
'17',
|
'18',
|
'19',
|
],
|
maximumLevel: 50,
|
})
|
|
// 高德地图图层变量
|
//高德矢量地图数据图层,自带注记
|
const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({
|
url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
|
layer: 'tdtVecBasicLayer',
|
style: 'default',
|
format: 'image/png',
|
tileMatrixSetID: 'GoogleMapsCompatible',
|
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
maximumLevel: 18,
|
tilingScheme: new AmapMercatorTilingScheme(),
|
credit: 'amap_SL',
|
})
|
|
//高德影像地图数据图层,自带注记
|
const imageryProvider_ammap = new Cesium.UrlTemplateImageryProvider({
|
url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
|
layer: 'tdtVecBasicLayer',
|
style: 'default',
|
format: 'image/png',
|
tileMatrixSetID: 'GoogleMapsCompatible',
|
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
maximumLevel: 18,
|
tilingScheme: new AmapMercatorTilingScheme(),
|
credit: 'amap_stand',
|
})
|
// 高德影像地图数据图层,注记
|
const imageryProvider_ammapBz = new Cesium.UrlTemplateImageryProvider({
|
url: 'https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8',
|
tilingScheme: new AmapMercatorTilingScheme(),
|
minimumLevel: 3,
|
})
|
const _init = async id => {
|
Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
|
// 西南东北,默认显示中国
|
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
|
viewer = new Cesium.Viewer(id, {
|
terrain: Terrain.fromWorldTerrain(),
|
infoBox: false, // 禁用沙箱,解决控制台报错
|
animation: false, // 左下角的动画仪表盘
|
baseLayerPicker: false, // 右上角的图层选择按钮
|
geocoder: false, // 搜索框
|
homeButton: false, // home按钮
|
sceneModePicker: false, // 模式切换按钮
|
timeline: false, // 底部的时间轴
|
navigationHelpButton: false, // 右上角的帮助按钮,
|
selectionIndicator: false, // 是否显示选择指示器
|
baseLayer: false,
|
fullscreenButton: false,
|
})
|
|
// viewer.scene.globe.depthTestAgainstTerrain = true;
|
|
viewer.imageryLayers.removeAll()
|
|
globalBaseMapLayers = []
|
|
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
|
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
|
) // 禁用双击
|
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100
|
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000
|
// viewer.scene.camera.setView({
|
// destination: Cesium.Cartesian3.fromDegrees(115.856725497,28.624514734, 8000)
|
// });
|
// // 添加地形数据
|
|
// viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
|
// url: 'https://data.marsgis.cn/terrain',
|
// });
|
|
// viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
|
// url: Cesium.IonResource.fromAssetId(1),
|
// requestWaterMask: false,
|
// requestVertexNormals: true,
|
// })
|
|
window.$viewer = viewer
|
loadLAYER()
|
}
|
|
const loadLAYER = () => {
|
let mapLayers = []
|
|
globalBaseMapLayers.length &&
|
globalBaseMapLayers.forEach(item => {
|
if (item.mapLayer) item.mapLayer.show = false
|
})
|
|
// 高德影像地图数据图层
|
if (store.state.common.mapSetting.mode === 3) {
|
mapLayers.push(
|
...[
|
{ key: 'imageryProvider_ammap', layer: imageryProvider_ammap },
|
{ key: 'imageryProvider_ammapBz', layer: imageryProvider_ammapBz },
|
]
|
)
|
}
|
// 高德地图矢量图层加载
|
if (store.state.common.mapSetting.mode === 2) {
|
mapLayers.push({
|
key: 'imageryProvider_ammapSL',
|
layer: imageryProvider_ammapSL,
|
})
|
}
|
|
// 标准地图加载
|
if (store.state.common.mapSetting.mode === 0) {
|
mapLayers.push(
|
...[
|
{ key: 'imageryProvider_standZh', layer: imageryProvider_standZh },
|
{ key: 'imageryProvider_stand', layer: imageryProvider_stand },
|
]
|
)
|
}
|
|
// 路线图加载
|
if (
|
store.state.common.mapSetting.roadLine === true &&
|
store.state.common.mapSetting.mode === 1
|
) {
|
mapLayers.push({ key: 'annotation', layer: annotation })
|
}
|
|
// 天地图图层加载
|
if (store.state.common.mapSetting.mode === 1) {
|
mapLayers.push({
|
key: 'imageryProvider_tdt',
|
layer: imageryProvider_tdt,
|
})
|
}
|
|
// 创建一个Set来快速查找array2中的id
|
let keyBaseMap = new Set(globalBaseMapLayers.map(item => item.key))
|
let keyMapLayers = new Set(mapLayers.map(item => item.key))
|
|
let keyExistBaseMap = mapLayers.filter(item => !keyBaseMap.has(item.key))
|
|
let keyNoExistBaseMap = globalBaseMapLayers.filter(item => keyMapLayers.has(item.key))
|
|
keyExistBaseMap.length &&
|
keyExistBaseMap.forEach(item => {
|
let curLayer = {
|
key: item.key,
|
mapLayer: viewer?.imageryLayers.addImageryProvider(item.layer),
|
}
|
|
if (curLayer.key == 'imageryProvider_standZh') {
|
curLayer.mapLayer.brightness = 0.6 // 亮度(默认值)
|
curLayer.mapLayer.contrast = 1.8 // 对比度(负值降低对比度)
|
curLayer.mapLayer.hue = 1 // 色相(弧度值,3.0可能导致紫色)
|
curLayer.mapLayer.saturation = 0 // 增加饱和度强化蓝色
|
curLayer.mapLayer.gamma = 0.3 // 伽马校正(小于1.0使颜色更鲜艳)
|
curLayer.invertColor = true // 启用反色
|
}
|
|
if (curLayer.key == 'imageryProvider_stand') {
|
curLayer.mapLayer.brightness = 0.6 // 亮度(默认值)
|
curLayer.mapLayer.contrast = 1.8 // 对比度(负值降低对比度)
|
curLayer.mapLayer.hue = 1 // 色相(弧度值,3.0可能导致紫色)
|
curLayer.mapLayer.saturation = 0 // 增加饱和度强化蓝色
|
curLayer.mapLayer.gamma = 0.3 // 伽马校正(小于1.0使颜色更鲜艳)
|
curLayer.invertColor = true // 启用反色
|
// curLayer.filterRGB = [0, 50, 100]
|
addBlueFilter({
|
bInvertColor: true,
|
bFilterColor: true,
|
filterColor: '#4e70a6'
|
},viewer)
|
}
|
|
if (curLayer.mapLayer) curLayer.mapLayer.show = true
|
|
viewer?.imageryLayers.lowerToBottom(curLayer.mapLayer)
|
|
globalBaseMapLayers.push(curLayer)
|
})
|
|
keyNoExistBaseMap.length &&
|
keyNoExistBaseMap.forEach(item => {
|
if (item.mapLayer) item.mapLayer.show = true
|
|
viewer?.imageryLayers.lowerToBottom(item.mapLayer)
|
})
|
// 2D/3D切换
|
switchModel(store.state.common.mapSetting.visual)
|
}
|
|
const addCustomLayers = (layerName, options) => {
|
if (options.type == 'arcgis') {
|
var imageryProvider = new Cesium.WebMapTileServiceImageryProvider({
|
url: options.src,
|
layer: options.title,
|
style: 'default',
|
format: 'image/png',
|
tileMatrixSetID: 'default',
|
tilingScheme: new Cesium.GeographicTilingScheme(),
|
tileMatrixLabels: [
|
'0',
|
'1',
|
'2',
|
'3',
|
'4',
|
'5',
|
'6',
|
'7',
|
'8',
|
'9',
|
'10',
|
'11',
|
'12',
|
'13',
|
'14',
|
'15',
|
'16',
|
'17',
|
'18',
|
'19',
|
],
|
})
|
|
customMapLayer[layerName] = viewer?.imageryLayers.addImageryProvider(imageryProvider)
|
|
// const layerProvider = new Cesium.ArcGisMapServerImageryProvider({
|
// url: options.src,
|
// tilingScheme: new Cesium.GeographicTilingScheme()
|
// })
|
// customMapLayer[layerName] = viewer?.imageryLayers.addImageryProvider(layerProvider)
|
}
|
}
|
|
const removeCustomLayers = (layerName = '') => {
|
if (layerName) {
|
if (customMapLayer[layerName]) {
|
viewer?.imageryLayers.remove(customMapLayer[layerName])
|
|
delete customMapLayer[layerName]
|
}
|
} else {
|
for (let k in customMapLayer) {
|
viewer?.imageryLayers.remove(customMapLayer[k])
|
}
|
|
customMapLayer = {}
|
}
|
}
|
|
// 切换不同背景图层
|
const patternMap = () => {
|
const imageryLayers = viewer?.scene.imageryLayers
|
// 切换为标准图层
|
if (store.state.common.mapSetting.mode === 0) {
|
const tdtImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtImg_c')
|
const tdtZwImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtZwImg_c')
|
viewer?.imageryLayers.remove(tdtImg_c)
|
viewer?.imageryLayers.remove(tdtZwImg_c)
|
} else {
|
const tdtStand_c = imageryLayers?._layers.find(
|
v => v.imageryProvider.credit?.html === 'stand_tc'
|
)
|
const tdtStand_zj = imageryLayers?._layers.find(
|
v => v.imageryProvider.credit?.html === 'stand_zj'
|
)
|
viewer?.imageryLayers.remove(tdtStand_c)
|
viewer?.imageryLayers.remove(tdtStand_zj)
|
}
|
loadLAYER()
|
}
|
|
// 生成或删除路网图层
|
const roadPattern = flag => {
|
if (store.state.common.mapSetting.mode === 0) return
|
const imageryLayers = viewer?.scene.imageryLayers
|
const tdtZwImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtZwImg_c')
|
if (!flag) {
|
viewer?.imageryLayers.remove(tdtZwImg_c)
|
} else {
|
viewer?.imageryLayers.addImageryProvider(annotation)
|
}
|
}
|
|
// 二维三维切换
|
// 切换为二三维模式
|
const switchModel = type => {
|
switch (type) {
|
case '2D':
|
viewer?.scene.morphTo2D(0)
|
// viewer?.scene.camera.setView({
|
// orientation: {
|
// pitch: Cesium.Math.toRadians(-60),
|
// heading: Cesium.Math.toRadians(0),
|
// },
|
// });
|
break
|
case '3D':
|
viewer?.scene.morphTo3D(0)
|
// viewer?.scene.camera.setView({
|
// orientation: {
|
// pitch: Cesium.Math.toRadians(-90),
|
// heading: Cesium.Math.toRadians(0),
|
// },
|
// });
|
break
|
default:
|
break
|
}
|
}
|
|
/**
|
* @description: 地图暗黑模式切换
|
* @param {*} viewer 地图实例
|
* @param {*} options 配置项
|
* @return {*}
|
*/
|
const darkMap = (viewer, isDark = false, options) => {
|
const defaultOptions = {
|
brightness: 1,
|
contrast: 1,
|
gamma: 1,
|
hue: 0,
|
saturation: 1,
|
}
|
|
!isDark && Object.assign(options, defaultOptions)
|
|
const baseLayer = viewer.imageryLayers.get(0)
|
baseLayer.brightness = options.brightness || 0
|
baseLayer.contrast = options.contrast || 0
|
baseLayer.gamma = options.gamma || 2
|
baseLayer.hue = options.hue || 0
|
baseLayer.saturation = options.saturation || 0
|
|
const baseFragShader = viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources
|
for (let i = 0; i < baseFragShader.length; i++) {
|
const strS = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
|
let strT = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
|
if (options.invertColor) {
|
strT += `
|
color.r = 1.0 - color.r;
|
color.g = 1.0 - color.g;
|
color.b = 1.0 - color.b;
|
`
|
}
|
if (options.filterRGB.length > 0) {
|
strT += `
|
color.r = color.r * ${options.filterRGB[0]}.0/255.0;
|
color.g = color.g * ${options.filterRGB[1]}.0/255.0;
|
color.b = color.b * ${options.filterRGB[2]}.0/255.0;
|
`
|
}
|
if (!isDark) {
|
//恢复默认
|
baseFragShader[i] = baseFragShader[i].replace(strT, strS)
|
} else {
|
// 替换为暗黑模式
|
baseFragShader[i] = baseFragShader[i].replace(strS, strT)
|
}
|
}
|
}
|
|
const switchDarkModel = () => {
|
const isDark = store.state.common.mapSetting.isDark
|
darkMap(viewer, isDark, {
|
//反色
|
invertColor: true,
|
//滤色值 [176, 224, 230]
|
filterRGB: [60, 145, 172],
|
})
|
}
|
|
//移除DataSource中所有实体
|
const removeAllDataSource = () => {
|
viewer?.dataSources.removeAll()
|
}
|
|
// 清除所有标记点
|
const removeAllPoint = () => {
|
if (viewer) {
|
viewer?.entities?.removeAll()
|
// viewer?.scene?.primitives?.removeAll();
|
}
|
}
|
|
// 通过点ID删除
|
const removeById = id => {
|
viewer?.entities.removeById(id)
|
const pointEntity = viewer?.entities.getById(id)
|
if (pointEntity && pointEntity !== undefined) {
|
viewer?.entities.remove(pointEntity)
|
}
|
}
|
|
// 通过点ID获取实体
|
const getEntityById = id => {
|
const pointEntity = viewer?.entities.getById(id)
|
return pointEntity
|
}
|
|
// 添加标记点
|
const addPoint = pointOption => {
|
if (!pointOption.longitude && !pointOption.latitude) return
|
const position = Cesium.Cartesian3.fromDegrees(
|
pointOption.longitude,
|
pointOption.latitude,
|
pointOption?.altitude || 0
|
)
|
viewer?.entities.add({
|
position,
|
billboard: pointOption.billboard,
|
point: pointOption.point,
|
label: pointOption.label,
|
id: pointOption.id,
|
})
|
}
|
|
const addPolyline = pointOption => {
|
return viewer?.entities.add({
|
polyline: pointOption.polyline,
|
id: pointOption.id,
|
})
|
}
|
|
// 更新图片实体位置
|
function updateEntityPosition (longitude, latitude, id, params) {
|
const entity = getEntityById(id)
|
const position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
|
const heading = Cesium.Math.toRadians(-params.heading)
|
if (Cesium.defined(entity)) {
|
entity.position = position
|
entity.billboard.rotation = heading
|
}
|
}
|
|
// 飞行 flyto
|
const flyTo = (pointOption, time = 4, height = 3000, orientation = {}) => {
|
if (!pointOption.longitude && !pointOption.latitude) return
|
const destination = Cesium.Cartesian3.fromDegrees(
|
pointOption.longitude,
|
pointOption.latitude,
|
height
|
)
|
const duration = time
|
viewer?.camera.flyTo({
|
destination,
|
duration,
|
orientation,
|
})
|
}
|
|
// 鼠标点击事件
|
const addLeftClickEvent = (sid, cb, eventKey = 'handler') => {
|
if (handlerEvents.handler) removeLeftClickEvent()
|
if (handlerEvents[eventKey]) removeLeftClickEvent(eventKey)
|
|
handlerEvents[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
|
handlerEvents[eventKey].setInputAction(function (click) {
|
const pick = viewer?.scene.pick(click.position)
|
|
if (pick && pick.primitive && pick.primitive?.customParams?.type == '3DTileset') {
|
return cb(click, pick, viewer, handlerEvents[eventKey])
|
}
|
|
if (pick && pick.id && (pick.id._id === sid || pick.id._id.includes(sid))) {
|
cb(click, pick, viewer, handlerEvents[eventKey])
|
}
|
|
if (sid === null) {
|
cb(click, pick, viewer, handlerEvents[eventKey])
|
}
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
}
|
|
// 移除鼠标点击事件
|
const removeLeftClickEvent = (eventKey = 'handler') => {
|
if (handlerEvents[eventKey] == null) return
|
handlerEvents[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
handlerEvents[eventKey] = null
|
}
|
|
// 鼠标左键按下事件
|
let leftDownClickHandler = { handler: null }
|
const addLeftDownClickEvent = (sid, cb, eventKey = 'handler') => {
|
if (leftDownClickHandler.handler) removeLeftDownClickEvent()
|
if (leftDownClickHandler[eventKey]) removeLeftDownClickEvent(eventKey)
|
|
leftDownClickHandler[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
|
|
leftDownClickHandler[eventKey].setInputAction(function (click) {
|
const pick = viewer?.scene.pick(click.position)
|
cb(click, pick, viewer)
|
}, Cesium.ScreenSpaceEventType.LEFT_DOWN)
|
}
|
|
// 移除鼠标左键按下事件
|
const removeLeftDownClickEvent = (eventKey = 'handler') => {
|
if (leftDownClickHandler[eventKey] == null) return
|
leftDownClickHandler[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN)
|
|
leftDownClickHandler[eventKey] = null
|
}
|
|
// 鼠标右击事件
|
let leftUpClickHandler = { handler: null }
|
const addLeftUpClickEvent = (sid, cb, eventKey = 'handler') => {
|
if (leftUpClickHandler.handler) removeLeftUpClickEvent()
|
if (leftUpClickHandler[eventKey]) removeLeftUpClickEvent(eventKey)
|
|
leftUpClickHandler[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
|
|
leftUpClickHandler[eventKey].setInputAction(function (click) {
|
const pick = viewer?.scene.pick(click.position)
|
cb(click, pick, viewer)
|
}, Cesium.ScreenSpaceEventType.LEFT_UP)
|
}
|
|
// 移除鼠标右键事件
|
const removeLeftUpClickEvent = (eventKey = 'handler') => {
|
if (leftUpClickHandler[eventKey] == null) return
|
leftUpClickHandler[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP)
|
|
leftUpClickHandler[eventKey] = null
|
}
|
|
// 鼠标右击事件
|
let rightClickHandler
|
const addRightClickEvent = (sid, cb) => {
|
if (rightClickHandler) removeRightClickEvent()
|
|
rightClickHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
|
|
rightClickHandler.setInputAction(function (click) {
|
const pick = viewer?.scene.pick(click.position)
|
cb(click, pick, viewer)
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
}
|
|
// 移除鼠标右键事件
|
const removeRightClickEvent = () => {
|
if (!rightClickHandler) return
|
rightClickHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
rightClickHandler = null
|
}
|
|
// 鼠标移动事件
|
let LeftMounseHandler
|
const addLeftmounseEvent = (sid, cb) => {
|
if (LeftMounseHandler) removeLeftmounseEvent()
|
LeftMounseHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
|
LeftMounseHandler.setInputAction(function (event) {
|
const cartesian3 = viewer?.scene.globe.pick(
|
viewer?.camera.getPickRay(event.startPosition),
|
viewer?.scene
|
)
|
cb(cartesian3, viewer)
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
}
|
|
// 移除鼠标移动事件
|
const removeLeftmounseEvent = () => {
|
if (LeftMounseHandler == null) return
|
LeftMounseHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
LeftMounseHandler = null
|
}
|
|
let MounseHandler
|
const addMounseHandler = (sid, cb) => {
|
if (MounseHandler == null) removeMounseEvent()
|
|
MounseHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
|
|
MounseHandler.setInputAction(function (movement) {
|
let mouseInfo = _getMouseInfo(movement.endPosition)
|
|
cb(mouseInfo, viewer)
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
}
|
|
const _getMouseInfo = position => {
|
let scene = viewer.scene
|
let target = scene.pick(position)
|
let cartesian = undefined
|
let surfaceCartesian = undefined
|
let wgs84Position = undefined
|
let wgs84SurfacePosition = undefined
|
if (scene.pickPositionSupported) {
|
cartesian = scene.pickPosition(position)
|
}
|
if (cartesian) {
|
let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian)
|
if (c) {
|
wgs84Position = {
|
lng: Cesium.Math.toDegrees(c.longitude),
|
lat: Cesium.Math.toDegrees(c.latitude),
|
alt: c.height,
|
}
|
}
|
}
|
if (
|
scene.mode === Cesium.SceneMode.SCENE3D &&
|
!(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 {
|
target: target,
|
windowPosition: position,
|
position: cartesian,
|
wgs84Position: wgs84Position,
|
surfacePosition: surfaceCartesian,
|
wgs84SurfacePosition: wgs84SurfacePosition,
|
}
|
}
|
|
// 移除鼠标移动事件
|
const removeMounseEvent = () => {
|
if (MounseHandler == null) return
|
MounseHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
MounseHandler = null
|
}
|
|
// 视角变化时间
|
let mapViewHandler = null
|
const addCameraMoveEvent = cb => {
|
if (mapViewHandler) removeCameraMoveEvent()
|
|
mapViewHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
mapViewHandler.setInputAction(event => {
|
cb(event)
|
}, Cesium.ScreenSpaceEventType.WHEEL)
|
}
|
|
const removeCameraMoveEvent = () => {
|
if (mapViewHandler == null) return
|
mapViewHandler.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL)
|
mapViewHandler = null
|
}
|
|
// 添加entity
|
const addCustomEntityDataSource = (sourceName, entities) => {
|
if (!customEntityDataSources[sourceName]) {
|
customEntityDataSources[sourceName] = new Cesium.CustomDataSource()
|
window.$viewer?.dataSources.add(customEntityDataSources[sourceName])
|
}
|
|
let entity = customEntityDataSources[sourceName].entities.add(entities)
|
|
return entity
|
}
|
|
const clearCustomEntityDataSource = sourceName => {
|
if (customEntityDataSources[sourceName]) {
|
customEntityDataSources[sourceName]?.entities.removeAll()
|
}
|
}
|
|
const removeAllCustomEntityDataSource = sourceName => {
|
if (customEntityDataSources[sourceName]) {
|
customEntityDataSources[sourceName]?.entities.removeAll()
|
window.$viewer.dataSources.remove(customEntityDataSources[sourceName])
|
delete customEntityDataSources[sourceName]
|
}
|
}
|
|
// 添加entity
|
const addCustomImageryProviderDataSource = imageryLayers => {
|
return viewer?.imageryLayers.addImageryProvider(imageryLayers)
|
}
|
|
const showCustomImageryProviderDataSource = (imageryLayers, show) => {
|
if (imageryLayers) {
|
imageryLayers.show = show
|
}
|
}
|
|
const removeAllCustomImageryProviderDataSource = imageryLayers => {
|
if (imageryLayers) {
|
viewer?.imageryLayers.remove(imageryLayers)
|
}
|
}
|
|
// 添加范围的圆
|
const addEllipse = ({ longitude, latitude, dist = 7000 }) => {
|
if (!longitude && !latitude) return
|
// 定义起点位置
|
const position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
|
// 画圆
|
|
viewer?.entities.add({
|
position,
|
id: 'rangeEllipse',
|
name: 'rangeEllipse',
|
ellipse: {
|
semiMinorAxis: dist,
|
semiMajorAxis: dist,
|
outline: true,
|
material: Cesium.Color.CORNFLOWERBLUE.withAlpha(0.3),
|
},
|
})
|
// 添加距离虚线
|
// addDistLine({ longitude, latitude, dist });
|
}
|
|
const addDistLine = ({ longitude, latitude, dist = 7 }) => {
|
// 定义起点位置
|
const startPosition = Cesium.Cartesian3.fromDegrees(longitude, latitude)
|
// 计算目标位置(7公里处)
|
const offsetCartesian = Cesium.Cartesian3.fromDegrees(
|
longitude,
|
latitude +
|
Cesium.Math.toDegrees(
|
dist / (Cesium.Ellipsoid.WGS84.maximumRadius * Math.cos(Cesium.Math.toRadians(latitude)))
|
) // 7公里的偏移
|
)
|
// 将目标位置转换为经纬度
|
// const offsetCartographic = Cesium.Cartographic.fromCartesian(offsetCartesian);
|
// const offsetLongitude = Cesium.Math.toDegrees(offsetCartographic.longitude);
|
// const offsetLatitude = Cesium.Math.toDegrees(offsetCartographic.latitude);
|
addPolyline({
|
id: 'dist_line',
|
polyline: {
|
width: 5,
|
positions: [startPosition, offsetCartesian],
|
material: new Cesium.PolylineGlowMaterialProperty({
|
glowPower: 0.2,
|
taperPower: 0.5,
|
color: Cesium.Color.CORNFLOWERBLUE,
|
}),
|
},
|
})
|
}
|
|
// 添加圆
|
const addCircle = option => {
|
if (!option.longitude && !option.latitude) return
|
// 定义起点位置
|
const { longitude, latitude } = option
|
const position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
|
viewer.entities.add({
|
position,
|
id: option.id,
|
ellipse: {
|
semiMinorAxis: option.radius,
|
semiMajorAxis: option.radius,
|
height: option.height || 120,
|
material: Cesium.Color.fromCssColorString(option.color).withAlpha(0.1),
|
outline: true,
|
outlineColor: Cesium.Color.fromCssColorString(option.color),
|
outlineWidth: 3,
|
},
|
})
|
}
|
|
//
|
/**
|
* @description: 添加矩形
|
* @param {*} option { id: string, color: string, positions: array[ lng,lat,height ] }
|
* @return {*} void 0
|
*/
|
const addPolygon = option => {
|
if (option.positions.length === 0) return
|
|
let zIndex = {}
|
|
if (option.zIndex) {
|
zIndex = {
|
zIndex: option.zIndex,
|
}
|
}
|
|
// 定义起点位置
|
viewer.entities.add({
|
id: option.id,
|
polygon: {
|
hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(option.positions),
|
material: Cesium.Color.fromCssColorString(option.color).withAlpha(0.1),
|
extrudedHeight: 0,
|
outline: true,
|
outlineColor: Cesium.Color.fromCssColorString(option.color),
|
outlineWidth: 3,
|
},
|
...zIndex,
|
})
|
}
|
|
// Cesium矢量切片是否加载完成
|
const isLoadingCompleted = () => {
|
return new Promise((resolve, reject) => {
|
const helper = new Cesium.EventHelper()
|
helper.add(viewer?.scene.globe.tileLoadProgressEvent, function (e) {
|
if (e === 0) {
|
resolve(true)
|
}
|
})
|
})
|
}
|
|
// 获取屏幕四个角经纬度
|
const getScreenCorner = () => {
|
const camera = viewer.scene.camera
|
const canvas = viewer.canvas
|
|
// 获取屏幕左下角和右上角的世界坐标
|
const leftBottom = new Cesium.Cartesian2(0, canvas.clientHeight)
|
const rightTop = new Cesium.Cartesian2(canvas.clientWidth, 0)
|
|
// 将屏幕坐标转为世界坐标
|
const leftBottomWorld = camera.pickEllipsoid(leftBottom, viewer.scene.globe.ellipsoid)
|
const rightTopWorld = camera.pickEllipsoid(rightTop, viewer.scene.globe.ellipsoid)
|
|
// 将世界坐标转为经纬度
|
const leftBottomCartographic =
|
viewer.scene.globe.ellipsoid.cartesianToCartographic(leftBottomWorld)
|
const rightTopCartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(rightTopWorld)
|
|
// 获取经纬度
|
const leftBottomLonLat = [
|
Cesium.Math.toDegrees(leftBottomCartographic.longitude),
|
Cesium.Math.toDegrees(leftBottomCartographic.latitude),
|
]
|
const rightTopLonLat = [
|
Cesium.Math.toDegrees(rightTopCartographic.longitude),
|
Cesium.Math.toDegrees(rightTopCartographic.latitude),
|
]
|
|
// 返回四个角的经纬度
|
return {
|
lb: leftBottomLonLat,
|
rb: [rightTopLonLat[0], leftBottomLonLat[1]], // 右下角
|
rt: rightTopLonLat,
|
lt: [leftBottomLonLat[0], rightTopLonLat[1]], // 左上角
|
}
|
}
|
|
// 加载3D建筑模型
|
let tileset = null
|
|
function setBuilding3dModel () {
|
try {
|
const resource = Cesium.IonResource.fromAssetId(96188)
|
tileset = new Cesium.Cesium3DTileset({
|
url: resource,
|
})
|
|
tileset.customParams = {
|
type: '3DTileset',
|
}
|
|
viewer.scene.primitives.add(tileset)
|
} catch (error) {
|
console.log(`Error loading tileset: ${error}`)
|
}
|
}
|
|
function removeBuilding3dModel () {
|
if (tileset) {
|
viewer.scene.primitives.remove(tileset)
|
}
|
}
|
|
const viewerDestory = () => {
|
viewer && viewer.destroy()
|
viewer = null
|
window.$viewer = null
|
}
|
|
let tilesetArr = []
|
|
const add3Dtileset = () => {
|
let url = '/3Dtile/kjds/tileset.json'
|
|
let tileset = new Cesium.Cesium3DTileset({
|
url: url,
|
})
|
|
tileset.customParams = {
|
type: '3DTileset',
|
}
|
|
tilesetArr.push(tileset)
|
|
tilesetArr.forEach(i => viewer?.scene.primitives.add(i))
|
}
|
|
const remove3Dtileset = () => {
|
if (tilesetArr.length > 0) {
|
tilesetArr.forEach(i => viewer.scene.primitives.remove(i))
|
}
|
|
tilesetArr = []
|
}
|
|
let pointEditHandler
|
// 航点航线编辑相关事件
|
const pointInitEvent = (lefet_down, mouse_move, left_up) => {
|
if (!pointEditHandler) {
|
pointEditHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
|
}
|
|
const events = {
|
lefet_down,
|
mouse_move,
|
left_up,
|
}
|
|
pointEditBindEvent(events)
|
pointEditBindEvent(events, Cesium.KeyboardEventModifier.CTRL)
|
pointEditBindEvent(events, Cesium.KeyboardEventModifier.ALT)
|
pointEditBindEvent(events, Cesium.KeyboardEventModifier.SHIFT)
|
pointEditBindEvent(events, Cesium.KeyboardEventModifier.META)
|
}
|
|
const pointEditBindEvent = (events, e) => {
|
if (pointEditHandler) {
|
pointEditHandler.setInputAction(
|
events.lefet_down(e),
|
Cesium.ScreenSpaceEventType.LEFT_DOWN,
|
e
|
)
|
pointEditHandler.setInputAction(
|
events.mouse_move(e),
|
Cesium.ScreenSpaceEventType.MOUSE_MOVE,
|
e
|
)
|
pointEditHandler.setInputAction(events.left_up(e), Cesium.ScreenSpaceEventType.LEFT_UP, e)
|
}
|
}
|
|
const pointUnInitEvent = () => {
|
pointEditUnBindEvent()
|
pointEditUnBindEvent(Cesium.KeyboardEventModifier.CTRL)
|
pointEditUnBindEvent(Cesium.KeyboardEventModifier.ALT)
|
pointEditUnBindEvent(Cesium.KeyboardEventModifier.SHIFT)
|
pointEditUnBindEvent(Cesium.KeyboardEventModifier.META)
|
|
pointEditHandler = null
|
}
|
|
const pointEditUnBindEvent = e => {
|
pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN, e)
|
pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE, e)
|
pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP, e)
|
}
|
|
return {
|
_init,
|
patternMap,
|
loadLAYER,
|
roadPattern,
|
switchModel,
|
switchDarkModel,
|
removeAllDataSource,
|
removeAllPoint,
|
removeById,
|
getEntityById,
|
addPoint,
|
addPolyline,
|
updateEntityPosition,
|
flyTo,
|
addLeftClickEvent,
|
removeLeftClickEvent,
|
addRightClickEvent,
|
removeRightClickEvent,
|
addLeftmounseEvent,
|
removeLeftmounseEvent,
|
|
addLeftUpClickEvent,
|
removeLeftUpClickEvent,
|
|
addLeftDownClickEvent,
|
removeLeftDownClickEvent,
|
|
addMounseHandler,
|
removeMounseEvent,
|
|
addCameraMoveEvent,
|
removeCameraMoveEvent,
|
addCircle,
|
addPolygon,
|
addEllipse,
|
isLoadingCompleted,
|
getScreenCorner,
|
setBuilding3dModel,
|
removeBuilding3dModel,
|
|
viewerDestory,
|
|
globalCesium: window.globalCesium || Cesium,
|
|
addCustomEntityDataSource,
|
clearCustomEntityDataSource,
|
removeAllCustomEntityDataSource,
|
_getMouseInfo,
|
|
addCustomImageryProviderDataSource,
|
showCustomImageryProviderDataSource,
|
removeAllCustomImageryProviderDataSource,
|
|
addCustomLayers,
|
removeCustomLayers,
|
add3Dtileset,
|
remove3Dtileset,
|
|
// 航线规划---航点航线
|
pointInitEvent,
|
pointUnInitEvent,
|
}
|
}
|