leaflet地圖分級設(shè)色

關(guān)鍵詞:leaflet; geojson; wkt; 分級設(shè)色; 地圖渲染庐椒;顏色映射颅悉;顏色轉(zhuǎn)換衔统;圖例

案例需求:各省級專題數(shù)據(jù)分級設(shè)色
數(shù)據(jù)準備:1.地圖數(shù)據(jù)geojson格式(https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json)來源:http://datav.aliyun.com/portal/school/atlas/area_selector
2.專題數(shù)據(jù)提针,通過隨機數(shù)生成

示例
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>leaflet分層渲染</title>
  <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
  <link  rel="stylesheet">
  <script src="https://cdn.bootcdn.net/ajax/libs/leaflet/1.7.1/leaflet.min.js"></script>

  <style>
    body{
      width: calc(100vw);
      height: calc(100vh);
      padding: 0;
      margin: 0;
    }
    .map{
      width: 100%;
      height: 100%;
      background-color: #fff;
    }
    .legend{
      position: absolute;
      right: 20px;
      bottom: 20px;
      z-index: 999;
    }
    .legend ul li{
      padding:0;
      margin:0;
      list-style:none;
      display: flex;
      align-items: center;
      margin-bottom: 5px;
    }
    .legend ul li i{
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      margin-right: 5px;
    }
  </style>
</head>
<body onload="init()">
  <div id="map" class="map"></div>
  <div class="legend"></div>
</body>
<script>
  let map;
  let separatedColors = ['#DAF7A6', '#FFC300', '#FF5733', '#C70039', '#900C3F', '#581845'];//離散顏色
  let minVal = 1;
  let maxVal = 100;
  function init(){
    initMap();
    initLegend();
  }
  function initMap(){
    map = L.map('map', {
      crs: L.CRS.EPSG4326,
      center: [40.83, 113.31],
      zoom: 3,
      zoomControl: true
    });
    let vecUrl = 'http://t0.tianditu.gov.cn/DataServer?T=vec_c&X={x}&Y={y}&L={z}&tk=c04e7575a1f250c6f22ba42fa9c8aa63';
    let baseLayer = L.tileLayer(vecUrl, {zoomOffset: 1});
    map.addLayer(baseLayer)
    let url = 'https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json';
    axios.get(url).then(res => {
      let geojson = res.data;
      L.geoJSON(geojson, {
        onEachFeature: function(feature, layer){
          //生成1-100的隨機整數(shù)藕甩,作為每個要素的某一專題屬性值
          feature.properties.value = random(1, 100);
          feature.properties.color = getSeparatedColorByVal(minVal, maxVal, separatedColors, feature.properties.value);
          layer.setStyle({
            stroke: false,//取消邊框
            color: feature.properties.color,
            fillOpacity: 0.6//默認0.2
          });
        }
      }).addTo(map);
    });
  }

  //初始化圖例
  function initLegend(){
    let legend = getLegend(minVal, maxVal, separatedColors);
    let legendDom = document.getElementsByClassName('legend')[0];
    let insertDom = document.createElement('ul');
    let str = ``;
    for(let i = 0; i < legend.length; i++){
      str += `<li><i style="background: ${legend[i].color}"></i>${legend[i].region.join('-')}</li>`;
    }
    insertDom.innerHTML = str;
    legendDom.appendChild(insertDom);
  }

  //生成指定范圍的隨機整數(shù)
  function random(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
  }
  //根據(jù)離散顏色及數(shù)據(jù)范圍生成對應(yīng)值的顏色
  function getSeparatedColorByVal(minVal, maxVal, colors, val){
    let length = colors.length;
    let avg = ((maxVal - minVal)/length).toFixed(4);
    //生成等分區(qū)間
    let regions = [];
    for(let i = 0; i < length; i++){
      if(i === length -1){
        regions.push([(minVal + avg * i), maxVal]);
      }else{
        regions.push([(minVal + avg * i), (minVal + avg * (i + 1))]);
      }
    }
    //返回對應(yīng)值顏色
    for(let i = 0; i < regions.length; i++){
      if(val >= regions[i][0] && val <= regions[i][1]){
        return colors[i];
      }
    }
  }
  
  //生成圖例
  function getLegend(minVal, maxVal, colors){
    let length = colors.length;
    let avg = ((maxVal - minVal)/length).toFixed(4);
    //生成等分區(qū)間
    let regions = [];
    for(let i = 0; i < length; i++){
      if(i === length -1){
        regions.push([(minVal + avg * i).toFixed(2), maxVal.toFixed(2)]);
      }else{
        regions.push([(minVal + avg * i).toFixed(2), (minVal + avg * (i + 1)).toFixed(2)]);
      }
    }
    let legend = [];
    for(let i = 0; i< length; i++){
      legend.push({
        color: colors[i],
        region: regions[i]
      });
    }
    return legend;
  }
</script>
</html>
效果
渲染效果
以上使用的離散顏色數(shù)組渲染施敢,生成連續(xù)顏色可使用如下方法
  //根據(jù)數(shù)值范圍、顏色范圍(16進制類型)狭莱,獲取數(shù)值范圍中某一數(shù)值對應(yīng)顏色范圍中的顏色
  //顏色要求:選擇相鄰色系
  function getContinuationColorByVal(minVal, maxVal, firstColor, secondColor, val){
    let ratio = (val-minVal)/(maxVal - minVal);
    let fArr = hex2RgbArr(firstColor);
    let sArr = hex2RgbArr(secondColor);
    let color = [];
    for(let i = 0; i < fArr.length; i++){
      let c = (fArr[i]<sArr[i]?fArr[i]:sArr[i]) + Math.abs(((sArr[i]-fArr[i])*ratio).toFixed(0));
      color.push(c);
    }
    return rgbArr2Hex(color);
  }
  //16進制顏色轉(zhuǎn)rgb顏色數(shù)組
  function hex2RgbArr(hex){
    // 16進制顏色值的正則
    var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
    // 把顏色值變成小寫
    var color = hex.toLowerCase();
    if (reg.test(color)) {
      // 如果只有三位的值僵娃,需變成六位,如:#fff => #ffffff
      if (color.length === 4) {
        var colorNew = '#';
        for (var i = 1; i < 4; i += 1) {
          colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
        }
        color = colorNew;
      }
      // 處理六位的顏色值腋妙,轉(zhuǎn)為RGB
      var colorChange = [];
      for (var i = 1; i < 7; i += 2) {
        colorChange.push(parseInt('0x' + color.slice(i, i + 2)));
      }
      return colorChange;
    }
  }
  //rgb顏色數(shù)組[255, 255, 255]轉(zhuǎn)16進制顏色#ffffff
  function rgbArr2Hex(rgbArr){
    let strHex = '#';
    // 轉(zhuǎn)成16進制
    for (var i = 0; i < rgbArr.length; i++) {
      let hex = Number(rgbArr[i]).toString(16);
      hex = hex.length == 1 ? '0' + hex : hex;
      strHex += hex;
    }
    return strHex;
  }
實際開發(fā)默怨,地圖要素范圍數(shù)據(jù)可能后端返回wkt類型數(shù)據(jù),wkt數(shù)據(jù)轉(zhuǎn)換layer圖層骤素,需用leaflet插件leaflet-omnivore
//wkt轉(zhuǎn)leaflet layer
wkt2Layer(wktShape) {
  if(!!wktShape){
    var geoJson = omnivore.wkt.parse(wktShape);
    let feature = geoJson.getLayers()[0].feature;
    return L.GeoJSON.geometryToLayer(feature);
   }
}

參考資料:
https://blog.csdn.net/mossbaoo/article/details/93484635
https://htmlcolorcodes.com/zh/yanse-xuanze-qi/
http://datav.aliyun.com/tools/atlas/#&lat=30.37018632615852&lng=106.68898666525287&zoom=3.5
http://www.reibang.com/p/1cbfa0ed2051

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末匙睹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谆甜,更是在濱河造成了極大的恐慌垃僚,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件规辱,死亡現(xiàn)場離奇詭異谆棺,居然都是意外死亡,警方通過查閱死者的電腦和手機罕袋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門改淑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浴讯,你說我怎么就攤上這事朵夏。” “怎么了榆纽?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵仰猖,是天一觀的道長捏肢。 經(jīng)常有香客問我,道長饥侵,這世上最難降的妖魔是什么鸵赫? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮躏升,結(jié)果婚禮上辩棒,老公的妹妹穿的比我還像新娘。我一直安慰自己膨疏,他們只是感情好一睁,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著佃却,像睡著了一般者吁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上双霍,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天砚偶,我揣著相機與錄音,去河邊找鬼洒闸。 笑死,一個胖子當著我的面吹牛均芽,可吹牛的內(nèi)容都是我干的丘逸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼掀宋,長吁一口氣:“原來是場噩夢啊……” “哼深纲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起劲妙,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤湃鹊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后镣奋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體币呵,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年侨颈,在試婚紗的時候發(fā)現(xiàn)自己被綠了余赢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡哈垢,死狀恐怖妻柒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耘分,我是刑警寧澤举塔,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布绑警,位于F島的核電站,受9級特大地震影響央渣,放射性物質(zhì)發(fā)生泄漏待秃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一痹屹、第九天 我趴在偏房一處隱蔽的房頂上張望章郁。 院中可真熱鬧,春花似錦志衍、人聲如沸暖庄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽培廓。三九已至,卻和暖如春春叫,著一層夾襖步出監(jiān)牢的瞬間肩钠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工暂殖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留价匠,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓呛每,卻偏偏與公主長得像踩窖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晨横,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容