OpenLayers Workshop(四)WebGL Meteor Shower

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 渲染的特征的地图的感觉。

发表评论