From 2800fa4f32f3900509cb4d6eefaf2bfaf54efdd7 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Mon, 21 Apr 2025 18:29:09 +0800
Subject: [PATCH] fix: 天气显示
---
src/utils/cesium/common.js | 353 ++++++++++++++++++++++++++++++----------------------------
1 files changed, 182 insertions(+), 171 deletions(-)
diff --git a/src/utils/cesium/common.js b/src/utils/cesium/common.js
index b93ec12..053ff70 100644
--- a/src/utils/cesium/common.js
+++ b/src/utils/cesium/common.js
@@ -6,189 +6,200 @@
* @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';
+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 { 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;
-};
+ 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 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;
+ // 计算朝向角度的弧度值(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;
+ 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 '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 '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;
+ case 'A': // 向左(heading - 90°)
+ newLon -= moveStep * Math.cos(headingRad)
+ newLat += moveStep * Math.sin(headingRad)
+ break
- default:
- console.warn("无效方向");
- return null;
- }
+ default:
+ console.warn('无效方向')
+ return null
+ }
- return { longitude: newLon, latitude: newLat };
+ 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)
+ }
+}
+
--
Gitblit v1.9.3