上回,我們在《mapboxgl 地圖樣式 - 唯一值渲染》中了解到case、match、get等表達式,通過表達式來完成了唯一值渲染。
在實際情況下,我們還經常需要進行重分類渲染,将某範圍的值重分為一類,并将另一個範圍重分為其它類。
今天我們繼續了解新的表達式來實作重分類渲染。
重分類效果圖:
方式一:使用step表達式
"fill-color":[
"step",
["get","population"],
"#ffd0a6", 50,
"#ffaa7f", 100,
"#ff704e", 150,
"#f04040", 200,
"#b50a09"
]
上面表達式的意思是:
- get擷取屬性值population,小于50,顔色是
#ffd0a6
- 大于等于50,但小于100時,顔色是
#ffaa7f
- 大于等于100,但小于150時,顔色是
#ff704e
- 大于等于150,但小于200時,顔色是
#f04040
- 大于等于200,顔色是
#b50a09
看到這裡是不是奇怪step是起什麼作用的?step譯為步,一步一步就是分段的意思,它産生階梯式結果,把一段值歸為一類,小于50的是一類,大于等于50又小于100是一類,每一類step都會輸出一個值,在效果圖中展示為50萬人口以下地區是一個顔色,大于等于50又小于100萬人口區間的地區為另一個顔色。
我們在下篇漸變色渲染的文章中将會了解interpolate表達式,與step表達式産生的階梯式結果相反,interpolate表達式将會産生連續結果。
翻譯成js是:
function getColor(feature){ //feature是geojosn格式中的Feature
if(feature.properties.population<50){
return '#ffd0a6'
}
else if(feature.properties.population<100){
return '#ffaa7f'
}
...
else{
return '#b50a09'
}
}
step表達式文法規則:
-
是表達式的名稱"step"
-
是輸入值,必須為數值類型或者是數值表達式["get","adcode"]
-
是輸出值"#ffd0a6"
-
是判斷值50
- ...(根據實際情況兩兩出現的輸出值、判斷值)
-
是輸出值"#b50a09"
step表達式有5個必需參數,并且不能亂序:表達式的名稱、輸入值、輸出值、判斷值,... ...,輸出值(省略部分為輸出值、判斷值,在省略部分裡如果出現了,就必須兩兩出現)。也就是說除了表達式的名稱和輸入值以外,最少還需要一個輸出值、一個判斷值、再加一個輸出值。
//必需參數
"fill-color":[
"step", //表達式的名稱
["get","population"], //輸入值
"#ffd0a6", //輸出值
50, //判斷值
"#b50a09" //輸出值
]
step表達式寫起來較為簡潔,但需要注意的一點是判斷值必須遵循升序規則。
線上示例:http://gisarmory.xyz/blog/index.html?demo=mapboxglStyleReclass2
方式二:使用 case 表達式
case表達式類似js裡的if判斷語句。表達式的實作效果比較依賴于屬性值,通常我們先使用
get表達式
去擷取屬性值,再去判斷這個屬性值,以此達到在同一圖層上實作不同的展示效果。
"fill-color":[
"case",
['boolean',['<',["get","population"],50]],"#ffd0a6",
['boolean',['<',["get","population"],100]],"#ffaa7f",
['boolean',['<',["get","population"],150]],"#ff704e",
['boolean',['<',["get","population"],200]],"#f04040",
'#b50a09'
]
上面表達式的意思是:
- t擷取屬性值population,小于50,顔色是
#ffd0a6
- 大于等于50,但小于100時,顔色是
#ffaa7f
- 大于等于100,但小于150時,顔色是
#ff704e
- 大于等于150,但小于200時,顔色是
#f04040
- 大于等于200,顔色是
#b50a09
線上示例:http://gisarmory.xyz/blog/index.html?demo=mapboxglStyleReclass1
翻譯成js是:
function getColor(feature){ //feature是geojosn格式中的Feature
if(feature.properties.population<50){
return '#ffd0a6'
}
else if(feature.properties.population<100){
return '#ffaa7f'
}
...
else{
return '#b50a09'
}
}
case表達式寫起來較為繁瑣,但它對判斷值沒有升序這種要求,隻要是true或false就行了。
方式三:分圖層設定
{
"id": "beijing200plus",
"type": "fill",
"source": "beijing",
"paint":{
"fill-color":"#b50a09"
},
"filter":['>=',["get","population"],200]
},
{
"id": "beijing200",
"type": "fill",
"source": "beijing",
"paint":{
"fill-color":"#f04040"
},
"filter":['all',['<',["get","population"],200],['>=',["get","population"],150]]
},
{
"id": "beijing150",
"type": "fill",
"source": "beijing",
"paint":{
"fill-color":"#ff704e"
},
"filter":['all',['<',["get","population"],150],['>=',["get","population"],100]]
},
{
"id": "beijing100",
"type": "fill",
"source": "beijing",
"paint":{
"fill-color":"#ffaa7f"
},
"filter":['all',['<',["get","population"],100],['>=',["get","population"],50]]
},
{
"id": "beijing50",
"type": "fill",
"source": "beijing",
"paint":{
"fill-color":"#ffd0a6"
},
"filter":['<',["get","population"],50]
}
分圖層是使用filter篩選實作,上面代碼裡出現了新的表達式all,all表達式相當于js裡的
&&
,當他後面的參數都為true就會傳回true,否則傳回false,我們舉個例子:
"filter":['all',['<',["get","population"],200],['>=',["get","population"],150]]
翻譯成js是:
function getFilter(feature){ //feature是geojosn格式中的Feature
if(feature.properties.population<200 && feature.properties.population>=150){
return true
}else{
return false
}
}
filter分圖層可以在maputnik中直接調顔色,但是圖層會變多,不友善管理。
線上示例:http://gisarmory.xyz/blog/index.html?demo=mapboxglStyleReclass3
最後小結:
- case和filter的優點都是相對于step而言的,而且case和filter寫起來都避免不了繁瑣這一點。
- 僅從“重分類”概念的角度來說,最合适的表達式是step,它本身産生分段式結果會更契合“重分類”這一概念。
- case和filter更适合作為一種“補充”,在某些情況下使用。因為它們并不要求判斷值必須升序,更為靈活。
- 在mapbox裡重分類更推薦使用step表達式,case表達式和filter分圖層可以作為補充方法來了解。
* * *
原文位址:http://gisarmory.xyz/blog/index.html?blog=mapboxglStyleReclass
歡迎關注《GIS兵器庫》
本文章采用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協定 進行許可。歡迎轉載、使用、重新釋出,但務必保留文章署名《GIS兵器庫》(包含連結: http://gisarmory.xyz/blog/),不得用于商業目的,基于本文修改後的作品務必以相同的許可釋出。