前端实现克里金插值分析(一)

news2025/7/19 11:22:13

作者:yangjunlin

最近不少小伙伴问我怎么搞前端插值分析,我在github上查找了一些资料,目前最常用的方式是webgis框架+idw(反距离权重算法)+d3-contour的方式实现,这种方式是比较简单同时基本能满足一般的气象分析,比如局部的平均降水发布图等,下来我将详细的讲述具体的实现方式

首先我们需要知道什么是d3-contour,具体的使用方式是什么,可以参考https://www.wenjiangs.com/doc/d3-contour-2这个文档,阅读之后我们发现他是一个类库,
在这里插入图片描述
以我的角度理解是将任意一个矩形,将其分成若干个单位相同的正方形格子,并且记录下每个正方形中的value值(非常类似栅格图像以像素为单位进行分割)。我红框圈起来的就非常能体现,一个256*256的矩形盒子以0.5为单位的正方形进行切割,每个正方形有个值,然后调用方法,只需要传入thresholds阈值返回的并返回每个阈值对应的等值线坐标数组。看到这里是不是有点想法了,我们只要想方法将我们分析的区域搞成矩形,并同时将其分割成若干个单位相同的正方形,然后将采样点和这个‘单位’正方形关联起来。既然提到了单位正方形,就非常类似咋们的像元了,因此废话不多说直接上代码

首先准备数据

全国面数据 2.2011年各地区气象站点数据(属性值中包含降雨量)
在这里插入图片描述

具体实现步骤

    1. 刚才咱们说需要把分析区域搞为矩形区域,能最快能想到的方式是利用turf的bbox拿到矩形范围,当然比如openlayer等都自带可以获得几何矩形范围的方法。因为我使用的iclient for mapboxgl 就行开发的,这个webgis库并没带有该方法,所以我采取的turf获取
import bbox from '@turf/bbox'
let box = bbox(region);
    1. 下一步就是切割了,经过查找资料发现最快捷的方式其实就是将矩形几何范围转为几何像素的范围,该范围内的单位刚好就是一个像素,像素可以理解为就是正方形的,并且后面站点的坐标也能直接转为像素,也方便站点值与切割的小矩形(像元)进行关联。因此我们现在只需要将得到的几何范围(左上右下)转为像素坐标得到一个像素范围,其实每个单位代表一个像元即上文提到的’小矩形’(当然也有弊端,zoom级别不同,导致单位像元的大小不一致的情况)
let p = map.project(pos);
    1. 然后我们就能得到上面讲的size(n,m)就是像元范围的上下的差值以及左右的插值
let cw = pxregion.xmax - pxregion.xmin;
let ch = pxregion.ymax - pxregion.ymin;
    1. 现在就要给像素范围里面的每个小正方形(像素)填值,之前我们提到过可以直接将气象点的坐标转为像素坐标,但是有个注意点,如果要将气象点的值与像素范围上的像素关联起来(类似空间上的传递赋值)是需要坐标一致的,现在我们拿到的像素范围的坐标是以(像素范围的最小x,像素范围最小的y)作为左下的原点,那么现在就需要将气象点的像素坐标值,减去分析像素范围的最小x和像素范围最小的y,来得到统一坐标系下的站点的像素位置和值
let p = map.project([data[i].x, data[i].y])
_data.push({
                   x: p['x'] - pxregion.xmin,
                   y: p['y'] - pxregion.ymin,
                   value: _value
               })
  • 5.现在我们已经拿到了n,m分析范围,和n,m上某些像元的值,下一步需要做的就是利用反距离权重来得到,像素范围内的每个像素的值,具体的实现方式网上有很多算法,我取了一个常用的
        const dlen = d.length;
       let matrixData = new Array(width * height);
       let idwcount = 0
       for (let i = 0, k1 = 0; i < height; i++) {
           for (let j = 0; j < width; j++, k1++) {
               let sum0 = 0,
                   sum1 = 0;
               for (let k = dlen - 1; k >= 0; k--) {
                   const dk = d[k];
                   const dis = Math.pow((i - dk.y), 2) + Math.pow((j - dk.x), 2);
                   sum0 += dk.value / dis;
                   sum1 += 1 / dis;
                   idwcount++
               }
               matrixData[k1] = sum0 / sum1
           }
       }
return matrixData;
    1. 反距离插值以后我们就能得到像素范围内的每个像元的值,然后利用d3-contour得到等值区域。[20, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000, 20000],这个是分析的阈值,可根据你们直接想分段的情况进行填写
contours.thresholds([20, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000, 20000])(idwdata).forEach((fakegeometry) => {})
    1. 现在返回的是不同阈值下的假的几何坐标和对应的阈值,为什么说假的呢,因为现在的这个坐标还是像素坐标,他不是正真的几何坐标,因此还需要转换将像素坐标转为几何坐标,记得要将以前为了统一坐标而减去的分析像素范围的最小x和像素范围最小的y加上,加上以后再进行转换
let data = map.unproject([coordinates[i][j][m][0] + pxregion.xmin, coordinates[i][j][m][1] + pxregion.ymin])
coordinates[i][j][m] = [data.lng, data.lat]
    1. 得到最终geometry和对应的阈值以后很快的能将其构造成feature,但是还没结束,现在得到的分析结果依然是个矩形范围,我们需要得到拿来分析的几何的范围,因此还需要将分析出的结果与分析几何进行相交操作,我这边依然用的turf来进行相交
import intersect from '@turf/intersect' 
dataset.features.map(item => {
       let resfea = intersect(item, region.features[0])
       resfea['properties']['value'] = item['properties']['value']
       datasetres.features.push(resfea)
   })
    1. 最后利用mapboxgl进行要素渲染,我们来看下结果,并且分析出来的结果与采样点对比基本一致
      在这里插入图片描述

后言

最后,这个才做好了一半,为什么说只做好了一半呢,因为有两个大原因1.分析的速度很慢,将主线程卡住了,导致整个界面都没法动,用户体验不好只是不要卡到主进程,2.分析的快慢和你所展示地图的zoom有关系,并且如果当你放的越大的时候,还没法分析出结果或者结果错误(这是因为我们使用的webgis框架自带的坐标转像素坐标导致,这个的结果和当前zoom有直接关系)。我们后面应该采取何种方式避免zoom级别导致的问题并做性能上的优化呢?大家可以关注我的下篇文章,前端克里金插值分析的优化和提升。下篇文章中我将放出全部完整代码及数据(像素渲染和网格渲染都将分别放出)

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

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

相关文章

Netty入门学习

同步&#xff1a;当调用方法的线程和接收结果的线程是同一个&#xff0c;这意味着阻塞&#xff0c;那么是同步。 异步&#xff1a;当调用方法的线程和处理结果的线程不是同一个&#xff0c;这意味着不是阻塞&#xff0c;是异步。 下图是一个简单的Netty的客户端和服务器端 【…

论文阅读笔记 | 三维目标检测——VoxelNet算法

如有错误&#xff0c;恳请指出。 文章目录1.背景2. 网络结构2.1 体素特征表示2.2 卷积特征提取2.3 RPN网络3. 实验结果paper&#xff1a;《VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection》 1.背景 以往的3d检测器都难免利用了手工设计特征(hand-…

ES6 入门教程 29 ArrayBuffer 29.1 ArrayBuffer 对象

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程29 ArrayBuffer29.1 ArrayBuffer 对象29.1.1 概述29.1.2 ArrayBuffer.prototype.byteLength29.1.3 ArrayBuffer.prototype.s…

善网ESG周报(第二期)

ESG报告&#xff1a; 聚焦五大战略&#xff0c;信公股份首次披露ESG报告 近日&#xff0c;信公股份发布首份ESG报告&#xff0c;报告主要涵盖可持续发展战略、高效现代的公司治理、可持续的商业模式与创新、传递社会影响力和守护地球家园等几个维度。 能链智电发布ESG报告&a…

SpringBoot——指标监控,自定义指标监控

为什么要进行指标监控&#xff1f; 在微服务架构中多个组件部署以后&#xff0c;我们需要能够监控到每个组件的健康情况&#xff0c;因此SpringBoot抽取了Actuator用于监控组件。 1.Java自带的监控工具&#xff08;不推荐&#xff09; 步骤&#xff1a; winr输入cmd 回车 进…

广告机联物联卡联网的优势?

广告机联物联卡联网的优势&#xff1f; 随着技术的发展、物联网技术的应用、物联网卡的授权&#xff0c;广告模式也在悄然发生变化&#xff0c;从传统的电视、报纸、杂志等广告模式逐渐转变为建筑之间的广告机。最常见的是地铁、公交车等公共区域设置的广告机或广告屏幕。 一…

67. SAP ABAP 监控用户事物码和程序执行的工具介绍

本文咱们不谈 ABAP 代码编写,而是介绍 SAP ABAP 系统里,如果想查找某个用户在某个时间段之内,在系统干了哪些事情,应该具体如何去做,SAP 又是提供了哪些工具来满足这种监控需求。 本文写作动机来源于一位朋友向我发起的咨询: 我们抛开 SAPGUI Script 这个因素不谈,本文…

第七章《Java的异常处理》第2节:异常的分类及处理方法

异常可以分为多种类型,Java语言允许程序员使用不同的方式来处理不同种类的异常,这样可以实现对异常的精细化处理。 7.2.1异常的分类 7.1小节中提到Exception是用来表示异常的类,但Exception并非Java语言中唯一用来表示异常的类,它只是庞大的异常类家族中的一员。下图7-7就…

[附源码]java毕业设计游戏网站设计

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

第八章 动态规划 5 AcWing 1591. 快速排序

第八章 动态规划 5 AcWing 1591. 快速排序 原题链接 AcWing 1591. 快速排序 算法标签 DP 思路 直接枚举a[i]之前所有元素与a[i]之后所有元素 判断 时间复杂度 O(N2)O(1010)O(N^2)O(10^{10})O(N2)O(1010) 超时 a[i]之前所有元素小于a[i] &#xff0c;即小于a[i]之前所有元…

YOLO算法(You Only Look Once)系列讲解与实现(待完善)

文章目录前言一、指标分析1.mAP (mean Average Precision)2.IOU二、YOLO1.YOLO-v1&#xff08;1&#xff09;步骤&#xff08;2&#xff09;网络结构&#xff08;3&#xff09;损失函数&#xff08;4&#xff09;存在问题2.YOLO-v2&#xff08;1&#xff09;新的尝试-Better&am…

Pod的生命周期

Pod的生命周期 与容器一样&#xff0c;Pod也有生命周期&#xff0c;Pod在整个生命周期中被定义为各种状态。了解这些状态对于后面我们学习Pod的调度是有帮助的。 Pending 挂起状态&#xff0c;Pod已经被K8s系统所认可&#xff0c;但是目前还有一个或多个容器镜像还没有被创建&…

Git错误:Incorrect username or password (access token)

目录 问题描述&#xff1a; 解决办法&#xff1a; 步骤一&#xff1a;进入电脑控制界面 步骤二&#xff1a;进入用户账户 步骤三&#xff1a;管理你的凭据 步骤四&#xff1a;选择Windows凭据 步骤五&#xff1a;找到gitee 步骤六&#xff1a;修改正确的用户名和密码 问…

【学习笔记23】JavaScript数组的遍历方法

笔记首发 1、forEach 语法: 数组.forEach(function(item, index, origin){})参数&#xff1a; item: 数组实际每一项的值index: 数组每一项对应的下标origin:原数组 作用: 遍历数组返回值: 返回值是undefined&#xff0c;哪怕你手写了return&#xff0c;也是undefined var arr…

springboot 使用shiro集成阿里云短信验证码

目录 1.阿里云短信验证码服务 2.发送短信验证码 3.多个realm配置 4.验证短信验证码 5.一些拓展思路 引言&#xff1a;短信验证码是通过发送验证码到手机的一种有效的验证码系统&#xff0c;主要用于验证用户手机的合法性及敏感操作的身份验证。在注册和修改密码时需要用到…

手摸手教会你在idea中配置Tomcat进行servlet/jsp开发(多图超详)

1. 下载安装idea&#xff0c;创建project&#xff0c;如果没有JDK可以通过idea指定文件夹并下载JDK。工程就是普通的Java工程&#xff0c;名字为webdemo 2.因为是Web项目&#xff0c;所以要对这个普通的项目进行WEB扶持^^&#xff0c;在项目名称webdemo上右键单间选择菜单项&qu…

Hive搭建

Hive系列第二章 第二章 Hive搭建 2.1 MySQL5.6安装 1、检查删除已有的 有就删除&#xff0c;没有就不用管。 rpm -qa | grep mysql rpm -e mysql-libs-5.1.73-8.el6_8.x86_64 --nodepsrpm -qa | grep mariadb rpm -e --nodeps mariadb-libs-5.5.56-2.el7.x86_642、删除mysql分…

Windows下Labelimg标注自己的数据集使用(Ubuntu18.04)Jetson AGX Orin进行YOLO5训练测试完整版教程

一、环境配置介绍 整个实现过程所涉及的文件目录&#xff0c;其中&#xff0c;自备表示自己需要准备的&#xff0c;生成表示无需自己准备。 使用yolov5时出现“assertionerror:no labels found in */*/*/JPEGImages.cache can not train without labels”问题 很多朋友都会遇…

SpringBoot+Vue项目医疗管理系统

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…

待办事项是什么意思,怎么用?

待办事项是什么意思&#xff0c;为什么要用&#xff1f;待办事项工具怎么设置&#xff1f;这里一文给你讲清&#xff01; 废话不多说&#xff0c;下面直接教你&#xff1a;梳理待办事项清单的方法&#xff0c;以及待办工具的操作实操步骤。想要快速提升工作效率的小伙伴&#…