cesium 轨迹线

news2024/11/13 16:17:21

在智慧城市项目中,轨迹线一般用来表现城市道路的流动效果。和cesium动态线篇效果类似,只是这里是通过设置高亮占比,而不是通过传入一张图片。

1. 自定义TrialFlowMaterialProperty类

1.1. 自定义 TrialFlowMaterialProperty 类
/*
 * @Description: 
 * @Author: maizi
 * @Date: 2024-08-16 15:06:46
 * @LastEditTime: 2024-08-26 17:47:26
 * @LastEditors: maizi
 */

function TrialFlowMaterialProperty(options) {
  options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);

  this._definitionChanged = new Cesium.Event();
  this._color = undefined;
  this._speed = undefined;
  this._ratio = undefined;
  this._tranparent = undefined;
 
  this.color = options.color || Cesium.Color.fromBytes(0, 255, 255, 255);
  this.speed = options.speed || 1;
  this.ratio = options.ratio || 0.2;
  this.tranparent = options.tranparent || 0.2;
}

Object.defineProperties(TrialFlowMaterialProperty.prototype, {
  isConstant: {
    get: function () {
      return (
        Cesium.Property.isConstant(this._color) 
        && Cesium.Property.isConstant(this._speed)
        && Cesium.Property.isConstant(this._ratio) 
        && Cesium.Property.isConstant(this._tranparent) 
      );
    },
  },

  definitionChanged: {
    get: function () {
      return this._definitionChanged;
    },
  },

  color: Cesium.createPropertyDescriptor("color"),
  speed: Cesium.createPropertyDescriptor("speed"),
  ratio: Cesium.createPropertyDescriptor("ratio"),
  tranparent: Cesium.createPropertyDescriptor("tranparent"),
});


TrialFlowMaterialProperty.prototype.getType = function (time) {
  return "TrialFlow";
};

TrialFlowMaterialProperty.prototype.getValue = function (time, result) {
  if (!Cesium.defined(result)) {
    result = {};
  }

  result.color = Cesium.Property.getValueOrClonedDefault(this._color, time);
  result.speed = Cesium.Property.getValueOrClonedDefault(this._speed, time);
  result.ratio = Cesium.Property.getValueOrUndefined(this._ratio, time);
  result.tranparent = Cesium.Property.getValueOrUndefined(this._tranparent, time);
  return result;
};


TrialFlowMaterialProperty.prototype.equals = function (other) {
  const res = this === other || (other instanceof TrialFlowMaterialProperty &&
    Cesium.Property.equals(this._color, other._color) &&
    Cesium.Property.equals(this._speed, other._speed))&&
    Cesium.Property.equals(this._ratio, other._ratio) &&
    Cesium.Property.equals(this._tranparent, other._tranparent)
  return res;
};
export default TrialFlowMaterialProperty;
1.2. 材质shader
uniform vec4 color;
uniform float speed;
uniform float ratio;
uniform float tranparent;

czm_material czm_getMaterial(czm_materialInput materialInput){
   czm_material material = czm_getDefaultMaterial(materialInput);
  vec2 st = materialInput.st;
  float time = fract(czm_frameNumber * speed / 1000.0);
  float alpha = smoothstep(time - ratio, time, st.s) * step(-time, -st.s);
  alpha += tranparent;
  material.diffuse= color.rgb;
  material.alpha = alpha;
  return material;
}
1.3. 添加到缓存
/*
 * @Description: 
 * @Author: maizi
 * @Date: 2024-08-16 16:21:55
 * @LastEditTime: 2024-08-26 18:00:42
 * @LastEditors: maizi
 */
import TrialFlowMaterial from '../shader/TrialFlowMaterial.glsl'

Cesium.Material.TrialFlow = 'TrialFlow'
Cesium.Material._materialCache.addMaterial(
  Cesium.Material.TrialFlow,
  {
    fabric: {
      type: Cesium.Material.TrialFlow,
      uniforms: {
        color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
        speed: 1,
        ratio: 0.2,
        tranparent: 0.2
      },
      source: TrialFlowMaterial,
    },
    translucent: function (material) {
      return true
    },
  }
)

2. 完整示例代码

TrialFlowLine.js

/*
 * @Description:
 * @Author: maizi
 * @Date: 2022-05-27 11:36:22
 * @LastEditTime: 2023-04-26 17:38:41
 * @LastEditors: maizi
 */
const merge = require('deepmerge')
import { TrialFlowMaterialProperty } from '../../materialProperty/index.js'
const defaultStyle = {
  speed: 10,
  ratio: 0.2,
  tranparent: 0.2,
  color: "#ffff00",
  lineWidth: 8
}

class TrialFlowLine {
  constructor(viewer, coords, options = {}) {
    this.viewer = viewer
    this.coords = coords;
    this.options = options;
    this.props = this.options.props;
    this.style = merge(defaultStyle, this.options.style || {});
   
    this.entity = null;
    this.material = null
    this.points = []
    this.init();
  }

  init() {
    this.createMaterial();
    this.entity = new Cesium.Entity({
      id: Math.random().toString(36).substring(2),
      type: "trial_flow_line",
      polyline: {
        positions: this.getPositons(),
        width: this.style.lineWidth,
        material: this.material,
        //clampToGround: true
      }
    });
  }

  addPoints() {
    this.coords.forEach((coord) => {
      const point = new Cesium.Entity({
        position: Cesium.Cartesian3.fromDegrees(coord[0],coord[1],coord[2]),
        point: {
          color: Cesium.Color.DARKBLUE.withAlpha(.4),
          pixelSize: 6,
          outlineColor: Cesium.Color.YELLOW.withAlpha(.8),
          outlineWidth: 4
        }     
      }); 
      this.viewer.entities.add(point)
      this.points.push(point)
    })
  }

  removePoints() {
    this.points.forEach((point) => {
      this.viewer.entities.remove(point)
    })
    this.points = []
  }

  getPositons() {
    const positions = []
    this.coords.forEach((coord) => {
      positions.push(Cesium.Cartesian3.fromDegrees(coord[0], coord[1], coord[2]));
    })
    return positions
  }

  createMaterial() {
    this.material = new TrialFlowMaterialProperty({
      color: new Cesium.Color.fromCssColorString(this.style.color),
      speed:this.style.speed,
      ratio: this.style.ratio,
      tranparent: this.style.tranparent
    });
  }

  updateStyle(style) {
    this.style = merge(defaultStyle, style);
    this.entity.polyline.width = this.style.lineWidth
    this.material.color = new Cesium.Color.fromCssColorString(this.style.color)
    this.material.speed = this.style.speed
    this.material.ratio = this.style.ratio
    this.material.tranparent = this.style.tranparent
  }

  setSelect(enabled) {
    if (enabled) {
      this.addPoints()
    } else {
      this.removePoints()
    }
  }
}

export {
  TrialFlowLine
}

MapWorks.js

import GUI from 'lil-gui'; 
// 初始视图定位在中国
import { TrialFlowLine } from './TrialFlowLine'

Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);

let viewer = null;
let graphicLayer = null
let graphicList = []
let selectGraphic = null
let eventHandler = null
let gui = null

function initMap(container) {
  viewer = new Cesium.Viewer(container, {
    animation: false,
    baseLayerPicker: false,
    fullscreenButton: false,
    geocoder: false,
    homeButton: false,
    infoBox: false,
    sceneModePicker: false,
    selectionIndicator: false,
    timeline: false,
    navigationHelpButton: false, 
    scene3DOnly: true,
    orderIndependentTranslucency: false,
    contextOptions: {
      webgl: {
        alpha: true
      }
    }
  })
  viewer._cesiumWidget._creditContainer.style.display = 'none'
  viewer.scene.fxaa = true
  viewer.scene.postProcessStages.fxaa.enabled = true
  if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
    // 判断是否支持图像渲染像素化处理
    viewer.resolutionScale = window.devicePixelRatio
  }
  // 移除默认影像
  removeAll()
  // 地形深度测试
  viewer.scene.globe.depthTestAgainstTerrain = true
  // 背景色
  viewer.scene.globe.baseColor = new Cesium.Color(0.0, 0.0, 0.0, 0)
  // 太阳光照
  viewer.scene.globe.enableLighting = true;

  // 初始化图层
  initLayer()
  // 初始化鼠标事件
  initClickEvent()
  //调试
  window.viewer = viewer
}

function initGui() {
  let params = {
    ...selectGraphic.style
  }
  gui = new GUI()
  let layerFolder = gui.title('样式设置')
  layerFolder.add(params, 'speed', 0, 100).step(1.0).onChange(function (value) {
    selectGraphic.updateStyle(params)
  })
  layerFolder.add(params, 'ratio', 0, 1.0).step(0.01).onChange(function (value) {
    selectGraphic.updateStyle(params)
  })
  layerFolder.add(params, 'tranparent', 0, 1.0).step(0.01).onChange(function (value) {
    selectGraphic.updateStyle(params)
  })
  layerFolder.add(params, 'lineWidth', 1, 30).step(1).onChange(function (value) {
    selectGraphic.updateStyle(params)
  })
  layerFolder.addColor(params, 'color').onChange(function (value) {
    selectGraphic.updateStyle(params)
  })
}


function initLayer() {
  const layerProvider = new Cesium.ArcGisMapServerImageryProvider({
    url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
  });
  viewer.imageryLayers.addImageryProvider(layerProvider);
  graphicLayer = new Cesium.CustomDataSource('graphicLayer')
  viewer.dataSources.add(graphicLayer)
}

function loadTrialFlowLine(lines) {
  lines.forEach(line => {
    const trialFlowLine = new TrialFlowLine(viewer, line.points)
    graphicList.push(trialFlowLine)
    graphicLayer.entities.add(trialFlowLine.entity)
  });
  viewer.flyTo(graphicLayer)
}

function initClickEvent() {
  eventHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  initLeftClickEvent()
  initMouseMoveEvent()
}

function initLeftClickEvent() {
  eventHandler.setInputAction((e) => {
    if (selectGraphic) {
      selectGraphic.setSelect(false)
      selectGraphic = null
    }
    if (gui) {
      gui.destroy()
    }
    let pickedObj = viewer.scene.pick(e.position);
    if (pickedObj && pickedObj.id) {
      if (pickedObj.id.type === 'trial_flow_line') {
        selectGraphic = getGraphicById(pickedObj.id.id)
        if (selectGraphic) {
          selectGraphic.setSelect(true)
          initGui()
        }
      }
    }
  },Cesium.ScreenSpaceEventType.LEFT_CLICK)
}

function initMouseMoveEvent() {
  eventHandler.setInputAction((e) => {
    const pickedObj = viewer.scene.pick(e.endPosition);
    if (pickedObj && pickedObj.id) {
      if (pickedObj.id.type === 'trial_flow_line') {
        // 改变鼠标状态
        viewer._element.style.cursor = "";
        document.body.style.cursor = "pointer";
      } else {
        viewer._element.style.cursor = "";
        document.body.style.cursor = "default";
      }
    } else {
      viewer._element.style.cursor = "";
      document.body.style.cursor = "default";
    }
  },Cesium.ScreenSpaceEventType.MOUSE_MOVE)
}

function getGraphicById(id) {
  let line = null
  for (let i = 0; i < graphicList.length; i++) {
    if (graphicList[i].entity.id === id) {
      line = graphicList[i]
      break
    } 
  }
  return line
}

function removeAll() {
  viewer.imageryLayers.removeAll();
}

function destroy() {
  viewer.entities.removeAll();
  viewer.imageryLayers.removeAll();
  viewer.destroy();
}




export {
  initMap,
  loadTrialFlowLine,
  destroy
}

TrialFlowLine.vue

<!--
 * @Description: 
 * @Author: maizi
 * @Date: 2023-04-07 17:03:50
 * @LastEditTime: 2024-08-26 18:00:57
 * @LastEditors: maizi
-->

<template>
  <div id="container">
  </div>
</template>

<script>
import * as MapWorks from './js/MapWorks'
export default {
  name: 'TrialFlowLine',
  mounted() {
    this.init();
  },
  methods:{
    init(){
      let container = document.getElementById("container");
      MapWorks.initMap(container)
      //创建
      let lines = [
        {
          points: [
            [104.068822,30.654807,10],
            [104.088822,30.654807,10],
          ]
        },
        {
          points: [
            [104.068822,30.655807,10],
            [104.088822,30.655807,10],
          ]
        },
      ];
      MapWorks.loadTrialFlowLine(lines)
    }
  },

  beforeDestroy(){
    //实例被销毁前调用,页面关闭、路由跳转、v-if和改变key值
    MapWorks.destroy();
  }
}
</script>

<style lang="scss" scoped>
#container{
  width: 100%;
  height: 100%;
  background: rgba(7, 12, 19, 1);
  overflow: hidden;
  background-size: 40px 40px, 40px 40px;
  background-image: linear-gradient(hsla(0, 0%, 100%, 0.05) 1px, transparent 0), linear-gradient(90deg, hsla(0, 0%, 100%, 0.05) 1px, transparent 0);
}


</style>

3. 运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2085380.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MES管理系统助力印刷企业实现智能化工艺流程

在印刷这一古老而充满活力的行业中&#xff0c;科技的浪潮正以前所未有的速度重塑着每一个生产环节。随着制造业数字化转型的深入&#xff0c;引入MES管理系统&#xff0c;为印刷企业带来了从原材料入库到成品出库的全流程智能化变革&#xff0c;不仅提升了生产效率&#xff0c…

基于SpringBoot+Vue+MySQL的网上商城系统

系统背景 随着社会的快速发展&#xff0c;计算机的影响是全面且深入的。人们生活水平的不断提高&#xff0c;日常生活中人们对网上商城购物系统方面的要求也在不断提高&#xff0c;购物的人数更是不断增加&#xff0c;使得网上商城购物系统的开发成为必需而且紧迫的事情。网上商…

无人机图传通信模组,抗干扰、稳定传输,8公里图传模组原理

在蔚蓝的天空下&#xff0c;无人机如同自由的精灵&#xff0c;穿梭于云间&#xff0c;为我们捕捉那些令人心动的瞬间。而在这背后&#xff0c;有一项技术正悄然改变着航拍的世界&#xff0c;那就是无人机图传通信模组。今天&#xff0c;就让我们一起揭开它的神秘面纱&#xff0…

在蓝桥云课ROS中快速搭建Arduino开发环境

普通方式 一步步慢悠悠的搭建和讲解需要5-6分钟&#xff1a; 如何在蓝桥云课ROS中搭建Arduino开发环境 视频时间&#xff1a;6分40秒 高效方式 如何高效率在蓝桥云课ROS中搭建Arduino开发环境 视频时间&#xff1a;1分45秒 配置和上传程序到开发板 上传程序又称为下载程序h…

匠心服务·智启新程丨2025华清远见新品发布会在北京隆重举行

2024年8月23日&#xff0c;华清远见教育科技集团的“匠心服务智启新程”2025新品发布会在北京隆重举行。云集多位行业专家学者、知名企业代表&#xff0c;聚焦市场新动向&#xff0c;站在行业技术最前沿&#xff0c;以多元化视角深入解读当前行业面临的新机遇新挑战&#xff0c…

信创环境下怎么做好信创防泄露?

为实现信创环境下的数据防泄露和“一机两用”标准落地&#xff0c;依靠十几年的沙盒技术积累&#xff0c;研发出了支持统信UOS/麒麟等信创OS的沙箱&#xff0c;配合零信任SDP网关&#xff0c;提高数据安全&#xff0c;实现“一机两用”安全解决方案。 信创防泄漏的需求 信创环…

从每 N 行找出需要数据拼成一行

Excel某表格不规范&#xff0c;每两行6列对应规范表格的一行3列&#xff0c;分别是&#xff1a;第1行第1列或第2行第1列&#xff08;两者重复&#xff0c;取其一即可&#xff09;、第2行第2列、第1行第3列。 ABC1John DoeCompany A2John Doejohn.doeexample.com3Jane SmithCom…

盘点国内外好用的12款文件加密软件|2024年好用的加密软件有哪些

在当今信息化时代&#xff0c;企业和个人都面临着数据泄露的风险。为了保护敏感信息&#xff0c;文件加密软件已经成为不可或缺的工具。本文将盘点国内外好用的12款文件加密软件&#xff0c;并提供其在2024年的使用推荐&#xff0c;帮助用户更好地保护数据安全。 1. 安秉加密软…

【html+css 绚丽Loading】 000024 八方流转杖

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

储能电池热失控监测系统的关键应用场景与安全防护

​ ​储能电池热失控监测系统主要应用于以下几个关键领域&#xff0c;以确保电池系统的安全、稳定运行&#xff0c;并预防因热失控引发的安全事故&#xff1a; ​ ​1.大型可再生能源发电储能 ​ ​这类应用常见于太阳能光伏电站、风力发电场等场景&#xff0c;其中储…

锂电池的使用真有所谓的小技巧吗

个人体会&#xff0c;真有的。 避免&#xff1a;过充过放 使用时间超过8年的锂电&#xff0c;风险很高。 网络信息繁杂 充斥着大量不明所以的内容。 自己实践才行。 掌握方式不合适&#xff0c;必须换电池了。 换过屏幕和电池&#xff0c;使用过程中损坏了。 2015年使用…

5个适合初学者的机器学习算法:线性回归、逻辑回归、决策树、随机森林和K近邻【源码与示例】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

渠道分销|行业SaaS的三重机会

大家好&#xff0c;我是林叔&#xff0c;今天&#xff0c;我想和大家聊聊我在这个行业里观察到的一个重要趋势——行业SaaS的三重机会。近年来&#xff0c;SaaS&#xff08;Software-as-a-Service&#xff0c;软件即服务&#xff09;市场在中国蓬勃发展&#xff0c;尤其是在行业…

MS9123 宏晶微 USB 投屏控制芯片 可提供开发资料

1. 基本介绍 MS9123 是一款单芯片 USB 投屏器&#xff0c;内部集成了 USB2.0 控制器和数据收发模块、视频 DAC 和音视频处理模块&#xff0c;MS9123 可以通过 USB 接口显示或者扩展 PC、智能手机、平板电脑的显示信 息到更大尺寸的显示设备上&#xff0c;支持 CVBS、S-Vi…

k8s1.23 部署Prometheus-Operator集群监控

1. Prometheus-Operator介绍 Prometheus Operator 为 Kubernetes 提供了对 Prometheus 相关监控组件的本地部署和管理方案&#xff0c;该项目的目的是为了简化和自动化基于 Prometheus 的监控栈配置&#xff0c;主要包括以下几个功能&#xff1a; kubernetes自定义资源&#…

day15JS-es6的基础语法

1. 严格模式 1.1 严格模式的使用方法 使用方法1&#xff1a;"use strict"; 开启严格模式。 使用方法2&#xff1a;<script type"moaule"></script> 当设置script标签为模块化时&#xff0c;自动启用严格模式。 1.2 严格模式的限制 1. 要求变量…

Android U 多任务启动分屏——整体流程介绍

序 原生的分屏功能是在多任务中&#xff0c;点击应用图标选择分屏&#xff0c;在选择多任务中的其他应用进行分屏 整体流程 层级结构 #1 DefaultTaskDisplayArea typeundefined modefullscreen override-modefullscreen requested-bounds[0,0][0,0] bounds[0,0][1440,2960…

【系统架构师软考】重难点划分及学习要点(一)

目录 引言 综合知识 案例分析 案例分析题型及选择策略 历年案例分析题型及分值分布 学习与应试策略 论文 考试规则 写作要求与技巧 忌讳与注意事项 常见题目与考查方向 引言 系统架构师软考是许多IT从业人员进阶的必经之路。面对这门考试&#xff0c;如何有效划分重难…

spring揭秘14-JdbcTemplate概述与使用操作对象访问数据

文章目录 【README】【1】JdbcTemplate概述【1.1】Jdbc原生api操作数据库【1.1.1】基于JdbcPreparedStatement批量更新 【1.2】JdbcTemplate概述【1.2.1】JdbcTemplate类图【1.2.2】使用DataSourceUtils管理Connection【1.2.3】设置Statement参数&#xff08;控制行为&#xff…

Shopee联盟营销案例对saas行业的启示

在跨境电商的浩瀚海洋中&#xff0c;Shopee以其独特的联盟营销&#xff08;AMS&#xff09;策略&#xff0c;为众多品牌商家开辟了新的增长航道。作为深耕SaaS企业渠道分销多年的林叔&#xff0c;我今天想和大家分享一个来自Shopee的成功营销案例&#xff0c;并从中提炼出对Saa…