将卫星图片改为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

@@ -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>