地圖樣式是由 style 類控制的,其包含了地圖樣式的方方面面,例如,填充色、圖標樣式、圖片樣式、規則圖形樣式、邊界樣式、文字樣式等,樣式一般針對矢量要素圖層。
矢量圖層樣式可以事先寫好,寫成靜態的,矢量圖層直接按照定義好的樣式渲染,也可以動態使用樣式的 set()
方法,但是要注意刷新矢量圖層,重新渲染,否則動態樣式不生效。
一、ol.style
1. 可以配置的選項
/** * @typedef {{geometry: (undefined|string|ol.geom.Geometry|ol.style.GeometryFunction), * fill: (ol.style.Fill|undefined), * image: (ol.style.Image|undefined), * stroke: (ol.style.Stroke|undefined), * text: (ol.style.Text|undefined), * zIndex: (number|undefined)}} * @api */
- geometry,要素的屬性,或者要素,或者一個返回一個地理要素的函數,用來渲染成相應的地理要素;
- fill,填充要素的樣式;
- image,圖片樣式,類型為
ol.style.Image
; - stroke,要素邊界樣式,類型為
ol.style.Stroke
; - text,要素文字的樣式,類型為
ol.style.Text
; - zIndex,CSS中的zIndex,即疊置的層次,為數字類型。
2. 子類
- ol.style.Circle,針對矢量要素設置圓形的樣式,繼承
ol.style.Image
; - ol.style.Icon,針對矢量數據設置圖標樣式,繼承
ol.style.Image
; - ol.style.Fill,針對矢量要素設置填充樣式;
- ol.style.RegularShape,對矢量要素設置規則的圖形樣式,如果設置
radius
,結果圖形是一個規則的多邊形,如果設置radius1
和radius2
,結果圖形將是一個星形; - ol.style.Stroke,矢量要素的邊界樣式;
- ol.style.Text,矢量要素的文字樣式。
可以看出這些樣式都是針對矢量要素的。
二、舉例說明
假設有一個矢量圖層,使用如下的樣式配置圖層:
var style = new ol.style.Style({ fill: new ol.style.Fill({ //矢量圖層填充顏色,以及透明度 color: 'rgba(255, 255, 255, 0.6)' }), stroke: new ol.style.Stroke({ //邊界樣式 color: '#319FD3', width: 1 }), text: new ol.style.Text({ //文本樣式 font: '12px Calibri,sans-serif', fill: new ol.style.Fill({ color: '#000' }), stroke: new ol.style.Stroke({ color: '#fff', width: 3 }) }) });
按照以上配置,效果如下圖:
1. geometry - 地理屬性
geometry
可以是要素的地理屬性,或者 geometry
,或者一個返回 geometry
類型的函數。一般與 image
樣式配合使用,表示 image 放置的位置,如下面的例子:
new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: 'orange' }) }), geometry: function(feature) { // return the coordinates of the first ring of the polygon var coordinates = feature.getGeometry().getCoordinates()[0]; return new ol.geom.MultiPoint(coordinates); } })
2. fill - 填充樣式
color: 'rgba(255, 255, 255, 0.9)'
,配置了圖層的要素的填充顏色和透明度,格式為 [R, G, B, A],分別代表 RGB 的三個分量,A 代表 alpha,即透明度。以上顏色配置為白色,每個分量值是 [0, 255] 區間內的值,越小,越暗;越大,越亮。透明度為 0.9,透明度是一個 [0, 1] 區間內的值,越小,要素越是透明;越大,越不透明。
更改顏色 [0, 255, 0, 0.9],將顏色的綠色分量調為最大,其他顏色分量調為 0,那么地圖的背景色應該變為純綠色,刷新瀏覽器,得到下圖:
更改透明度[255, 255, 255, 0.1],將透明度分量改為 0.1 ,預期圖層將變得非常透明,刷新瀏覽器,得到如下圖:
3. image - 圖片樣式
樣式主要針對矢量圖層(vector layer),矢量圖層中包含一個或多個要素(feature),要素中包含一個地理屬性(geometry)表示地理位置,還可能包含一個或多個其他屬性,比如要素的名稱、類型等等,要素可以使用單獨的樣式,這時候要使用 feature.setStyle(ol.style.Style)
來設置單獨使用的樣式,否則直接繼承矢量圖層的樣式。
使用 setStyle 方法設置單個要素樣式,首先定義一個圖標樣式:
var iconStyle = new ol.style.Style({ image: new ol.style.Icon(({ src: 'data/icon.png' })) });
設置一個顯示在特定位置的圖片圖標,使用 ol.style.Icon
配置該屬性,src
屬性設置了圖片的地址,還可以設置透明度等屬性。接下來定義一個點要素:
var iconFeature = new ol.Feature({ geometry: new ol.geom.Point([0, 0]), });
將樣式應用於點要素:iconFeature.setStyle(iconStyle);
,最后定義一個矢量圖層,並加入該要素:
var iconLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: [iconFeature] }) });
得到結果是,在[0, 0]坐標處顯示一個圖標,如圖:
該樣式有一個特性,就是地圖中不顯示相應區域時候,圖片默認不加載,當該區域在地圖視口中,才會加載圖片,當然這是為了節省帶寬,提高性能。如果我們將圖層的style屬性配置為iconStyle,那么結果是一樣的,其結果是圖層中的所有要素都會是一樣的樣式。需要指出的是,該樣式只針對於點要素。
4. stroke - 邊界線條
color: '#319FD3', width: 1
,配置要素邊界的顏色為 ‘#319FD3’,16 進制顏色代碼,width 說明線條寬度為 1 像素。更改顏色為紅色:’#FF0000’,結果如下圖:
更改線條寬度:width:10,得到如下結果:
5. text - 文字
設置矢量圖層中的各個要素中要顯示的文字的字體類型,線條填充顏色,線條邊界顏色,因為文字的線條本身就具有寬度,所以有填充色和邊界顏色說法。如下面的例子,設置了文字的大小、字體、填充色和邊界顏色:
text: new ol.style.Text({ font: '12px Calibri,sans-serif', //字體與大小 fill: new ol.style.Fill({ //文字填充色 color: '#000' }), stroke: new ol.style.Stroke({ //文字邊界寬度與顏色 color: '#fff', width: 3 }) })
font: '12px Calibri,sans-serif',
指定了文字的大小和字體,我們修改文字大小為 24px
,得到如下結果:
fill
規定了文字筆畫線條的填充顏色,修改為 #FFF
,結果應該是白色。結果如圖:
stroke
規定了文字的邊緣線條的顏色和寬度,其實文字本身就像一個地理要素一樣,有填充和線條樣式,可以看出文字的筆畫線條外邊緣有白色,就是這個樣式在起作用。
6. 條件樣式
條件樣式是將樣式配置為一個回調函數,其參數包含要素本身和分辨率,可以根據要素本身的屬性和地圖的分辨率,顯示動態的樣式,形式如style: function(feature, resolution) {}
。
例如,以下代碼段配置當分辨率小於 5000 時候,在要素上顯示一個標簽,標識要素名稱:
style: function(feature, resolution) { style.getText().setText(resolution < 5000 ? feature.get('name') : ''); return styles; }
三、總結
樣式主要針對矢量圖層數據,既可以配置一個全局的樣式,也可以針對每個feature
單獨配置;既可以應用統一的樣式,也可以根據要素和分辨率應用條件樣式。樣式應用是非常靈活的。
另外,樣式是可以多個一起起作用的,就如同 HTML
的元素樣式類 class
可以有多個一樣。如下例子中,就應用了兩個樣式,一個是應用於多邊形本身,另一個用於繪制每個多邊形的頂點:
var styles = [ new ol.style.Style({ stroke: new ol.style.Stroke({ color: 'blue', width: 3 }), fill: new ol.style.Fill({ color: 'rgba(0, 0, 255, 0.1)' }) }), new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: 'orange' }) }), geometry: function(feature) { // return the coordinates of the first ring of the polygon var coordinates = feature.getGeometry().getCoordinates()[0]; return new ol.geom.MultiPoint(coordinates); } }) ];