下面介绍一下前端JavaScript代码各函数的逻辑功能:
在介绍js函数前,首先介绍一下后台web接口的数据结构:
使用$.parseJSON将result反序列化为JSON对象,表示包含经纬度坐标的全国空气站点信息的数组。
根据date,hour,type从后台查询指定日期指定小时的指定监测因子(AQI,PM2.5,PM10,O3,CO,NO2,SO2等)的全国空气站点的数据
使用$.parseJSON将result反序列化为JSON对象,用字典表示各个空气站点的数据(字典键为空气站点编码,字典值为数值)。
如下图,将地图范围沿着纵向和横向划分为多个网格,对应每个网格单独生成canvas叠加到了地图上。
前端html和js代码如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html,
body,
#allmap {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
#allmap img {
height: 100%;
}
</style>
<script type="text/javascript" src="https://underscorejs.net/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="https://underscorejs.net/js/underscore.js"></script>
<script type="text/javascript" src="static/lib/kriging.js"></script>
<script type="text/javascript" src="static/js/china.js"></script>
<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=wWy2A8K94nhntYTYUHS19RXW"></script>
<title>空气质量空间插值可视化</title>
</head>
<body>
<div id="allmap"></div>
<script type="text/javascript">
// 百度地图API功能
var map = new BMap.Map("allmap");
map.centerAndZoom(new BMap.Point(116.403765, 39.914850), 5);
map.enableScrollWheelZoom();
function loadMarkers(points) {
map.clearOverlays();
$.each(points, (i, x) => {
//console.log(x);
var position = new BMap.Point(x['经度'], x['纬度']);
var marker1 = new BMap.Marker(position);
dictMarker[x['编号']] = marker1;
map.addOverlay(marker1);
marker1.addEventListener("click", function() {
var attrs = _.omit(x, ['编号', '经度', '纬度','value2']);
var content = _.map(attrs, (x, i) => `${i}:${x}`).join('<br>');
var infoWindow = new BMap.InfoWindow(content);
marker1.openInfoWindow(infoWindow);
});
})
}
dictMarker = {};
$.get('api/stations', function(data) {
data = JSON.parse(data['result']);
window.points = data;
dictPoints = _.indexBy(points, '编号');
//loadMarkers(data);
refreshCanvas();
})
function refreshCanvas() {
var date = location.search.match(/date=([^&]*)/i);
var hour = location.search.match(/hour=([^&]*)/i);
if (!!date) {
date = date[1];
} else {
date = "20210610";
}
if (!!hour) {
hour = hour[1];
} else {
hour = "0";
}
var type = "PM2.5";
$.post('api/stations', {
date: date,
hour: hour,
type: type
}, function(data) {
data = JSON.parse(data['result']);
var airData = _.find(data, {
hour: parseInt(hour),
type: type
});
airData = _.omit(airData, ['date', 'hour', 'type']);
var trainData = _.compact(_.map(airData, function(item, index) {
if (!item) {
return null;
}
result = _.result(dictPoints, index, null);
if (!!result) {
result['value']=item;
result['value2'] = _.sortedIndex(standards, item);
}
return result;
}));
window.data1 = trainData;
window.canvas = getCanvas(trainData);
})
}
var [width, height] = [10, 5];
var [offsetX, offsetY] = [10, 5];
let canvas = null; //画布
let colors = ["green", "#82D827", "yellow", "#FFDF00", "orange", "#FF5E00",
"red", "#B71850", "purple", "#952E81","brown"];
var standards = [25, 50, 75, 100, 125, 150, 175, 200, 250, 300];
function getCanvas(data) {
var values = _.pluck(data, 'value2');
var lngs = _.pluck(data, '经度');
var lats = _.pluck(data, '纬度');
var indexes = _.unique(values);
var colors0 = colors.slice(_.min(indexes), _.max(indexes) + 1);
var [minX, minY, maxX, maxY] = [_.min(lngs), _.min(lats), _.max(lngs), _.max(lats)];
var bounds = [
[
[minX, minY],
[minX, maxY],
[maxX, maxY],
[maxX, minY]
]
];
console.log(bounds);
bounds = _.flatten(china.geometry.coordinates,true);
console.time();
window.variogram = kriging.train(values, lngs, lats, 'exponential', 0, 100);
console.timeEnd();
console.time();
window.grid = kriging.grid(bounds, variogram, (maxY - minY) / 500);
console.timeEnd();
console.time();
var lngs = _.range(minX - offsetX, maxX + offsetX, width);
var lats = _.range(minY - offsetY, maxY + offsetY, height);
_.map(lngs, function(m) {
canvas = document.createElement('canvas');
canvas.width = width * 5;
canvas.height = height * 5;
canvas.style.display = 'block';
canvas.getContext('2d').globalAlpha = 0.75;
[minX, maxX] = [m, m + width]
_.map(lats, function(n) {
[minY, maxY] = [n, n + height]
kriging.plot(canvas, grid, [minX, maxX], [minY, maxY], colors0);
addOverlay([minX, minY], [maxX, maxY], canvas);
})
})
console.timeEnd();
}
function addOverlay(west_south, east_north, canvasSource) {
var west_south = new BMap.Point(west_south[0], west_south[1]);
var east_north = new BMap.Point(east_north[0], east_north[1]);
var bounds = new BMap.Bounds(west_south, east_north);
var canvasOverlay = new BMap.GroundOverlay(bounds, {
imageURL: canvasSource.toDataURL(),
opacity: 0.6
});
map.addOverlay(canvasOverlay);
}
</script>
</body>
</html>
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。