mapboxgl 地圖樣式 - 唯一值渲染
mapboxgl 中提供了強大的地圖樣式編輯功能,樣式表達式是其一大特色。
唯一值渲染是GIS中常見的專題圖渲染方式,今天我們來看一下如何用 mapboxgl 中的樣式表達式實現這一效果。
在網上找了一份北京市的行政區劃圖,目標是各個區設置上不同的顏色。效果如下:

方式一:使用 case 表達式
這種做法的好處是可以靈活修改每個區的顏色。
"fill-color":[
"case",
["boolean",["==",["get","name"],"懷柔區"],false],"#FFFFCC",
["boolean",["==",["get","name"],"密云區"],false],"#CCFFFF",
["boolean",["==",["get","name"],"平谷區"],false],"#FFCCCC",
["boolean",["==",["get","name"],"通州區"],false],"#FFFF99",
["boolean",["==",["get","name"],"房山區"],false],"#CCCCFF",
["boolean",["==",["get","name"],"延慶區"],false],"#FFCC99",
["boolean",["==",["get","name"],"門頭溝區"],false],"#CCFF99",
["boolean",["==",["get","name"],"大興區"],false],"#66CCFF",
["boolean",["==",["get","name"],"順義區"],false],"#99CCFF",
["boolean",["==",["get","name"],"海淀區"],false],"#CCCCCC",
["boolean",["==",["get","name"],"西城區"],false],"#CCFFCC",
["boolean",["==",["get","name"],"東城區"],false],"#CC99CC",
["boolean",["==",["get","name"],"朝陽區"],false],"#99CC99",
["boolean",["==",["get","name"],"石景山區"],false],"#CCCC99",
["boolean",["==",["get","name"],"昌平區"],false],"#FF9969",
["boolean",["==",["get","name"],"豐臺區"],false],"#999999",
"black"
]
上面表達式的意思是,從數據中獲取 name 屬性的值,判斷是哪個區,然后設置相應的顏色。
case表達式語法,詳見官方說明
mapboxgl 表達式的基本語法:
1、一組中括號[ ]代表一個完整的表達式,中括號中第一個參數聲明表達式的類型,后面是表達式的參數。
2、表達式可以嵌套。
關于表達式的詳細介紹,后續會用單獨一篇文章來寫,這里只做個簡單說明。
上面這段表達式如果翻譯成 js 大致是這樣的:
function getColor(feature){ //feature是geojosn格式中的Feature
if(feature.properties.name === "懷柔區"){
return "#FFFFCC"
}
else if(features[i].name === "密云區"){
return "#CCFFFF"
}
...
else{
return "black"
}
}
在線示例,瀏覽器 F12 可以查看完整代碼。
方式二:使用 match 表達式
match 和 case 類似,但在寫法上更為簡潔
"fill-color":[
"match",
["get","name"],
"懷柔區","#FFFFCC",
"密云區","#CCFFFF",
"平谷區","#FFCCCC",
"通州區","#FFFF99",
"房山區","#CCCCFF",
"延慶區","#FFCC99",
"門頭溝區","#CCFF99",
"大興區","#66CCFF",
"順義區","#99CCFF",
"海淀區","#CCCCCC",
"西城區","#CCFFCC",
"東城區","#CC99CC",
"朝陽區","#99CC99",
"石景山區","#CCCC99",
"昌平區","#FF9969",
"豐臺區","#999999",
"black"
]
翻譯成js是下面這樣:
function getColor(feature){ //feature是geojosn格式的Feature
switch(feature.properties.name){ //["get","name"]
case "懷柔區":
return "#FFFFCC"
case "密云區":
return "#CCFFFF"
...
default
return "black"
}
}
方式三:根據 id 匹配顏色
前兩種表達式適合數據量較小時使用。當數據量較大時,可以通過設置一組顏色,根據數據中的某個id字段進行匹配來實現。
"fill-color":[
"to-color",[
"at",
["%", ["get", "adcode"], 13],
["literal",["#00FFCC","#CCFFFF","#FFCCCC","#FFFF99","#CCCCFF","#FFCC99","#CCFF99","#66CCFF","#99CCFF","#CCFFCC","#99CC99","#CCCC99","#FF9969"]]
]
]
上面表達式的意思是,會用數據中 adcode 的屬性值除以13然后取余數,根據余數從顏色數組中取一個顏色。
表達式詳細說明:
["get", "adcode"]表達式get從數據中獲取adcode屬性的值。["%", ["get", "adcode"], 13]表達式%將adcode的值除以13并取余數,這里的13代表顏色數組的個數。["literal",["#00FFCC",...]]表達式literal用來聲明一個顏色數組,因為在這里中括號被默認是表達式,所以想要定義真正的數組就要用literal包裝一下。["at",["%", ["get", "adcode"], 13],["literal","#00FFCC",...]]表達式at是根據求余的值從顏色數組中取顏色。["to-color", ["at",["%", ["get", "adcode"], 13],["literal","#00FFCC",...]]]表達式to-color是將字符串轉為mapboxgl 的顏色類型,不然會報錯。
翻譯成js是下面這樣:
function getColor(feature){ //feature是geojosn格式的Feature
const colors = ["#00FFCC","#CCFFFF","#FFCCCC","#FFFF99","#CCCCFF","#FFCC99","#CCFF99","#66CCFF","#99CCFF","#CCFFCC","#99CC99","#CCCC99","#FF9969"]
const index = feature.properties.adcode % 13
return colors[index]
}
方式四:從屬性中取顏色
這種方式比較簡單,就是直接把顏色放到數據中,通過 get 表達式獲取出來直接用。缺點就是要去改數據。
下圖是在數據中增加顏色數據:

使用表達式直接獲取顏色:
"fill-color":["get","color"]
方式五:分圖層設置顏色
通過圖層的 filter篩選條件實現,每個區設置成一個圖層,然后設置每個圖層的顏色。
圖層樣式設置方式:
[
{
"id": "beijing-haidian",
"type": "fill",
"source": "beijing",
"paint":{
"fill-color":"#FFCC99"
},
"filter":["==",["get","name"], "海淀區"]
},
{
"id": "beijing-chaoyang",
"type": "fill",
"source": "beijing",
"paint":{
"fill-color":"#FFCCCC"
},
"filter":["==",["get","name"], "朝陽區"]
}
...
]
這種做法的好處是,可以在 maputnik 中直接選顏色,因為在 maputnik 中,表達式是不支持直接在界面上選顏色的,只能自己編輯。
選顏色效果如下圖:

這種方式的缺點也很明顯:圖層由一個變成了16個,style 文件會變的很啰嗦,圖層管理不太方便。
最后
后續會將表達式作為一個系列更新幾篇,敬請關注。
原文地址:http://gisarmory.xyz/blog/index.html?blog=mapboxglStyleUniqueValue
歡迎關注《GIS兵器庫》

本文章采用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名《GIS兵器庫》(包含鏈接: http://gisarmory.xyz/blog/),不得用于商業目的,基于本文修改后的作品務必以相同的許可發布。

浙公網安備 33010602011771號