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

官网示例: 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() 函数进行一些初始化设置。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebGIS,即基于Web的地理信息系统,是一种通过Web技术实现地理信息系统功能的方式。在开发实例方面,可以借助CSDN平台上的资源进行学习和参考。 CSDN是一个技术社区,汇聚了众多IT从业者的知识和经验。在CSDN上可以找到很多关于WebGIS开发的教程和案例,供开发者学习和借鉴。 一个WebGIS开发实例包括以下步骤: 1.需求分析:首先要明确开发的WebGIS系统的需求,确定要实现的功能和目标。 2.数据收集和处理:收集地理信息数据,如地图、卫星影像、矢量数据等。对这些数据进行处理和转换,以便于在WebGIS系统中使用。 3.系统设计:根据需求确定系统的架构和各个模块的功能。选择合适的开发工具和技术,例如使用JavaScriptHTML、CSS等前端技术进行地图的呈现和交互,后端可以选择使用Java、Python等语言进行数据处理和业务逻辑的实现。 4.系统开发:按照系统设计的要求,逐步开发各个模块。使用CSDN平台上的教程和案例进行学习和参考,可以加速开发的进度和提高开发的质量。 5.测试和调试:在开发过程中进行测试,保证系统的稳定性和正确性。对系统进行调试,解决出现的问题和bug。 6.部署和上线:将开发完成的WebGIS系统部署到服务器上,上线供用户访问和使用。 总之,CSDN平台是一个非常有价值的资源,可以为WebGIS开发者提供学习和参考的资料。通过学习CSDN上的教程和案例,可以更加高效地进行WebGIS的开发实践。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值