前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >将数据压缩到图片并在前端做解析渲染

将数据压缩到图片并在前端做解析渲染

作者头像
lzugis
发布2019-08-14 14:31:45
7500
发布2019-08-14 14:31:45
举报
文章被收录于专栏:跟牛老师一起学WEBGIS

概述

在做前后端数据交互的时候,你一定遇到过这样的问题:数据量大,尤其是在气象行业!在本文,讲解一种将数据压缩到图片并在前端实现数据的解析与展示的功能。

流程

整体操作流程图如下图:

操作流程
操作流程

实现的效果

1.前端绘制数据图; 2.移动鼠标展示鼠标所在位置的值; 3.间隔展示数据值;

实现后效果
实现后效果

关键实现

1、获取图片并解析数据
代码语言:javascript
复制
var img = new Image();
img.src = 'css/ws_china.png';
img.onload = function () {
  var canvas = document.createElement('canvas');
  width = img.width;
  height = img.height;
  dx = (geoBounds[2] - geoBounds[0])/width;
  dy = (geoBounds[3] - geoBounds[1])/height;
  canvas.height = height;
  canvas.width = width;
  document.body.appendChild(canvas);
  var ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  imgPixels = ctx.getImageData(0, 0, width, height);
  var image = ctx.createImageData(width, height);
  // canvas先绘制行,在绘制列
  for(var j = 0;j<height;j++){
    for(var i = 0;i<width;i++){
      var _ji = (j * 4) * width + i * 4;
      var r = imgPixels.data[_ji], g = imgPixels.data[_ji+1] ,b = imgPixels.data[_ji+2];
      var val = r * 256 + g + b * 0.01;
      val = Number(val.toFixed(2));
      var c = getColor(val);
      image.data[_ji + 0] = parseInt(c[0]);
      image.data[_ji + 1] = parseInt(c[1]);
      image.data[_ji + 2] = parseInt(c[2]);
      image.data[_ji + 3] = val === 0 ? 0 : parseInt(c[3]);
    }
  }
  ctx.putImageData(image, 0, 0);
}
2、前端渲染数据图

用ol里面最简单的方式,staticImage的方式渲染,代码如下:

代码语言:javascript
复制
var imageLayer = new ol.layer.Image({
  source: null,
  opacity: 0.85
});
map.addLayer(imageLayer);
var source = new ol.source.ImageStatic({
  url: canvas.toDataURL("image/png"),
  imageExtent: bounds
});
imageLayer.setSource(source);
3、鼠标移动效果

通过注册map的pointermove事件,结合overlay实现鼠标移动展示鼠标所在位置的值。

代码语言:javascript
复制
var popup = new ol.Overlay({
  element: document.getElementById('popup'),
  position: null,
  positioning: 'center-left',
  offset: [16, 0]
});
map.addOverlay(popup);
map.on('pointermove', function (e) {
  var geoPt = ol.proj.toLonLat(e.coordinate);
  var val = getVal(geoPt);
  if(val) {
    document.getElementById('popup').innerText = val.toFixed(1);
    popup.setPosition(e.coordinate);
  } else  {
    popup.setPosition(null);
  }
});
4、在地图上渲染值

在地图上的渲染:1、用vector实现数据的展示;2、按照屏幕位置,做了等间距展示;3、奇偶行数的错行展示。

代码语言:javascript
复制
var textLayer = new ol.layer.Vector({
  source: null,
  opacity: 0.85,
  style: function (feat) {
    var val = feat.get("val");
    if(val) {
      return new ol.style.Style({
        text: new ol.style.Text({
          font: 'normal 14px 黑体',
          text: val.toFixed(1),
          fill: new ol.style.Fill({
            color: '#ff0000'
          }),
          stroke: new ol.style.Stroke({
            color: '#ffff',
            width: 2
          })
        })
      })
    } else {
      return null;
    }
    
  }
});
map.addLayer(textLayer);
var _source = new ol.source.Vector({
  features: []
});
textLayer.setSource(_source);
map.on("moveend", function () {
  _source.clear();
    var extent = map.getView().calculateExtent();
    var geoExtent = ol.proj.transformExtent(extent, 'EPSG:3857', 'EPSG:4326');
    var lonmin, lonmax, latmin, latmax;
    lonmin = geoExtent[0] > geoBounds[0] ? geoExtent[0] : geoBounds[0];
    latmin = geoExtent[1] < geoBounds[1] ? geoExtent[1] : geoBounds[1];
    lonmax = geoExtent[2] > geoBounds[2] ? geoExtent[2] : geoBounds[2];
    latmax = geoExtent[3] < geoBounds[3] ? geoExtent[3] : geoBounds[3];
    var topLeft = [lonmin, latmax];
    var topLeft3857 = ol.proj.fromLonLat(topLeft);
    var topLeftPixel = map.getPixelFromCoordinate(topLeft3857);
    var topLeftSetPixel = [topLeftPixel[0] + intervalPixel, topLeftPixel[1]];
    var topLeftSet3857 = map.getCoordinateFromPixel(topLeftSetPixel);
    var topLeftSet = ol.proj.toLonLat(topLeftSet3857);
    var intervalDegree = topLeftSet[0] - topLeft[0];
    var nx = Math.floor((lonmax - lonmin) / intervalDegree),
      ny = Math.floor((latmax - latmin) / intervalDegree * 2);
    var _features = [];
    // y是固定的,x根据奇偶行变换
    for(var i = 0;i<=ny;i++) {
      var lat = latmax - i * intervalDegree / 2;
      var lonAdd = i%2 !==0 ? intervalDegree / 2 : 0;
      for(var j=0;j<=nx;j++) {
        var lon = lonmin + j * intervalDegree;
        lon = lon + lonAdd ;
        var lonLat = [lon + dx/2, lat + dy/2];
        var coord = ol.proj.fromLonLat(lonLat);
        if(ol.extent.containsCoordinate(extent, coord)) {
          var val = getVal(lonLat);
          _features.push(new ol.Feature({
            geometry: new ol.geom.Point(coord),
            val: val
          }));
        }
      }
    }
    _source.addFeatures(_features);
});

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年08月05日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 流程
  • 实现的效果
  • 关键实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档