Mapboxgl + KrigingJS 实现插值图

  1. 地图容器初始化

    • 使用隐藏的Canvas元素(canvasMap)作为后续插值渲染的绘图板

    • 依赖Mapbox GL JS地图库进行地理空间数据展示

  2. 圆形区域生成

    // 定义 createCircle 函数
    const createCircle = (center, radius, points) => {
        if (!points) points = 64;
        
        const coords = {
            longitude: center[0],
            latitude: center[1]
        };
        
        const km = radius / 1000.0;
        
        const ret = [];
        const distanceX = km / (111.32 * Math.cos((coords.latitude * Math.PI) / 180));
        const distanceY = km / 110.574;
        
        let theta, x, y;
        for (let i = 0; i < points; i++) {
            theta = (i / points) * (2 * Math.PI);
            x = distanceX * Math.cos(theta);
            y = distanceY * Math.sin(theta);
        
            ret.push([coords.longitude + x, coords.latitude + y]);
        }
        ret.push(ret[0]);
        
        return ret;
    };
        
    // 调用 createCircle 函数并绘制多边形
    const polygonPoints = createCircle([120.199071, 30.010606], 2000, 64);
    const circlePolygon = turf.polygon([polygonPoints]);
    • 基于圆心坐标和半径生成规则多边形

    • 使用turf.js进行地理空间计算

  3. 地图图层叠加

    window.glMap.addLayer({
         id: 'unique-layer-id', // 添加唯一 ID
         type: 'fill',
         source: {
             type: 'geojson',
             data: circlePolygon
         },
         paint: {
             'fill-color': 'red',
              'fill-opacity': 0.5
         }
    });
    • 为圆形区域添加填充层

    • 半透明填充效果增强可视化层次感

  4. 克里金插值分析

    const getValueTYZ = (points = []) => {
       // 构造插值数据
       const t = [];
       const x = [];
       const y = [];
       points.forEach(site => {
           const { level = 0, longitude, latitude } = site;
           t.push(level);
           x.push(parseFloat(longitude));
           y.push(parseFloat(latitude));
       });
       console.log(t, 't')
       return { t, x, y };
    };
    
    const { t, x, y } = getValueTYZ(points);
    
    let canvas = document.getElementById('canvasMap');
    
    canvas.width = 6000;
    canvas.height = 6000;
    
    // 训练克里金模型
    let variogram = kriging.train(t, x, y, 'exponential', 0, 255);
    console.log((ylim[1] - ylim[0]) / 1000)
    let grid = kriging.grid(range, variogram, 0.0003);
    • 使用预设采样点数据(包含经纬度和污染等级)

    • 采用指数型变异函数模型

    • 生成高密度插值网格(步长0.0003度)

  5. 可视化渲染

    //将得到的格网grid渲染至canvas上
    kriging.plot(canvas, grid, [xlim[0], xlim[1]], [ylim[0], ylim[1]], this.colors);
    // canvas图片处理
    function drawImage(x, y, alpha) {
        let ctx = canvas.getContext('2d');
        // 启用抗锯齿
        ctx.imageSmoothingEnabled = true;
        ctx.imageSmoothingQuality = 'high'; // 可选值:'low', 'medium', 'high'
        // 绘制图片
        let imgData = ctx.getImageData(x, y, canvas.width, canvas.height);
        for (let i = 0, len = imgData.data.length; i < len; i += 4) {
            // 改变每个像素的透明度
            imgData.data[i + 3] = imgData.data[i + 3] * alpha;
        }
        // 将获取的图片数据放回去。
        ctx.putImageData(imgData, x, y);
        return canvas.toDataURL('image/png');
    }
    
    window.glMap.addSource('kriging', {
        type: 'image',
        url: drawImage(0, 0, 0.95),
        coordinates: [coordinates[0], coordinates[3], coordinates[2], coordinates[1]],
    });
    window.glMap.addLayer({
        id: 'kriging',
        type: 'raster',
        source: 'kriging',
        paint: {
        'raster-opacity': 1,
        },
    });
    • 将插值结果渲染到6000x6000像素的Canvas

    • 使用预设的渐变色谱进行颜色映射

    • 调整整体透明度后转换为数据URL

    • 将处理后的Canvas图像作为栅格图层叠加到地图

    • 精确匹配地理边界坐标实现空间对齐

技术亮点分析:

  1. 多图层复合可视化

    • 基础底图

    • 半透明圆形区域

    • 插值结果栅格图

    • 采样点标记(注释状态)

    • 通过图层叠加实现多维数据展示

  2. 性能优化策略

    • 离屏Canvas渲染:避免直接操作地图DOM

    • 大尺寸Canvas:保证插值结果精度(6000x6000px)

    • WebGL加速:依赖Mapbox GL的WebGL渲染能力

  3. 空间分析算法

    • 克里金插值:适用于地理空间数据的统计插值方法

    • Turf.js:处理地理空间计算(质心计算、多边形生成等)

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小佟Q_Q!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值