OpenLayers基础教程——WebGLPoints图层样式的设置方法

HerryDong 2024-07-07 10:33:02 阅读 99

1、前言

前一篇博客介绍了如何在<code>OpenLayers中使用WebGLPoints加载海量数据点的方法,这篇博客就来介绍一下WebGLPoints图层的样式设置问题。

2、样式运算符

VectorLayer图层中,我们只需要创建一个ol.style.Style对象即可,WebGLPoints则不同,它并不是基于Canvas进行绘制,因此其样式渲染不能直接使用ol.style.Style,取而代之的是使用样式表达式进行渲染。

2.1、读取运算符

['get', 'attributeName']

['var', 'varName']

['time']

['zoom']

['resolution']

2.2、数学运算符

['*', value1, value2]

['/', value1, value2]

['+', value1, value2]

['-', value1, value2]

['clamp', value, low, high]

['%', value1, value2]

['^', value1, value2]

2.3、变换运算符

['case', condition1, output1, ...conditionN, outputN, fallback]

['match', input, match1, output1, ...matchN, outputN, fallback]

['interpolate', interpolation, input, stop1, output1, ...stopN, outputN]

2.4、逻辑运算符

['<', value1, value2]

['<=', value1, value2]

['>', value1, value2]

['>=', value1, value2]

['==', value1, value2]

['!=', value1, value2]

['!', value1]

['between', value1, value2, value3]

2.5、转换运算符

['array', value1, ...valueN]

['color', red, green, blue, alpha]

3、简单渲染

简单颜色渲染很简单,只需要使用['color', red, green, blue, alpha]即可,第一个参数为固定值‘color’,后面的参数依次为红、绿、蓝、透明度。下面的代码会将要素渲染为红色点:

<!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8">code>

<meta name="viewport" content="width=device-width, initial-scale=1.0">code>

<title>WebGL</title>

<style>

html,

body,

#map {

width: 100%;

height: 100%;

margin: 0;

padding: 0;

}

</style>

<link rel="stylesheet" href="ol/ol.css" />code>

<script src="ol/ol.js"></script>code>

</head>

<body>

<div id="map"></div>code>

<script>

// 创建图层

var layer = new ol.layer.WebGLPoints({

source: new ol.source.Vector({

features: [

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.0]),

"type": "学校",

"dbm": 1

}),

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.1]),

"type": "学校",

"dbm": 2

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.0]),

"type": "超市",

"dbm": 3

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.1]),

"type": "超市",

"dbm": 4

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.0]),

"type": "医院",

"dbm": 5

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.1]),

"type": "医院",

"dbm": 6

}),

]

}),

style: {

symbol: {

symbolType: 'circle',

size: 40,

color: ['color', 255, 0, 0, 1]

}

}

});

// 创建地图

var map = new ol.Map({

target: 'map',

layers: [

layer

],

view: new ol.View({

projection: 'EPSG:4326',

center: [120, 30],

zoom: 10

})

});

</script>

</body>

</html>

运行结果如下图所示:

在这里插入图片描述

4、分类渲染

测试数据中的<code>type字段将要素分成了3类,即:学校、超市、医院。现在要求将学校渲染为红色、超市渲染为绿色、医院渲染为蓝色。此时需要使用match表达式,其形式如下所示:

['match', type的值, '学校', 红色, '超市', 绿色, '医院', 蓝色, 默认颜色]

那么type的值又该如何获取?其实很简单,使用['get', 'attributeName']表达式即可,所以最后的样式表达式如下所示:

['match', ['get', 'type'], '学校', 红色, '超市', 绿色, '医院', 蓝色, 默认颜色]

代码如下所示:

<!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8">code>

<meta name="viewport" content="width=device-width, initial-scale=1.0">code>

<title>WebGL</title>

<style>

html,

body,

#map {

width: 100%;

height: 100%;

margin: 0;

padding: 0;

}

</style>

<link rel="stylesheet" href="ol/ol.css" />code>

<script src="ol/ol.js"></script>code>

</head>

<body>

<div id="map"></div>code>

<script>

// 创建图层

var layer = new ol.layer.WebGLPoints({

source: new ol.source.Vector({

features: [

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.0]),

"type": "学校",

"dbm": 1

}),

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.1]),

"type": "学校",

"dbm": 2

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.0]),

"type": "超市",

"dbm": 3

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.1]),

"type": "超市",

"dbm": 4

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.0]),

"type": "医院",

"dbm": 5

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.1]),

"type": "医院",

"dbm": 6

}),

]

}),

style: {

symbol: {

symbolType: 'circle',

size: 40,

color: [

'match',

['get', 'type'],

'学校', ['color', 255, 0, 0, 1],

'超市', ['color', 0, 255, 0, 1],

'医院', ['color', 0, 0, 255, 1],

['color', 255, 0, 0, 1]

]

}

}

});

// 创建地图

var map = new ol.Map({

target: 'map',

layers: [

layer

],

view: new ol.View({

projection: 'EPSG:4326',

center: [120, 30],

zoom: 10

})

});

</script>

</body>

</html>

运行结果如下图所示:

在这里插入图片描述

5、分级渲染

测试数据中包含一个<code>dbm字段,现在根据dbm的范围进行分级渲染,规定如下:

1、dbm∈[1, 2],渲染为红色

2、dbm == 3,渲染为绿色

3、dbm == 4,渲染为蓝色

4、dbm∈[5, 6],渲染为黄色

此时需要使用case表达式,其形式如下所示:

['case', 'dbm∈[1,2]', 红色, 'dbm==3', 绿色, 'dbm==4', 蓝色, 'dbm∈[5,6]', 红色, 默认颜色]

在判断dbm的值的范围时,需要使用逻辑表达式:

['==', dbm, 3]

['==', dbm, 4]

['between', dbm, 1, 2]

['between', dbm, 5, 6]

最后,使用['get', 'attributeName']表达式获取字段值:

['get', 'dbm']

代码如下所示:

<!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8">code>

<meta name="viewport" content="width=device-width, initial-scale=1.0">code>

<title>WebGL</title>

<style>

html,

body,

#map {

width: 100%;

height: 100%;

margin: 0;

padding: 0;

}

</style>

<link rel="stylesheet" href="ol/ol.css" />code>

<script src="ol/ol.js"></script>code>

</head>

<body>

<div id="map"></div>code>

<script>

// 创建图层

var layer = new ol.layer.WebGLPoints({

source: new ol.source.Vector({

features: [

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.0]),

"type": "学校",

"dbm": 1

}),

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.1]),

"type": "学校",

"dbm": 2

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.0]),

"type": "超市",

"dbm": 3

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.1]),

"type": "超市",

"dbm": 4

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.0]),

"type": "医院",

"dbm": 5

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.1]),

"type": "医院",

"dbm": 6

}),

]

}),

style: {

symbol: {

symbolType: 'circle',

size: 40,

color: [

'case',

['between', ['get', 'dbm'], 1, 2], ['color', 255, 0, 0, 1],

['==', ['get', 'dbm'], 3], ['color', 0, 255, 0, 1],

['==', ['get', 'dbm'], 4], ['color', 0, 0, 255, 1],

['between', ['get', 'dbm'], 5, 6], ['color', 255, 255, 0, 1],

['color', 255, 0, 0, 1]

]

}

}

});

// 创建地图

var map = new ol.Map({

target: 'map',

layers: [

layer

],

view: new ol.View({

projection: 'EPSG:4326',

center: [120, 30],

zoom: 10

})

});

</script>

</body>

</html>

运行结果如下图所示:

在这里插入图片描述

6、根据地图缩放等级渲染

现做如下规定:

1、地图缩放等级<code>zoom∈(0, 10],渲染为红色

2、地图缩放等级zoom∈(10, 12],渲染为绿色

3、地图缩放等级zoom∈(12, 14],渲染为蓝色

4、其余缩放等级,渲染为黄色

看了上面的例子之后,相信同志们应该想到了:利用['zoom']获取地图缩放等级,然后利用case表达式进行情况分类,最后每种情况利用逻辑表达式判断即可。代码如下:

<!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8">code>

<meta name="viewport" content="width=device-width, initial-scale=1.0">code>

<title>WebGL</title>

<style>

html,

body,

#map {

width: 100%;

height: 100%;

margin: 0;

padding: 0;

}

</style>

<link rel="stylesheet" href="ol/ol.css" />code>

<script src="ol/ol.js"></script>code>

</head>

<body>

<div id="map"></div>code>

<script>

// 创建图层

var layer = new ol.layer.WebGLPoints({

source: new ol.source.Vector({

features: [

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.0]),

"type": "学校",

"dbm": 1

}),

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.1]),

"type": "学校",

"dbm": 2

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.0]),

"type": "超市",

"dbm": 3

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.1]),

"type": "超市",

"dbm": 4

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.0]),

"type": "医院",

"dbm": 5

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.1]),

"type": "医院",

"dbm": 6

}),

]

}),

style: {

symbol: {

symbolType: 'circle',

size: 40,

color: [

'case',

['<=', ['zoom'], 10], ['color', 255, 0, 0, 1],

['<=', ['zoom'], 12], ['color', 0, 255, 0, 1],

['<=', ['zoom'], 14], ['color', 0, 0, 255, 1],

['color', 255, 255, 0, 1]

]

}

}

});

// 创建地图

var map = new ol.Map({

target: 'map',

layers: [

layer

],

view: new ol.View({

projection: 'EPSG:4326',

center: [120, 30],

zoom: 10

})

});

</script>

</body>

</html>

运行结果如下图所示:

在这里插入图片描述

7、根据地图分辨率渲染

根据地图分辨率渲染也很简单,只需要把上面的<code>['zoom']替换成['resolution']即可。不过考虑到resolution值是一个小数,因此这里将resolution乘以10000之后再进行判断,代码如下:

<!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8">code>

<meta name="viewport" content="width=device-width, initial-scale=1.0">code>

<title>WebGL</title>

<style>

html,

body,

#map {

width: 100%;

height: 100%;

margin: 0;

padding: 0;

}

</style>

<link rel="stylesheet" href="ol/ol.css" />code>

<script src="ol/ol.js"></script>code>

</head>

<body>

<div id="map"></div>code>

<script>

// 创建图层

var layer = new ol.layer.WebGLPoints({

source: new ol.source.Vector({

features: [

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.0]),

"type": "学校",

"dbm": 1

}),

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.1]),

"type": "学校",

"dbm": 2

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.0]),

"type": "超市",

"dbm": 3

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.1]),

"type": "超市",

"dbm": 4

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.0]),

"type": "医院",

"dbm": 5

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.1]),

"type": "医院",

"dbm": 6

}),

]

}),

style: {

symbol: {

symbolType: 'circle',

size: 40,

color: [

'case',

['<=', ['*', ['resolution'], 10000], 2], ['color', 255, 0, 0, 1],

['<=', ['*', ['resolution'], 10000], 3], ['color', 0, 255, 0, 1],

['<=', ['*', ['resolution'], 10000], 4], ['color', 0, 0, 255, 1],

['<=', ['*', ['resolution'], 10000], 5], ['color', 255, 255, 0, 1],

['<=', ['*', ['resolution'], 10000], 6], ['color', 255, 0, 255, 1],

['<=', ['*', ['resolution'], 10000], 7], ['color', 0, 255, 255, 1],

['color', 300, 200, 100, 1]

]

}

}

});

// 创建地图

var map = new ol.Map({

target: 'map',

layers: [

layer

],

view: new ol.View({

projection: 'EPSG:4326',

center: [120, 30],

zoom: 10

})

});

</script>

</body>

</html>

运行结果如下图所示:

在这里插入图片描述

8、设置要素的形状和透明度

在<code>symbol对象中,symbolType参数用于定义要素的形状,它可以设置为circle、triangle、square、image。例如将symbolType设置为triangle

symbol: {

symbolType: 'circle',

size: 40,

color: ['color', 255, 0, 0, 1]

}

此时要素会被渲染为三角形,如下图所示:

在这里插入图片描述

将<code>symbolType设置为square

symbol: {

symbolType: 'square',

size: 40,

color: ['color', 255, 0, 0, 1]

}

此时要素会被渲染为正方形,如下图所示:

在这里插入图片描述

如果希望设置透明度,只需要添加<code>opacity属性即可,例如将透明度设置为0.3

symbol: {

symbolType: 'circle',

size: 40,

color: ['color', 255, 0, 0, 1],

opacity: 0.3

}

如下图所示:

在这里插入图片描述

9、设置要素的尺寸

上面的代码主要针对<code>color属性进行设置,其实不仅仅是colorsize属性同样可以使用样式表达式。现在根据dbm值生成不同大小的要素,代码如下:

<!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8">code>

<meta name="viewport" content="width=device-width, initial-scale=1.0">code>

<title>WebGL</title>

<style>

html,

body,

#map {

width: 100%;

height: 100%;

margin: 0;

padding: 0;

}

</style>

<link rel="stylesheet" href="ol/ol.css" />code>

<script src="ol/ol.js"></script>code>

</head>

<body>

<div id="map"></div>code>

<script>

// 创建图层

var layer = new ol.layer.WebGLPoints({

source: new ol.source.Vector({

features: [

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.0]),

"type": "学校",

"dbm": 1

}),

new ol.Feature({

geometry: new ol.geom.Point([120.0, 30.1]),

"type": "学校",

"dbm": 2

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.0]),

"type": "超市",

"dbm": 3

}),

new ol.Feature({

geometry: new ol.geom.Point([120.1, 30.1]),

"type": "超市",

"dbm": 4

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.0]),

"type": "医院",

"dbm": 5

}),

new ol.Feature({

geometry: new ol.geom.Point([120.2, 30.1]),

"type": "医院",

"dbm": 6

}),

]

}),

style: {

symbol: {

symbolType: 'circle',

size: [

'case',

['==', ['get', 'dbm'], 1], 10,

['==', ['get', 'dbm'], 2], 20,

['==', ['get', 'dbm'], 3], 30,

['==', ['get', 'dbm'], 4], 40,

['==', ['get', 'dbm'], 5], 50,

['==', ['get', 'dbm'], 6], 60,

20

],

color: ['color', 255, 0, 0, 1],

}

}

});

// 创建地图

var map = new ol.Map({

target: 'map',

layers: [

layer

],

view: new ol.View({

projection: 'EPSG:4326',

center: [120, 30],

zoom: 10

})

});

</script>

</body>

</html>

运行结果如下图所示:

在这里插入图片描述

10、结语

本文主要介绍了<code>OpenLayersWebGLPoints图层的样式设置方法。其实刚接触样式表达式的时候觉得这种方法很反人类,但是习惯之后发现它的灵活度很高,本文也只列举了一些常见的用法,有兴趣的同志可以去官网查看更详细的文档。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。