/*
|
* @Author: GuLiMmo 2820890765@qq.com
|
* @Date: 2024-03-22 14:17:13
|
* @LastEditors: GuLiMmo 2820890765@qq.com
|
* @LastEditTime: 2024-04-17 11:12:20
|
* @FilePath: /bigScreen/src/utils/cesium/common.js
|
* @Description:
|
*/
|
import * as Cesium from 'cesium'
|
import JsZip from 'jszip'
|
import _ from 'lodash'
|
import axios from 'axios'
|
import { analyzeKmzFile, XMLToJSON } from './kmz'
|
import { getCenterPoint, getLnglatDist, getShortestDistance } from './mapUtil'
|
|
// 图斑航线计算
|
export const polygonRoutePlanning = (polygonList, startPostion) => {
|
// 起始点位
|
const { longitude, latitude } = startPostion
|
// 计算中心点
|
const polygonCenterArr = polygonList.map(polygon => {
|
const newPolygon = [...new Set(polygon.map(lnglat => lnglat.join(',')))]
|
return {
|
center: getCenterPoint(polygon),
|
polygon: newPolygon.map(item => item.split(',')),
|
}
|
})
|
// 机场到中心点的距离排序
|
const airportDistanceArr = polygonCenterArr.sort((prev, next) => {
|
const prevDistance = getLnglatDist(longitude, latitude, prev.center.lng, prev.center.lat)
|
const nextDistance = getLnglatDist(longitude, latitude, next.center.lng, next.center.lat)
|
return prevDistance - nextDistance
|
})
|
|
const sortPolygon = []
|
function getFirstPolygon(arr, start) {
|
const { slongitude, slatitude } = start
|
// 机场到中心点的距离排序
|
const airportDistanceArr = arr.sort((prev, next) => {
|
const prevDistance = getLnglatDist(slongitude, slatitude, prev.center.lng, prev.center.lat)
|
const nextDistance = getLnglatDist(slongitude, slatitude, next.center.lng, next.center.lat)
|
return prevDistance - nextDistance
|
})
|
const polygon = _.cloneDeep(airportDistanceArr[0])
|
if (polygon === void 0) return
|
sortPolygon.push(polygon)
|
airportDistanceArr.splice(0, 1)
|
if (airportDistanceArr.length > 0) {
|
getFirstPolygon(airportDistanceArr, {
|
slongitude: polygon.center.lng,
|
slatitude: polygon.center.lat,
|
})
|
}
|
}
|
getFirstPolygon(polygonCenterArr, {
|
slongitude: longitude,
|
slatitude: latitude,
|
})
|
// 计算图斑内点位飞行顺序
|
let result = [[longitude, latitude]]
|
sortPolygon.forEach((item, index) => {
|
const { polygon } = item
|
// 取出当前图斑之前最后一个点
|
const prevPolygon = result[result.length - 1]
|
const [slng, slat] = prevPolygon
|
const nextPolygon = airportDistanceArr[index + 1]
|
// 求出距离上一个点最近的点,作为第一个点
|
const sequence = polygon.sort((prev, next) => {
|
const [prevLng, prevLat] = prev
|
const [nextLng, nextLat] = next
|
const prevDistance = getLnglatDist(slng, slat, prevLng, prevLat)
|
const nextDistance = getLnglatDist(slng, slat, nextLng, nextLat)
|
return prevDistance - nextDistance
|
})
|
// 第一个点位
|
const firstLnglat = [...sequence[0]]
|
// 去除第一个点位
|
const cloneSequence = _.cloneDeep(sequence)
|
cloneSequence.splice(0, 1)
|
if (nextPolygon) {
|
// 获取两个经纬度组两个最近的点位
|
const { index: lnglatIndex } = getShortestDistance(cloneSequence, nextPolygon.polygon)
|
const lastLnglat = _.cloneDeep(cloneSequence[lnglatIndex[0]])
|
// 删除飞行的最后一个点
|
cloneSequence.splice(lnglatIndex[0], 1)
|
const centerLnglatList = cloneSequence.sort((prev, next) => {
|
const [prevLng, prevLat] = prev
|
const [nextLng, nextLat] = next
|
const prevDistance = getLnglatDist(longitude, latitude, prevLng, prevLat)
|
const nextDistance = getLnglatDist(longitude, latitude, nextLng, nextLat)
|
return prevDistance - nextDistance
|
})
|
result = [...result, firstLnglat, ...centerLnglatList, lastLnglat]
|
} else {
|
// const last = polygon.sort((prev, next) => {
|
// const [prevLng, prevLat] = prev;
|
// const [nextLng, nextLat] = next;
|
// const prevDistance = getLnglatDist(longitude, latitude, prevLng, prevLat);
|
// const nextDistance = getLnglatDist(longitude, latitude, nextLng, nextLat);
|
// return prevDistance - nextDistance;
|
// });
|
result = [...result, ...sequence]
|
// result = [...result, ...last]
|
}
|
})
|
return result
|
}
|
|
export const getWaylineFilePoints = async fileUrl => {
|
const fileRes = await analyzeKmzFile(fileUrl)
|
const waylineContent = await fileRes['fileInfoObj']?.['wpmz/waylines.wpml']
|
const xml = XMLToJSON(waylineContent)
|
const placemarkArr = xml?.Document?.Folder.Placemark
|
const points = placemarkArr.map(placemark => {
|
const lnglat = placemark.Point.coordinates?.['#text'].split(',')
|
return {
|
longitude: lnglat[0],
|
latitude: lnglat[1],
|
}
|
})
|
return points
|
}
|
|
// 传入方向,计算移动点位经纬度
|
export function movePosition(lon, lat, heading, direction) {
|
// 计算朝向角度的弧度值(Cesium 是基于地理坐标系,heading=0 指向正北)
|
const headingRad = Cesium.Math.toRadians(heading)
|
const moveStep = 0.00005 // 移动步长
|
let newLon = lon
|
let newLat = lat
|
|
switch (direction) {
|
case 'W': // 向前(heading 方向)
|
newLon += moveStep * Math.sin(headingRad)
|
newLat += moveStep * Math.cos(headingRad)
|
break
|
|
case 'S': // 向后(反方向)
|
newLon -= moveStep * Math.sin(headingRad)
|
newLat -= moveStep * Math.cos(headingRad)
|
break
|
|
case 'D': // 向右(heading + 90°)
|
newLon += moveStep * Math.cos(headingRad)
|
newLat -= moveStep * Math.sin(headingRad)
|
break
|
|
case 'A': // 向左(heading - 90°)
|
newLon -= moveStep * Math.cos(headingRad)
|
newLat += moveStep * Math.sin(headingRad)
|
break
|
|
default:
|
console.warn('无效方向')
|
return null
|
}
|
|
return { longitude: newLon, latitude: newLat }
|
}
|
|
/**
|
* 添加蓝色滤镜
|
* @param options
|
* @param viewer
|
* @param layer
|
*/
|
export const addBlueFilter = (options, viewer, layer) => {
|
if (layer){
|
layer.brightness = 0.6 // 亮度(默认值)
|
layer.contrast = 1.8 // 对比度(负值降低对比度)
|
layer.hue = 1 // 色相(弧度值,3.0可能导致紫色)
|
layer.saturation = 0 // 增加饱和度强化蓝色
|
layer.gamma = 0.3 // 伽马校正(小于1.0使颜色更鲜艳)
|
}
|
|
const { bInvertColor, bFilterColor, filterColor } = options
|
|
const color = new Cesium.Color.fromCssColorString(filterColor)
|
const filterRGB = [
|
Math.round(color.red * 255),
|
Math.round(color.green * 255),
|
Math.round(color.blue * 255)
|
]
|
let fragShader = viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources
|
for (let i = 0; i < fragShader.length; i++) {
|
const strS = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
|
let strT = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
|
if (bInvertColor) {
|
strT += `
|
color.r = 1.0 - color.r;
|
color.g = 1.0 - color.g;
|
color.b = 1.0 - color.b;
|
`
|
}
|
if (bFilterColor) {
|
strT += `
|
color.r = color.r * ${filterRGB[0]}.0/255.0;
|
color.g = color.g * ${filterRGB[1]}.0/255.0;
|
color.b = color.b * ${filterRGB[2]}.0/255.0;
|
`
|
}
|
fragShader[i] = fragShader[i].replace(strS, strT)
|
}
|
}
|