iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 29
0
Modern Web

30天前端網頁技術超入門介紹系列 第 29

Day29. 地圖應用教學

  • 分享至 

  • xImage
  •  

地圖應用其實不算前端網頁必備技術,不過也可以學習到圖資資料處理及畫面渲染等,而且也蠻好玩的XD

本文其實算前陣子做完的口罩地圖分享,所以一如往常的是 Leaflet 框架 與 OpenStreetMap 圖資的教學。

Leaflet 與 OpenStreetMap 簡單介紹

Leaflet

根據官網說得,是一個極小的 JS 框架。主要用於呈現地圖上面的效果。(例如在地圖上放上圖標!
https://ithelp.ithome.com.tw/upload/images/20201006/20119051x98RCp2ROM.png

OpenStreetMap

這是一個開源的圖資,跟 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 之中。

#maphtmlbody 標籤添加寬高,這樣地圖才會顯現。

html,body {
    width: 100%;
    height: 100%;
    overflow: hidden;
}
#map {
    width: 100%;
    height: 100%;
}

https://ithelp.ithome.com.tw/upload/images/20201008/2011905142IS8a1e9M.png

地圖圖層!

地圖都是由好幾的圖層疊起來的,最底下是圖資,再來才是 icon、圖片、座標之類的。
這裡我們先新增一個座標!! 一樣按照官網提供的程式碼。

L.marker([51.5, -0.09]).addTo(map)
        .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
        .openPopup();

.bindPopup() 可以放 HTML 的語法在裡面,為一個彈跳視窗。
.openPopup() 為預設開啟彈跳視窗,刪掉的話就為關閉,但還是可以點擊圖示來開啟視窗。
marker([經緯度座標]),雖然中文念經緯度,但參數一是放緯度喔!! 參數二才是經度。

https://ithelp.ithome.com.tw/upload/images/20201008/20119051ROmA7P7yxn.png
讀到現在大概知道想要增加座標的話只要用迴圈不斷重跑 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 就可以使用了。
https://ithelp.ithome.com.tw/upload/images/20201008/20119051aQZgRFVmrl.png

尋找自己的座標!

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 可以把顯示位置提示字關閉。
輸入上面程式碼後,瀏覽器會跳出詢問資訊,問你是否允許提供位置,允許的話就會標記你的座標。

切換地圖位置!

假如我想要點擊資訊欄並跳轉到該資訊的位置,這裡我用先前製作的口罩地圖作範例
https://ithelp.ithome.com.tw/upload/images/20201008/20119051zPrd3xUh5Q.png
只要點擊該藥局位置,就能從高雄瞬間轉移到花蓮喔~~

使用 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 陣列的處理 - 取得陣列內不重複資料、刪除陣列中指定值、判斷是否有符合的字串 這篇文章內的處理,有遇到問題可以去翻翻看。


上一篇
Day28. Prototype(原型) 基本介紹
下一篇
Day30. 前端網頁技術還可以往哪裡前進?(還有小小完賽感言!
系列文
30天前端網頁技術超入門介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言