本篇要解決的問題
之前有寫過一系列的 Google Maps API 學習筆記。Google Maps 好用,但過了一定的額度會收費,當時就有人留言問說免費地圖的事,有留上了心。
原本是直接找 OpenStreetMap 的 API,後來看到文件上回來的都是用 XML,實在是懶得處理轉 JSON 這段。之後幸運地找到一個可以接 OpenStreetMap 的 Leaflet,一個用 JavaScript 接 API 的開源碼,就翻了一下文件,整理成這篇。
本篇會示範的功能如下:
- 使用者請求地點,建立地圖
- 放置 + 客製 marker
- Popup
- Tooltip
- Map click event
- 外部 zoom in、zoom out
- 改變地圖樣式
本篇主要參考文件:Leaflet Quick Start Guide
後續各段會用到的參考文件,將寫在各段之中。
本篇最後會完成的 Demo:
https://letswritetw.github.io/letswrite-leaflet-osm-basic/
請求地點,建立地圖
跟 Google Maps API 一樣,Leaflet 在建立地圖時需要一個中心點。
跟使用者請求所在位置座的座標,需要使用者同意,因此也要先預設一個當使用者拒絕時,或是所擁有的裝置不支援提供所在座標時的地點。
本篇預設地點設為台北市立動物園~ 想去看水豚君啊~~~
關於找地點的座標,August 用的是比較簡單的方法,如果有人有更好的方法歡迎留言提供。
首先進到 Google Maps 的網站,搜尋想要知道座標的地點,我們這邊搜尋「動物園」後,選到動物園,接著按下資料卡片的「分享」:
接著點擊「複製連結」:
然後把複製的網址貼到瀏覽器上打開,短網址會回復成原網址,就能從網址中看見座標,像這樣:
這是 August 知道不用接任何 API 就能找到一個地點座標的方式。
跟使用者要權限
當我們跟使用者要權限時,使用者會看到這樣的請求:
當使用者按下了「允許」,我們就可以得到使用者的座標,程式碼如下:
建立地圖
不管有沒有取到使用者的所在位置,都一樣可以建立 OpenStreepMap 的地圖。
首先先引用 CSS、JS:
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js"></script>
接著在我們要放置地圖的地方,放上一個空 div 並帶上我們指定的 id:
<div id="map"></div>
下一步,給我們的 div 一個高度:
#map {
height: 180px;
}
高度的部份本篇的 Demo 是用 50vh
,實際應用時依各頁面的狀況再作修改。
最後就是用 Leaflet 來建立地圖:
Options 的部份可自行參考 文件,這邊僅列出 August 覺得會用到的。
L.tileLayer
這個是指地圖要讀取哪一個樣式,文件中的預設樣式就是這個:
https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
少了 tileLayer
地圖會是一片灰。
開啟頁面後,地圖就出來了:
放置 Marker
放置 marker 的方式就是新增一個出來後,add 到 map 裡,程式碼如下:
center
就是要放置的座標。
預設的 Maker 樣式如下:
客製 Maker 圖示
Marker 可以用客製的 icon,如下:
我們這邊多放置幾個來看:
一次放置多個可以用迴圈,Demo 的原始檔會附上。
Marker 加上 Popup
Marker 能加上 Popup 跟 Tooltip。
Popup 可以預設打開。
openPopup()
就是打開 Popup。
Popup 長這個樣子:
Marker 加上 Tooltip
Tooltip 就是我們常見的 Tooltip(嗯?有寫跟沒寫一樣)。
一樣可以預設要不要打開,也可以設定顯示的位置:
Tooltip 長這樣:
Map 點擊事件
Leaflet 可以監聽 Map 的點擊。
在官方的範例就有示範點擊地圖後,加上一個 Popup 寫著此處座標,這邊 August 改寫一下:
隨便點擊地可上任一地方,就會出現寫著座標的 Popup:
zoom in, zoom out
除了地圖上預設的功能鍵,也可以用地圖外的按鈕,用 function 執行 zoom in、zoom out。
map.zoomIn(1);
map.zoomOut(1);
數字是一次要 zoom 多少,實際測了一下,zoom 的值是 0 – 18。
0 是世界地圖,18 就是到街景了。
改變地圖樣式 Layer
參考:How to change base layer using JS and leaflet layers control
除了預設的地圖樣式,還有蠻多種樣式可以使用的,在 Leaflet Provider Demo 上可以看到多種,大部份也都有附上 Layer 的網址。
不過,有些不確定是否有收費,因為看到需要 token。
改變地圖樣式的按鈕,可以放在地圖之中,也可以在地圖之外放按鈕控制。
在地圖之內
在地圖之內,總覺得樣式有點陽春 XD~
但勝在方便。
把控制選項放在地圖上,長這樣:
Hover 時會秀出選單:
實際使用,覺得切換的時間有點久,大家看 Demo 時要等一下。
最喜歡的是深色的一款 Stadia.AlidadeSmoothDark,不過這款免費使用下有限制,可以看 官網 說明。
在地圖之外
改變 Layer 主要是這行:
L.tileLayer('layer 的 url').addTo(map);
因此要用地圖外面的按鈕來切換地圖的樣式,只需要寫 click 時執行上面那行就行。
本篇 Demo 及原始碼
最後附上本篇的 Demo 網址,及原始碼的 Github 網址。
Demo:https://letswritetw.github.io/letswrite-leaflet-osm-basic/
Github:https://github.com/letswritetw/letswrite-leaflet-osm-basic
Top comments (0)