Cesium为军工助力!动态绘制各类交互式态势图

大家好,我是日拱一卒的攻城师不浪,专注可视化、数字孪生、前端提效、nodejs、AI学习、GIS等学习沉淀,这是2024年输出的第33/100篇文章。
交流合作:brown_7778

前言

什么是态势图

态势图(Situation Map)是一种用于表示空间环境中动态或静态信息的地图,它能够展示事件资源威胁其他关键因素的地理位置及其变化情况。

通过可视化的方式,态势图帮助决策者在复杂环境中迅速获取关键信息,从而做出及时而准确的决策。

随着地理信息系统(GIS)的不断发展,态势图军事应急管理地理规划等领域中扮演着越来越重要的角色。

军工领域

在军工领域,态势图是军事指挥控制系统中的核心组件。

它们能够实时展示战场上的动态信息,如部队的部署位置、敌军动向、武器系统状态等。这种可视化工具对于战术指挥、作战计划制定和战场态势感知至关重要。

应急管理

在应急管理领域,态势图能够帮助管理者协调资源和人员应对自然灾害、山林火灾、事故或突发事件。通过态势图,可以清晰地看到灾害影响范围救援力量分布资源需求逃生路线等关键信息,从而实现有效的应急响应和资源调配。

地理规划

在地理规划中,态势图用于展示和分析区域开发土地利用交通网络等方面的信息。能帮助规划者更清晰的理解地理空间关系、评估环境影响,并做出科学的规划决策。

Cesium中绘制态势图

OK,接下来我们主要介绍一下在Cesium中如何绘制态势图,主要包括各种箭头类型的绘制,如直线箭头攻击箭头钳击箭头等。

源码地址在文末。

箭头绘制的核心算法

algorithm.js是实现复杂箭头绘制的核心脚本。

这里定义了多种箭头类型的绘制算法,如双箭头(doubleArrow)、三箭头(threeArrow)以及带尾攻击箭头(tailedAttackArrow)。

这些算法通过接收用户点击的多个点,并计算出箭头的控制点和多边形点来实现箭头形状的生成。

以下是doubleArrow函数的部分代码与解析:

xp.algorithm.doubleArrow = function (inputPoint) {
  // 初始化结果对象
  var result = {
    controlPoint: null,
    polygonalPoint: null
  };

  // 根据输入点数量决定不同的箭头形状
  var t = inputPoint.length;
  if (!(2 > t)) {
    if (2 == t) return inputPoint;

    // 获取关键点
    var o = this.points[0], 
        e = this.points[1], 
        r = this.points[2];

    // 计算连接点和临时点位置
    3 == t ? this.tempPoint4 = xp.algorithm.getTempPoint4(o, e, r) : this.tempPoint4 = this.points[3];
    3 == t || 4 == t ? this.connPoint = P.PlotUtils.mid(o, e) : this.connPoint = this.points[4];

    // 根据点的顺序计算箭头的左右侧点位
    P.PlotUtils.isClockWise(o, e, r) 
        ? (n = xp.algorithm.getArrowPoints(o, this.connPoint, this.tempPoint4, !1), g = xp.algorithm.getArrowPoints(this.connPoint, e, r, !0)) 
        : (n = xp.algorithm.getArrowPoints(e, this.connPoint, r, !1), g = xp.algorithm.getArrowPoints(this.connPoint, o, this.tempPoint4, !0));

    // 生成最终的箭头形状并返回
    result.controlPoint = [o, e, r, this.tempPoint4, this.connPoint];
    result.polygonalPoint = Cesium.Cartesian3.fromDegreesArray(xp.algorithm.array2Dto1D(f));
  }
  return result;
};

该函数首先根据输入点的数量确定是否继续进行箭头的绘制,接着计算关键点的位置,并通过getArrowPoints函数计算出箭头形状的多个控制点,最终生成一个包含箭头形状顶点的数组。

基于Cesium的箭头实体管理

arrowClass.js定义了具体的箭头类(如StraightArrow)和其行为管理。

通过结合Cesium的ScreenSpaceEventHandler事件处理机制,开发者可以方便地在地图上绘制、修改和删除箭头实体。

以下是StraightArrow类的部分代码与解析:

StraightArrow.prototype.startDraw = function () {
  var $this = this;
  this.state = 1;

  // 单击事件,获取点击位置并创建箭头起点
  this.handler.setInputAction(function (evt) {
    var cartesian = getCatesian3FromPX(evt.position, $this.viewer);
    if (!cartesian) return;
    
    // 处理点位并开始绘制箭头
    if ($this.positions.length == 0) {
      $this.firstPoint = $this.creatPoint(cartesian);
      $this.floatPoint = $this.creatPoint(cartesian);
      $this.positions.push(cartesian);
    }
    if ($this.positions.length == 3) {
      $this.firstPoint.show = false;
      $this.floatPoint.show = false;
      $this.handler.destroy();
      $this.arrowEntity.objId = $this.objId;
      $this.state = -1;
    }
    $this.positions.push(cartesian.clone());
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  // 鼠标移动事件,实时更新箭头形状
  this.handler.setInputAction(function (evt) {
    if ($this.positions.length < 1) return;
    var cartesian = getCatesian3FromPX(evt.endPosition, $this.viewer);
    if (!cartesian) return;
    
    $this.floatPoint.position.setValue(cartesian);
    if ($this.positions.length >= 2) {
      if (!Cesium.defined($this.arrowEntity)) {
        $this.positions.push(cartesian);
        $this.arrowEntity = $this.showArrowOnMap($this.positions);
      } else {
        $this.positions.pop();
        $this.positions.push(cartesian);
      }
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
};

startDraw函数中,通过设置单击和鼠标移动事件,开发者可以实时捕获用户的操作,并根据点击位置动态绘制箭头。

最终的箭头形状会随着鼠标的移动而更新,当点击完成时箭头形状被确定。

工具类与辅助函数

plotUtil.js提供了一些用于计算几何关系的实用工具函数。

例如,distance函数计算两个点之间的距离,而getThirdPoint函数根据给定的两个点和角度,计算出第三个点的位置。 这些工具函数被广泛用于箭头的绘制逻辑中,以确保箭头的形状符合预期。

以下是distancegetThirdPoint函数的代码示例:

P.PlotUtils.distance = function (t, o) {
  return Math.sqrt(Math.pow(t[0] - o[0], 2) + Math.pow(t[1] - o[1], 2));
};

P.PlotUtils.getThirdPoint = function (t, o, e, r, n) {
  var g = P.PlotUtils.getAzimuth(t, o),
      i = n ? g + e : g - e,
      s = r * Math.cos(i),
      a = r * Math.sin(i);
  return [o[0] + s, o[1] + a];
};

这些函数都是为复杂箭头形状的计算提供了基础,确保在地图上绘制的箭头具有精确的几何形态。

总结

以上主要介绍了在Cesium中实现态势图的一些关键代码以及解释,更多细节请参考项目源码,如果有帮助也请给一个免费的star

【项目开源地址】:https://github.com/tingyuxuan2302/cesium-vue3-vite/blob/github/src/views/geometry/arrow.vue

作者的Cesium系列课程《Cesium从入门到实战》,让不了解Cesium的小伙伴拥有一个完整的学习路线以及常用API的教学,学完后能够直接上手做项目且不再迷茫,课程细节联系作者:brown_7778(备注来意)。

另外有需要进技术产品开发交流群(可视化&WebGIS)可以加我:brown_7778(备注来意),也欢迎数字孪生可视化领域的交流合作。

最后,如果觉得文章对你有帮助,也希望可以一键三连👏👏👏,支持我持续开源和分享~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值