面向战场的cesium基础到进阶的案例展示(我相信VIP总是有原因的)

该博客详细介绍了如何使用Cesium进行战场环境的模拟,包括加载通讯飞机、运输机与无人机协同、雷达及导弹操作、干扰波发射和飞机环飞等场景。通过实例代码展示了Cesium在三维可视化中的应用,适合具备js和Vue经验的开发者参考。
摘要由CSDN通过智能技术生成

cesium 前置说明(友情提示,关注重点代码,其他影响复现的都可以删除或者替换数值解决)

  • 这里面用到了cesium的模型加载、图片加载、着色器、实时改变模型状态、模型删除等知识点,这需要你自己去观摩
  • 下述会包含所有相关代码,他们的联系其实在代码中能看到(比如飞机操作类会调用时间类等),代码相对复杂,需要有一定js编码经验及vue编程经验的人去理解查看。
  • 已经加载了cesium基础框架
    • 没有加载好的,直接看cesium官网示例:https://sandcastle.cesium.com/
  • 准备好数据基础参数(我自定义了与飞机相关的json数据,放在文末位置了,可以直接使用)

展示整体场景的结构

  1. 场景展示:
  • 关联通讯飞机及飞机展示通讯监测范围
    在这里插入图片描述

  • 运输机释放无人机,无人机与运输机协同飞行
    在这里插入图片描述
    在这里插入图片描述

  • 雷达开启及发射导弹
    在这里插入图片描述

  • 飞机发射干扰波
    在这里插入图片描述

  • 飞机绕环飞行
    在这里插入图片描述

  1. 定义飞机操作类、飞机基础类、雷达操作类、时间类、场景类、场景绑定类、主要程序入口类
  • 主要程序入口类

//加载战场
battleFieldLoading(viewer);
//加载多个交互场景
battleFieldCommunication(viewer);

// 以下定义均是引用其他类
var tt = new TimeTool(2000, 100);
radarStation.loadTimeModule(tt);
planes.loadTimeModule(tt);


//战场加载
export function battleFieldLoading(viewer: Cesium.Viewer) {
    //定义全局时间
    tt.setMoudule(viewer);
    // 加载多个雷达:6000为扫描半径 米
    radarStation.addRadarByJson(viewer, Cesium.Color.RED, 6000, [0, 1, 2, 3, 4, 5, 7, 8]);
    // 加载诱饵机
    planes.setLinePositions("red", "DECOYS")
    planes.loadPlaneByTrajectory(viewer, "red", "DECOYS", false);
    // 加载多个电子站专用飞机EW
    planes.setLinePositions("red", "AIREW");
    planes.loadPlaneByTrajectory(viewer, "red", "AIREW", false);
    // 加载F135飞机
    planes.setLinePositions("red", "F35")
    planes.loadPlaneByTrajectory(viewer, "red", "F35", false);
    // 加载货运机
    planes.setLinePositions("red", "KINETICS")
    planes.loadPlaneByTrajectory(viewer, "red", "KINETICS", false);
    planes.showPlaneCommunication(viewer, "red", "KINETICS");
    planes.showNonPlaneCommunication(viewer, "red", "KINETICS", "F35", [1, 3], [7, 8]);
    planes.loadPlaneSector(viewer, "red", "KINETICS", [0, 1, 2, 3]);
    //加载蓝方-ISR飞机
    planes.setCirclePositions([116.10417676302052, 22.949787916971527, 1000], 2000, "ISRS", viewer);
    planes.loadPlaneByTrajectory(viewer, "blue", "ISRS", false);
    planes.loadPlaneUpgradewave(viewer, "blue", "ISRS", [0, 1], 2);
};
export function battleFieldCommunication(viewer: Cesium.Viewer) {
    var lt = new ListernTool();
    lt.addInterval(viewer, tt, radarStation, planes);//添加所有飞机交互的效果
    // var modelIndicator = "modelIndicator";
    // var modelcss = document.getElementById(modelIndicator);
    // lt.addClickTrigger(modelcss); //添加飞机信息显示
}
  • 飞机操作类

import * as Cesium from "cesium";
import * as variable from '@/data/aircraft.json';
import { TimeTool } from "@/libs/battlefield-show/time";
import { findModel, getPointOnCircle, removeModel } from "@/libs/battlefield-show/effect";
import { default as TrailMaterial, generateCurve } from "@/libs/materials/PolylineTrailMaterialProperty.js"
import { deepClone, getSurroundingsPoint } from "@/libs/Utils";
import { planeFactory } from "@/libs/battlefield-show/plane";
const bs = (variable as any);
export var planes = {
    positions: new Array<Array<Array<number>>>,
    planeFactory: planeFactory(),
    // 获得线性轨迹点
    setLinePositions: function (role: string, PlaneName: string): any {
        let PlaneXs = bs.players[role][PlaneName];
        this.positions.length = 0;
        for (let i: number = 0; i < PlaneXs.length; i++) {
            var startposition = Cesium.Cartesian3.fromDegrees(PlaneXs[i]["startposition"][0], PlaneXs[i]["startposition"][1], PlaneXs[i]["startposition"][2]);
            var endposition = Cesium.Cartesian3.fromDegrees(PlaneXs[i]["endPosition"][0], PlaneXs[i]["endPosition"][1], PlaneXs[i]["endPosition"][2]);
            let flightData: Array<Array<number>> = new Array<Array<any>>;
            flightData.push([startposition.x, startposition.y, startposition.z]);
            flightData.push([endposition.x, endposition.y, endposition.z]);
            this.positions.push(flightData);
        }
    },
    //加载全局时间
    timeTool: new TimeTool(2000, 1),
    loadTimeModule: function (TimeTool) {
        this.timeTool = TimeTool;
    },
    // 根据轨迹加载飞机
    loadPlaneByTrajectory: function (viewer: Cesium.Viewer, role: string, PlaneName: string, ishightLight: boolean) {
        let totalSeconds = this.timeTool.getTotalSeconds();
        let start = this.timeTool.getStart();
        let stop = this.timeTool.getStop();
        let PlaneXs = bs.players[role][PlaneName];
        var tep = 0;
        const curPostions = this.positions;
        tep = Math.ceil(totalSeconds / curPostions[0].length);
        for (let ai: number = 0; ai < curPostions.length; ai++) {
            // 添加位置信息
            const positionProperty = new Cesium.SampledPositionProperty();
            const time = Cesium.JulianDate.addSeconds(start, 0, new Cesium.JulianDate());
            const position = new Cesium.Cartesian3(curPostions[ai][0][0], curPostions[ai][0][1], curPostions[ai][0][2]);
            positionProperty.addSample(time, position);
            for (let i: number = 1; i < curPostions[ai].length; i++) {
                const dataPoint = curPostions[ai][i];
                // console.log("当前高度",dataPoint[2]);
                const time = Cesium.JulianDate.addSeconds(start, (i + 1) * tep, new Cesium.JulianDate());
                const position = new Cesium.Cartesian3(dataPoint[0], dataPoint[1], dataPoint[2]);
                positionProperty.addSample(time, position);
            }
            // const eyeOffsetW = new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -100000));
            if (PlaneXs[ai]["image"].search("png") != -1) {
                var entity = viewer.entities.getById(PlaneXs[ai]["id"]);
                if (entity == null) {
                    var PlaneplaneEntity = viewer.entities.add({
                        id: PlaneXs[ai]["id"],
                        availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: stop })]),
                        label: {
                            font: "12px Helvetica",
                            text: PlaneXs[ai]["label"],
                            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                            outlineWidth: 2,
                            verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //垂直方向以底部来计算标签的位置
                            pixelOffset: new Cesium.Cartesian2(-10, 20),   //偏移量
                            disableDepthTestDistance: Number.POSITIVE_INFINITY,
                            show: true
                        },
                        position: positionProperty,
                        billboard: {
                            scale: 1,//放大倍数
                            width: PlaneXs[ai]["width"],
                            height: PlaneXs[ai]["height"],
                            //  eyeOffset:  eyeOffsetW,
                            image: `images/${PlaneXs[ai]["image"]}`//getImageUrl(res!.image),
                        },
                        orientation: new Cesium.VelocityOrientationProperty(positionProperty),
                    });
                }
                else {
                    entity.show = true;
                }
            } else {
                var entity = viewer.entities.getById(PlaneXs[ai]["id"]);
                var planeColor = Cesium.Color.RED;
                if (role == "blue") {
                    planeColor = Cesium.Color.BLUE;
                }
                if (entity == null) {
                    const PlaneplaneUri = Cesium.IonResource.fromAssetId(1433937);
                    var PlaneplaneEntity = viewer.entities.add({
                        id: PlaneXs[ai]["id"],
                        availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: stop })]),
                        label: {
                            font: "12px Helvetica",
                            text: PlaneXs[ai]["label"],
                            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                            outlineWidth: 2,
                            verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //垂直方向以底部来计算标签的位置
                            pixelOffset: new Cesium.Cartesian2(-10, 20),   //偏移量
                            disableDepthTestDistance: Number.POSITIVE_INFINITY,
                            show: true
                        },
                        position: positionProperty,
                        // Attach the 3D model instead of the green point.
                        model: {
                            uri: `models/aircraft/${PlaneXs[ai]["image"]}`,
                            scale: 5000,//放大倍数
                            color: Cesium.Color.fromAlpha(planeColor, 0.5),//设置模型颜色与透明度
                            colorBlendMode: Cesium.ColorBlendMode.HIGHLIGHT  //设置颜色与原纹理的混合关系
                            // silhouetteColor: Cesium.Color.fromAlpha(Cesium.Color.BLUE, 1),//设置模型外轮廓颜色与透明度
                            // silhouetteSize: Cesium.Color.fromAlpha(Cesium.Color.RED, 1),//设置模型颜色与透明度
                        },
                        orientation: new Cesium.VelocityOrientationProperty(positionProperty)
                    });
                } else {
                    entity.show = true;
                }
            }
        }
    },
    // loadPlaneByLineTra: function (viewer: Cesium.Viewer, role: string, planeName: string, ishightLight: boolean) {
    //     let planeXs = bs.players[role][planeName];
    //     var planeColor = Cesium.Color.RED;
    //     if (role == "blue") {
    //         planeColor = Cesium.Color.BLUE;
    //     }
    //     for (let ai: number = 0; ai < planeXs.length; ai++) {
    //         var plane = this.planeFactory.createPlane(planeXs[ai]["id"], planeXs[ai]["label"], planeXs[ai]["model"], planeXs[ai]["width"], planeXs[ai]["height"],
    //             planeXs[ai]["image"]);
    //         plane.setLinePositions(planeXs[ai]["startposition"], planeXs[ai]["endPosition"]);
    //         plane.fly(viewer, planeColor, this.timeTool);
    //     }
    // },
    loadLineEntity(viewer, deplyTime, totalSeconds, start, axPositions, _difLng, _difLat) {
        // var isExist = findModel(viewer, "CSWSUR");
        // if (isExist) {
        //     return;
        // }
        // removeModel(viewer, "CSWSUR");
        var timdif = 0;
        const comlinesEntity = viewer.entities.add({
            id: "CSWSUR",
            name: "Red polygon on surface",
            polyline: {
                positions: new Cesium.CallbackProperty((time) => {
                    timdif = Cesium.JulianDate.secondsDifference(time, start);
                    if (timdif < deplyTime) {
                        return null;
                    }
                    // // 超出绑定时间
                    // if (timdif > totalSeconds) {
                    //     timdif = 0.0;
                    // }
                    let positions: number[] = [];
                    for (var i: number = 0; i < axPositions.length; i++) {
                        var _currentPoLng = axPositions[i][0] - _difLng * (timdif - deplyTime);
                        var _currentPoLat = axPositions[i][1] + _difLat * (timdif - deplyTime);
                        var _curentHeight = 100;
                        positions.push(_currentPoLng);
                        positions.push(_currentPoLat);
                        positions.push(_curentHeight);
                    }
                    return Cesium.Cartesian3.fromDegreesArrayHeights(positions);
                }, false),
                material: new Cesium.PolylineGlowMaterialProperty({
                    glowPower: 0.2,
                    taperPower: 0.5,
                    color: Cesium.Color.WHITE,
                })
            },
        });
        comlinesEntity.label = new Cesium.LabelGraphics({
            // position:
            text: 'Red polygon on surface',
            style: Cesium.LabelStyle.FILL,
            fillColor: Cesium.Color.WHITE,
            font: 'normal 32px MicroSoft YaHei',
            showBackground: true,
            scale: 0.5,
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            disableDepthTestDistance: 10000.0
        });
    },
    //加载集群多边形
    showPolygonByTrajectory: function (viewer: Cesium.Viewer, role: string, PlaneName: string, positions) {
        let totalSeconds = this.timeTool.getTotalSeconds();
        let start = this.timeTool.getStart();
        let PlaneXs = bs.players[role][PlaneName];
        let height = bs.players.red.allHeight;
        var axPositions = positions;
        axPositions = [
            PlaneXs[0]["startposition"][0],
            PlaneXs[0]["startposition"][1],
            height,
            PlaneXs[1]["startposition"][0],
            PlaneXs[1]["startposition"][1],
            height,
            PlaneXs[6]["startposition"][0],
            PlaneXs[6]["startposition"][1],
            height,
            PlaneXs[7]["startposition"][0],
            PlaneXs[7]["startposition"][1],
            height,
            PlaneXs[10]["startposition"][0],
            PlaneXs[10]["startposition"][1],
            height,
            PlaneXs[9]["startposition"][0],
            PlaneXs[9]["startposition"][1],
            height,
            PlaneXs[8]["startposition"][0],
            PlaneXs[8]["startposition"][1],
            height,
            PlaneXs[3]["startposition"][0],
            PlaneXs[3]["startposition"][1],
            height,
            PlaneXs[2]["startposition"][0],
            PlaneXs[2]["startposition"][1],
            height,
            PlaneXs[0]["startposition"][0],
            PlaneXs[0]["startposition"][1],
            height
        ];
        var _difLng = (PlaneXs[0]["startposition"][0] - PlaneXs[0]["endPosition"][0]) / totalSeconds;
        var _difLat = (PlaneXs[0]["startposition"][1] - PlaneXs[0]["endPosition"][1]) / totalSeconds;
        var timdif = 0.0;
        this.loadLineEntity(viewer, timdif, totalSeconds, start, axPositions, _difLng, _difLat);
    },
    // 加载飞机
    showC130ReleaseColony: function (viewer: Cesium.Viewer, releasePlane: number, initTime: number) {
        let C130 = bs.players["red"]["C130"];
        var startPos = C130[0]["startposition"];
        var endPos = C130[0]["endPosition"];
        let totalSeconds = this.timeTool.getTotalSeconds();
        let start = this.timeTool.getStart();
        var positions: Array<Array<number>> = [];
        for (let i = 0; i < releasePlane; i++) {
            var endPositionX: number = startPos[0] + 0.02 * (Math.random() * 20 - 10);
            var endPositionY: number = startPos[1] + 0.04 * Math.random() * 10;
            positions.push([endPositionX, endPositionY]);
            // 添加集群飞机的位置信息
            var CMpositionProperty = new Cesium.SampledPositionProperty();
            var time = Cesium.JulianDate.addSeconds(start, 0, new Cesium.JulianDate());
            var startPocCeium = Cesium.Cartesian3.fromDegrees(startPos[0], startPos[1], startPos[2]);
            CMpositionProperty.addSample(time, startPocCeium);
            var midTime = Cesium.JulianDate.addSeconds(start, initTime, new Cesium.JulianDate());
            var midPosition = Cesium.Cartesian3.fromDegrees(endPositionX, endPositionY, startPos[2]);
            CMpositionProperty.addSample(midTime, midPosition);
            var endTime = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate());
            var endPosition = Cesium.Cartesian3.fromDegrees(endPositionX, endPositionY + 0.2, startPos[2]);
            CMpositionProperty.addSample(endTime, endPosition);
            // 添加C130位置信息
            var C130positionProperty = new Cesium.SampledPositionProperty();
            var time = Cesium.JulianDate.addSeconds(start, 0, new Cesium.JulianDate());
            var startPocCeium = Cesium.Cartesian3.fromDegrees(startPos[0], startPos[1], startPos[2]);
            C130positionProperty.addSample(time, startPocCeium);
            var midTime = Cesium.JulianDate.addSeconds(start, initTime, new Cesium.JulianDate());
            var midPosition = Cesium.Cartesian3.fromDegrees(startPos[0], startPos[1], startPos[2]);
            C130positionProperty.addSample(midTime, midPosition);
            var endTime = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate());
            var endPosition = Cesium.Cartesian3.fromDegrees(endPos[0], endPos[1], endPos[2]);
            C130positionProperty.addSample(endTime, endPosition);
            var entity = viewer.entities.getById("CSW-" + i);
            if (entity == null) {
                var CSW = viewer.entities.add({
                    id: "CSW-" + i,
                    availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: endTime })]),
                    label: {
                        font: "12px Helvetica",
                        text: "CSW-" + i,
                        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                        outlineWidth: 2,
                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //垂直方向以底部来计算标签的位置
                        pixelOffset: new Cesium.Cartesian2(-10, 20),   //偏移量
                        disableDepthTestDistance: Number.POSITIVE_INFINITY,
                        show: true
                    },
                    position: CMpositionProperty,
                    // position: Cesium.Cartesian3.fromDegrees(115.52764038352255, 22.027391974778062, 100),
                    billboard: {
                        scale: 1,//放大倍数
                        width: 25,
                        height: 10,
                        //  eyeOffset:  eyeOffsetW,
                        image: `images/mq4.png`//getImageUrl(res!.image),
                    },
                    orientation: new Cesium.VelocityOrientationProperty(CMpositionProperty),
                });
                var C130Entity = viewer.entities.add({
                    id: "C130-" + i,
                    availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: endTime })]),
                    label: {
                        font: "12px Helvetica",
                        text: "C130-" + i,
                        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                        outlineWidth: 2,
                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //垂直方向以底部来计算标签的位置
                        pixelOffset: new Cesium.Cartesian2(-10, 20),   //偏移量
                        disableDepthTestDistance: Number.POSITIVE_INFINITY,
                        show: true
                    },
                    position: C130positionProperty,
                    // position: Cesium.Cartesian3.fromDegrees(115.52764038352255, 22.027391974778062, 100),
                    billboard: {
                        scale: 1,//放大倍数
                        width: 75,
                        height: 30,
                        //  eyeOffset:  eyeOffsetW,
                        image: `images/c130.png`//getImageUrl(res!.image),
                    },
                    orientation: new Cesium.VelocityOrientationProperty(C130positionProperty),
                });
                // viewer.flyTo(planeEntity);
            }
            else {
                // entity.show = true;
            }
        }
        var position = getSurroundingsPoint(positions);
        var _difLng = 0 / totalSeconds;
        var _difLat = 0.2 / (totalSeconds - initTime);
        console.log(position);
        this.loadLineEntity(viewer, initTime, totalSeconds, start, position, _difLng, _difLat);
    },
    // 添加飞机线路
    //加载同种飞机通讯线路
    showPlaneCommunication: function (viewer: Cesium.Viewer, role: string, PlaneName: string) {
        let totalSeconds = this.timeTool.getTotalSeconds();
        let start = this.timeTool.getStart();
        let stop = this.timeTool.getStop();
        let PlaneXs = bs.players[role][PlaneName];
        const latdif = (PlaneXs[0]["endPosition"][0] - PlaneXs[0]["startposition"][0]) / totalSeconds;
        const lngdif = (PlaneXs[0]["endPosition"][1] - PlaneXs[0]["startposition"][1]) / totalSeconds;
        var timdif = 0.0;
        var startPoints = [0, 1, 0];
        var endPoints = [1, 3, 2];
        for (let i: number = 0; i < startPoints.length; i++) {
            var correctLocI = 0;
            var correctLoc = 0;
            viewer.entities.add({ // 背景线
                description: 'background-line',
                polyline: {
                    width: 3,
                    positions: new Cesium.CallbackProperty((time) => {
                        if (timdif > totalSeconds) {
                            timdif = 0.0;
                        }
                        timdif = Cesium.JulianDate.secondsDifference(time, start);
                        if (correctLocI = 0) {
                            correctLoc = timdif;
                            correctLocI += 1;
                        }
                        let curstartpositLat = PlaneXs[startPoints[i]]["startposition"][0] &#
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

河南-殷志强

希望我的文章能帮助到你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值