> ## Content Index
> Fetch the complete content index at: https://blog.anthea.day/llms.txt
> Use this file to discover other available public pages before exploring further.

# 歡迎來到 GIS 的世界－ Day 25：旅遊規劃小專案的 網頁呈現
- URL: https://blog.anthea.day/series-2022-ithome-25/
- Published: 2022-10-08T16:01:48.000Z
- Updated: 2026-11-06T19:47:11.000Z
- Author: Anthea / 芫荽
- Tags: #Migrated-1792241843742, #Import 2026-10-17 12:57, Coding, 2022 iThome 鐵人賽：歡迎來到 GIS 的世界

有了 API 可以取得資料之後，接下來要使用 Leaflet 來把結果渲染出來。

Leaflet 的使用邏輯很簡單：

1. 初始化
2. 新增點位

### 1\. 初始化

就像一開始提到的動詞 — — 渲染，要使用 Leaflet 前必須準備一個空間讓他發揮，於是我們建立一個空白的 `div`，也別忘記先把 `css` `js` 檔案的 CDN 掛載上去：

```HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>旅遊規劃</title>
    
    <!-- Leaflet 的 CSS -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css"
          integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
          crossorigin=""/>
    <style>
        
        /* 設定高度給 Leaflet 使用 */
        body{
            height: 98vh;
        }
        
        /* 設定高度給 Leaflet 使用 */
        #app, #map{
            height: 100%;
        }
    </style>
</head>
<body>
<!-- 搭配前端套件 Vue3 使用，所以另外建立一個 #app -->
<div id="app">
    
    <!-- 實際上放置 Leaflet 的地方 -->
    <div id="map"></div>
</div>

<!-- Leaflet 本體 -->
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js"
        integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
        crossorigin=""></script>
<!-- Axios（選用） -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
<!-- Vue3（選用） -->
<script src="https://unpkg.com/vue@3"></script>
</body>
</html>
```

接著要來初始化地圖：

```HTML
<!DOCTYPE html>
<html lang="en">
<body>
<!-- 前略 -->
<script>
    const app = Vue.createApp({
        data(){},
        methods:{
            initMap(data){
                // 初始化地圖
                
                // 'map' 中放入指定渲染節點的 id
                // setView([lat,lon]) 放入預設載入的中心位置
                let map = L.map('map').setView([24.175339, 120.648586], 19);
                
                // 新增 OSM 的圖磚
                L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
            },
            getScenicSpots(){
                // 取得景點資料
                axios({
                    method: 'get',
                    url: './api/ScenicSpot'
                }).then(res => {
                    this.initMap(res.data);
                }).catch(err => {
                    console.log(err);
                })
            },
        },
        mounted(){
            // Vue 掛載之後執行
            this.getScenicSpots();
        }
    });
    app.mount('#app');
</script>
</body>
</html>
```

成功載入的話會看到以逢甲附近為中心點的地圖，可以隨意縮放移動。

### 2\. 新增點位

新增點位的方式很簡單，在載入圖磚之後把所有座標都利用 `marker()` 來建立成一個圖層之後，附加到原本的 map 上即可：

```JS
initMap(data){
    // 設定地圖
    let map = L.map('map').setView([24.175339, 120.648586], 19);
    
    // 新增圖磚
    L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
    
    // 建立點位
    let layer = data.map(ele => { L.marker([ele.y, ele.x]).addTo(map) });
    
    // 新增點位到圖磚上
    map.addLayer(layer);
}
```

成功執行的話，會看到原本地圖靠近中間底部的地方有一個點，他就是我們渲染出來的景點之一：

![](https://cdn-images-1.medium.com/max/800/0*davqnCBbjal2Vwwq.jpg)

這個時候如果你努力的滾滑鼠滾輪，用力的把他們縮小，你會發現你的網頁變的很卡，然後密集恐懼症開始發作：

![](https://cdn-images-1.medium.com/max/800/0*Le-9DOvYcfN15RPa.png)

這種顯示方式太不優雅了！所以我們要利用 Leaflet 的套件 — — Leaflet.markercluster 來優化一下網頁的呈現。

Cluster 翻譯為叢集，這個套件的目的是讓我們把地圖縮小到一定比例的時候，幫助我們把多個目標合併成一個點，看起來會比較舒適，效果如下圖：

![](https://cdn-images-1.medium.com/max/800/0*AObWJWCuDTHhFJGZ.png)

### 使用 markercluster

以下是縮放到不同尺寸的樣子：

```JS
initMap(data){
    let map = L.map('map').setView([24.175339, 120.648586], 19);
    L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
    
    // 原始
    // let coor = data.map(ele => { L.marker([ele.y, ele.x]).addTo(map) });
    // map.addLayer(coor);
    // Cluster
    
    let markers = L.markerClusterGroup();
    data.map(ele => { markers.addLayer(L.marker([ele.y, ele.x])) })
    map.addLayer(markers);
}
```

![](https://cdn-images-1.medium.com/max/800/0*pBmPEp16J_vpGJCE.png)

![](https://cdn-images-1.medium.com/max/800/0*V0Zu5_WNH8TNos4z.png)

![](https://cdn-images-1.medium.com/max/800/0*w8fBtYj9jNGP0QTe.jpg)

可以看到預設就會有不同顏色代表不同數量的呈現，並且移動到 cluster 上方還會很貼心的幫你標示出這個 cluster 所代表的區域，點擊之後會自動幫你 zoom in 🤩

當然顏色、標示這些功能都可以做調整，只是我會著墨在後端比較多，因此這篇文章只會介紹到這裡，其餘功能如果摸索上有問題，也歡迎留言一起討論喔。

#### References

- [Leaflet.markercluster GitHub](https://github.com/Leaflet/Leaflet.markercluster?ref=blog.anthea.day)