代码编织梦想

(1)主要过程:结合Kriging.js 实现 Mapboxgl 上的插值图

(2)效果:

(3)代码

HTML 、CSS:

<head>
    <meta charset="UTF-8" />
    <title>Mapboxgl(canvas) + kriging.js</title>
    <style>
        html,
        body,
        #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
    <link rel="stylesheet" href="../lib/js/geoglobe/mapbox-gl.css" type="text/css" />
    <script type="text/javascript" src="../lib/js/geoglobe/mapbox-gl.js"></script>
    <script type="text/javascript" src="../lib/js/turf/turf_new.min.js"></script>
    <script type="text/javascript" src="../lib/js/interpolation/kriging_noModule.js"></script>
    <!-- 行政区划数据 (为了偷懒使用了js的形式) -->
    <script src="./data/wuhanShi.js"></script>
    <body>
        <!-- 用于绘制插值图的canvas -->
        <canvas id="canvasMap" style="display: none; opacity: 0.2"></canvas>
        <div id="map"></div>
        <script src="./js/mapboxKriging.js"></script>
    </body>
</head>

完整 JS:


// 颜色范围 (自定义)
const colors = [
    'rgba(0,0,0,0)',
    'rgb( 82 , 184 , 70 )',
    'rgb(90,187,68)',
    'rgb(98,189,66)',
    'rgb(106,192,63)',
    'rgb(114,194,61)',
    'rgb(122,197,59)',
    'rgb(130,199,57)',
    'rgb(138,202,55)',
    'rgb(146,204,52)',
    'rgb(154,207,50)',
    'rgb(162,209,48)',
    'rgb(171,212,46)',
    'rgb(179,215,44)',
    'rgb(187,217,41)',
    'rgb(195,220,39)',
    'rgb(203,222,37)',
    'rgb(211,225,35)',
    'rgb(219,227,33)',
    'rgb(227,230,30)',
    'rgb(235,232,28)',
    'rgb( 243 , 235 , 26 )',
    'rgb(243,230,26)',
    'rgb(243,224,27)',
    'rgb(243,219,27)',
    'rgb(244,213,28)',
    'rgb(244,208,28)',
    'rgb(244,203,29)',
    'rgb(244,197,29)',
    'rgb(244,192,30)',
    'rgb(244,186,30)',
    'rgb(244,181,30)',
    'rgb(245,176,31)',
    'rgb(245,170,31)',
    'rgb(245,165,32)',
    'rgb(245,159,32)',
    'rgb(245,154,33)',
    'rgb(245,149,33)',
    'rgb(246,143,34)',
    'rgb(246,138,34)',
    'rgb(246,132,35)',
];

let canvasImg, // 用于插值的画布
    map, // 地图实例
    points, // 插值点 通过随机数产生;
    range; // 插值范围

// 插值范围 外边界
// 可以使用 turf.js 库,获取行政区划的bbox,即为外边界
let xlim = [113.70228083999996, 115.08257304000006];
let ylim = [29.96907695999994, 31.36125996000004];

// 用于将canvas导出的图片放置在地图上合适位置
let coordinates = [
    [xlim[0], ylim[1]],
    [xlim[0], ylim[0]],
    [xlim[1], ylim[0]],
    [xlim[1], ylim[1]],
];

// 地图初始化
function init() {
    map = new mapboxgl.Map({
        container: 'map',
        style: {
            version: 8,
            sources: {
                cartodb: {
                    tiles: ['http://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'],
                    tileSize: 256,
                    type: 'raster',
                },
            },
            layers: [
                {
                    id: 'cartodb',
                    type: 'raster',
                    source: 'cartodb',
                },
            ],
        },
        center: [114.44515001943142, 30.649477958235423],
        zoom: 8.3,
        pitch: 0,
    });
    // 地图加载
    map.on('load', () => {
        createPoints();
        addStateLayer();
        cavasLayer();
    });
}
// 添加边界图层
function addStateLayer() {
    let wuhanFeatures = [];
    wuhanShi.features.forEach((element) => {
        wuhanFeatures.push({
            type: 'Feature',
            properties: element.attributes,
            geometry: {
                type: 'Polygon',
                coordinates: element.geometry.rings,
            },
        });
    });
    map.addSource('wuhan', {
        type: 'geojson',
        data: {
            type: 'FeatureCollection',
            features: wuhanFeatures,
        },
    });
    map.addLayer({
        id: 'wuhan',
        source: 'wuhan',
        type: 'line',
        paint: {
            'line-color': 'black',
            'line-width': 2,
        },
    });

    //  插值范围
    range = wuhanFeatures[0].geometry.coordinates;
}
// 创建用于插值的随机数据点
function createPoints() {
    var randomPoints = turf.randomPoint(25, {
        bbox: [113.70228083999996, 29.96907695999994, 115.08257304000006, 31.36125996000004],
    });
    randomPoints.features.forEach((item, index) => {
        item.properties = {
            z: Math.round(Math.random() * 100),
            id: index,
        };
    });
    // console.log(randomPoints); // 打印randomPoints查看插值点数据
    // 插值点图层
    map.addSource('point', {
        type: 'geojson',
        data: randomPoints,
    });
    map.addLayer({
        id: 'point',
        source: 'point',
        type: 'circle',
        paint: {
            'circle-color': 'black',
        },
    });

    // 插值点数据
    points = randomPoints.features;
}
//进行克里金插值
function loadkriging() {
    var canvas = document.getElementById('canvasMap');
    canvas.width = 1000;
    canvas.height = 1000;
    var n = points.length;
    var t = []; // 数值
    var x = []; // 经度
    var y = []; // 纬度
    for (var i = 0; i < n; i++) {
        t.push(points[i].properties.z);
        x.push(points[i].geometry.coordinates[0]);
        y.push(points[i].geometry.coordinates[1]);
    }
    //对数据集进行训练
    var variogram = kriging.train(t, x, y, 'exponential', 0, 100);

    //使用variogram对象使polygons描述的地理位置内的格网元素具备不一样的预测值,最后一个参数,是插值格点精度大小
    var grid = kriging.grid(range, variogram, (ylim[1] - ylim[0]) / 250);

    //将得到的格网grid渲染至canvas上
    kriging.plot(canvas, grid, [xlim[0], xlim[1]], [ylim[0], ylim[1]], colors);

    // 将插值结果进行处理,转换为图片格式以便作为图层接入mapboxgl地图中
    return drawImage(0, 0, 0.5);
}
// canvas图片处理
function drawImage(x, y, alpha) {
    // 获取canvas元素对应的DOM对象
    var canvas = document.getElementById('canvasMap');
    // 获取在canvas上绘图的CanvasRenderingContext2D对象
    var ctx = canvas.getContext('2d');
    // 绘制图片
    // ctx.drawImage(image, x, y);
    // 获取从x、y开始,宽为image.width、高为image.height的图片数据
    // 也就是获取绘制的图片数据
    var imgData = ctx.getImageData(x, y, canvas.width, canvas.height);
    for (var 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');
}

// 添加一个raster图层到地图中,使用的数据源是canvas转换为的图片形式(插值结果)
function cavasLayer() {
    map.addSource('kriging', {
        type: 'image',
        url: loadkriging(),
        coordinates: [coordinates[0], coordinates[3], coordinates[2], coordinates[1]],
    });
    map.addLayer({
        id: 'kriging',
        type: 'raster',
        source: 'kriging',
        paint: {
            'raster-opacity': 1,
        },
    });
}


init();

我觉得应该不能再详细了...

(4)还存在的问题:目前够用。如有问题请联系我改正!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/VarLInKe/article/details/115347201

Cesium+kriging.js实现雨量插值-爱代码爱编程

0.前言 网上有很多关于openlayers的克里金插值,但是最近在学习cesium,也想在cesium中做,但是好像网上相关的例子一个都没有。所以我就自己尝试去做。 1.克里金插值 克里金插值也称作空间局部插值法,或空间自协方差最佳插值法,它以变异函数理论和结构分析为基础, 在特定区域内对区域化变量进行无偏最优估计,被广泛应用于土壤制图领域,是一种非常重

GIS开发:推荐mapbox gl js-爱代码爱编程

mapbox是一个开源的地图类库,通过使用mapbox的类库,可以很方便的构建web、app等地图应用,支持的地图sdk有web、ios、Android和Unity。 mapbox gl js是mapbox地图的一部分,使用了webgl技术渲染地图上的一些酷炫的效果。 网址: https://docs.mapbox.com/mapbox-gl-js/o

Coding and Paper Letter(八十)-爱代码爱编程

新一期资源整理。 文章目录 1 Coding:2 Paper: 1 Coding: 1.城市模拟综合。 UrbanSimulationSynthesis 2.基于 bookdown 的 ElegantBook。 ElegantBookdown 3.R语言包lifecycle,生命周期提供了一组工具和约定来管理导出功能的生命周期。

色斑图制作及后端无人值守自动出图kriging.js+chrome+html2canvas.js+DOS+BIGEMAP超低成本实现气象要素色斑图-爱代码爱编程

目录 一、问题由来 二、探索 三、尝试 四、修正 五、优化方案 六、kriging.js 使用感受小结 七、参考文章 八、原始例程下载 下载连接:https://download.csdn.net/download/jessezappy/16769114 一、问题由来        因业务需要,需要根据小时温度、雨量等气象数据自动生成色

应用统计学跟统计学_在实践中使用地统计学-爱代码爱编程

应用统计学跟统计学 介绍(Introduction) In this article, you will understand what is geostatistics, and how to use kriging, an interpolation method, to make estimates usin

MapboxMap 之 Expression(五)-爱代码爱编程

系列文章目录 TypesLookupDecisionMath String Color Zoom Heatmap Feature data Variable binding Ramps, scales, curves 目录 系列文章目录 前言 一、String 1. concat 2. upcase 3.downcase 二、Color

python 等值面 插值_对离散点进行克里金插值并输出矢量等值面-爱代码爱编程

kriging-contour 基于克里金插值算法,根据离散点位置及其权重,生成等值面矢量数据(GeoJSON格式)和栅格数据(Canvas绘制图片),这些数据在任何WebGIS客户端上都可通用展示。 兼容性 该库生成结果是geojson和canvas上绘制两种形式,这种通用结果可以在ol,mapbox,leaflet,arcgis api等各种

Mapbox常用表达式整理(3)-爱代码爱编程

文章目录 表达式参考Decision 判定操作符!, !=, <, <=, ==, >, >=(高频率使用)all 逻辑与(高频率使用)any 逻辑或case 条件 (高频率使用)match (高频率使用)Ramps, scales, curvesinterpolate(高频率使用)step(高频率使用)String 字符串

kriging克里金插值以及前端渲染jS代码部分解释-爱代码爱编程

.html中的方法调用 //训练使用高斯过程与贝叶斯先验 let variogram=kriging.train(positions.map(pos=>pos[2]),positions.map(pos=>pos[0]),positions.map(pos=>pos[1]),params.krigingModel,params

JavsScript 浮点数计算精度问题解决-爱代码爱编程

问题描述 在 JavaScript 中整数和浮点数都属于 Number 数据类型,均以 64 位浮点数形式储存。浮点数在进行四则运算时常常会发现出现精度问题,在浏览器控制台试验如下所示: > 0.1+0.2 < 0.30000000000000004 > 0.3-0.2 < 0.09999999999999998 >

2021-12-23 睡前故事--jQuery-添加元素之append、prepend、after、before的区别-爱代码爱编程

jQuery-添加元素之append、prepend、after、before的区别 小萝卜儿灵魂画师🖌上线,用下图瞎编🩸一篇睡前故事为大家分析上面这四者的区别: 【心血来潮❤写的,故事纯属瞎编,不喜勿喷哟😄】 小萝卜儿的睡前故事之第一篇~🌛 很久很久以前,在一片沙漠色森林里🌲,有两只可爱滴小兔兔🐰,一只叫小黑,一只叫小灰,它们是形影不离滴好盆友🪴,

不做卷王,只做优质打工人——字节实习生2021年度总结-爱代码爱编程

你好,我是TianTian。 之前直系学弟投稿了一篇文章,记录了进入字节的心里路程,内容很长: 学弟进字节了 学弟是22届毕业的,目前还是大四,如果你有问题想咨询的话,学弟微信:codebangbang。 最近他去字节实习了,两个月的实习时间,到底带给他啥感受,一起来看看,以下是正文。 导语 距离上一次写文章已经过去两个多

Buffer的使用-爱代码爱编程

数据的二进制 计算机中所有的内容:文字、数字、图片、音频、视频最终都会使用二进制来表示。JavaScript可以直接去处理非常直观的数据:比如字符串,我们通常展示给用户的也是这些内容。不对啊,JavaScript不是也可以处理图片吗? 事实上在网页端,图片我们一直是交给浏览器来处理的;JavaScript或者HTML,只是负责告诉浏览器一个图片的地

Asp.net core 使用Vue-爱代码爱编程

版本 .net 3.1 vue3.0 Vue设置 vue设置很简单,写完程序后运行打包命令: npm run build 生成了静态文件,目录如下: Asp.net Core设置 将vue生成的静态文件全部复制到wwwroot目录下,没有就创建一个 在Startup.cs的Configure中添加如下代码: using Microsoft

PHP表单验证及安全-爱代码爱编程

文章目录 一、表单简介二、表单验证实例三、$_SERVER["PHP_SELF"] 变量的跨站脚本利用与避免 一、表单简介 表单(Form)在网页中主要负责数据采集功能。 一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI(公共网关接口)程序的URL以及数据提交到服务器的方法。 表单域:包含了文本框、密码框

分享11个网页游戏和9个黑客源码,总有一款适合你-爱代码爱编程

黑客和网页游戏源码 分享11个网页游戏和9个黑客源码,总有一款适合你源码下载地址:20个你喜欢的.rar - 蓝奏云 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下...,大家下载后可以看到。 PHP网页游戏xnova(ogame)-银河帝国v0.8版源码 JavaScript 连连看游戏代码[测试通过] JavaScript网页版泡