1、前言
前一篇博客介绍了如何在
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’
,后面的参数依次为红、绿、蓝、透明度。下面的代码会将要素渲染为红色点:
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>WebGL</title><style>html,
body,
#map{width: 100%;height: 100%;margin: 0;padding: 0;}</style><linkrel="stylesheet"href="ol/ol.css"/><scriptsrc="ol/ol.js"></script></head><body><divid="map"></div><script>// 创建图层var layer =newol.layer.WebGLPoints({source:newol.source.Vector({features:[newol.Feature({geometry:newol.geom.Point([120.0,30.0]),"type":"学校","dbm":1}),newol.Feature({geometry:newol.geom.Point([120.0,30.1]),"type":"学校","dbm":2}),newol.Feature({geometry:newol.geom.Point([120.1,30.0]),"type":"超市","dbm":3}),newol.Feature({geometry:newol.geom.Point([120.1,30.1]),"type":"超市","dbm":4}),newol.Feature({geometry:newol.geom.Point([120.2,30.0]),"type":"医院","dbm":5}),newol.Feature({geometry:newol.geom.Point([120.2,30.1]),"type":"医院","dbm":6}),]}),style:{symbol:{symbolType:'circle',size:40,color:['color',255,0,0,1]}}});// 创建地图var map =newol.Map({target:'map',layers:[
layer
],view:newol.View({projection:'EPSG:4326',center:[120,30],zoom:10})});</script></body></html>
运行结果如下图所示:
4、分类渲染
测试数据中的
type
字段将要素分成了
3
类,即:
学校、超市、医院
。现在要求将学校渲染为红色、超市渲染为绿色、医院渲染为蓝色。此时需要使用
match
表达式,其形式如下所示:
['match', type的值, '学校', 红色, '超市', 绿色, '医院', 蓝色, 默认颜色]
那么
type
的值又该如何获取?其实很简单,使用
['get', 'attributeName']
表达式即可,所以最后的样式表达式如下所示:
['match', ['get', 'type'], '学校', 红色, '超市', 绿色, '医院', 蓝色, 默认颜色]
代码如下所示:
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>WebGL</title><style>html,
body,
#map{width: 100%;height: 100%;margin: 0;padding: 0;}</style><linkrel="stylesheet"href="ol/ol.css"/><scriptsrc="ol/ol.js"></script></head><body><divid="map"></div><script>// 创建图层var layer =newol.layer.WebGLPoints({source:newol.source.Vector({features:[newol.Feature({geometry:newol.geom.Point([120.0,30.0]),"type":"学校","dbm":1}),newol.Feature({geometry:newol.geom.Point([120.0,30.1]),"type":"学校","dbm":2}),newol.Feature({geometry:newol.geom.Point([120.1,30.0]),"type":"超市","dbm":3}),newol.Feature({geometry:newol.geom.Point([120.1,30.1]),"type":"超市","dbm":4}),newol.Feature({geometry:newol.geom.Point([120.2,30.0]),"type":"医院","dbm":5}),newol.Feature({geometry:newol.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 =newol.Map({target:'map',layers:[
layer
],view:newol.View({projection:'EPSG:4326',center:[120,30],zoom:10})});</script></body></html>
运行结果如下图所示:
5、分级渲染
测试数据中包含一个
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']
代码如下所示:
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>WebGL</title><style>html,
body,
#map{width: 100%;height: 100%;margin: 0;padding: 0;}</style><linkrel="stylesheet"href="ol/ol.css"/><scriptsrc="ol/ol.js"></script></head><body><divid="map"></div><script>// 创建图层var layer =newol.layer.WebGLPoints({source:newol.source.Vector({features:[newol.Feature({geometry:newol.geom.Point([120.0,30.0]),"type":"学校","dbm":1}),newol.Feature({geometry:newol.geom.Point([120.0,30.1]),"type":"学校","dbm":2}),newol.Feature({geometry:newol.geom.Point([120.1,30.0]),"type":"超市","dbm":3}),newol.Feature({geometry:newol.geom.Point([120.1,30.1]),"type":"超市","dbm":4}),newol.Feature({geometry:newol.geom.Point([120.2,30.0]),"type":"医院","dbm":5}),newol.Feature({geometry:newol.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 =newol.Map({target:'map',layers:[
layer
],view:newol.View({projection:'EPSG:4326',center:[120,30],zoom:10})});</script></body></html>
运行结果如下图所示:
6、根据地图缩放等级渲染
现做如下规定:
1、地图缩放等级
zoom∈(0, 10]
,渲染为红色
2、地图缩放等级
zoom∈(10, 12]
,渲染为绿色
3、地图缩放等级
zoom∈(12, 14]
,渲染为蓝色
4、其余缩放等级,渲染为黄色
看了上面的例子之后,相信同志们应该想到了:利用
['zoom']
获取地图缩放等级,然后利用
case
表达式进行情况分类,最后每种情况利用逻辑表达式判断即可。代码如下:
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>WebGL</title><style>html,
body,
#map{width: 100%;height: 100%;margin: 0;padding: 0;}</style><linkrel="stylesheet"href="ol/ol.css"/><scriptsrc="ol/ol.js"></script></head><body><divid="map"></div><script>// 创建图层var layer =newol.layer.WebGLPoints({source:newol.source.Vector({features:[newol.Feature({geometry:newol.geom.Point([120.0,30.0]),"type":"学校","dbm":1}),newol.Feature({geometry:newol.geom.Point([120.0,30.1]),"type":"学校","dbm":2}),newol.Feature({geometry:newol.geom.Point([120.1,30.0]),"type":"超市","dbm":3}),newol.Feature({geometry:newol.geom.Point([120.1,30.1]),"type":"超市","dbm":4}),newol.Feature({geometry:newol.geom.Point([120.2,30.0]),"type":"医院","dbm":5}),newol.Feature({geometry:newol.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 =newol.Map({target:'map',layers:[
layer
],view:newol.View({projection:'EPSG:4326',center:[120,30],zoom:10})});</script></body></html>
运行结果如下图所示:
7、根据地图分辨率渲染
根据地图分辨率渲染也很简单,只需要把上面的
['zoom']
替换成
['resolution']
即可。不过考虑到
resolution
值是一个小数,因此这里将
resolution
乘以
10000
之后再进行判断,代码如下:
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>WebGL</title><style>html,
body,
#map{width: 100%;height: 100%;margin: 0;padding: 0;}</style><linkrel="stylesheet"href="ol/ol.css"/><scriptsrc="ol/ol.js"></script></head><body><divid="map"></div><script>// 创建图层var layer =newol.layer.WebGLPoints({source:newol.source.Vector({features:[newol.Feature({geometry:newol.geom.Point([120.0,30.0]),"type":"学校","dbm":1}),newol.Feature({geometry:newol.geom.Point([120.0,30.1]),"type":"学校","dbm":2}),newol.Feature({geometry:newol.geom.Point([120.1,30.0]),"type":"超市","dbm":3}),newol.Feature({geometry:newol.geom.Point([120.1,30.1]),"type":"超市","dbm":4}),newol.Feature({geometry:newol.geom.Point([120.2,30.0]),"type":"医院","dbm":5}),newol.Feature({geometry:newol.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 =newol.Map({target:'map',layers:[
layer
],view:newol.View({projection:'EPSG:4326',center:[120,30],zoom:10})});</script></body></html>
运行结果如下图所示:
8、设置要素的形状和透明度
在
symbol
对象中,
symbolType
参数用于定义要素的形状,它可以设置为
circle、triangle、square、image
。例如将
symbolType
设置为
triangle
:
symbol:{symbolType:'circle',size:40,color:['color',255,0,0,1]}
此时要素会被渲染为三角形,如下图所示:
将
symbolType
设置为
square
:
symbol:{symbolType:'square',size:40,color:['color',255,0,0,1]}
此时要素会被渲染为正方形,如下图所示:
如果希望设置透明度,只需要添加
opacity
属性即可,例如将透明度设置为
0.3
:
symbol:{symbolType:'circle',size:40,color:['color',255,0,0,1],opacity:0.3}
如下图所示:
9、设置要素的尺寸
上面的代码主要针对
color
属性进行设置,其实不仅仅是
color
,
size
属性同样可以使用样式表达式。现在根据
dbm
值生成不同大小的要素,代码如下:
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>WebGL</title><style>html,
body,
#map{width: 100%;height: 100%;margin: 0;padding: 0;}</style><linkrel="stylesheet"href="ol/ol.css"/><scriptsrc="ol/ol.js"></script></head><body><divid="map"></div><script>// 创建图层var layer =newol.layer.WebGLPoints({source:newol.source.Vector({features:[newol.Feature({geometry:newol.geom.Point([120.0,30.0]),"type":"学校","dbm":1}),newol.Feature({geometry:newol.geom.Point([120.0,30.1]),"type":"学校","dbm":2}),newol.Feature({geometry:newol.geom.Point([120.1,30.0]),"type":"超市","dbm":3}),newol.Feature({geometry:newol.geom.Point([120.1,30.1]),"type":"超市","dbm":4}),newol.Feature({geometry:newol.geom.Point([120.2,30.0]),"type":"医院","dbm":5}),newol.Feature({geometry:newol.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 =newol.Map({target:'map',layers:[
layer
],view:newol.View({projection:'EPSG:4326',center:[120,30],zoom:10})});</script></body></html>
运行结果如下图所示:
10、结语
本文主要介绍了
OpenLayers
中
WebGLPoints
图层的样式设置方法。其实刚接触样式表达式的时候觉得这种方法很反人类,但是习惯之后发现它的灵活度很高,本文也只列举了一些常见的用法,有兴趣的同志可以去官网查看更详细的文档。
版权归原作者 HerryDong 所有, 如有侵权,请联系我们删除。