区域等值面、热力图

讲讲项目背景,大屏专题图要绘制一个地区区域环境扩散效果,初步一开始感觉是一个热力图,后面经过描述确认不是,而是一个根据点位进行区域绘制的等值面

我以为的:
在这里插入图片描述
最后实际上的
在这里插入图片描述
第一张图是ui效果图,第二张图是确定功能需求后绘制的,说实话,看到ui效果图时我第一反应是热力图,因为这个扩散效果太像了,当时自己想的是这个图有河道,那就说明是地图,是地图那就说明可能需要缩放和拖拽,一开始项目中因为是大屏数据可视化,已经引入了echarst包,所以根据echarst绘制了一个地区区域面
,如下:

echarts + canvas

主要还是echarts社区给力,各种可视化图形基本都有
社区地址
社区查找示例筛选热力图,找到下面两个示例,跟我想要的效果很相似
在这里插入图片描述在这里插入图片描述
最后结论是这种热力效果有缺陷,那就是echarts绘制区域断面是根据registerMap函数绘制的,根据断面地理坐标geojson文件绘制出来一个图层
echarts.registerMap(‘fenyang’, geoJson);
而热力图图层无法融入registerMap创建的图层中去,当图形缩小到一定程度时,热力图层将变成一个矩形方块,看起来很不友好,所以淘汰

高德地图

使用高德绘制上述图形还是可以轻轻松松的,网上示例文档很多,这里就不介绍了,如有需要,留言,根据需要我会在写一篇博客,帮助有需要的朋友。
这里淘汰原因,项目中只有这一块用到了地图,引入高德显得过于臃肿。

项目领导反映这一块内容别用地图,且这不是一个热力图,不需要地图缩放,拖拽功能,可以用canvas绘制,冥思苦想了一会,不是热力图那看起来就有点类似等值面效果了,用canvas画这个断面不是啥问题,可是这个颜色渲染还没弄过,恰逢这时,领导给出回应,可以试试克里金插值算法试试,有这方面的插件。
在这里插入图片描述

kriging + canvas

克里金插值算法这是个啥,听都没听过,抱着学习心态去找度娘,翻了两个小时的博客文档最后决定自己造轮子,没有找到我可以用的示例,这里分享插件地址和两篇博客
插件地址
思路引用一
思路引用二

代码分享

其实我不怎么想贴的,因为文件结构有点多,算了还是分享出来,以免网友恶意揣测狗博主——问题没解决还瞎引导思路。

<!DOCTYPE html>
<html lang='En'>
  <hEad>
    <mEta charsEt='UTF-8'>
    <titlE>leaflet克里金空间插值</titlE>
    <stylE>
      html, Body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #canvasMap{
        /* width: 440px;
        height: 295px; */
        width: 300px;
        height: 300px;
      }
      #map{
        width: 100%;
        height: 0;
        margin: 0;
        padding: 0;
        ovErFlow: hiddEn;
        cursor: dEFault;
      }
    </stylE>
    <script src='world.js'></script>
    <script src='point.js'></script>
    <script src='kriging.js'></script>
  </hEad>
  <Body>
    <canvas id='canvasMap'></canvas>
    <div id='map'></div>
  </Body>
  <script>
    //world.js,是插值之后需要裁切的图形边界信息
    //point.js,是要插值的离散的点
    //遍历world边界数据,生成scope边界线
    let positions = [];
    world[0].forEach(function (point) {
      positions.push([point[1], point[0]]);
    });
    // 边界经度值极大值极小值,纬度极大值极小值
    let miny = Math.min(...world[0].map((v) => v[1]));
    let maxy = Math.max(...world[0].map((v) => v[1]));
    let minx = Math.min(...world[0].map((v) => v[0]));
    let maxx = Math.max(...world[0].map((v) => v[0]));
    let xlim = [minx, maxx];
    let ylim = [miny, maxy];
    //进行克里金插值
    function loadkriging()
    {
      var canvas = document.getElementById('canvasMap');
      canvas.width = 250;
      canvas.height = 250;
      var n = points.length;
      var t = [];//数值
      var x = [];//经度
      var y = [];//纬度
      for (var i = 0; i < n; i++)
      {
        t.push(points[i].attributes.TN_);
        x.push(points[i].geometry.x);
        y.push(points[i].geometry.y);
      }
      // 对数据集进行训练
      var variogram = kriging.train(t, x, y, 'exponential', 0, 100);
      // 改值越大,边界线越圆滑,反之锯齿越严重
      var tole = 300;
      //使用variogram对象使polygons描述的地理位置内的格网元素具备不一样的预测值,最后一个参数,是插值格点精度大小
      var grid = kriging.grid(world, variogram, (ylim[1]-ylim[0])/tole);
      var color = [
      '#7e0123',
      '#7f0124',
      '#7f0124',
      '#7f0125',
      '#7f0125',
      '#800125',
      '#800126',
      '#800126',
      '#800127',
      '#810127',
      '#810127',
      '#810128',
      '#810128',
      '#820129',
      '#820129',
      '#820129',
      '#82012a',
      '#83012a',
      '#83012b',
      '#83012b',
      '#84012b',
      '#84012c',
      '#84012c',
      '#84012d',
      '#85012d',
      '#85012e',
      '#85012e',
      '#86012f',
      '#86012f',
      '#860130',
      '#860130',
      '#870130',
      '#870131',
      '#870131',
      '#870132',
      '#880132',
      '#880132',
      '#880133',
      '#890133',
      '#890134',
      '#890134',
      '#890134',
      '#8a0135',
      '#8a0135',
      '#8a0136',
      '#8a0136',
      '#8b0136',
      '#8b0137',
      '#8b0037',
      '#8b0038',
      '#8c0038',
      '#8c0038',
      '#8c0039',
      '#8c0039',
      '#8d003a',
      '#8d003a',
      '#8d003a',
      '#8d003b',
      '#8e003b',
      '#8e003c',
      '#8e003c',
      '#8f003c',
      '#8f003d',
      '#8f003d',
      '#8f003e',
      '#90003e',
      '#90003e',
      '#90003f',
      '#90003f',
      '#910040',
      '#910040',
      '#910040',
      '#910041',
      '#920041',
      '#920042',
      '#920042',
      '#920043',
      '#930043',
      '#930043',
      '#930044',
      '#940044',
      '#940045',
      '#940045',
      '#940045',
      '#950046',
      '#950046',
      '#950047',
      '#950047',
      '#960047',
      '#960048',
      '#960048',
      '#960049',
      '#970049',
      '#970049',
      '#97004a',
      '#97004a',
      '#98004b',
      '#98004b',
      '#99004a',
      '#9a0049',
      '#9b0049',
      '#9c0048',
      '#9d0047',
      '#9e0046',
      '#9f0046',
      '#a00045',
      '#a10044',
      '#a20043',
      '#a30043',
      '#a40042',
      '#a50041',
      '#a60040',
      '#a70040',
      '#a8003f',
      '#aa003e',
      '#ab003d',
      '#ac003d',
      '#ad003c',
      '#ae003b',
      '#af003a',
      '#b0003a',
      '#b10039',
      '#b20038',
      '#b30037',
      '#b40037',
      '#b50036',
      '#b60035',
      '#b70034',
      '#b80034',
      '#b90033',
      '#ba0032',
      '#bb0031',
      '#bc0030',
      '#bd0030',
      '#be002f',
      '#bf002e',
      '#c0002d',
      '#c1002d',
      '#c2002c',
      '#c3002b',
      '#c4002a',
      '#c5002a',
      '#c60029',
      '#c70028',
      '#c80027',
      '#c90027',
      '#ca0026',
      '#cc0025',
      '#cd0024',
      '#ce0024',
      '#cf0023',
      '#d00022',
      '#d10021',
      '#d20021',
      '#d30020',
      '#d4001f',
      '#d5001e',
      '#d6001e',
      '#d7001d',
      '#d8001c',
      '#d9001b',
      '#da001b',
      '#db001a',
      '#dc0019',
      '#dd0018',
      '#de0017',
      '#df0017',
      '#e00016',
      '#e10015',
      '#e20014',
      '#e30014',
      '#e40013',
      '#e50012',
      '#e60011',
      '#e70011',
      '#e80010',
      '#e9000f',
      '#ea000e',
      '#eb000e',
      '#ec000d',
      '#ee000c',
      '#ef000b',
      '#f0000b',
      '#f1000a',
      '#f20009',
      '#f30008',
      '#f40008',
      '#f50007',
      '#f60006',
      '#f70005',
      '#f80005',
      '#f90004',
      '#fa0003',
      '#fb0002',
      '#fc0002',
      '#fd0001',
      '#fe0000',
      '#fe0100',
      '#fe0300',
      '#fe0400',
      '#fe0500',
      '#fe0600',
      '#fe0800',
      '#fe0900',
      '#fe0a00',
      '#fe0b00',
      '#fe0d00',
      '#fe0e00',
      '#fe0f00',
      '#fe1100',
      '#fe1200',
      '#fe1300',
      '#fe1400',
      '#fe1600',
      '#fe1700',
      '#fe1800',
      '#fe1900',
      '#fe1b00',
      '#fe1c00',
      '#fe1d00',
      '#fe1f00',
      '#fe2000',
      '#fe2100',
      '#fe2200',
      '#fe2400',
      '#fe2500',
      '#fe2600',
      '#fe2700',
      '#fe2900',
      '#fe2a00',
      '#fe2b00',
      '#fe2d00',
      '#fe2e00',
      '#fe2f00',
      '#fe3000',
      '#fe3200',
      '#fe3300',
      '#fe3400',
      '#fe3500',
      '#fe3700',
      '#fe3800',
      '#fe3900',
      '#fe3b00',
      '#fe3c00',
      '#fe3d00',
      '#fe3e00',
      '#ff4000',
      '#ff4100',
      '#ff4200',
      '#ff4300',
      '#ff4500',
      '#ff4600',
      '#ff4700',
      '#ff4900',
      '#ff4a00',
      '#ff4b00',
      '#ff4c00',
      '#ff4e00',
      '#ff4f00',
      '#ff5000',
      '#ff5100',
      '#ff5300',
      '#ff5400',
      '#ff5500',
      '#ff5700',
      '#ff5800',
      '#ff5900',
      '#ff5a00',
      '#ff5c00',
      '#ff5d00',
      '#ff5e00',
      '#ff5f00',
      '#ff6100',
      '#ff6200',
      '#ff6300',
      '#ff6500',
      '#ff6600',
      '#ff6700',
      '#ff6800',
      '#ff6a00',
      '#ff6b00',
      '#ff6c00',
      '#ff6d00',
      '#ff6f00',
      '#ff7000',
      '#ff7100',
      '#ff7300',
      '#ff7400',
      '#ff7500',
      '#ff7600',
      '#ff7800',
      '#ff7900',
      '#ff7a00',
      '#ff7b00',
      '#ff7d00',
      '#ff7e00',
      '#ff7f00',
      '#ff8100',
      '#ff8200',
      '#ff8300',
      '#ff8500',
      '#ff8600',
      '#ff8700',
      '#ff8800',
      '#ff8a00',
      '#ff8b00',
      '#ff8c00',
      '#ff8e00',
      '#ff8f00',
      '#ff9000',
      '#ff9200',
      '#ff9300',
      '#ff9400',
      '#ff9500',
      '#ff9700',
      '#ff9800',
      '#ff9900',
      '#ff9b00',
      '#ff9c00',
      '#ff9d00',
      '#ff9f00',
      '#ffa000',
      '#ffa100',
      '#ffa200',
      '#ffa400',
      '#ffa500',
      '#ffa600',
      '#ffa800',
      '#ffa900',
      '#ffaa00',
      '#ffac00',
      '#ffad00',
      '#ffae00',
      '#ffb000',
      '#ffb100',
      '#ffb200',
      '#ffb300',
      '#ffb500',
      '#ffb600',
      '#ffb700',
      '#ffb900',
      '#ffba00',
      '#ffbb00',
      '#ffbd00',
      '#ffbe00',
      '#ffbf01',
      '#ffc001',
      '#ffc201',
      '#ffc301',
      '#ffc401',
      '#ffc601',
      '#ffc701',
      '#ffc801',
      '#ffca01',
      '#ffcb01',
      '#ffcc01',
      '#ffcd01',
      '#ffcf01',
      '#ffd001',
      '#ffd101',
      '#ffd301',
      '#ffd401',
      '#ffd501',
      '#ffd701',
      '#ffd801',
      '#ffd901',
      '#ffdb01',
      '#ffdc01',
      '#ffdd01',
      '#ffde01',
      '#ffe001',
      '#ffe101',
      '#ffe201',
      '#ffe401',
      '#ffe501',
      '#ffe601',
      '#ffe801',
      '#ffe901',
      '#ffea01',
      '#ffeb01',
      '#ffed01',
      '#ffee01',
      '#ffef01',
      '#fff101',
      '#fff201',
      '#fff301',
      '#fff501',
      '#fff601',
      '#fff701',
      '#fff801',
      '#fffa01',
      '#fffb01',
      '#fffc01',
      '#fffe01',
      '#ffff01',
      '#fcff01',
      '#fafe01',
      '#f7fe01',
      '#f5fe01',
      '#f2fe01',
      '#f0fd01',
      '#edfd01',
      '#eafd01',
      '#e8fd01',
      '#e5fc01',
      '#e3fc01',
      '#e0fc01',
      '#defb01',
      '#dbfb01',
      '#d9fb01',
      '#d6fb01',
      '#d3fa01',
      '#d1fa01',
      '#cefa01',
      '#ccfa01',
      '#c9f901',
      '#c7f901',
      '#c4f901',
      '#c1f801',
      '#bff801',
      '#bcf801',
      '#baf801',
      '#b7f701',
      '#b5f701',
      '#b2f701',
      '#aff701',
      '#adf601',
      '#aaf601',
      '#a8f601',
      '#a5f501',
      '#a3f501',
      '#a0f501',
      '#9ef501',
      '#9bf401',
      '#98f401',
      '#96f401',
      '#93f401',
      '#91f301',
      '#8ef301',
      '#8cf301',
      '#89f201',
      '#86f201',
      '#84f201',
      '#81f201',
      '#7ff101',
      '#7cf101',
      '#7af101',
      '#77f101',
      '#74f001',
      '#72f001',
      '#6ff001',
      '#6def01',
      '#6aef01',
      '#68ef01',
      '#65ef01',
      '#62ee01',
      '#60ee01',
      '#5dee01',
      '#5bee01',
      '#58ed01',
      '#56ed01',
      '#53ed01',
      '#51ec01',
      '#4eec01',
      '#4bec01',
      '#49ec01',
      '#46eb01',
      '#44eb01',
      '#41eb01',
      '#3feb01',
      '#3cea01',
      '#39ea01',
      '#37ea01',
      '#34e901',
      '#32e901',
      '#2fe901',
      '#2de901',
      '#2ae801',
      '#27e801',
      '#25e801',
      '#22e801',
      '#20e701',
      '#1de701',
      '#1be701',
      '#18e601',
      '#16e601',
      '#13e601',
      '#10e601',
      '#0ee501',
      '#0be501',
      '#09e501',
      '#06e501',
      '#04e401',
      '#01e401',
      ]
  
      //将得到的格网grid渲染至canvas上
      kriging.plot(canvas, grid, [xlim[0], xlim[1]], [ylim[0], ylim[1]], color.reverse());
  
      // 绿,黄绿,橙黄绿,红橙黄绿,紫红橙黄绿,洋红紫红橙黄绿
      // #01e401,#ffff01,#ff7e00,#fe0000,#98004b,#7e0123,
      // 黄绿 #ffff01  #01e401
      // 橙黄绿 #01e401 #ff7e00 #ffff01  #01e401
      // 红橙黄绿 #01e401 #fe0000 #ff7e00 #ffff01  #01e401
      // 紫红橙黄绿 #01e401 #98004b #fe0000 #ff7e00 #ffff01  #01e401
      // 洋红紫红橙黄绿 #01e401 #7e0123 #98004b #fe0000 #ff7e00 #ffff01  #01e401
      // 
    }
    loadkriging();
  </script>
</html>

这里可以看到我声明的色值数组很长,因为建立的色系过渡数组太短的话,颜色过渡效果看起来非常差,说起来找色系过渡的编程处理方式还找了半天。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
A year and a half year ago, I published this article to the Codeguru site and got a number of requests about the Kriging algorithm contour map. Unfortunately, my project was changed shortly after that article and later I quit the company so I couldn‘t find time to finish this Contour business. A week ago, I happened to need a contour map again so I decided to solve the Kriging algorithm. I searched the Internet for a commercial library but they all look ugly and hard to use. So, I made up my mind to make my own algorithm. The Kriging algorithm is easy to find, but this algorithm needs a Matrix and solver (LU-Decomposition). Again, I couldn‘t find suitable code for this. I tried to use GSL first but this made my code too big and was slower. Finally, I went back to "Numerical Recipe in C"—yes, that horrible-looking C code—and changed the code there to my taste.If you read this article before, the rendering part hasn‘t been changed much. I added the Kriging algorithm and revised the codes a little bit. Following is the Kriging Algorithm:templatedouble GetDistance(const ForwardIterator start, int i, int j){ return ::sqrt(::pow(((*(start+i)).x - (*(start+j)).x), 2) + ::pow(((*(start+i)).y - (*(start+j)).y), 2));}templatedouble GetDistance(double xpos, double ypos, const ForwardIterator start, int i){ return ::sqrt(::pow(((*(start+i)).x - xpos), 2) + ::pow(((*(start+i)).y - ypos), 2));}templateclass TKriging : public TInterpolater{public: TKriging(const ForwardIterator first, const ForwardIterator last, double dSemivariance) : m_dSemivariance(dSemivariance) { m_nSize = 0; ForwardIterator start = first; while(start != last) { ++m_nSize; ++start; } m_matA.SetDimension(m_nSize, m_nSize); for(int j=0; j<m_nSize; j++) { for(int i=0; i<m_nSize; i++) { if(i == m_nSize-1 || j == m_nSize-1) { m_matA(i, j) = 1; if(i == m_nSize-1 && j == m_nSize-1) m_matA(i, j) = 0; continue; } m

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杀猪刀-墨林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值