Openlayers指南

您所在的位置:网站首页 openlayers教程详细 Openlayers指南

Openlayers指南

#Openlayers指南| 来源: 网络整理| 查看: 265

在叠加海量数据量,使用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 }) });

全部叠加后的数据如下所示:

image 2.WebGL渲染

前面使用的是用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 })

渲染后的效果如下所示:

image

但是看上去有点问题,叠加上去的图形是正方形的,不是圆形,是因为着色器默认为正方形的,需要自己定义一个片段着色器,将图形设置成圆形的。

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] }); } }

使用片段着色器处理后,将看到圆形了,如下所示:

image

个人博客



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3