地圖應用其實不算前端網頁必備技術,不過也可以學習到圖資資料處理及畫面渲染等,而且也蠻好玩的XD
本文其實算前陣子做完的口罩地圖分享,所以一如往常的是 Leaflet 框架 與 OpenStreetMap 圖資的教學。
根據官網說得,是一個極小的 JS 框架。主要用於呈現地圖上面的效果。(例如在地圖上放上圖標!
這是一個開源的圖資,跟 Google Map、Apple Maps 等圖資一樣,差別在於他只提供地圖,但不提供商家資訊、公共設施等資訊,這些都需要開發者自行加入才行~
首先,我們建立一個區塊來表示地圖要放在那裏<div id="map"></div>
並使用 CDN 來引入 Leaflet 框架
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
基礎應用。L 指的是這整個框架,裡面包含所有的應用。
以下為地圖設定,第一個參數代表要將 map 放在哪個 ID 上;第二個參數是物件格式,center 用於定位、zoom 用於控制初始的縮放大小,數字越小地圖越遠。
var map = L.map('map', {
center: [51.505, -0.09],
zoom: 13
});
載入圖資,告訴 Leaflet 框架你要使用的圖資是哪一種。下面程式碼為官網提供的 OpenStreetMap 的起手式。
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
.addTo(map)
代表加入 map 這個 ID 之中。
將 #map
及 html
、body
標籤添加寬高,這樣地圖才會顯現。
html,body {
width: 100%;
height: 100%;
overflow: hidden;
}
#map {
width: 100%;
height: 100%;
}
地圖都是由好幾的圖層疊起來的,最底下是圖資,再來才是 icon、圖片、座標之類的。
這裡我們先新增一個座標!! 一樣按照官網提供的程式碼。
L.marker([51.5, -0.09]).addTo(map)
.bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
.openPopup();
.bindPopup()
可以放 HTML 的語法在裡面,為一個彈跳視窗。.openPopup()
為預設開啟彈跳視窗,刪掉的話就為關閉,但還是可以點擊圖示來開啟視窗。marker([經緯度座標])
,雖然中文念經緯度,但參數一是放緯度喔!! 參數二才是經度。
讀到現在大概知道想要增加座標的話只要用迴圈不斷重跑 marker 的座標就可以獲得大量座標了吧~~
我還想要有紅色座標!
這裡放上顏色座標 GitHub。
按照他的使用說明,不須引入 CDN 也能使用。
var redIcon = new L.Icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
L.marker([51.51, -0.09], {icon: redIcon}).bindPopup('我是紅色座標 icon').addTo(map)
點入 icon 中複製該網址,貼到上面物件中的 iconUrl
就可以使用了。
Leaflet.Locate 這個套件需要先引入 Leaflet 框架才能使用。
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@[VERSION]/dist/L.Control.Locate.min.css" />
<script src="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@[VERSION]/dist/L.Control.Locate.min.js" charset="utf-8"></script>
可以參考他的連結選用需要的舊版本,想直接使用最新版本將 @[VERSION]
刪除即可。
L.control.locate({showPopup: false}).addTo(map).start();
showPopup
預設為 true,設為 false 可以把顯示位置提示字關閉。
輸入上面程式碼後,瀏覽器會跳出詢問資訊,問你是否允許提供位置,允許的話就會標記你的座標。
假如我想要點擊資訊欄並跳轉到該資訊的位置,這裡我用先前製作的口罩地圖作範例
只要點擊該藥局位置,就能從高雄瞬間轉移到花蓮喔~~
使用 Leaflet 框架自己的方法setView([經緯度], 時間)
時間這個不太確定,因為我怎麼嘗試都覺得效果一樣...
先將該藥局經緯度標出來,
在對 map 使用
-----
item.addEvenListener('click', function(){
const lat = 藥局緯度;
const lng = 藥局經度;
map.setView([lat, lng], 1300);
})
Leaflet.markercluster
因為每個座標都是 png,假如像口罩地圖那樣,每次大約都有5000~6000筆資料的話電腦會跑不動...
引入 CDN。
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.4.1/MarkerCluster.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.4.1/MarkerCluster.Default.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.4.1/leaflet.markercluster.js"></script>
並建立 MarkerClusterGroup 的圖層
let markers = new L.MarkerClusterGroup().addTo(map);
就可以用迴圈將座標全部放進 markers
圖層中。
終於寫完了~~ 竟然變成整系列中目前最長的文章... 看看明天的能不能超越吧~~
關於地圖的操作,其實資料處理很大一部份會用到 Day17. JavaScript 陣列的處理 - 取得陣列內不重複資料、刪除陣列中指定值、判斷是否有符合的字串 這篇文章內的處理,有遇到問題可以去翻翻看。