mapbox标识重点关注的要素

本文介绍了如何在WebGIS中处理要素重叠问题,通过在地图上高亮显示特定字段值最大的要素,并使用动态脉冲点突出显示,同时提供了关键代码示例,包括要素查找最大值的方法和图层布局技巧。
摘要由CSDN通过智能技术生成

贴个群号

WebGIS学习交流群461555818,欢迎大家

效果图

有的时候我们会有这样的需求,就是在一坨要素里面,我们想要展示一个重点关注的要素,比如说是温度站点的话,我们要在地图上很明显的看到温度最高的那个站点,如果是降雨站点的话,我们要在地图上看到降雨最高的站点,随之而来就会产生这样的需求。 很合理的需求。
请添加图片描述

原理和源码

首先建议大家去看看我这篇博客,这个是在要素重叠的时候,如何让叠在一起的要素里面,只展示某个字段值最大或者最下的办法,要不然你即使实现了这个功能,但是这个点位存在要素重叠,但是重点标识的脉冲效果已经出来了,很自然的就以为这个点就是那个重点的点,然后一点开气泡或者弹窗,发现不是,那就太尴尬了,所以我们一定要要素重叠的时候,将重点的点首先要放在最上面。

https://blog.csdn.net/Sakura1998gis/article/details/136505302?spm=1001.2014.3001.5502

然后我们再考虑如何实现这个脉冲点。
首先我们地图初始化的时候,就要先加载好这个脉冲点图层,数据源采用geojson,但是这个时候是空的geojson,里面不要放什么数据

    const pulsingDotRed = {
        width: sizeRed,
        height: sizeRed,
        data: new Uint8Array(sizeRed * sizeRed * 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 = (sizeRed / 2) * 0.3;
            const outerRadius = (sizeRed / 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-red', pulsingDotRed, { pixelRatio: 2 });

    map.addSource('dot-point-red', {
        'type': 'geojson',
        'data': {
            'type': 'FeatureCollection',
            'features': []
        }
    });
    map.addLayer({
        'id': 'dot-point-red',
        'type': 'symbol',
        'source': 'dot-point-red',
        'layout': {
            visibility: 'visible',
            'icon-image': 'pulsing-dot-red',
            'icon-allow-overlap' : true,
            'icon-ignore-placement':true,
        }
    });

然后这个时候要注意一点,就是这个图层的位置,这个位置很讲究,因为他其实也是一个图层,他的位置必须放在所有点图层的下方,这样才会有一个图标,后面有这个脉冲点的效果。不然脉冲点在点图标的上面,看到的就不是这个感觉了。
这里可以参考我这篇博客,将这个脉冲点图层的位置移动到点定位图层的下方,就可以保证脉冲点图层永远处于所有点图层的下方了。

https://blog.csdn.net/Sakura1998gis/article/details/130545521?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171409878516800178580025%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=171409878516800178580025&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-3-130545521-null-null.nonecase&utm_term=%E5%AE%9A%E4%BD%8D&spm=1018.2226.3001.4450

然后生成点图层的时候,我们要找到我们想要重点关注的那个要素,这里我提供一个方法,参数1是图层的geojson,参数2是要根据那个字段来找最大值

//找到geojson中,指定属性的最大值的要素
const findFeatureWithMaxValue =(geojson, propertyName)=>{  
  // 首先确保geojson和propertyName是有效的  
  if (!geojson || !geojson.features || !propertyName) {  
    throw new Error('Invalid input: geojson or propertyName is missing');  
  }  
  
  // 初始化最大值和对应的feature  
  let maxValue = -Infinity;  
  let maxFeature = null;  
  
  // 遍历所有的features  
  geojson.features.forEach(function(feature) {  
    // 检查属性是否存在并且是数值类型  
    if (feature.properties && typeof feature.properties[propertyName] === 'number') {  
      const currentValue = feature.properties[propertyName];  
      // 如果当前值大于已知的最大值,则更新最大值和对应的feature  
      if (currentValue > maxValue) {  
        maxValue = currentValue;  
        maxFeature = feature;  
      }  
    }  
  });
  // 返回具有最大属性值的feature  
  return maxFeature;  
}

这个方法会将最大值的要素返回,返回之后,将这个要素的经纬度封装成一个点要素,塞进脉冲点图层中,就可以了。

      if(maxFeature){
        this.map.getSource('dot-point-red').setData({
            "type": "FeatureCollection",
            "features": [
                {
                    'type': 'Feature',
                    'geometry': {
                        'type': 'Point',
                        'coordinates':[maxFeature.properties.lgtd,maxFeature.properties.lttd] // icon position [lng, lat]
                    }
                }
            ]
        })
      }else{
        this.map.getSource('dot-point-red').setData({
            "type": "FeatureCollection",
            "features": [
            ]
        })
      }
  • 21
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值