将卫星图片改为3D模型

This commit is contained in:
2024-01-05 17:40:51 +08:00
parent d2cd84dab5
commit bcb9c769c4
32 changed files with 1054 additions and 136 deletions

View File

@@ -1,42 +1,69 @@
import { app, globalShortcut, BrowserWindow, dialog } from 'electron'
import { app, globalShortcut, BrowserWindow, ipcMain, dialog } from 'electron'
import { join } from 'path'
const child_process = require('child_process')
const crypto = require('crypto')
function queryKeys(keyPath: string, value: string) {
function queryPass(passPath: string, passValue: string) {
return new Promise(function (resolve, reject) {
try {
child_process.exec(`reg query ${keyPath} /v ${value}`, (error: Error, stdout: string, stderr: string) => {
if (error) {
reject(error);
return;
}
resolve({stdout, stderr});
});
child_process.exec(`reg query ${passPath} /v ${passValue}`, (error: Error, stdout: string, stderr: string) => {
if (error) {
reject(error)
return
}
resolve({stdout, stderr})
});
} catch (error) {
reject(error);
reject(error)
}
});
})
}
const keyPath = 'HKEY_CURRENT_USER\\SOFTWARE\\HwaSmart'
const value = 'global-navigation-satellite-system'
function queryKey(keyPath: string, keyValue: string) {
return new Promise(function (resolve, reject) {
try {
child_process.exec(`reg query ${keyPath} /v ${keyValue}`, (error: Error, stdout: string, stderr: string) => {
if (error) {
reject(error)
return
}
resolve({stdout, stderr})
})
} catch (error) {
reject(error)
}
})
}
function cryptMD5(GUID: string) {
let md5 = crypto.createHash('md5')
let ciphertext = md5.update(GUID).digest('hex')
return ciphertext.slice(0,8)+'-'+ciphertext.slice(8,12)+'-'+ciphertext.slice(12,16)+'-'+ciphertext.slice(16,20)+'-'+ciphertext.slice(20,32)
}
const passPath = 'HKEY_CURRENT_USER\\SOFTWARE\\HwaSmart'
const passValue = 'BDAuthorization'
const keyPath = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography'
const keyValue = 'MachineGuid'
async function checkLaunchEnv() {
try {
const result: any = await queryKeys(keyPath, value);
// console.log('stdout', result.stdout);
return true
const passResult: any = await queryPass(passPath, passValue)
const keyResult: any = await queryKey(keyPath, keyValue)
if(cryptMD5(keyResult.stdout.slice(83,119) + 'BD') == passResult.stdout.slice(72,108)){
return true
}else{
return false
}
// 成功
// 查询到 有这个app启动项
} catch (error) {
// 没有查询到该app启动项目
// console.log('error :>> ', error);
return false
}
}
function createWindow() {
const win = new BrowserWindow({
fullscreen: true,
@@ -53,13 +80,33 @@ function createWindow() {
} else {
win.loadFile('dist/render/index.html')
}
ipcMain.on('CLOSE', (event) => {
const res = dialog.showMessageBox({
type: 'warning',
title: '警告',
message: '确定要关闭软件吗?',
detail: '关闭软件',
cancelId: 1, // 按esc默认点击索引按钮
defaultId: 0, // 默认高亮的按钮下标
buttons: ['确认', '取消'], // 按钮按索引从右往左排序
})
res.then((data)=>{
if(data.response == 0){
win.close()
}else{
console.log('not close software')
}
})
})
}
async function main() {
// 异步代码
const checkReault: any = await checkLaunchEnv()
console.log('env right:', checkReault);
console.log('env right:', checkReault)
// 异步代码执行完毕后执行的代码
if (checkReault) {
@@ -88,4 +135,4 @@ async function main() {
}
}
main();
main()

View File

@@ -1,42 +1,382 @@
<template>
<vc-viewer class="vc-viewer" :animation="true" :showCredit="false" :shouldAnimate="true" :sceneModePicker="true" @ready="onViewerReady">
<vc-viewer
class="vc-viewer"
:animation="true"
:showCredit="false"
:shouldAnimate="true"
:sceneModePicker="true"
@ready="onViewerReady"
>
<vc-layer-imagery>
<vc-provider-imagery-singletile :url="earth" />
</vc-layer-imagery>
<vc-navigation :offset="[10, 40]" :position="'top-left'" :printOpts="false" :locationOpts="false" :otherOpts="false" />
<vc-navigation
:offset="[10, 40]"
:position="'top-left'"
:printOpts="false"
:locationOpts="false"
:otherOpts="false"
/>
<SatelliteSystemView />
</vc-viewer>
</template>
<script lang="ts" setup>
import earth from '../assets/earth.jpg'
import SatelliteSystemView from './SatelliteSystemView.vue';
import { defineAsyncComponent, ref, watch } from "vue";
import earth from "../assets/earth.jpg";
// 由于组件 SatelliteSystemView 加载的数据量较大,会影响到卫星模型加载的速度,因此使用 defineAsyncComponent 来延迟加载组件 SatelliteSystemView
const SatelliteSystemView = defineAsyncComponent(
() => import("./SatelliteSystemView.vue")
);
// 初始化视图参数
const onViewerReady = ({ viewer }) => {
viewer.scene.debugShowFramesPerSecond = false
window.viewer = viewer;
const scene = viewer.scene;
const camera = viewer.camera;
// 显示FPS的控件,便于优化
scene.debugShowFramesPerSecond = true;
// 设置单一光源,解决模型光照受时间影响问题
// DirectionalLight 表示 从无限远的地方向单一方向发射的光。
scene.light = new Cesium.DirectionalLight({
direction: new Cesium.Cartesian3(0.354925, -0.890918, -0.283358),
});
// 引入常用卫星模型
// 设置 minimumPixelSize 和 maximumPixelSize 都为 0 , show 为 false,使常用卫星模型无法被观察到
// 此处利用了缓存机制,提前加载模型,之后在子组件中再次加载并引用时速度会加快
// 模型对象构造方法
class Model {
constructor(modelUrl) {
const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(108.55, 34.32, 0.0)
);
this.model = viewer.scene.primitives.add(
Cesium.Model.fromGltf({
url: `./models/geo/${modelUrl}.glb`,
modelMatrix: modelMatrix,
minimumPixelSize: 0,
maximumPixelSize: 0,
show: false,
})
);
}
}
const GEOModel = new Model("BeidouGEO");
const MEOModel = new Model("BeidouMEO");
const IGSOModel = new Model("BeidouIGSO");
const GPSIIFModel = new Model("GPSII-F");
const GPSIIRModel = new Model("GPSII-R");
const GPSIIIAModel = new Model("GPSIII-A");
const GPSIIRMModel = new Model("GPSIIR-M");
const GLONASSGLOKModel = new Model("GLONASSGLO-K");
const GLONASSGLOMModel = new Model("GLONASSGLO-M");
const GalileoMEOModel = new Model("GalileoMEO");
class CustomPrimitive {
constructor(options) {
this.show = options.show;
this._primitives = options._primitives;
}
update(frameState) {
if (!this.show) {
return;
}
for (var t = this._primitives, i = 0; i < t.length; ++i) {
t[i].update(frameState);
}
}
}
class CustomPolyline {
constructor(options) {
this.show = options.show;
this._polylines = options._polylines;
this.modelMatrix = options.modelMatrix;
this._batchTable = options._batchTable;
this._createBatchTable = options._createBatchTable;
this._createVertexArray = options._createVertexArray;
this._external = options._external;
this._highlightColor = options._highlightColor;
this._mode = options._mode;
this._modelMatrix = options._modelMatrix;
this._opaqueRS = options._opaqueRS;
this._polylineBuckets = options._polylineBuckets;
this._polylinesRemoved = options._polylinesRemoved;
this._polylinesToUpdate = options._polylinesToUpdate;
this._polylinesUpdated = options._polylinesUpdated;
this._positionBuffer = options._positionBuffer;
this._positionBufferUsage = options._positionBufferUsage;
this._propertiesChanged = options._propertiesChanged;
this._texCoordExpandAndBatchIndexBuffer =
options._texCoordExpandAndBatchIndexBuffer;
this._translucentRS = options._translucentRS;
this._uniformMap = options._uniformMap;
this._useHighlightColor = options._useHighlightColor;
this._vertexArrays = options._vertexArrays;
this.mymark = true;
this._colorCommands = [];
options._colorCommands.forEach((element) => {
let adrawcommand = new Cesium.DrawCommand(element);
this._colorCommands.push(adrawcommand);
});
}
update(frameState) {
if (!this.show) {
return;
}
// if(this._mode !== viewer.scene._mode){
// this._colorCommands.forEach(item => {
// if(viewer.scene._mode == 0){
// item.boundingVolume = this._vertexArrays[0].buckets[0].bucket.polylines[0]._boundingVolume
// }
// else if(viewer.scene._mode == 1){
// item.boundingVolume = this._vertexArrays[0].buckets[0].bucket.polylines[0]._boundingVolume2D
// }
// else if(viewer.scene._mode == 3){
// item.boundingVolume = this._vertexArrays[0].buckets[0].bucket.polylines[0]._boundingVolumeWC
// }
// })
// this._mode = viewer.scene._mode
// }
this._colorCommands.forEach((item) => {
frameState.commandList.push(item);
});
}
}
// 限定缩放大小
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 10000000 // 相机高度的最小值设定为 10000000 米
// 修改infobox的样式
scene.screenSpaceCameraController.minimumZoomDistance = 10000000; // 相机高度的最小值设定为 10000000 米
scene.screenSpaceCameraController.maximumZoomDistance = 200000000; // 相机高度的最大值设定为 200000000 米
const clickStatus = ref();
const clickName = ref("cesium-sceneModePicker-button3D");
const infoBox = viewer.infoBox.frame;
infoBox.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-popups allow-forms')
infoBox.setAttribute('src', '') //必须设置src为空 否则不会生效
infoBox.addEventListener('load', function () {
const infoBoxDescriptionElement = infoBox.contentWindow.document.getElementsByClassName('cesium-infoBox-description')[0]
infoBoxDescriptionElement.style.fontSize = 'larger'
infoBoxDescriptionElement.style.paddingLeft = '20px'
infoBoxDescriptionElement.style.paddingRight = '20px'
})
}
let initialPosition = "";
let initialDirection = "";
// 修改infobox的样式
infoBox.setAttribute(
"sandbox",
"allow-same-origin allow-scripts allow-popups allow-forms"
);
infoBox.setAttribute("src", ""); // 必须设置src为空 否则不会生效
infoBox.addEventListener("load", function () {
clickStatus.value = JSON.stringify(camera.position);
viewer.infoBox.container
.getElementsByClassName("cesium-infoBox-camera")[0]
.addEventListener("click", () => {
// 完成当前相机飞行并立即将相机移动到最终目的地。
camera.completeFlight();
// 在相机停止移动时再进行操作,防止相机位置的抖动
let removeChanged = camera.moveEnd.addEventListener(() => {
clickStatus.value = JSON.stringify(camera.position);
// 调整相机到初始位置后移除监听事件
removeChanged();
});
});
const infoBoxDescriptionElement = infoBox.contentWindow.document.getElementsByClassName(
"cesium-infoBox-description"
)[0];
infoBoxDescriptionElement.style.fontSize = "larger";
infoBoxDescriptionElement.style.paddingLeft = "20px";
infoBoxDescriptionElement.style.paddingRight = "20px";
infoBoxDescriptionElement.style.paddingBottom = "10px";
// 关闭按钮的样式
const InfoBoxClose = viewer.infoBox.container.getElementsByClassName(
"cesium-infoBox-close"
)[0];
InfoBoxClose.style.padding = 0;
InfoBoxClose.style.width = "30px";
InfoBoxClose.style.height = "30px";
InfoBoxClose.style.position = "absolute";
InfoBoxClose.style.top = 0;
InfoBoxClose.style.left = "30px";
InfoBoxClose.style.zIndex = 99;
});
// 改变相机位置
const allfly = (x, y, z, h, p, r) => {
camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(x, y, z),
orientation: {
heading: Cesium.Math.toRadians(h), // 方向,以弧度为单位的航向角。
pitch: Cesium.Math.toRadians(p), // 倾斜角度,以弧度为单位的俯仰角。
roll: r,
},
});
};
const waitit = (waitallow, waitTime, x, y, z, h, p, r, buttonName) => {
if (waitallow) {
setTimeout(() => {
allfly(x, y, z, h, p, r);
if (buttonName == "cesium-sceneModePicker-button2D") {
scene.camera.position.z = 63781370;
// 相机高度问题,scene.mapProjection.ellipsoid.maximumRadius是个常数,API解释为获取椭球的最大半径为6,378,137,此处为地球半径。
// 所以三维转二维相机高度一直为12756274米,如果超过这个数值的话就不会显示模型。
// 解决办法为初始化后手动设置相机z值,具体大小视情况而定
}
}, waitTime);
} else {
allfly(x, y, z, h, p, r);
}
};
// 各视图的初始化相机位置
// window.document.getElementsByClassName('cesium-toolbar-button')[1].classList[2] 可以获取到选择后当前视图按钮的名称
const elementsFly = (waitallow) => {
if (
window.document.getElementsByClassName("cesium-toolbar-button")[1].classList[2] ==
"cesium-sceneModePicker-button3D"
) {
waitit(
waitallow,
2500,
108.55,
34.32,
100000000,
0,
-90,
0,
"cesium-sceneModePicker-button3D"
);
}
if (
window.document.getElementsByClassName("cesium-toolbar-button")[1].classList[2] ==
"cesium-sceneModePicker-button2D"
) {
waitit(
waitallow,
3500,
0,
0,
40000000,
0,
-90,
0,
"cesium-sceneModePicker-button2D"
);
}
if (
window.document.getElementsByClassName("cesium-toolbar-button")[1].classList[2] ==
"cesium-sceneModePicker-buttonColumbusView"
) {
waitit(
waitallow,
4500,
0,
-90,
40000000,
0,
-45,
0,
"cesium-sceneModePicker-buttonColumbusView"
);
}
initialPosition = JSON.stringify(camera.position);
initialDirection = JSON.stringify(camera.direction);
};
// 单击视图按钮时触发
window.document
.getElementsByClassName("cesium-toolbar-button")[0]
.addEventListener("click", () => {
if (
clickName.value !==
window.document.getElementsByClassName("cesium-toolbar-button")[1].classList[2]
) {
clickName.value = window.document.getElementsByClassName(
"cesium-toolbar-button"
)[1].classList[2];
elementsFly(true);
// 使用宏任务等待 _primitives 数组内容更新后再操作内容
setTimeout(() => {
let mypolylines;
mypolylines =
viewer.scene.primitives._primitives[
viewer.scene.primitives._primitives.length - 1
];
// console.log(window.nowModel)
// console.log(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1])
// if(window.nowModel == 'Beidou'){
// mypolylines = window.BeidouPolylines[0]
// console.log(mypolylines)
// }
// else if(window.nowModel == 'GPS'){
// mypolylines = window.GPSPolylines[0]
// console.log(mypolylines)
// }
// else if(window.nowModel == 'Galileo'){
// mypolylines = window.GalileoPolylines[0]
// console.log(mypolylines)
// }
// else if(window.nowModel == 'Glonass'){
// mypolylines = window.GlonassPolylines[0]
// console.log(mypolylines)
// }
// mypolylines = viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]
// if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1].constructor.name == 'PolylineCollection'){
viewer.scene.primitives.show = false;
// viewer.scene.primitives._primitives.pop()
let polylineowner = new CustomPolyline(mypolylines);
let newprimitive = new CustomPrimitive(viewer.scene.primitives._primitives[10]);
// viewer.scene.primitives._primitives.pop()
viewer.scene.primitives._primitives[10] = newprimitive;
viewer.scene.primitives._primitives.forEach((item, index) => {
if (item.mymark !== undefined) {
viewer.scene.primitives._primitives.splice(index, 1);
}
});
// viewer.scene.primitives._primitives.pop()
// viewer.scene.primitives._primitives.push(polylineowner)
viewer.scene.primitives.show = true;
// console.log(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1])
// }
}, 0);
}
});
// 在组件内部双击时触发
window.document
.getElementsByClassName("vc-viewer")[0]
.addEventListener("dblclick", () => {
if (initialDirection !== "") {
elementsFly(false);
}
});
// 相机位置发生变化时触发
watch(clickStatus, (value) => {
if (value !== initialPosition) {
elementsFly(false);
}
});
};
</script>
<style>
/* 隐藏动画仪表盘中的日期和时间 */
.vc-viewer .cesium-viewer .cesium-viewer-animationContainer svg > g > g text:not(:last-of-type) {
.vc-viewer
.cesium-viewer
.cesium-viewer-animationContainer
svg
> g
> g
text:not(:last-of-type) {
display: none;
}
</style>
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div v-show="!!src">
<img :src="src">
<img :src="src" @dblclick="close">
</div>
</template>
@@ -10,10 +10,14 @@ import { useStore } from 'vuex'
const store = useStore()
const src = computed(() => './image/flag/' + store.getters["satelliteSystem/name"] + '.png')
const close = () => {
window.ipcRenderer.send('CLOSE')
}
</script>
<style scoped>
img {
width: 169px;
}
</style>
</style>

View File

@@ -2,44 +2,325 @@
<vc-datasource-czml v-if="czml" :czml="czml" @ready="onDataSourceReady" />
</template>
<script lang="ts" setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
import entity from '../api/entity'
import { computed } from "vue";
import { useStore } from "vuex";
import entity from "../api/entity";
// 卫星轨道数据处理
let vcViewerInstance: any = null
const store = useStore()
const czml = computed(() => './CZML/' + store.getters["satelliteSystem/name"] + '.czml')
const onDataSourceReady = ({ viewer, cesiumObject }) => {
if (!vcViewerInstance) vcViewerInstance = viewer
let vcViewerInstance: any = null;
const store = useStore();
const czml = computed(() => "./CZML/" + store.getters["satelliteSystem/name"] + ".czml");
viewer.flyTo(cesiumObject)
entity.load(cesiumObject.entities.values)
const onDataSourceReady = ({ viewer, cesiumObject }) => {
if (!vcViewerInstance) vcViewerInstance = viewer;
// 引入常用卫星模型
// 设置 minimumPixelSize 和 maximumPixelSize 都为 0 , show 为 false,使常用卫星模型无法被观察到
// 此处利用了缓存机制,因为在父组件中模型已经加载过一次了,所以在此处再次加载模型并引用时速度会加快
// 模型对象构造方法
class Model {
constructor(modelUrl) {
const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(108.55, 34.32, 0.0)
);
this.model = viewer.scene.primitives.add(
Cesium.Model.fromGltf({
url: `./models/geo/${modelUrl}.glb`,
modelMatrix: modelMatrix,
minimumPixelSize: 0,
maximumPixelSize: 0,
show: false,
})
);
}
}
const GEOModel = new Model("BeidouGEO");
const MEOModel = new Model("BeidouMEO");
const IGSOModel = new Model("BeidouIGSO");
const GPSIIFModel = new Model("GPSII-F");
const GPSIIRModel = new Model("GPSII-R");
const GPSIIIAModel = new Model("GPSIII-A");
const GPSIIRMModel = new Model("GPSIIR-M");
const GLONASSGLOKModel = new Model("GLONASSGLO-K");
const GLONASSGLOMModel = new Model("GLONASSGLO-M");
const GalileoMEOModel = new Model("GalileoMEO");
// cesiumObject.entities.values[i].model.uri._value 存放czml文件加载的卫星模型数据
// model._resource 存放上方代码加载的卫星模型数据
// cesiumObject.entities.values[i].model.uri._value 模型加载地址为 http://localhost:3000/models/geo/geo.glb
// model._resource 模型加载地址为 ../../../public/models/geo/geo.glb
// model._resource 的模型加载速度快于 cesiumObject.entities.values[i].model.uri._value 且在数据改变时不需要重复加载
// 此处使用了提前加载一个不可观察的常用模型对象后复用该模型对象的办法来优化模型的加载速度
class CustomPrimitive {
constructor(options) {
this.show = options.show;
this._primitives = options._primitives;
}
update(frameState) {
if (!this.show) {
return;
}
for (var t = this._primitives, i = 0; i < t.length; ++i) {
t[i].update(frameState);
}
}
}
class CustomPolyline {
constructor(options) {
this.show = options.show;
this._polylines = options._polylines;
this.modelMatrix = options.modelMatrix;
this._batchTable = options._batchTable;
this._createBatchTable = options._createBatchTable;
this._createVertexArray = options._createVertexArray;
this._external = options._external;
this._highlightColor = options._highlightColor;
this._mode = options._mode;
this._modelMatrix = options._modelMatrix;
this._opaqueRS = options._opaqueRS;
this._polylineBuckets = options._polylineBuckets;
this._polylinesRemoved = options._polylinesRemoved;
this._polylinesToUpdate = options._polylinesToUpdate;
this._polylinesUpdated = options._polylinesUpdated;
this._positionBuffer = options._positionBuffer;
this._positionBufferUsage = options._positionBufferUsage;
this._propertiesChanged = options._propertiesChanged;
this._texCoordExpandAndBatchIndexBuffer =
options._texCoordExpandAndBatchIndexBuffer;
this._translucentRS = options._translucentRS;
this._uniformMap = options._uniformMap;
this._useHighlightColor = options._useHighlightColor;
this._vertexArrays = options._vertexArrays;
this.mymark = true;
this._colorCommands = [];
options._colorCommands.forEach((element) => {
// console.log(element)
// let adrawcommand = new Cesium.DrawCommand(element)
this._colorCommands.push(element);
});
}
update(frameState) {
if (!this.show) {
return;
}
// if(this._mode !== viewer.scene._mode){
// this._colorCommands.forEach(item => {
// if(viewer.scene._mode == 0){
// item.boundingVolume = this._vertexArrays[0].buckets[0].bucket.polylines[0]._boundingVolume
// }
// else if(viewer.scene._mode == 1){
// item.boundingVolume = this._vertexArrays[0].buckets[0].bucket.polylines[0]._boundingVolume2D
// }
// else if(viewer.scene._mode == 3){
// item.boundingVolume = this._vertexArrays[0].buckets[0].bucket.polylines[0]._boundingVolumeWC
// }
// })
// this._mode = viewer.scene._mode
// }
this._colorCommands.forEach((item) => {
frameState.commandList.push(item);
// console.log(frameState.commandList)
});
// for(let s = 0, l = !0, p = 0; p < this._vertexArrays.length; ++p) {
// for(let q = 0; q < this._vertexArrays[p].buckets.length; ++q) {
// for (let v, C, P = 0, d = 0; d < this._vertexArrays[p].buckets[q].bucket.polylines.length; ++d) {
// // let I = v.isTranslucent();
// // return e.color.alpha>0&&e.color.alpha<1
// s >= this._colorCommands.length ? (C = new Cesium.DrawCommand({ owner: this }), this._colorCommands.push(C)) : C = this._colorCommands[s],
// ++s,
// // T = Cesium.combine$2(d(v._uniforms), this._uniformMap),
// C.boundingVolume = Cesium.BoundingSphere.clone(new Cesium.BoundingSphere, C.boundingVolume),
// C.modelMatrix = Cesium.Matrix4.IDENTITY,
// C.shaderProgram = this._vertexArrays[p].buckets[q].bucket.shaderProgram,
// C.vertexArray = this._vertexArrays[p].buckets.va,
// C.renderState = this._opaqueRS,
// C.pass = Cesium.Pass.OPAQUE,
// C.debugShowBoundingVolume = this.debugShowBoundingVolume,
// C.pickId = "v_pickColor",
// C.uniformMap = this._uniformMap,
// C.count = P,
// C.offset = this._vertexArrays[p].buckets[q].offset,
// this._vertexArrays[p].buckets[q].offset += P,
// P = 0,
// l = !0,
// frameState.commandList.push(C)
// console.log(frameState.commandList)
// for (var R, b = 0; b < this._vertexArrays[p].buckets[q].bucket.polylines[d]._locatorBuckets.length; ++b) {
// this._vertexArrays[p].buckets[q].bucket.polylines[d]._locatorBuckets[b].locator === this._vertexArrays[p].buckets[q] && (P += this._vertexArrays[p].buckets[q].bucket.polylines[d]._locatorBuckets[b].count)
// }
// frameState.mode === 3 ? R = this._vertexArrays[p].buckets[q].bucket.polylines[d]._boundingVolumeWC : frameState.mode === 0 ? R = this._vertexArrays[p].buckets[q].bucket.polylines[d]._boundingVolume2D : frameState.mode === 1 ? defined(this._vertexArrays[p].buckets[q].bucket.polylines[d]._boundingVolume2D) && ((R = BoundingSphere.clone(this._vertexArrays[p].buckets[q].bucket.polylines[d]._boundingVolume2D, boundingSphereScratch2)).center.x = 0) : defined(this._vertexArrays[p].buckets[q].bucket.polylines[d]._boundingVolumeWC) && defined(this._vertexArrays[p].buckets[q].bucket.polylines[d]._boundingVolume2D) && (R = Cesium.BoundingSphere.union(this._vertexArrays[p].buckets[q].bucket.polylines[d]._boundingVolumeWC, this._vertexArrays[p].buckets[q].bucket.polylines[d]._boundingVolume2D, new Cesium.BoundingSphere)),
// l ? (l = !1, Cesium.BoundingSphere.clone(R, new Cesium.BoundingSphere)) : Cesium.BoundingSphere.union(R, new Cesium.BoundingSphere, new Cesium.BoundingSphere)
// }
// }
// }
}
}
// 使用宏任务等待 _primitives 数组内容更新后再操作内容
setTimeout(() => {
let mypolylines;
mypolylines =
viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length - 1];
// console.log(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]._polylines[0]._id.entityCollection._owner)
// console.log(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1].constructor.name)
// if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]._polylines[0]._id.entityCollection._owner._documentPacket.name == 'BEIDOU CZML Model'){
// window.nowModel = 'Beidou'
// window.BeidouPolylines = [viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]]
// if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1].constructor.name == 'PolylineCollection'){
// mypolylines = viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]
// console.log(mypolylines)
// }
// }
// else if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]._polylines[0]._id.entityCollection._owner._documentPacket.name == 'GPS CZML Model'){
// window.nowModel = 'GPS'
// window.GPSPolylines = [viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]]
// if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1].constructor.name == 'PolylineCollection'){
// mypolylines = viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]
// console.log(mypolylines)
// }
// }
// else if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]._polylines[0]._id.entityCollection._owner._documentPacket.name == 'GALILEO CZML Model'){
// window.nowModel = 'Galileo'
// window.GalileiPolylines = viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]
// if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1].constructor.name == 'PolylineCollection'){
// mypolylines = viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]
// console.log(mypolylines)
// }
// }
// else if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]._polylines[0]._id.entityCollection._owner._documentPacket.name == 'GLONASS CZML Model'){
// window.nowModel = 'Glonass'
// window.GlonassPolylines = viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]
// if(viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1].constructor.name == 'PolylineCollection'){
// mypolylines = viewer.scene.primitives._primitives[viewer.scene.primitives._primitives.length-1]
// console.log(mypolylines)
// }
// }
viewer.scene.primitives.show = false;
let polylineowner = new CustomPolyline(mypolylines);
let newprimitive = new CustomPrimitive(viewer.scene.primitives._primitives[10]);
viewer.scene.primitives._primitives[10] = newprimitive;
viewer.scene.primitives._primitives.forEach((item, index) => {
if (item.mymark) {
viewer.scene.primitives._primitives.splice(index, 1);
}
});
// viewer.scene.primitives._primitives.pop()
// viewer.scene.primitives._primitives.push(polylineowner)
viewer.scene.primitives.show = true;
}, 0);
cesiumObject.entities.values.forEach((element) => {
if (element.model !== undefined) {
// 调整卫星名称显示位置
element.label.pixelOffset._value = new Cesium.Cartesian2(12, 21);
// 根据卫星系统名称为其替换不同的卫星模型
if (element.properties.satelliteType._value == "Beidou") {
if (element.description._value.indexOf("GEO") !== -1) {
element.model.uri._value = GEOModel.model._resource;
} else if (element.description._value.indexOf("MEO") !== -1) {
element.model.uri._value = MEOModel.model._resource;
} else if (element.description._value.indexOf("IGSO") !== -1) {
element.model.uri._value = IGSOModel.model._resource;
}
} else if (element.properties.satelliteType._value == "GPS") {
// 指定基于漫反射和镜面反射图像的照明的贡献,调整模型亮度
element.model.imageBasedLightingFactor = new Cesium.Cartesian2(20, 1);
if (element.description._value.indexOf("II-F") !== -1) {
element.model.uri._value = GPSIIFModel.model._resource;
}
if (element.description._value.indexOf("II-R") !== -1) {
element.model.uri._value = GPSIIRModel.model._resource;
}
if (element.description._value.indexOf("III-A") !== -1) {
element.model.uri._value = GPSIIIAModel.model._resource;
}
if (element.description._value.indexOf("IIR-M") !== -1) {
element.model.uri._value = GPSIIRMModel.model._resource;
}
} else if (element.properties.satelliteType._value == "GLONASS") {
// 指定基于漫反射和镜面反射图像的照明的贡献,调整模型亮度
element.model.imageBasedLightingFactor = new Cesium.Cartesian2(10, 1);
if (element.description._value.indexOf("GLO-K") !== -1) {
element.model.uri._value = GLONASSGLOKModel.model._resource;
}
if (element.description._value.indexOf("GLO-M") !== -1) {
element.model.uri._value = GLONASSGLOMModel.model._resource;
}
} else if (element.properties.satelliteType._value == "Galileo") {
// 指定基于漫反射和镜面反射图像的照明的贡献,调整模型亮度
element.model.imageBasedLightingFactor = new Cesium.Cartesian2(20, 1);
if (element.description._value.indexOf("MEO") !== -1) {
element.model.uri._value = GalileoMEOModel.model._resource;
}
}
}
});
entity.load(cesiumObject.entities.values);
// 显示卫星导航系统的科普信息
viewer.selectedEntity = entity.find('Constellation')
}
viewer.selectedEntity = entity.find("Constellation");
// 设置相机初始位置
const allfly = (x, y, z, h, p, r) => {
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(x, y, z),
orientation: {
heading: Cesium.Math.toRadians(h), // 方向,以弧度为单位的航向角。
pitch: Cesium.Math.toRadians(p), // 倾斜角度,以弧度为单位的俯仰角。
roll: r,
},
});
};
if (
window.document.getElementsByClassName("cesium-toolbar-button")[1].classList[2] ==
"cesium-sceneModePicker-button3D"
) {
allfly(108.55, 34.32, 100000000, 0, -90, 0);
}
if (
window.document.getElementsByClassName("cesium-toolbar-button")[1].classList[2] ==
"cesium-sceneModePicker-button2D"
) {
allfly(0, 0, 40000000, 0, -90, 0);
viewer.scene.camera.position.z = 63781370;
}
if (
window.document.getElementsByClassName("cesium-toolbar-button")[1].classList[2] ==
"cesium-sceneModePicker-buttonColumbusView"
) {
allfly(0, -90, 40000000, 0, -45, 0);
}
};
// 显示/隐藏、跟踪卫星等交互操作
store.subscribeAction(({ type, payload }) => {
// 显示/隐藏卫星
if (type === 'satelliteSystem/toggleShow') {
const satellite = entity.get(payload)
if (!satellite) return
if (type === "satelliteSystem/toggleShow") {
const satellite = entity.get(payload);
if (!satellite) return;
satellite.show = !satellite.show
satellite.show = !satellite.show;
}
// 跟踪卫星
if (type === 'satelliteSystem/track') {
const satellite = entity.get(payload)
if (!satellite || !vcViewerInstance) return
if (type === "satelliteSystem/track") {
const satellite = entity.get(payload);
if (!satellite || !vcViewerInstance) return;
vcViewerInstance.selectedEntity = satellite
vcViewerInstance.trackedEntity = satellite
vcViewerInstance.selectedEntity = satellite;
vcViewerInstance.trackedEntity = satellite;
}
})
</script>
});
</script>

View File

@@ -2,11 +2,21 @@
<div>
<div id="satellite-table-container" class="text-white absolute bottom-0 text-center">
<button @click="show = !show" class="rounded border-blue-900 bg-blue-900">
<svg v-if="show" xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 13l-7 7-7-7m14-8l-7 7-7-7" />
<svg v-if="show" xmlns="http://www.w3.org/2000/svg" width="600" height="30" fill="none" viewBox="-10 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M -200 8 l 200 10 200 -10 m -400 -6 l 200 10 200 -10">
<animate attributeName="stroke" attributeType="XML"
from="#ffffff" to="#666666"
begin="0s" dur="1.5s"
fill="remove" repeatCount="indefinite"/>
</path>
</svg>
<svg v-else xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 11l7-7 7 7M5 19l7-7 7 7" />
<svg v-else xmlns="http://www.w3.org/2000/svg" width="600" height="30" fill="none" viewBox="-10 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M -200 20 l 200 -10 200 10 m -400 -6 l 200 -10 200 10">
<animate attributeName="stroke" attributeType="XML"
from="#ffffff" to="#666666"
begin="0s" dur="1.5s"
fill="remove" repeatCount="indefinite"/>
</path>
</svg>
</button>
<table ref="satelliteTable" v-show="show" class="text-center">
@@ -16,6 +26,7 @@
:key="label"
:style="{width: index == 1 ? '37.5vw' : '12.5vw'}">
{{ label }}
<input v-if="label == '显示/隐藏'" :indeterminate="someshow" :checked="allshow" type="checkbox" class="w-6 h-6 cursor-pointer" @change="allOnShowStateCheckboxChanged" />
</th>
</thead>
<tbody class="text-lg odd:bg-gray-50">
@@ -23,7 +34,7 @@
<td class="border border-gray-900"> {{ index + 1 }} </td>
<td class="border border-gray-900"> {{ id }} </td>
<td class="border border-gray-900">
<input :checked="show" type="checkbox" class="w-6 h-6 cursor-pointer" @change="onShowStateCheckboxChanged(id)" />
<input :checked="ashow" type="checkbox" class="w-6 h-6 cursor-pointer" @change="onShowStateCheckboxChanged(id)" />
</td>
<td class="border border-gray-900">
<button @click="onTrackButtonClicked(id)">
@@ -45,15 +56,71 @@ import { ref, computed, watch } from 'vue'
const show = ref(false)
const ashow = ref(true)
const someshow = ref(false)
const allshow = ref(true)
const showarr = ref({})
const store = useStore()
const satellites = computed(() => store.getters["satelliteSystem/satellites"])
const onTrackButtonClicked = id => store.dispatch('satelliteSystem/track', id)
const onShowStateCheckboxChanged = id => store.dispatch('satelliteSystem/toggleShow', id)
const store = useStore()
const satellites = computed(() => store.getters["satelliteSystem/satellites"])
const onTrackButtonClicked = (id) => {
store.dispatch('satelliteSystem/track', id)
}
const onShowStateCheckboxChanged = (id) => {
// console.log(window.viewer.scene.primitives._primitives[window.viewer.scene.primitives._primitives.length-1])
// window.viewer.scene.primitives._primitives[window.viewer.scene.primitives._primitives.length-1]._polylines.forEach(element => {
// if(element._id._id == id){
// if(element._show){
// element._show == false
// }else{
// element._show == true
// }
// }
// })
someshow.value = true
showarr.value[id] = !showarr.value[id]
store.dispatch('satelliteSystem/toggleShow', id)
let ashowsum = 0
satellites.value.forEach((item,index) => {
if(showarr.value[item.id] == true){
ashowsum = ashowsum + 1
}
})
if(ashowsum == 0){
someshow.value = false
}else if(ashowsum == satellites.value.length){
someshow.value = false
}
}
const allOnShowStateCheckboxChanged = () => {
if(allshow.value){
allshow.value = false
ashow.value = false
}else{
allshow.value = true
ashow.value = true
}
satellites.value.forEach(element => {
if(showarr.value[element.id] !== ashow.value){
onShowStateCheckboxChanged(element.id)
}
onShowStateCheckboxChanged(element.id)
})
someshow.value = false
}
// 表格数据更新时,滚动条回到最顶部
const satelliteTable = ref(null)
watch(satellites, () => satelliteTable.value.scrollTop = 0)
watch(satellites, () => {
ashow.value = true
someshow.value = false
allshow.value = true
showarr.value = {}
satellites.value.forEach(item => {
showarr.value[item.id] = false
})
satelliteTable.value.scrollTop = 0
})
</script>
<style scoped>

View File

@@ -0,0 +1,134 @@
PolylineCollection.prototype.update = function (e) {
if (removePolylines(this), 0 !== this._polylines.length && this.show) {
updateMode$1(this, e);
var t,
i = e.context,
r = e.mapProjection,
n = this._propertiesChanged;
if (this._createBatchTable) {
if (0 === ContextLimits.maximumVertexTextureImageUnits)
throw new RuntimeError("Vertex texture fetch support is required to render polylines. The maximum number of vertex texture image units must be greater than zero.");
createBatchTable(this, i),
this._createBatchTable = !1
}
if (this._createVertexArray || computeNewBuffersUsage(this))
createVertexArrays(this, i, r);
else if (this._polylinesUpdated) {
var a = this._polylinesToUpdate;
if (this._mode !== SceneMode$1.SCENE3D)
for (var o = a.length, s = 0; s < o; ++s)
(t = a[s]).update();
if (n[POSITION_SIZE_INDEX] || n[MATERIAL_INDEX])
createVertexArrays(this, i, r);
else for (var l = a.length, c = this._polylineBuckets, u = 0; u < l; ++u) {
n = (t = a[u])._propertiesChanged;
var d = t._bucket,
h = 0;
for (var p in c)
if (c.hasOwnProperty(p)) {
if (c[p] === d) {
n[POSITION_INDEX$4] && d.writeUpdate(h, t, this._positionBuffer, r);
break
}
h += c[p].lengthOfPositions
}
if ((n[SHOW_INDEX$4] || n[WIDTH_INDEX]) && this._batchTable.setBatchedAttribute(t._index, 0, new Cartesian2(t._width, t._show)), this._batchTable.attributes.length > 2) {
if (n[POSITION_INDEX$4] || n[POSITION_SIZE_INDEX]) {
var f = e.mode === SceneMode$1.SCENE2D ? t._boundingVolume2D : t._boundingVolumeWC,
m = EncodedCartesian3.fromCartesian(f.center, scratchUpdatePolylineEncodedCartesian),
g = Cartesian4.fromElements(m.low.x, m.low.y, m.low.z, f.radius, scratchUpdatePolylineCartesian4);
this._batchTable.setBatchedAttribute(t._index, 2, m.high),
this._batchTable.setBatchedAttribute(t._index, 3, g)
}
if (n[DISTANCE_DISPLAY_CONDITION]) {
var _ = scratchNearFarCartesian2;
_.x = 0,
_.y = Number.MAX_VALUE;
var y = t.distanceDisplayCondition;
defined(y) && (_.x = y.near, _.y = y.far),
this._batchTable.setBatchedAttribute(t._index, 4, _)
}
} t._clean()
}
a.length = 0,
this._polylinesUpdated = !1
}
n = this._propertiesChanged;
for (var v = 0; v < NUMBER_OF_PROPERTIES$2; ++v)
n[v] = 0;
var C = Matrix4.IDENTITY;
e.mode === SceneMode$1.SCENE3D && (C = this.modelMatrix);
var T = e.passes,
S = 0 !== e.morphTime;
if (defined(this._opaqueRS) && this._opaqueRS.depthTest.enabled === S || (this._opaqueRS = RenderState.fromCache({ depthMask: S, depthTest: { enabled: S } })), defined(this._translucentRS) && this._translucentRS.depthTest.enabled === S || (this._translucentRS = RenderState.fromCache({ blending: BlendingState$1.ALPHA_BLEND, depthMask: !S, depthTest: { enabled: S } })), this._batchTable.update(e), T.render || T.pick)
createCommandLists(this, e, this._colorCommands, C)
}
};
var boundingSphereScratch$2 = new BoundingSphere,
boundingSphereScratch2 = new BoundingSphere;
function createCommandLists(e, t, i, r) {
for (var n = t.context, a = t.commandList, o = i.length, s = 0, l = !0, c = e._vertexArrays, u = e.debugShowBoundingVolume, d = e._batchTable.getUniformMapCallback(), h = c.length, p = 0; p < h; ++p)
for (var f = c[p], m = f.buckets, g = m.length, _ = 0; _ < g; ++_) {
for (var y, v, C, T, S = m[_], A = S.offset, x = S.bucket.shaderProgram, E = S.bucket.polylines, b = E.length, P = 0, D = 0; D < b; ++D) {
var w = E[D],
M = createMaterialId(w._material);
if (M !== y) {
if (defined(y) && P > 0) {
var I = v.isTranslucent();
s >= o ? (C = new DrawCommand({ owner: e }), i.push(C)) : C = i[s],
++s,
T = combine$2(d(v._uniforms), e._uniformMap),
C.boundingVolume = BoundingSphere.clone(boundingSphereScratch$2, C.boundingVolume),
C.modelMatrix = r,
C.shaderProgram = x,
C.vertexArray = f.va,
C.renderState = I ? e._translucentRS : e._opaqueRS,
C.pass = I ? Pass$1.TRANSLUCENT : Pass$1.OPAQUE,
C.debugShowBoundingVolume = u,
C.pickId = "v_pickColor",
C.uniformMap = T,
C.count = P,
C.offset = A,
A += P,
P = 0,
l = !0,
a.push(C)
}
(v = w._material).update(n),
y = M
}
for (var R, O = w._locatorBuckets, B = O.length, L = 0; L < B; ++L) {
var F = O[L];
F.locator === S && (P += F.count)
}
t.mode === SceneMode$1.SCENE3D ? R = w._boundingVolumeWC : t.mode === SceneMode$1.COLUMBUS_VIEW ? R = w._boundingVolume2D : t.mode === SceneMode$1.SCENE2D ? defined(w._boundingVolume2D) && ((R = BoundingSphere.clone(w._boundingVolume2D, boundingSphereScratch2)).center.x = 0) : defined(w._boundingVolumeWC) && defined(w._boundingVolume2D) && (R = BoundingSphere.union(w._boundingVolumeWC, w._boundingVolume2D, boundingSphereScratch2)),
l ? (l = !1, BoundingSphere.clone(R, boundingSphereScratch$2)) : BoundingSphere.union(R, boundingSphereScratch$2, boundingSphereScratch$2)
} defined(y) && P > 0 && (
s >= o ? (C = new DrawCommand({ owner: e }), i.push(C)) : C = i[s],
++s,
T = combine$2(d(v._uniforms), e._uniformMap),
C.boundingVolume = BoundingSphere.clone(boundingSphereScratch$2, C.boundingVolume),
C.modelMatrix = r,
C.shaderProgram = x,
C.vertexArray = f.va,
C.renderState = v.isTranslucent() ? e._translucentRS : e._opaqueRS,
C.pass = v.isTranslucent() ? Pass$1.TRANSLUCENT : Pass$1.OPAQUE,
C.debugShowBoundingVolume = u,
C.pickId = "v_pickColor",
C.uniformMap = T,
C.count = P,
C.offset = A,
l = !0,
a.push(C)
),
y = void 0
}
i.length = s
}
function computeNewBuffersUsage(e) {
var t = !1,
i = e._propertiesChanged,
r = e._positionBufferUsage;
return i[POSITION_INDEX$4] ? r.bufferUsage !== BufferUsage$1.STREAM_DRAW ? (t = !0, r.bufferUsage = BufferUsage$1.STREAM_DRAW, r.frameCount = 100) : r.frameCount = 100 : r.bufferUsage !== BufferUsage$1.STATIC_DRAW && (0 === r.frameCount ? (t = !0, r.bufferUsage = BufferUsage$1.STATIC_DRAW) : r.frameCount--),
t
}

View File

@@ -19,9 +19,11 @@ const actions = {
commit('setSatellites', satellites)
},
track () {},
track () {
},
toggleShow () {},
toggleShow () {
},
}
// mutations
@@ -41,4 +43,4 @@ export default {
getters,
actions,
mutations
}
}