cesium 实战系列之图标
cesium 图标我们都知道viewer.entities.add添加个图片、文字啥的都是很简单的网上随便一搜有都是那么我今天就弄点不一样的。canvas 标识牌我们普通的标识牌只能单纯的放图片/文字然而很多时候需要放的内容不仅仅是单纯的图片/文字比如我要看设备id、设备状态、设备名称、设备编号、不同设备状态设置不同的背景等等那这种就需要用到canvas来把所需要的内容画在画布上然后生成图片再绑定到标识牌上。效果如下代码实现async function rankImg(station) { var bgImg station.status 已连接 ? static/img/control/normal.png : static/img/control/warning.png; let canvas document.createElement(canvas); let ctx canvas.getContext(2d); canvas.width bgImg.width; canvas.height bgImg.height; ctx.drawImage(bgImg, 0, 0); ctx.font bold 24px PangMenZhengDao; ctx.fillStyle station.status 已连接 ? #69FF80 : #FF0000; ctx.textAlign center; ctx.textBaseline middle; ctx.fillText(station.deviceId || station.id, 25, 18); ctx.font 12px Source Han Sans CN; ctx.fillStyle station.status 已连接 ? #69FF80 : #FF0000; ctx.textAlign center; ctx.textBaseline middle; ctx.fillText(station.status 已连接 ? 已连接 : 未连接, 25, 40); ctx.font 12px Source Han Sans CN; ctx.fillStyle #fff; ctx.textAlign center; ctx.textBaseline middle; ctx.fillText(station.jammmc, 88, 14); ctx.font bold 22px PangMenZhengDao; ctx.fillStyle #fff; ctx.textAlign center; ctx.textBaseline middle; ctx.fillText(station.sbbh, 85, 35); return canvas.toDataURL(image/png); } async function createSingleMark(stations) { stations.forEach(async(station) { var textValue station.jammmc; var lng parseFloat(station.lon); var lat parseFloat(station.lat); const imgData await rankImg(station); var entityId hot_point_ station.id; // 先删除已存在的实体避免重复添加 const existingEntity viewer.entities.getById(entityId); if (existingEntity) { viewer.entities.remove(existingEntity); } var bilload viewer.entities.add({ id: entityId, name: textValue, position: Cesium.Cartesian3.fromDegrees(lng, lat, 0), billboard: { image: imgData, scale: 1, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.CENTER, }, }); }) } createSingleMark([ { id:1, sbbh:12, jammmc:地面干扰设备, status:已连接, lon:116.85701689886864, lat:40.46263853921053 }, { id:2, sbbh:13, jammmc:地面干扰设备2, status:未连接, lon:116.81701689886864, lat:40.46263853921053 } ])扩散光圈图标先看效果扩散光圈实现方法先准备一个光圈图片然后利用cesium 的 eclipse 的长半轴、短半轴属性semiMajorAxis、semiMinorAxis实现扩散效果。光圈图片如下代码实现var r { minR: 300, maxR: 800, R: 100 } function changeR() { r.R r.R 2.5 if (r.R r.maxR) { r.R r.minR } let result r.R return result } function changeR2() { let result r.R return result } //扩散圆圈 function createPoint() { viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(120.1804,28.6626, 100), ellipse: { semiMajorAxis: new Cesium.CallbackProperty(changeR, false), semiMinorAxis: new Cesium.CallbackProperty(changeR2, false), material: new Cesium.ImageMaterialProperty({ image: static/img/hot_point.png, repeat: new Cesium.Cartesian2(1.0, 1.0), transparent: true, }), height: 100, // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND //如果有地形需要开启贴地 } }) } createPoint()动态光圈先看效果动态光圈实现思路通过html创建div实例然后通过append绑定在页面上之后再利用css animation 实现动画效果然后通过cesium监测实时更新图标位置的方法将图标绑定在地图上。具体代码//闪烁圆点 showTipsImageBg({ htmlstr: div style div classhtmlsymbol_gpsdot div classhtmlsymbol_gpsdot2 div classhtmlsymbol_gpsdot3div classhtmlsymbol_reallocationtipxxxxxxxxxxx大街/div/div /div /div /div }, 119.0789, 28.5227, 0); var infoTipsArray []; // 开启监听器--无论对当前地球做的任何操作都会监听到 let postRender viewer.scene.postRender.addEventListener(() { infoTipsArray.forEach(function (item) { var scratch new Cesium.Cartesian2(); var pos Cesium.Cartesian3.fromDegrees(item.lng, item.lat, item.height); var canvasPosition viewer.scene.cartesianToCanvasCoordinates(pos, scratch); if (canvasPosition) { var bubbledom item.dom; bubbledom.css({ top: canvasPosition.y - (item.ishalf ? bubbledom.outerHeight() / 2 : (bubbledom.outerHeight() - 10)), left: canvasPosition.x - bubbledom.outerWidth() / 2 $(#cesiumContainer).offset().left }); } }); }) function showTipsImageBg(config, lng, lat, height, ishalf) { var bubbledom $(div classinfotips2 style (config.color ? (background-color: config.color ;) : ) div classbubblecsscont config.htmlstr /div/div); var pos Cesium.Cartesian3.fromDegrees(lng, lat, height); var scratch new Cesium.Cartesian2(); var canvasPosition viewer.scene.cartesianToCanvasCoordinates(pos, scratch); if (Cesium.defined(canvasPosition)) { $(#content).append(bubbledom); bubbledom.css({ top: canvasPosition.y - (ishalf ? bubbledom.outerHeight() / 2 : (bubbledom.outerHeight() - 10)), left: canvasPosition.x - bubbledom.outerWidth() / 2 $(#cesiumContainer).offset().left }); } infoTipsArray.push({ dom: bubbledom, lng: lng, lat: lat, height: height, ishalf: ishalf ? true : false }); }style langscss .htmlsymbol_cont{ position: relative; width: 100%; } /*模拟百度地图发光圆圈效果*/ .htmlsymbol_gpsdot { animation: htmlsymbol_gpssploosh 2.5s cubic-bezier(0.165, 0.84, 0.44, 1); } .htmlsymbol_gpsdot2 { animation: htmlsymbol_gpssploosh2 2.5s cubic-bezier(0.165, 0.84, 0.44, 1); } .htmlsymbol_gpsdot3 { animation: htmlsymbol_gpssploosh3 2.5s cubic-bezier(0.165, 0.84, 0.44, 1); } .htmlsymbol_gpsdot,.htmlsymbol_gpsdot2,.htmlsymbol_gpsdot3{ height: 12px; width: 12px; font-size: 12px; color: #fff; line-height: 20px; text-align: center; /*opacity: 0.99;*/ border-radius: 100%; position: absolute; z-index: 10; animation-iteration-count:infinite; background: transparent; } keyframes htmlsymbol_gpssploosh { 0% { box-shadow: 0 0 0 0px rgba(2,220,57, 0.7); background: rgba(2,220,57, 0.7); } 100% { box-shadow: 0 0 0 40px rgba(2,220,57, 0); background: rgba(2,220,57, 0); } } keyframes htmlsymbol_gpssploosh2 { 0% { box-shadow: 0 0 0 0px rgba(2,220,57, 0.7); background: rgba(2,220,57, 0.7); } 100% { box-shadow: 0 0 0 25px rgba(2,220,57, 0); background: rgba(2,220,57, 0.3); } } keyframes htmlsymbol_gpssploosh3 { 0% { box-shadow: 0 0 0 0px rgba(2,220,57, 0.7); background: rgba(2,220,57, 0.7); } 100% { box-shadow: 0 0 0 10px rgba(2,220,57, 0); background: rgba(2,220,57, 1); } } .htmlsymbol_reallocationtip{ position:absolute; bottom: -25px; border-radius: 4px; left:-25px; width: 70px; height:20px; line-height: 1.5em; /*background-color: rgba(0,0,0,0.1);*/ font-size: 12px; } /stylehtml仿标识牌图标既然可以通过html创建div的方式创建图标那我们都知道cesium有标识牌图标那是否可以通过html做一个标识牌图标呢于是他来了。效果代码实现其中showTipsImageBg 就是上述代码中的方法。showTipsImageBg({ htmlstr: div styleposition: relative;width:332px;height:222px;background:url(static/img/tip1.png) top center no-repeat;background-size:contain;text-align:left; div styleposition: absolute;top: 25px;height: 123px;left: 27px;right: 30px; div stylefloat:left;width:100px;height:100%;background:url(static/img/gugong.jpg) center center / cover no-repeat;/div div stylefloat:right;width:150px;height:100%; div stylefont-size:15px;font-weight:bold;xxxxxxx/div div stylefont-size:12px;color: #b7b7b7;简介xxxxxxxxxxxxxxxxxxxxxxxxxxx。/div div stylefont-size:12px;color: #b7b7b7;级别AAAAA级/div /div /div /div }, 119.5, 28.2, 0);echarts 图表图标那既然html都可以那图表是不是也可以呢于是乎就有了图表图标效果图表代码实现//图表 showTipsImageBg({ htmlstr: div stylepointer-events:auto;position: relative;width:332px;height:222px;background:url(static/img/tip1.png) top center no-repeat;background-size:contain;text-align:left; div idhtmltipChart styleposition: absolute;top: 25px;height: 123px;left: 27px;right: 30px;/div /div }, 119.8402, 28.4453, 0); // 图表渲染 var chartrender_2 function (domid) { var datalist [60, 220, 1053, 826]; var dom document.getElementById(domid); let myChart echarts.init(dom); var option { tooltip: { trigger: item, formatter: function (params) { // console.log(params); var vl params.value;; if (params.seriesName ! realdata) { vl 200 - vl; } return params.name : vl ; } }, // color:color, grid: { left: 30, right: 0, top: 20, bottom: 20, containLabel: false }, xAxis: { type: category, show: true, axisTick: { show: false }, axisLine: { show: false }, data: [丽水市, 杭州市, 松阳市, xxxx], axisLabel: { show: true, interval: 0, color: function (value, index) { // if(index 0) { // return red; // } // if(index 1) { // return #ff8447; // } // if(index 2) { // return #ffcc00; // } // return rgb(18,205,12) return #fff; }, fontSize: 10, } }, yAxis: { type: value, name: , show: true, axisTick: { show: false }, axisLine: { show: false }, splitLine: { lineStyle: { color: #282B33 } }, axisLabel: { show: true, color: function (value, index) { // if(index 0) { // return red; // } // if(index 1) { // return #ff8447; // } // if(index 2) { // return #ffcc00; // } // return rgb(18,205,12) return #fff; }, fontSize: 12, // fontWeight: bold } }, series: [ { name: realdata, type: bar, barWidth: 10, itemStyle: { normal: { color: new echarts.graphic.LinearGradient(1, 0, 0, 1, [{ offset: 0, color: #2A6BCD }, { offset: 1, color: #34F6F8 }]), barBorderRadius: [5, 5, 5, 5] } }, label: { normal: { position: top, show: true, color: white, formatter: function (params) { return params.value; }, } }, data: datalist } ] }; myChart.setOption(option); }; chartrender_2(htmltipChart);视频图标那既然图表都可以那视频是否可以呢于是乎。。。效果视频图标代码实现//视频播放 showTipsImageBg({ htmlstr: div stylepointer-events:auto;width:320px;height:200px;background:url(static/img/tip3.png);background-size:100% 100%;text-align:left; div idhtmltipChart styleposition: absolute;top: 25px;height: 170px;left: 23px;right: 23px; video srcstatic/img/360.mp4 stylewidth:100%;height:100%;object-fit:fill; controls autoplay/video /div /div }, 120.1352, 28.2061, 0);那既然视频都可以那自己随便做一个动图是不是也可以于是乎。。。雷达扫描模拟图标效果雷达扫描代码实现//雷达 showTipsImageBg({ htmlstr: div styleposition: relative;width:300px;height:300px;border:1px dashed rgba(255,255,255,.3);border-radius:50%; div idhtmlradar styleposition: absolute;width:100%;height:100%;canvas idhtmlradarcanvas width300px height300px/canvas/div /div }, 119.2302, 28.2093, 0, true); //绘制扇形雷达相关方法 var CFG { initDeg: 60,//扇形的初始角度 perDeg: 1//每次旋转角度 }; var can document.getElementById(htmlradarcanvas); var ctx can.getContext(2d); var deg 0;//记录已旋转角度 var raf window.requestAnimationFrame(loop); function loop() { deg (deg CFG.perDeg); can.height can.height; drawRadar(deg); raf window.requestAnimationFrame(loop); } function drawRadar(iDeg) { gradientFun(iDeg); } //渐变填充----保证渐变效果可根据实际性能进行设置线性渐变需要随时计算偏移不稳定 function gradientFun(iDeg) { // var grd ctx.createLinearGradient(175,100,can.width,150); // grd.addColorStop(0,rgba(0,255,0,0)); // grd.addColorStop(1,rgba(0,255,0,1)); var startopa 0.1;//初始的透明度 var endopa 0.9;//结束的透明度 var rad_step 1;//渲染间隔度数-角度 var sum_step (CFG.initDeg / rad_step);//总共渲染次数 var opa_step (endopa - startopa) / sum_step;//透明度步进 for (var i 0; i sum_step; i) { ctx.fillStyle rgba(0,150,150, (startopa opa_step * i) ); // console.log(ctx.fillStyle); ctx.beginPath(); ctx.moveTo(150, 150); ctx.arc(150, 150, 150, (-(CFG.initDeg * (1 - i / sum_step)) iDeg) / 180 * Math.PI, (-(CFG.initDeg * (1 - (i 1) / sum_step)) iDeg) / 180 * Math.PI); ctx.fill(); ctx.closePath(); } }

相关新闻

SMUDebugTool完整指南:AMD Ryzen平台的SMU调试、超频与硬件排障一站搞定

SMUDebugTool完整指南:AMD Ryzen平台的SMU调试、超频与硬件排障一站搞定

SMUDebugTool完整指南:AMD Ryzen平台的SMU调试、超频与硬件排障一站搞定 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目…

2026/10/16 6:58:35 阅读更多 →
cesium 实战系列之风场进阶版

cesium 实战系列之风场进阶版

在此前我写过一个关于风场的一个文章&#xff0c;今天的这个是在区域风场的基础上做的一个案例&#xff0c;可以动态改变例子个数、线宽度、移动速度、颜色和存活时间&#xff0c;先看效果&#xff1a; 风场进阶版代码实现&#xff1a; <div classwindycanvas_list><…

2026/10/18 16:47:45 阅读更多 →
LLM推理GPU利用率低的原因分析与优化策略

LLM推理GPU利用率低的原因分析与优化策略

1. 从“GPU利用率10%”的困惑说起如果你正在部署或使用一个大语言模型&#xff08;LLM&#xff09;&#xff0c;比如Llama、ChatGLM或者Qwen&#xff0c;然后满怀期待地打开nvidia-smi&#xff0c;看到的GPU利用率&#xff08;Volatile GPU-Util&#xff09;却只有个位数或者可…

2026/10/17 23:29:29 阅读更多 →

最新新闻

AI率过高怎么办?九款降AI率工具与避坑指南

AI率过高怎么办?九款降AI率工具与避坑指南

上个月帮一位在外地项目上常驻的在职朋友看论文。他发来一张截图&#xff0c;检测系统提示“疑似AI生成内容占比接近四成”&#xff0c;导师在批注里连续写了好几遍——这几段请你按自己的话重写。他挺委屈&#xff1a;内容确实是自己对着调研材料一点一点整理出来的&#xff0…

2026/10/19 23:26:19 阅读更多 →
开源代码评审工作流:本地化、可审计、可定制的LLM实践方案

开源代码评审工作流:本地化、可审计、可定制的LLM实践方案

1. 项目概述&#xff1a;这不是一个“工具”&#xff0c;而是一套可落地的开源代码评审工作流“open-code-review”这个名字乍一听像某个新发布的 CLI 工具&#xff0c;或者某家大厂刚开源的 AI 代码审查平台。但实际翻遍 GitHub、Hugging Face 和主流技术社区&#xff0c;你会…

2026/10/19 23:26:19 阅读更多 →
基于YOLO11的无人机检测识别系统设计与实现

基于YOLO11的无人机检测识别系统设计与实现

一提到毕设做深度学习目标检测&#xff0c;十个里有八个都在刷COCO、VOC数据集&#xff0c;真正能落到现实问题上的反而不多。但“空域安全无人机检测识别”这个方向不一样&#xff0c;它直接对准了一个真实且刚需的场景——机场周边、重要场馆、活动安保都需要防范低空慢速小目…

2026/10/19 23:23:08 阅读更多 →
BP-PID残差补偿控制:Simulink中可解释的神经网络增强型PID实现

BP-PID残差补偿控制:Simulink中可解释的神经网络增强型PID实现

简介&#xff1a;本资源是一套基于Simulink实现BP神经网络自整定PID控制器的完整工程实践材料&#xff0c;面向自动化、控制工程及人工智能交叉领域的高校学生、科研人员与工业控制工程师&#xff0c;解决传统PID参数依赖经验整定、适应性差、动态响应不足等实际问题。压缩包共…

2026/10/19 23:18:58 阅读更多 →
STM32 SD卡数据落盘实战:fatfs移植与CSV文件生成

STM32 SD卡数据落盘实战:fatfs移植与CSV文件生成

简介&#xff1a;这份资源面向嵌入式开发学习者与STM32工程师&#xff0c;聚焦在STM32F429平台上集成FatFS文件系统、驱动SD卡写入数据并生成.csv文件&#xff0c;同时结合以太网驱动搭建TCP服务器接收网络数据。内容覆盖FatFS的移植与参数配置、SDIO或SPI方式下的SD卡初始化与…

2026/10/19 23:16:55 阅读更多 →
AI视频生成工作流:从产品拆解到批量成片的完整指南

AI视频生成工作流:从产品拆解到批量成片的完整指南

去年年底接了一个电商代运营团队的活儿&#xff0c;帮他们把带货短视频从“每周人工憋3条”改成“一天批量出20条成片”。项目做完以后&#xff0c;团队里负责剪辑的同事跟我说了一句话&#xff0c;让我印象特别深&#xff1a;以前最怕的不是剪片子&#xff0c;而是想不出脚本、…

2026/10/19 23:05:36 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介&#xff1a;本资源为电源技术方向的学术研究文档&#xff0c;聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略&#xff0c;面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集&#xff0c;共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →