iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Software Development

歡迎來到 GIS 的世界!30 天從後端開始學 GIS系列 第 28

旅遊規劃小專案 6 - 重新渲染景點

  • 分享至 

  • xImage
  •  

文章同步發表至 medium

昨天提到我們想要做到重新渲染 markers 這件事情。從功能上來看,初始化地圖和新增 markers 的確是兩件事,所以我的思路會是把這兩件事情分開來,一開始就初始化,有資料之後才去渲染 markers。

為了做到這件事情,我們需要進行一些調整:

  1. 建立一個物件來接地圖,才能針對同一個地圖新增 markers
  2. 把初始化和新增 markers 的行為分開
  3. 把呼叫初始化地圖的部分修改成呼叫新增 markers
const app = Vue.createApp({
    data(){
        return{
            // 新增一個物件來接初始化之後的地圖
            map: null
        }
    },
    methods:{
        initMap(){
            // 把初始化後的物件丟到 Vue 裡
            this.map = L.map('map');
            
            this.map.setView([24.175339, 120.648586], 19);
            L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(this.map);
        },
        resetMarkers(data){
            // 建立 markers
            let markers = L.markerClusterGroup();
            data.map(ele => { markers.addLayer(L.marker([ele.y, ele.x])) })
            this.map.addLayer(markers);
        },
        getScenicSpots(){
            axios({
                method: 'get',
                url: './api/ScenicSpot'
            }).then(res => {
                // 改成呼叫 resetMarkers()
                this.resetMarkers(res.data);
            }).catch(err => {
                console.log(err);
            })
        },
        searchScenicByCounty(){
            Swal.fire({
               // ...
            }).then((result) => {
                if (result.isConfirmed) {
                    axios({
                        method: 'get',
                        url: `./api/ScenicSpot/${result.value}`
                    }).then(res => {
                        // 改成呼叫 resetMarkers()
                        this.resetMarkers(res.data);
                    }).catch(err => {
                        console.log(err);
                    })
                }
            })
        },
    },
    mounted(){
        // 先初始化地圖
        this.initMap();
        this.getScenicSpots();
    }
});
app.mount('#app');

來看看我們修正的第一版結果:

初始化和取得所有景點看起來是正常的,接下來我們試試景點查詢的功能:

操作起來沒問題,但因為我們沒有先把前一次新增上去的 markers 移除,所以新增進去的會和舊有的一起顯示,但這很明顯不是 Feature,是 Bug。

移除舊有 markers

我的思路還是很簡單,給他一個物件存起來,如果這個物件不是空的,那就把它整包移除:

const app = Vue.createApp({
    data(){
        return{
            map: null,
            
            // 新增一個物件來接 markers
            oldMarkers: null
        }
    },
    methods:{
        initMap(){
            // ...
        },
        resetMarkers(data){
            // 如果舊有的 markers 不是空的,就移除
            if (this.oldMarkers !== null) this.map.removeLayer(this.oldMarkers);
            
            let markers = L.markerClusterGroup();
            data.map(ele => { markers.addLayer(L.marker([ele.y, ele.x])) })
            this.map.addLayer(markers);
        },
        getScenicSpots(){
            // ...
        },
        searchScenicByCounty(){
            // ...
        },
    },
    mounted(){
        // ...
    }
});
app.mount('#app');

有新增移除之後的結果:

原本的 markers 都被移除了,只剩下我們查詢的縣市的景點們。

Reference


上一篇
旅遊規劃小專案 5 - 查詢介面
下一篇
旅遊規劃小專案 7 - 景點和旅館的交集
系列文
歡迎來到 GIS 的世界!30 天從後端開始學 GIS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言