当前位置: 首页 > news >正文

cesium canvas广告牌

在有些业务中,对场景中的广告牌样式要求比较高,需要动态显示一些数据,这个时候,我们可以通过将复杂背景样式制作成图片,通过canvas绘制图片和动态数据,从而达到比较好的显示效果。

1 CanvasMarker 类封装

CanvasMarker.js

/** @Description:* @Author: maizi* @Date: 2022-05-27 11:36:22* @LastEditTime: 2024-07-23 15:34:06* @LastEditors: maizi*/
const merge = require('deepmerge')const defaultStyle = {scale: 0.2,text: '0.0'
}
const monitorPanel =  require('@/assets/img/monitorPanel.png')class CanvasMarker {constructor(viewer, coords, options = {}) {this.viewer = viewer;this.coords = coords;this.options = options;this.props = this.options.props;this.baseHeight = this.coords[2] || 10;this.style = merge(defaultStyle, this.options.style || {});this.entity = null;this.canvas = nullthis.init();}init() {let img =  new Image();img.src = monitorPanel;img.onload = ()=> {this.picture = img;this.canvas = this.createCanvas()}this.entity = new Cesium.Entity({type: "canvas_point",props: this.props,position:Cesium.Cartesian3.fromDegrees(this.coords[0], this.coords[1], this.baseHeight),billboard: {image: new Cesium.CallbackProperty(() => {return this.canvas.toDataURL("image/png");}),scale:new Cesium.CallbackProperty(() => {return this.style.scale}),color: new Cesium.Color(1, 1, 1),disableDepthTestDistance: Number.POSITIVE_INFINITY,},});}createCanvas() {let canvas = null;if (this.canvas) {canvas = this.canvas} else {canvas = document.createElement("canvas");canvas.width = 512;canvas.height = 329;}let ctx = canvas.getContext("2d");ctx.clearRect(0, 0, canvas.width, canvas.height);ctx.drawImage(this.picture, 0, 0);ctx.fillStyle = "rgb(255, 255, 255)",ctx.font = "80px sans-serif",ctx.textBaseline = "middle",ctx.fillText("温度:", 50, canvas.height / 2);ctx.fillText(this.style.text, 270, canvas.height / 2);ctx.fillText("℃", 380, canvas.height / 2);// // 导出canvas为图片// var dataURL = canvas.toDataURL("image/png");// var link = document.createElement('a');// link.download = 'canvas-image.png';// link.href = dataURL;// link.click();return canvas;}setSelect(enabled) {if (enabled) {this.addPoint()} else {this.removePoint()}}addPoint() {this.point = new Cesium.Entity({position: Cesium.Cartesian3.fromDegrees(this.coords[0], this.coords[1],  this.baseHeight),point: {color: Cesium.Color.DARKBLUE.withAlpha(.4),pixelSize: 6,outlineColor: Cesium.Color.YELLOW.withAlpha(.8),outlineWidth: 4,disableDepthTestDistance: Number.POSITIVE_INFINITY}     }); this.viewer.entities.add(this.point)}removePoint() {if (this.point) {this.viewer.entities.remove(this.point)this.point = null}}updateStyle(style) {this.style = merge(this.style, style || {});this.createCanvas()}
}export {CanvasMarker
}

2 完整示例代码

MapWorks.js

import GUI from 'lil-gui'; 
// 初始视图定位在中国
import { CanvasMarker } from './CanvasMarker'Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);
//天地图key
const key = '39673271636382067f0b0937ab9a9677'let viewer = null;
let eventHandler = null;
let canvasLayer = null
let canvasList = []
let selectGraphic = null
let gui = nullfunction 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 = trueviewer.scene.postProcessStages.fxaa.enabled = trueif (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 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 === 'canvas_point') {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 === 'canvas_point') {// 改变鼠标状态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 graphic = nullfor (let i = 0; i < canvasList.length; i++) {if (canvasList[i].entity.id === id) {graphic = canvasList[i]break} }return graphic
}
function initGui() {let params = {...selectGraphic.style}gui = new GUI()let layerFolder = gui.title('参数设置')layerFolder.add(params, 'scale', 0.1, 2).step(0.1).onChange(function (value) {selectGraphic.updateStyle(params)})
}function addTdtLayer(options) {let url = `https://t{s}.tianditu.gov.cn/DataServer?T=${options.type}&x={x}&y={y}&l={z}&tk=${key}`const layerProvider = new Cesium.UrlTemplateImageryProvider({url: url,subdomains: ['0','1','2','3','4','5','6','7'],tilingScheme: new Cesium.WebMercatorTilingScheme(),maximumLevel: 18});viewer.imageryLayers.addImageryProvider(layerProvider);
}function initLayer() {addTdtLayer({type: 'img_w'})addTdtLayer({type: 'cia_w'})canvasLayer = new Cesium.CustomDataSource('canvasMarker')viewer.dataSources.add(canvasLayer)}function loadCanvasMarker(points) {points.forEach(item => {const canvasMarker = new CanvasMarker(viewer, item)canvasList.push(canvasMarker)canvasLayer.entities.add(canvasMarker.entity)});viewer.flyTo(canvasLayer)updateText()
}function updateText() {setInterval(()=>{canvasList.forEach((item) => {const text = Math.floor(30 * Math.random())item.updateStyle({text: text})})}, 2000)
}function removeAll() {viewer.imageryLayers.removeAll();
}function destroy() {viewer.entities.removeAll();viewer.imageryLayers.removeAll();viewer.destroy();
}export {initMap,loadCanvasMarker,destroy
}

CanvasMarker.vue

<!--* @Description: * @Author: maizi* @Date: 2023-04-07 17:03:50* @LastEditTime: 2023-04-11 18:07:29* @LastEditors: maizi
--><template><div id="container"></div>
</template><script>
import * as MapWorks from './js/MapWorks'
export default {name: 'CanvasMarker',mounted() {this.init();},methods:{init(){let container = document.getElementById("container");MapWorks.initMap(container)//创建告警点let points = [[104.074822, 30.659807, 60],[104.076822, 30.653807, 60],[104.075822, 30.652807, 60],[104.072822, 30.654807, 60]];MapWorks.loadCanvasMarker(points)}},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 运行效果

相关文章:

cesium canvas广告牌

在有些业务中&#xff0c;对场景中的广告牌样式要求比较高&#xff0c;需要动态显示一些数据&#xff0c;这个时候&#xff0c;我们可以通过将复杂背景样式制作成图片&#xff0c;通过canvas绘制图片和动态数据&#xff0c;从而达到比较好的显示效果。 1 CanvasMarker 类封装 …...

使用Floyd算法求解两点间最短距离

Floyd算法 Floyd算法又称为Floyd-Warshell算法&#xff0c;其实Warshell算法是离散数学中求传递闭包的算法&#xff0c;两者的思想是一致的。Floyd算法是求解多源最短路时通常选用的算法&#xff0c;经过一次算法即可求出任意两点之间的最短距离&#xff0c;并且可以处理有负权…...

linux“how_paras.sh“ E212: 无法打开并写入文件

经过一番测试和查找&#xff0c; [6localhost bin]$ find / -name "hello.sh" 2>/dev/null /home/6/bin/hello.sh [6localhost bin]$ ls hello.sh ls: 无法访问hello.sh: 没有那个文件或目录&#xff0c;为什么在/bin文件下却不能打开&#xff0c; [6localhost …...

CSS mask-image 实现边缘淡出过渡效果

使用场景 在生产环境中&#xff0c;遇到一个需求&#xff0c;需要在一个深色风格的大屏页面中&#xff0c;嵌入 Google Maps。为了减少违和感&#xff0c;希望地图四边能够淡出过渡。 这里的“淡出过渡”&#xff0c;关键是淡出&#xff0c;而非降低透明度。 基于 Google Ma…...

电子元器件—电容和电感(一篇文章搞懂电路中的电容和电感)(笔记)(面试考试必备知识点)电容和电感作用、用途、使用、注意事项、特点等(面试必备)-笔记(详解)

作者&#xff1a;Whappy 座右铭&#xff1a;不曾拥有&#xff0c;何来失去&#xff01; 时间&#xff1a;2024年8月2日08:40:04 一、电容的作用 储能&#xff1a; 电容器通过充电储存电荷在电容板上&#xff0c;形成电场储存电能。当需要释放储存的电能时&#xff0c;电荷…...

2024HDU Contest 5 Problem 5

题目链接 从大到小枚举gcd的值 d d d&#xff0c;以及编号为 d d d的倍数的点&#xff0c; [ d , 2 d , 3 d , … ] [d,2d,3d,\dots] [d,2d,3d,…]。 然后对于任何一条边 ( x , y ) (x,y) (x,y)&#xff0c;如果 x x x的子树和 y y y的子树里都有编号为 d d d倍数的点&#xf…...

nGQL入门

引言 nGQL&#xff08;NebulaGraph Query Language&#xff09;是用于操作 NebulaGraph 的查询语言。它的语法类似于 Cypher&#xff0c;但有自己独特的特性。以下是一些 nGQL 的基本语法和操作示例&#xff0c;以帮助你入门。 基本概念 节点&#xff08;Vertex&#xff09;…...

[CP_AUTOSAR]_系统服务_DEM模块(二)功能规范介绍

目录 1、DEM 功能规范描述1.1、Startup behavior1.2、Monitor re-initialization 在前面 《[CP_AUTOSAR]_系统服务_DEM模块&#xff08;一&#xff09;》文中&#xff0c;简要介绍了 DEM 模块的功能、与其它模块之间的功能交互&#xff0c;本文将接着介绍 DEM 模块的功能规范。…...

Linux中yum、rpm、apt-get、wget的区别,yum、rpm、apt-get常用命令,CentOS、Ubuntu中安装wget

文章目录 一、常见Linux发行版本二、Linux中yum、rpm、apt-get、wget的区别2.1 yum2.2 rpm2.3 apt-get2.4 wget2.5 总结 三、CentOS中yum的作用3.1 yum清空缓存列表3.2 yum显示信息3.3 yum搜索、查看3.4 yum安装3.5 yum删除、卸载程序3.6 yum包的升级、降级 四、Ubuntu中apt-ge…...

IPython的使用技巧2

关注我&#xff0c;持续分享逻辑思维&管理思维&面试题&#xff1b; 可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导&#xff1b; 推荐专栏《10天学会使用asp.net编程AI大模型》&#xff0c;目前已完成所有内容。一顿烧烤不到的费用&#xff0c;让人能紧跟时代的…...

win10打开程序闪退的解决方法,亲测好用

当我们在使用win10系统的时候&#xff0c;可能会遇到安装某些程序后无法正常使用&#xff0c;一打开就闪退&#xff0c;或者点击右下角图标就消失了&#xff0c;而其他程序却可以正常打开使用。下面小编就来和大家分享亲测好用的win10打开程序闪退的解决办法。 问题原因分析&a…...

木舟0基础学习Java的第二十一天(数据库,MySQL,SQLyog)

数据库 数据库&#xff1a;按照数据结构来组织 存储数据的厂库 数据管理系统(Database Management System,DBMS)&#xff1a;一套操作和管理数据库的软件 用于简历 使用 维护数据库 关系型数据库&#xff1a;采用关系模型作为数据组织方式 逻辑结构是一张二维表 由行和列组成…...

python-鼠标绘画线条程序

闲来无聊简单编写了一个绘图小程序。 主要思路 主要是基于Python中的内置模块turtle编写的&#xff0c;简单扩展了一下&#xff0c;通过绑定事件能够达到鼠标绘制、删除、存储已经绘制图案的线条这几个功能。 路径结构 -draw- define.py- main.py- myturtle.py使用 点住鼠…...

【Python实战】如何优雅地实现 PDF 去水印?

话接上篇&#xff0c;自动化处理 PDF 文档&#xff0c;完美实现 WPS 会员功能 小伙伴们更关心的是如何去除 PDF 中的水印~ 今天&#xff0c;就来分享一个超简单的 PDF 去水印方法~ 1. 原理介绍 在上一篇中&#xff0c;我们介绍了如何将 PDF 文档转换成图片&#xff0c;图片…...

Keysight(原Agilent) E4980AL 精密 LCR 表特性与技术指标

Keysight(原Agilent) E4980AL 精密 LCR 表为基础 LCR 表树立了行业标准&#xff0c;可在多个频率范围内提供更佳的精度、速度和通用性。E4980AL 结合了种类繁多的附件&#xff0c;适用于一般研发和生产环境中的各种元件和材料测量。也可通过频率升级而提升投资回报率。 Keysig…...

【运维】Redis主从复制 配置

【运维】Redis主从复制 配置 主库配置Master # 默认情况下&#xff0c;是 启用保护模式的&#xff0c;其他主机的客户端无法连接到 Redis 。当想要其他主机的客户端连接到 Redis 时&#xff0c;需要修改为 no 。protected-mode no 从库配置Slave # replicaof [master主机ip] …...

C++ 微积分 - 求导 - 自动微分(Automatic Differentiation)

C 微积分 - 求导 - 自动微分&#xff08;Automatic Differentiation&#xff09; flyfish 自动微分&#xff08;Automatic Differentiation&#xff0c;简称 AD&#xff09;是一种用于精确计算函数导数的技术。它结合了符号微分的准确性和数值微分的效率。自动微分的核心思想…...

面试题-每日5道

26.在 Queue 中 poll()和 remove()有什么区别? 相同点&#xff1a;都是删除第一个元素并返回。 不同点&#xff1a;如果没有元素poll()会返回null,而remove()会抛出NoSuchElementException异常 27.哪些集合类是线程安全的&#xff1f; Vector,Stock,Hashtable都是线程安全的&a…...

STM32卡死、跑飞如何调试确定问题

目录 前言 一、程序跑飞原因 二、调试工具 2.1Registers工具 2.2 Memory工具 2.3 Disassembly工具 2.4 Call Stack工具 三、找到程序跑飞位置 方式一、 方式二、 前言 我们初学STM32的时候代码难免会出现疏忽&#xff0c;导致程序跑飞&#xff0c;不再正常运行&#…...

代理模式和Spring MVC

Spring是一个分层的轻量级的开源Java框架。核心是IOC(Inverse of Control 控制反转)和AOP(Aspect Oriented Programming 面向切面编程) AOP 面向切面 AOP &#xff08;Aspect Orient Programming&#xff09;,直译过来就是 面向切面编程&#xff0c;AOP 是一种编程思想&#x…...

深入理解Vue slot的原理

文章目录 前言为什么需要插槽作用域插槽插槽的原理总结 前言 插槽是Vue中一个重要的特性&#xff0c;它有很多种用法&#xff1a;默认插槽、具名插槽、作用域插槽。尤其作用域插槽&#xff0c;还有一堆特性&#xff0c;比如解构prop&#xff0c;解构prop的时候还可以进行属性名…...

git fetch作用与用法

目录 git fetch作用 git fetch用法 git fetch作用 git fetch 命令在 Git 版本控制系统中扮演着重要的角色。其主要作用是从远程仓库获取最新版本的项目文件&#xff0c;但不会自动合并或修改你当前的工作。这意味着&#xff0c;使用 git fetch 后&#xff0c;你需要手动合并…...

pycharm如何查看git历史版本变更信息

通过名字查看不同版本 查看版本不同地方...

【2.2 python中的变量】

2.2 python中的变量 在Python中&#xff0c;变量是存储数据值的容器。Python是一种动态类型语言&#xff0c;这意味着你不需要在声明变量时指定变量的类型&#xff1b;Python会根据你赋给变量的值自动确定其类型。下面我将详细介绍Python中的变量&#xff0c;包括保留字&#…...

Python软体中找出一组字符串的最长公共前缀:算法与实现

Python软体中找出一组字符串的最长公共前缀:算法与实现 在处理字符串数据时,寻找多个字符串之间的共同特征是一个常见的需求。特别是在文件名、URL、或其他文本数据中,找到最长公共前缀(Longest Common Prefix, LCP)可以帮助我们进行更高效的搜索和分类。本文将详细介绍如…...

git lfs使用(huggingface下载大模型文件)-教程记录

写的比较清楚的教程&#xff0c;用于之后有需求时查找用&#xff1a; https://blog.csdn.net/flyingluohaipeng/article/details/130788293...

1. 什么是操作系统

文章目录 1.1 从功能上来看操作系统1.2 硬件资源 1.1 从功能上来看操作系统 对用户来说&#xff0c;操作系统是一个控制软件&#xff0c;可以用来管理应用程序&#xff0c;它可以限制不同的程序来占用的资源。对内部的软件来说&#xff0c;操作系统是一个管理外设和分配资源的…...

数据科学 - 数据预处理 (数据清洗,结构化数据)

1. 前言 数据清洗与结构化数据在数据分析和机器学习项目中扮演着至关重要的角色。随着大数据时代的到来&#xff0c;数据的质量、准确性和可用性成为决定项目成功与否的关键因素。 数据清洗提高数据质量&#xff0c;保证数据集的一致性&#xff1b;促进数据分析与挖掘&#xf…...

基于SpringBoot+Vue的校车调度管理系统(带1w+文档)

基于SpringBootVue的校车调度管理系统(带1w文档) 基于SpringBootVue的校车调度管理系统(带1w文档) 如今&#xff0c;因为无线网相关技术的快速&#xff0c;尤其是在网上进行资源的上传下载、搜索查询等技术&#xff0c;以及信息处理和语言开发技术的进步&#xff0c;同时编程语…...

基于改进拥挤距离的多模态多目标优化差分进化(MMODE-ICD)求解无人机三维路径规划(MATLAB代码)

一、无人机多目标优化模型 无人机三维路径规划是无人机在执行任务过程中的非常关键的环节&#xff0c;无人机三维路径规划的主要目的是在满足任务需求和自主飞行约束的基础上&#xff0c;计算出发点和目标点之间的最佳航路。 1.1路径成本 无人机三维路径规划的首要目标是寻找…...

做网站找个人还是找公司/品牌营销与推广

本节书摘来异步社区《淘宝店铺设计装修一册通》一书中的第2章&#xff0c;作者&#xff1a; 葛存山 责编&#xff1a; 赵轩, 更多章节内容可以访问云栖社区“异步社区”公众号查看。 2.4 创建文字 淘宝店铺设计装修一册通Photoshop提供了丰富的文字工具&#xff0c;可以在图像…...

网站建设属于淘宝哪种类目/电子商务

项目里需要用到扫描二维码&#xff0c;自己实现&#xff0c;不会。 找到了两种解决方案&#xff1a; 通过reqrcode.js&#xff0c;这是一个前端解析二维码内容的js库。如果二维码比较清晰&#xff0c;用这种效果也不错调用微信扫一扫功能&#xff0c;这种效果很好。但是调试接口…...

wordpress 文章链接地址/如何弄一个自己的网站

哈希 哈希有时候也被翻译为散列。 就是将任意长度的输入&#xff0c;通过哈希算法&#xff0c;压缩为某一固定长度的输出。 假如要快速读写100万条数据记录&#xff0c;要达到高速地存取&#xff0c;但是由于条件的限制&#xff0c;我们并没有能够容纳100万条记录的连续地址空…...

无忧网站建设价格/站长工具ip查询

首先介绍下参数模型和变参模型 机器学习算法可以被分为两大类&#xff1a;参数模型和变参模型。 对于参数模型&#xff0c;在训练过程中我们要学习一个函数&#xff0c;重点是估计函数的参数&#xff0c;然后对于新数据集&#xff0c;我们直接用学习到的函数对 齐分类。典型的…...

wordpress动静分离oss/企业查询app

功能介绍 自动扫描Spring的Controller代码并生成OpenAPI文档&#xff0c;无代码侵入。 对比与Swageer的代码侵入显得更加简洁。 项目地址&#xff1a;https://gitee.com/laofeng/yapidoc-maven-plugin 诞生原因 在开发的过程中&#xff0c;尤其是联调的过程中&#xff0c;接…...

绿色农业网站模板/什么是网店推广

文章目录信息要配置的环境一、配置SQLite二、配置Python环境三、配置Nginx四、配置virtualenv和VirtualenvWrapper五、配置mysql六、配置redis七、配置Git八、配置RVM信息 Linux系统&#xff1a;CentOS 7 远程终端&#xff1a;MobaXterm&#xff08;PS&#xff1a;这个真的超好…...