【WebGIS实例】(8)MapboxGL绘制闪烁的点

news2024/11/19 5:57:30

官网示例: Add an animated icon to the map | Mapbox GL JS

请添加图片描述

实现

示例数据

const sampleData = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "coordinates": [
          112.58261709330202,
          22.76596784315703
        ],
        "type": "Point"
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "coordinates": [
          113.59425670069453,
          23.67775776441485
        ],
        "type": "Point"
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "coordinates": [
          114.37244101407515,
          23.249455907195042
        ],
        "type": "Point"
      }
    }
  ]
}

主要内容

// !引入地图对象 const map = new mapboxgl.Map({{...}) 的那个
import map from "../creatMap.js"; 

export class AnimatedPoint {
  constructor() {
    const size = 200;
    const pulsingDot = {
      width: size,
      height: size,
      data: new Uint8Array(size * size * 4),

      // When the layer is added to the map,
      // get the rendering context for the map canvas.
      onAdd: function () {
        const canvas = document.createElement('canvas');
        canvas.width = this.width;
        canvas.height = this.height;
        this.context = canvas.getContext('2d');
      },

      // Call once before every frame where the icon will be used.
      render: function () {
        const duration = 1000;
        const t = (performance.now() % duration) / duration;

        const radius = (size / 2) * 0.3;
        const outerRadius = (size / 2) * 0.7 * t + radius;
        const context = this.context;

        // Draw the outer circle.
        context.clearRect(0, 0, this.width, this.height);
        context.beginPath();
        context.arc(
          this.width / 2,
          this.height / 2,
          outerRadius,
          0,
          Math.PI * 2
        );
        context.fillStyle = `rgba(255, 200, 200, ${1 - t})`;
        context.fill();

        // Draw the inner circle.
        context.beginPath();
        context.arc(
          this.width / 2,
          this.height / 2,
          radius,
          0,
          Math.PI * 2
        );
        context.fillStyle = 'rgba(255, 100, 100, 1)';
        context.strokeStyle = 'white';
        context.lineWidth = 2 + 4 * (1 - t);
        context.fill();
        context.stroke();

        // Update this image's data with data from the canvas.
        this.data = context.getImageData(
          0,
          0,
          this.width,
          this.height
        ).data;

        // Continuously repaint the map, resulting
        // in the smooth animation of the dot.
        map.triggerRepaint();

        // Return `true` to let the map know that the image was updated.
        return true;
      }
    };
    map.addImage('pulsing-dot', pulsingDot, { pixelRatio: 1 });
  }

  // 绘制点
  drawPoint(features) {
    // 如果已经存在名为animatedPoint的数据源了,就更新数据
    // 否则就新建一个数据源和图层
    if (map.getSource('animatedPoint')) {
      map.getSource('animatedPoint').setData({
        type: "FeatureCollection",
        features: features,
      });
    } else {
      map.addSource('animatedPoint', {
        type: "geojson",
        data: features
      })
      map.addLayer({
        'id': 'animatedPoint', //图层ID
        'type': 'symbol', //图层类型
        'source': 'animatedPoint', //数据源
        layout: {
          'icon-image': 'pulsing-dot',
          'icon-anchor': 'center',
        },
      })
    }
  }
  
  // 移除点图层
  clearPoint() {
    if (map.getSource('animatedPoint')) {
      map.removeLayer('animatedPoint')
      map.removeSource('animatedPoint')
    }
  }
}

调用

// 引入
import { AnimatedPoint } from './AnimatedPoint'

// 声明
window.animatedPoint = new AnimatedPoint()

// 绘制示例数据
window.animatedPoint.drawPoint(sampleData)

// 移除示例数据的图层
window.animatedPoint.clearPoint()

说明

核心对象介绍

这个功能的核心是const pulsingDot = {...}这一端,pulsingDot这个对象表示了一个动态的脉冲点,它包括以下属性和方法:

  1. widthheight:分别表示脉冲点的宽度和高度。
  2. data:表示以一维数组形式存储的像素数据,用于渲染动画效果。
  3. onAdd:用于添加脉冲点到地图中的方法,会创建一个 canvas 元素,并设置其尺寸与该对象的widthheight属性相同。
  4. render:用于在 canvas 上渲染动态脉冲点的方法。在方法内部,首先计算了当前时间相对于一个周期总时间的进度百分比t。接下来根据t来计算脉冲点的大小、颜色和边框等样式,并使用 canvas API 在画布上绘制出脉冲点的效果。最后将结果复制到该对象的data属性中,并通知地图进行重新绘制。

这个动态脉冲点的效果是通过定时调用render方法来实现的。每次调用此方法时,都会重新计算并绘制脉冲点的效果,并更新其中的像素数据(this.data)。在地图中加入此对象后,它会自动调用它的onAdd方法来初始化 canvas 并完成一些其他的设置。

最后的最后使用 map.triggerRepaint() 使地图视图进行重绘。

onAdd

onAdd 是 Mapbox GL JS API 中的一个函数,它是在将自定义地图元素添加到地图中时执行的回调函数。当您使用 map.addControl, map.addSource, 或者 map.addLayer 等方法将自定义的图层、控件或源加入到地图中时,Mapbox GL JS 会自动调用该元素的 onAdd() 函数进行一些初始化设置。

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

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

相关文章

5G干扰排查优化方案介绍!

干扰成因 干扰源的发射信号(阻塞信号、加性噪声信号)从天线口被放大发射出来后,经过了空间损耗L,最后进入被干扰接收机。如果空间隔离不够的话,进入被干扰接收机的干扰信号强度够大,将会使接收机信噪比恶化…

【教程】安装VSCode-Server

转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn] 前景提要 jupyter虽然好用,但他只能运行ipynb文件,对于py文件还是只能通过命令行来运行,不是很方便。 因此,通过安装vscode来运行py文件。而vscode-server支持像jup…

Centos-7安装步骤教程

提示: 鼠标移动到虚拟机内部单击或者按下Ctrl G,鼠标即可移入到虚拟机中,按下Ctrl Alt,鼠标即可移出虚拟机 目录 一、虚拟机的创建 1、创建新的虚拟机 2、选择典型,也可以自定义 3、安装程序光盘映像文件&#x…

618大促即将来临,速卖通、Lazada等平台如何快速提高排名和转化率?

速卖通每年三大促,328、618、双11。618马上就要来临,卖家朋友们都准备好了吗?今天陈哥就和大家聊聊怎么快速提高产品转化率。转化率是卖家在分析复盘时非常关键的因素,转化率的高低直接影响着卖家目前的关键词listing或者商品描述…

4.5 队列实现及其应用(上)

目录 顺序队列 创建空队列: 判断队列空: 入队: 队列 队列是限制在两端进行插入操作和删除操作的线性表 允许进行存入操作的一端称为“队尾” 允许进行删除操作的一端称为“队头” 当线性表中没有元素时,称为“空队” 特点 &am…

监控室值班人员脱岗识别算法 opencv

监控室值班人员脱岗识别算法模型通过pythonopencv网络深度学校模型技术,监控室值班人员脱岗识别算法模型实现企业总监控室值班人员脱岗、睡岗、玩手机等场景的AI识别,不需人为干预全天候自动识别。OpenCV的全称是Open Source Computer Vision Library&am…

git码云的使用-创建项目仓库-ssh协议配置步骤

目录 1、创建仓库 1.1 只填入仓库名即可-提交 1.2 本地项目上传到远程仓库 2、提交仓库 2.1 选择HTTPS协议 2.2 选择ssh协议 3、ssh协议配置步骤 3.1 打开 Git Bash 3.2 生成公钥:$ cd ~/.ssh (可忽略) 3.3 生成密钥 3.4 添加公钥…

【零基础QQ机器人开发三】程序上云篇

前言:本文为大家带来QQ机器人程序上云的教程,环境搭建请参考下面链接 【0基础QQ机器人开发】基于go-cqhttp的QQ机器人开发教程,仅供自学 【零基础QQ机器人开发二】服务器篇 文章目录 程序Logger类StatuStore类MultiFunc类QQBot类main.py 前言&#xff1a…

AP3266 DC-DC大功率同步降压恒流芯片 过EMC三级 摩托电动汽车灯IC

1,产品描述 AP3266 是高效率、外围简单、内置功率管的同步降压恒流芯片,适用于4-40V输入的降压LED恒流驱动芯片。输出功率可达 40W,电流3.6A。AP3266 可通过调节 OVP 端口的分压电阻,设定输出空载电压 保护,避免高压 空…

DenseNet与ResNet

ResNet(深度残差网络) 深度残差网络 DenseNet 采用密集连接机制,即互相连接所有的层,每个层都会与前面所有层在channel维度上连接在一起,实现特征重用,作为下一层的输入。 这样不但缓解了梯度消失的现象…

2023数维杯数学建模ABC题思路分析

占个位置吧,开始在本帖实时更新数维杯数学建模赛题思路代码,文章末尾获取! 持续为更新参考思路 赛题思路 已完成全部可以领取,详情看文末!!! 数维杯A题思路 A题是这次比赛比较难的题目&…

AI落地:如何用AI做出可用的PPT?

ChatGPT问世以来,很多工具都有了AI版。原来让我们头疼的PPT,这不现在也能一键生成了。 看了网友分享的各种一键生成PPT技术,真是牛。 很快没错,但是。。。缺点你是一句不提啊。 PPT做成这样,这要是直接用&#xff0c…

【MATLAB图像处理实用案例详解(8)】—— 图像数字水印算法

目录 一、背景意义二、基本原理三、算法介绍3.1 数字水印嵌入3.2 数字水印提取 四、程序实现 一、背景意义 数字水印技术作为信息隐藏技术的一个重要分支,是将信息(水印)隐藏于数字图像、视频、音频及文本文档等数字媒体中,从而实现隐秘传输、存储、标注…

基于等照度线和窗口匹配的图像修补算法

作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 一、关于图像修补 图像修补的目的是基于已有的图像信息或数据库内信息,对缺失区域进行合理地修复。在诸多领域如电影、…

35个开源的工业软件-工业4.0

不同的工业流程,需要不同的工业软件。面向研发设计环节的开源软件,今天就来介绍一下面向生产控制环节的开源软件,主要为可编程逻辑控制器(PLC)、分布式控制系统(DCS)、生产执行系统(MES&#xf…

以“阵地战”打法,多样性算力攻坚数字经济基础设施

作者 | 曾响铃 文 | 响铃说 人人都知道数字化转型进入深水区后,对算力的渴求在不断增长。 包括政务、能源、金融、制造业等领域的数字化转型铆足了劲头,不断向那些数字基础设施索要源源不断的算力。 但是,更应该注意到的是,在…

Debian 12 “Bookworm” 的新特性和发布日期

导读Debian 12 即将发布。了解一下更多关于其新特性和发布日期的相关信息。 debian 12 Debian 即将发布系统代号为 “书虫” 的新版本。与 Debian 11 “Bullseye” 相比,有许多改进和新功能。 Debian 12 “Bookworm” 包含了超过 11200 个新软件包,软件…

泰克RSA306B频谱分析仪测试信道功率方法

泰克RSA306B实时频谱分析仪是一种用于无线信号分析的仪器。它可以实时监控无线信号的频谱,帮助用户分析信号特征,掌握信号的功率、频率、调制等关键信息。在无线通信中,信道功率是一个非常重要的指标,它反映了信号在传输过程中的强…

基于matlab使用广义互相关和三角测量来确定宽带信号源的位置

一、前言 此示例说明如何使用广义互相关 (GCC) 和三角测量来确定宽带信号源的位置。为简单起见,此示例仅限于由一个源和两个接收传感器阵列组成的二维方案。您可以将此方法扩展到两个以上的传感器或传感器阵列以及三维。 二、介绍 源定位不同…

速锐得工业物联网技术无线自动化解决方案在物流业的应用

物流业一直走在工业物联网的最前沿,因为许多工业物联网的机会和技术与物流业完美匹配。因此,物流业多年依赖一直使用许多工业物联网相关的传感器和技术。 例如,多年来,物流业一直在包装、托盘和集装箱中使用条形码,从9…