进阶mapbox GL之paint和filter

概述

通过前面的文章初识mapbox GL我们对mapbox GL有了一个相对比较全面的认识,本节结合一些示例,重点讲述一下mapbox GL里面的filter和paint的用法。

说明

本文中的示例数据源是北京的区边界数据,格式为geojson,数据字段与详情如下:


示例数据

filter

filter是layer里面的一个属性,通过一些条件表达式实现仅显示与过滤器匹配的要素,即图层的过滤显示,其官方说明如下图:

filter

1、==和!=

==!=可实现根据某个字段图层的过滤展示。如:只在地图上展示昌平区或者在地图上展示除昌平外的所有区域。

// 只在地图上展示昌平区
var filter = ['==', 'name', '昌平区'];

//地图上展示除昌平外的所有区域
var filter = ['!=', 'name', '昌平区'];
['==', 'name', '昌平区']

['!=', 'name', '昌平区']

2、>、>=、<、<=

>、>=、<、<=是通过比较大小的方式,实现图层的过滤,所以此处需要的字段得是数字类型或者通过to-number将字段转换成数字类型。如:展示count>=10的区域。

var filter = ['>=', 'count', 10];
['>=', 'count', 10]

3、in和match

inmatch都可实现对图层根据某个字段进行多值过滤。如:在地图上展示昌平区和海淀区。

// in 
var filter = [
  'in', 
  'name',
  '昌平区',
  '海淀区'
];
// match
var filter = [
  "match",
  [
    "get",
    "name"
  ],
  [
    "昌平区",
    "海淀区",
  ],
  true,
  false
]
in和match

接着上面的例子,如果我们要实现在地图中展示除海淀和昌平区外的其他区域,我们可以直接用!in和将match的条件互换的方式来实现,如下:

// in 
var filter = [
  '!in', 
  'name',
  '昌平区',
  '海淀区'
];
// match
var filter = [
  "match",
  [
    "get",
    "name"
  ],
  [
    "昌平区",
    "海淀区",
  ],
  false,
  true
]
!in和match

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'
]
match

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
]

注意

  1. 第一个的判断是<;
  2. 中间的判断是>=<;
  3. 最后一个判断是>=;
    case

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'
]

说明:

  1. 对于非数值型的字段,我们可以用to-number对字段进行转换。
    step

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
]

说明:

  1. zoom是一个特殊字符,特制地图的缩放级别,同样的还有geometry-type,特指的是geom类型。
    interpolate

完整测试代码如下:

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: "'全新硬笔行书简'"
});
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容