Rendering meteorites with Canvas 2D 用Canvas 2D渲染陨石
在OpenLayers 6中,每一个地图中的图层都有一个独立的渲染器。先前,所有的图层渲染器都被一个独立的地图渲染器管理,并依赖一个单独的渲染策略。所以在OpenLayers 6之前,,你需要去在Canvas 2D和WebGL中选择选择一个去渲染所有的图层。在OpenLayers 6中,你的地图的图层可以拥有不同的渲染策略。例如,你可以用Canvas 2D去渲染某些图层,再用WebGL去渲染其它的。
ol/layer/Vector这个类使用Canvas 2D来渲染点线面。这个图层有一个全功能的、特征样式灵活的渲染器。对于数量极多的特征来说,WebGL是一个更加合适的技术。在这个模块中,我们首先使用Canvas 2D去渲染45,000个陨石的位置,然后再将这个样例迁移的WebGL中。
首先修改index.html文件,我们将要渲染一个全屏的页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OpenLayers</title>
<style>
html,
body,
#map-container {
margin: 0;
height: 100%;
width: 100%;
font-family: sans-serif;
}
</style>
</head>
<body>
<div id="map-container"></div>
</body>
</html>
然后我们从一个本地的CSV文件中获取并解析数据,将特征结果加入到vector source中,并把这些数据用vector layer渲染到地图上。那个meteorites.csv文件长这样:
name,mass,year,reclat,reclong
Aachen,21,1880,50.775000,6.083330
...
文件的第一行是一个标题行,在我们解析时会跳过。后续的行中包含位置的名称、陨石的质量、撞击的年份、用逗号分割的经纬度。我们使用一个XMLHttpRequest
的客户端来获取数据,并写一个简短的函数去解析文件中的每一行,并返回具有集合点的特征。
更新mian.js文件,并加载、渲染本地的CSV中的陨石撞击数据:
import 'ol/ol.css';
import {fromLonLat} from 'ol/proj';
import {Map, View} from 'ol';
import {Vector as VectorLayer, Tile as TileLayer} from 'ol/layer';
import {Vector as VectorSource, Stamen} from 'ol/source';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
const source = new VectorSource();
const client = new XMLHttpRequest();
client.open('GET', 'data/meteorites.csv');
client.onload = function() {
const csv = client.responseText;
const features = [];
let prevIndex = csv.indexOf('\n') + 1; // scan past the header line
let curIndex;
while ((curIndex = csv.indexOf('\n', prevIndex)) != -1) {
const line = csv.substr(prevIndex, curIndex - prevIndex).split(',');
prevIndex = curIndex + 1;
const coords = fromLonLat([parseFloat(line[4]), parseFloat(line[3])]);
if (isNaN(coords[0]) || isNaN(coords[1])) {
// guard against bad data
continue;
}
features.push(new Feature({
mass: parseFloat(line[1]) || 0,
year: parseInt(line[2]) || 0,
geometry: new Point(coords)
}));
}
source.addFeatures(features);
};
client.send();
new Map({
target: 'map-container',
layers: [
new TileLayer({
source: new Stamen({
layer: 'toner'
})
}),
new VectorLayer({
source: source
})
],
view: new View({
center: [0, 0],
zoom: 2
})
});
在获取并解析了这些数据后,特征将会被加入到vector source中。这个数据源将在一个tile layer上的vector layer渲染。我们没有在这里对特征进行任何自定义样式设置,重点只是想看看使用带有 45,000 个用 Canvas 2D 渲染的特征的地图的感觉。