iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
1
Modern Web

使用Leaflet及Folium開啟網頁地圖大門系列 第 6

06. Leaflet_Raster Layers

接著來介紹raster layer。Raster layer又稱柵格圖層或影像圖層,資料本身是以一格一格的像素組成,在GIS中常用網格圖層表示地形的高低起伏,圖片的圖層也是網格圖層的一種。

  • TileLayer
  • TileLayer.WMS
  • ImageOverlay
  • videoOverlay

TileLayer

TileLayer是以圖磚的方式存取圖層,最常見的Google Map地圖就是用許多塊正方形的圖磚組成地圖,當網路或是電腦跑比較慢的時候就可以看出一塊一塊的圖片在讀取中。由於Tile Layer可根據地圖檢視的範圍顯示相對應的圖磚,所以比起讀取整張地圖來說較有效率。

我在01. 起手式中是使用opentopomap作為建立tile layer作為底圖,使用的tile layer 連結為https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png,可以看到連結最後的副檔名為.png表示這個圖磚是png格式的圖片,另外還有{s}{z}{y}{x}等項目:

  • {s}
    tile 連結的subdomain,預設為a, b或c其中一個
  • {z}
    地圖的zoom等級
  • {y}
    圖磚的y座標
  • {x}
    圖磚的x座標
L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
        maxZoom: 14,
        attribution: 'Map data: © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
}).addTo(map);

選擇其他tile底圖

若想要連結其他tile底圖,可參考Leaflet Provider Demo。網頁右側可先選擇你想要的底圖,選完後在中間上面的地方可以直接複製程式碼使用,例如我現在選擇OpenStreetMap.BlackAndWhite:
OpenStreetMap.BlackAndWhite

就可以複製程式碼使用:

var OpenStreetMap_BlackAndWhite = L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', {
	maxZoom: 18,
	attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
});
OpenStreetMap_BlackAndWhite.addTo(myMap);

Leaflet官網還有提供許多底圖的連結,可參考Plugins - Leaflet - a JavaScript library for interactive maps

Tile Layer設定

在tile layer建立的時候,可以設定一些參數。在上面的程式碼中,我已經使用了maxZoom及attribution兩個option,其中attribution為繼承Layer的option,更多參數可參考下面:

  • minZoom:<Number>
    • 最小縮放zoom等級
    • 預設為0
  • maxZoom:<Number>
    • 最大縮放zoom等級
    • 預設為18
  • subdomains:<String>
    • {s}的參考字串
    • 預設為'abc'
  • errorTilrUrl:<String>
    • 讀取失敗時顯示的圖片連結
    • 預設為''
    • 在網路上找到這個圖舉例,連結為圖片連結,你也可以用自己喜歡的圖片http://bpic.588ku.com/element_pic/16/12/07/706f7ff4f15725b17ba1d30d384e6468.jpg
      706f7ff4f15725b17ba1d30d384e6468.jpg
    • 在body中加入以下程式碼。為了讓地圖讀取不到,將網址中的tile改為tilke,並加上errorTilrUrloption,讓地圖顯示我要的圖片,網址即為上面的圖片:
    <div id="mapid" style="width: 100%;"></div>
    <script>
        //scope
        (function($){
          $(document).ready(function(){
                $('#mapid').height(window.innerHeight);
    
                var myMap = L.map('mapid').setView([22.73444963475145, 120.28458595275877], 14);
    
                L.tileLayer('https://{s}.tilke.opentopomap.org/{z}/{x}/{y}.png', {
                    maxZoom: 14,
                    errorTileUrl: 'http://bpic.588ku.com/element_pic/16/12/07/706f7ff4f15725b17ba1d30d384e6468.jpg',
                    attribution: 'Map data: © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
                }).addTo(myMap);
            });
        })($)
    </script>
    
    最後就可以看到地圖都顯示同樣的圖片,因為tile由許多圖片組成,若有一片圖磚讀取失敗就會顯示,而上面的程式碼讓他一張圖片都讀不到,所以全部都會顯示讀取失敗的圖片。
    errorTilrUrl
  • zoomOffset:<Number>
    • 用來補償url中地圖的zoom等級
  • tms:<Boolean>
    • true反轉Y軸的編號
    • 預設為false
    • 若使用TMS服務時需設定為true
  • zoomReverse:<Boolean>
    • true:{z}數字 = maxZoom - zoom
    • 預設為false
  • detectRetina:<Boolean>
    • 設定Retina是否支援Retina高畫質圖磚
    • 預設為false
  • crossOrigin:<Boolean>
    • 預設為false
    • true可取得pixel數據

TileLayer.WMS

用於讀取顯示OGC標準的WMS地圖服務,台灣提供WMS的塗層資源很少,所以這邊參考Leaflet官方網站提供的範例加入地圖中:

var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", {
    layers: 'nexrad-n0r-900913',
    format: 'image/png',
    transparent: true,
    attribution: "Weather data © 2012 IEM Nexrad"
}).addTo(myMap);

上面的程式碼加入的是美國的氣象雷達圖層,台灣也有雷達回波圖的資訊,但在開放資料中格式寫得不太清楚,所以還需要花一些時間研究,如果接下來這幾天有成功的話,會在之後的文章中跟大家分享~
讓我們先來看看成果吧!

tileLayer_WMS

ImageOverlay

用於影像套疊,可套疊衛星雲圖或是自製的地圖,套疊在地圖上可以看出相對關係。

試著加入中央氣象局提供的衛星雲圖開放資料做套疊,使用下列程式碼建立imageOvelay圖層:

var imageUrl = 'https://opendata.cwb.gov.tw/fileapi/opendata/MSC/O-B0028-003.jpg',
    imageBounds = [[18.600625745, 115.976888855], [27.79937425, 126.02300114]];
imageUrlLayer = L.imageOverlay(imageUrl, imageBounds, {
    opacity:0.4
}).addTo(myMap);

imageOverlay還有一些選項可以設定,上面則使用了最常用的opacity(透明度),可以看到下面的地圖中,有淡淡的藍色圖塊,那個就是中央氣象局提供的衛星雲圖,調整成透明度40%的樣子。

ImageOvlay

videoOverlay

用於影片套疊作為動態展示使用,若要實際運用到地圖中的話,可以套疊衛星雲圖的影片,觀看颱風動畫,輸入下列程式碼建立簡單的videoOverlay:

var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm',
    videoBounds = [[ 32, -130], [ 13, -100]];
L.videoOverlay(videoUrl, videoBounds).addTo(myMap);
myMap.fitBounds(videoBounds);

videoOverlay還可以設定autoplay(自動播放)及loop(循環播放),預設都是true,若要關掉則在程式碼中設定為false即可。下面是加入地圖的結果:

videoOverlay.gif

今天介紹的圖層雖然只有4種,但也是寫了不少,希望大家能耐心地看完,並有所收穫,明天繼續加油!!!


上一篇
05. Leaflet_UI Layers
下一篇
07. Leaflet_Vector Layers(上)
系列文
使用Leaflet及Folium開啟網頁地圖大門30

1 則留言

0
carlosauyeung306
iT邦新手 5 級 ‧ 2020-07-13 09:25:01

你好, 我用 imageOverlay有這句error , 請問知不知是什麼原因?

jquery-3.2.1.min.js:2 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
at e._updateContent (leaflet.js:5)
at e.update (leaflet.js:5)
at e.onAdd (leaflet.js:5)
at e.onAdd (leaflet.js:5)
at e._layerAdd (leaflet.js:5)
at e.whenReady (leaflet.js:5)
at e.addLayer (leaflet.js:5)
at e.openPopup (leaflet.js:5)
at HTMLDocument. ((index):60)
at j (jquery-3.2.1.min.js:2)

塔塔墨 iT邦新手 5 級 ‧ 2020-07-20 01:08:54 檢舉

請問可提供程式碼嗎?這樣比較能找出錯誤的原因

我要留言

立即登入留言