進階mapbox GL之paint和filter
- 2020 年 3 月 31 日
- 筆記
概述
通過前面的文章初識mapbox GL我們對mapbox GL有了一個相對比較全面的認識,本節結合一些示例,重點講述一下mapbox GL裏面的filter和paint的用法。
說明
本文中的示例數據源是北京的區邊界數據,格式為geojson,數據字段與詳情如下:

filter
filter是layer裏面的一個屬性,通過一些條件表達式實現僅顯示與過濾器匹配的要素,即圖層的過濾顯示,其官方說明如下圖:

1、==和!=
==
和!=
可實現根據某個字段圖層的過濾展示。如:只在地圖上展示昌平區或者在地圖上展示除昌平外的所有區域。
// 只在地圖上展示昌平區 var filter = ['==', 'name', '昌平區']; //地圖上展示除昌平外的所有區域 var filter = ['!=', 'name', '昌平區'];


2、>、>=、<、<=
>、>=、<、<=
是通過比較大小的方式,實現圖層的過濾,所以此處需要的字段得是數字類型或者通過to-number
將字段轉換成數字類型。如:展示count>=10
的區域。
var filter = ['>=', 'count', 10];

3、in和match
in
和match
都可實現對圖層根據某個字段進行多值過濾。如:在地圖上展示昌平區和海淀區。
// in var filter = [ 'in', 'name', '昌平區', '海淀區' ]; // match var filter = [ "match", [ "get", "name" ], [ "昌平區", "海淀區", ], true, false ]

接着上面的例子,如果我們要實現在地圖中展示除海淀和昌平區外的其他區域,我們可以直接用!in
和將match
的條件互換的方式來實現,如下:
// in var filter = [ '!in', 'name', '昌平區', '海淀區' ]; // match var filter = [ "match", [ "get", "name" ], [ "昌平區", "海淀區", ], false, true ]

4、多條件
有時候,會存在多條件的過濾,例如:我們選擇type==1
並且count>10
的區域,我們可以這麼寫:
var filter = [ 'all', ['>=', 'count', 10], ['==', 'type', 1] ]

當然,有時我們會存在根據幾何類型來進行過濾,此時,我們可用:
var filter = [ "==", ["geometry-type"], "LineString" ];
paint
paint
是layer的一個屬性,負責圖層的渲染與呈現。
1、match
match
通常用於枚舉型的字段渲染,如唯一值渲染。
'circle-color': [ 'match', ['get', 'type'], 1, '#FFD273', 2, '#E86D68', '#A880FF' ]

2、case
case
通常用於分段數值型的字段渲染,值域是前關後開,如分級渲染。
'circle-color': [ 'case', ['<', ['get', 'speed'], 10.8], 'rgba(0,0,0,0)', //<10.8 ['<', ['get', 'speed'], 17.2], 'rgba(153, 255, 153, .9)', //>=10.8 & <17.2 ['<', ['get', 'speed'], 24.5], 'rgba(102, 204, 255, .9)', ['<', ['get', 'speed'], 32.7], 'rgba(255, 255, 102, .9)', ['<=', ['get', 'speed'], 41.5], 'rgba(253, 139, 0, .9)', ['<=', ['get', 'speed'], 50.1], 'rgba(255, 51, 0, .9)', //>=41.5 & <50.1 'rgba(255, 0, 255, .9)' // 默認值, >=50.1 ]
注意:
- 第一個的判斷是
<
; - 中間的判斷是
>=
和<
; - 最後一個判斷是
>=
;

3、step
step
和上面的case
很類似,只是值域是前開後關的。
// <=100, 100-500, >500 "circle-color": [ "step", ["get", "count"], "#51bbd6", 100, "#f1f075", 500, "#f28cb1" // other ] 'circle-color': [ 'step', ['to-number', ['get', 'CID']], '#0098A3', 10, '#00CA8D', 20, '#37C508', 30, '#98F300', 40, '#EFFF85' ]
說明:
- 對於非數值型的字段,我們可以用
to-number
對字段進行轉換。

4、interpolate
interpolate
,中文的翻譯是「插值」,在mapbox GL中,我們可通過interpolate
實現按照比例的插值渲染。
// <=8, 8-10, >10 "background-color": [ "interpolate", ["linear"], ["zoom"], 8, "rgba(0, 0, 255, 0.2)", 10, "rgba(255, 0, 0, 0.2)" ] // <=20, 20-60, 60-100, >100 'fill-extrusion-color': [ 'interpolate', ['linear'], ['get', 'height'], 20, 'rgba(255,255,191, 0.65)', 60, 'rgba(253,174,97, 0.65)', 100, "rgba(215,25,28, 0.65)" ] // exponential,指數 "fill-opacity": [ "interpolate", ["exponential", 1.5], ["zoom"], 2, 0.3, 7, 0 ]
說明:
zoom
是一個特殊字符,特製地圖的縮放級別,同樣的還有geometry-type
,特指的是geom類型。

完整測試代碼如下:
var rootPath = 'http://127.0.0.1:3000/mapbox/lib/'; // var filter = ['match', ['get', 'name'], // ['昌平區', '海淀區'], false, true // ]; // var filter = ['!in', 'name', '昌平區', '海淀區']; // var filter = [ // 'all', // ['>=', 'count', 10], // ['==', 'type', 1] // ]; var filter = ['>=', 'count', 0]; // var fillColor = 'rgba(255, 0, 0, 0.5)'; // 唯一值圖 // var fillColor = [ // 'match', // ['get', 'type'], // 1, '#FFD273', // 2, '#E86D68', // '#A880FF' // ]; // 分級色彩圖 // var fillColor = [ // 'case', // ['<', ['get', 'count'], 10], '#FFD273', // ['<', ['get', 'count'], 20], '#E86D68', // ['<', ['get', 'count'], 30], '#A880FF', // ['<', ['get', 'count'], 40], '#68E0E8', // ['<=', ['get', 'count'], 50], '#9BFF69', // '#000' // 默認值 // ]; // 比例符號圖 var fillColor = [ 'interpolate', ['linear'], ['get', 'count'], 15, '#FFD273', 30, '#E86D68', 50, '#9BFF69' ]; // 步長圖 // var fillColor = [ // 'step', // ['get', 'count'], // '#0098A3', // 10, '#00CA8D', // 20, '#37C508', // 30, '#98F300', // 40, '#EFFF85' // ] var mapStyle = { "version": 8, "name": "Dark", "sources": { "geojson": { type: 'geojson', data: '../data/beijing.geojson' } }, "glyphs": rootPath + "fonts/mapbox/{fontstack}/{range}.pbf", "layers": [{ "id": "background", "type": "background", "paint": { "background-color": "#999" } }, { 'id': 'geojson', 'source': 'geojson', 'type': 'fill', 'paint': { 'fill-color': fillColor, 'fill-opacity': .8 }, filter: filter }, { 'id': 'geojson-border', 'source': 'geojson', 'type': 'line', 'paint': { 'line-color': '#FFF', 'line-width': 1.5 }, filter: filter }, { 'id': 'points', 'type': 'symbol', 'source': 'geojson', 'layout': { 'text-field': ['get', 'name'], "text-size": 22 }, paint: { 'text-color': '#000000' }, filter: filter } ] }; map = new mapboxgl.Map({ container: 'map', maxZoom: 18, minZoom: 6, zoom: 8, center: { lng: 116.6552, lat: 40.2482 }, style: mapStyle, attributionControl: false, localIdeographFontFamily: "'全新硬筆行書簡'" });