Openlayers指南 |
您所在的位置:网站首页 › openlayers教程详细 › Openlayers指南 |
在叠加海量数据量,使用WebGL可以提升性能,因为WebGL是基于GPU来渲染的。这里主要介绍将CSV中的数据叠加到地图上来,首先使用的是用普通的canvas来叠加二维数据,然后再使用WebGL来叠加数据。 1.Canvas 2D渲染在Openlayers 6中,地图的每个图层都是单独进行渲染的。之前所有图层都是在一个单独的渲染器上完成的。所以在Openlayers 6之前,只能选择Canvas 2D或者WebGL渲染所有图层,但在Openlayers 6可以为不同的图层选择不同的渲染策略,也就是说有些图层可用Canvas 2D渲染,有些图层可以用WebGL渲染。ol/layer/Vector可以用Canvas 2D来渲染点、线、面,这个图层具有丰富的渲染可能,可以渲染不同的样式。但是对于海量的数据来说,WebGL是最佳的选择。下面使用Canvas 2D来加载*45,000 **个点。 加载CSV这里主要使用csv文件来加载数据,文件中的数据格式为如下所示: name,mass,year,reclat,reclong Aachen,21,1880,50.775000,6.083330修改main.js后的代码如下所示: 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 }) });全部叠加后的数据如下所示: 前面使用的是用Canvas 2D来渲染的,这里主要介绍一下WebGL怎么渲染要矢量图层。使用的是静态样式,如果使用动态样式来渲染,WebGL是最好的选择。在Openlayers中可以使用一起工具来使用WebGL渲染数据。步骤如下所示: 2.1引入相关工具这里渲染的是点坐标,需要引入PointsLayer和一个数学函数工具。 import Renderer from 'ol/renderer/webgl/PointsLayer'; import {clamp} from 'ol/math'; 2.2创建自定义图层继承VectorLayer创建一个子类,重写createRenderer方法,并返回新的Renderer对象,在构造函数中设置colorCallback和sizeCallback,分别用于设置颜色和尺寸。 const color = [1, 0, 0, 0.5]; class CustomLayer extends VectorLayer { createRenderer() { return new Renderer(this, { colorCallback: function(feature, vertex, component) { return color[component]; }, sizeCallback: function(feature) { return 18 * clamp(feature.get('mass') / 200000, 0, 1) + 8; } }); } }创建好自定义图层后,然后再进行实例化,并指定source,如下所示: new CustomLayer({ source: source })渲染后的效果如下所示: 但是看上去有点问题,叠加上去的图形是正方形的,不是圆形,是因为着色器默认为正方形的,需要自己定义一个片段着色器,将图形设置成圆形的。 class CustomLayer extends VectorLayer { createRenderer() { return new Renderer(this, { colorCallback: function(feature, vertex, component) { return color[component]; }, sizeCallback: function(feature) { return 18 * clamp(feature.get('mass') / 200000, 0, 1) + 8; }, //! [fragment] fragmentShader: ` precision mediump float; varying vec2 v_texCoord; varying vec4 v_color; void main(void) { vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0); float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y; float value = 2.0 * (1.0 - sqRadius); float alpha = smoothstep(0.0, 1.0, value); gl_FragColor = v_color; gl_FragColor.a *= alpha; }` //! [fragment] }); } }使用片段着色器处理后,将看到圆形了,如下所示: 个人博客 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |