概述
在做前后端数据交互的时候,你一定遇到过这样的问题:数据量大,尤其是在气象行业!在本文,讲解一种将数据压缩到图片并在前端实现数据的解析与展示的功能。
流程
整体操作流程图如下图:
实现的效果
1.前端绘制数据图;
2.移动鼠标展示鼠标所在位置的值;
3.间隔展示数据值;
关键实现
1、获取图片并解析数据
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的方式渲染,代码如下:
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实现鼠标移动展示鼠标所在位置的值。
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、奇偶行数的错行展示。
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);
});
技术博客
CSDN:http://blog.csdn.NET/gisshixisheng
在线教程
https://edu.csdn.net/course/detail/799
https://edu.csdn.net/course/detail/7471
联系方式
类型 | 内容 |
---|---|
1004740957 | |
公众号 | lzugis15 |
niujp08@qq.com | |
webgis群 | 452117357 |
Android群 | 337469080 |
GIS数据可视化群 | 458292378 |