四章-40-使用WebGL渲染海量图标
2020-04-21 本文已影响0人
彩云飘过
本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers 5.3.x api。
源码 见 1040.html ,对应的 官网示例 https://openlayers.org/en/latest/examples/webgl-points-layer.html?q=WebGL
https://openlayers.org/en/latest/examples/icon-sprite-webgl.html?q=WebGL
https://openlayers.org/en/latest/examples/filter-points-webgl.html?q=WebGL
ol.Map:canvas方式渲染
ol.WebGLMap:WebGL方式渲染
image.png
image.png
使用同一个图源
image.png
<!DOCTYPE html>
<html>
<head>
<title>使用WebGL渲染海量图标</title>
<link rel="stylesheet" href="../include/ol.css" type="text/css" />
<script src="../include/ol.js"></script>
</head>
<body>
<div id="info"> </div>
<div id="map" class="map"></div>
<script>
// 根据位移取得不同姿态的蝴蝶
var iconInfo = [
{
offset: [0, 0],
opacity: 1.0,
rotateWithView: true,
rotation: 0.0,
scale: 1.0,
size: [55, 55]
}, {
offset: [110, 86],
opacity: 0.75,
rotateWithView: false,
rotation: Math.PI / 2.0,
scale: 1.25,
size: [55, 55]
}, {
offset: [55, 0],
opacity: 0.5,
rotateWithView: true,
rotation: Math.PI / 3.0,
scale: 1.5,
size: [55, 86]
}, {
offset: [212, 0],
opacity: 1.0,
rotateWithView: true,
rotation: 0.0,
scale: 1.0,
size: [44, 44]
}];
var i;
//根据iconInfo得到全部的Icon类实例,图源时同一张,因为offset的不同,所以Icon类实例拿到图片中蝴蝶也就不同
var iconCount = iconInfo.length;
var icons = new Array(iconCount);
for (i = 0; i < iconCount; ++i) {
var info = iconInfo[i];
icons[i] = new ol.style.Icon({
offset: info.offset,
opacity: info.opacity,
rotateWithView: info.rotateWithView,
rotation: info.rotation,
scale: info.scale,
size: info.size,
crossOrigin: 'anonymous',
src: '../data/Butterfly.png'
});
}
//随机生成一些坐标,给每一个要素样式化
var featureCount = 150000;
var features = new Array(featureCount);
var feature, geometry;
var e = 25000000;
for (i = 0; i < featureCount; ++i) {
geometry = new ol.geom.Point(
[2 * e * Math.random() - e, 2 * e * Math.random() - e]);
feature = new ol.Feature(geometry);
feature.setStyle(
new ol.style.Style({
image: icons[i % (iconCount )]
})
);
features[i] = feature;
}
var vectorSource = new ol.source.Vector({
features: features
});
var vector = new ol.layer.Vector({
source: vectorSource
});
var map = new ol.WebGLMap({ // 关键点,使用WebGLMap ,而不是使用Map (使用canvas技术)
layers: [vector],
target: document.getElementById('map'),
view: new ol.View({
center: [0, 0],
zoom: 5
})
});
// 鼠标在地图上单击时显示单击位置有多少多少个蝴蝶
map.on('click', function(evt) {
var info = document.getElementById('info');
info.innerHTML =
'正在统计蝴蝶数 ...';
//为模拟计算机思考过程,增加延时操作
window.setTimeout(function() {
var features = [];
map.forEachFeatureAtPixel(evt.pixel, function(feature) {
features.push(feature);
return false;
});
if (features.length === 1) {
info.innerHTML = '点击到一只';
} else if (features.length > 1) {
info.innerHTML = '点击到 ' + features.length + ' 只蝴蝶';
} else {
info.innerHTML = '一只都没点到哟';
}
}, 500);
});
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
var hit = map.hasFeatureAtPixel(pixel);
map.getTarget().style.cursor = hit ? 'pointer' : '';
});
</script>
</body>
</html>