进阶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: "'全新硬笔行书简'" });