天天看點

mapboxgl 地圖樣式 - 重分類渲染

上回,我們在《mapboxgl 地圖樣式 - 唯一值渲染》中了解到case、match、get等表達式,通過表達式來完成了唯一值渲染。

在實際情況下,我們還經常需要進行重分類渲染,将某範圍的值重分為一類,并将另一個範圍重分為其它類。

今天我們繼續了解新的表達式來實作重分類渲染。

重分類效果圖:

mapboxgl 地圖樣式 - 重分類渲染

方式一:使用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表達式文法規則:

  1. "step"

    是表達式的名稱
  2. ["get","adcode"]

    是輸入值,必須為數值類型或者是數值表達式
  3. "#ffd0a6"

    是輸出值
  4. 50

    是判斷值
  5. ...(根據實際情況兩兩出現的輸出值、判斷值)
  6. "#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

最後小結:

  1. case和filter的優點都是相對于step而言的,而且case和filter寫起來都避免不了繁瑣這一點。
  2. 僅從“重分類”概念的角度來說,最合适的表達式是step,它本身産生分段式結果會更契合“重分類”這一概念。
  3. case和filter更适合作為一種“補充”,在某些情況下使用。因為它們并不要求判斷值必須升序,更為靈活。
  4. 在mapbox裡重分類更推薦使用step表達式,case表達式和filter分圖層可以作為補充方法來了解。

* * *

原文位址:http://gisarmory.xyz/blog/index.html?blog=mapboxglStyleReclass

歡迎關注《GIS兵器庫》

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