# Leaflet新手村 > 撰寫於 2021/05 > 萌新專用使用教學,讓我們來歡樂的戳戳史萊姆吧(๑╹ヮ╹๑)ノ [TOC] ###### tags: `技術文件` ## leaflet官方介紹 * [官方網站](https://leafletjs.com/) * 於 2020/09/04 釋出 Leaflet 1.7.1版本。 * 開源的 Javascript 函式庫。 * 對行動裝置友善的互動地圖。 * 檔案大小只有 39kb。 * 有很多擴充插件。 * 齊全的 [API文檔](https://leafletjs.com/reference-1.7.1.html)和[易讀的原始碼](https://github.com/Leaflet/Leaflet)。 * 最重要的是,官方提供簡單易懂的一些[基本使用教學文](https://leafletjs.com/examples.html),讓你可以輕鬆上手(ゝ∀・)╭☆ ### Docs&Plugin 使用訣竅 > 只講我有些許了解或是使用過的部分,如未來有使用到其他功能,會再補充。 #### Tile & image layers有哪些地圖資源可以用呢? > 以下介紹如何找到不同的地圖資源。 1. 官網點選 ==Plugins== ![](https://i.imgur.com/f57iDsY.png) 2. 點選 Tile & image layers 下方的 ==Basemap providers== ![](https://i.imgur.com/Te0Lbqv.png) 3. 可以看到很多不同的地圖,我們就選 ==leaflet-providers==來看看吧~ ![](https://i.imgur.com/LbCI3Yq.png) 4. 打開 ==leaflet-providers==頁面,點選 ==右邊連結== ![](https://i.imgur.com/6pTxh5b.png) 5. 就可以看到 L.tileLayer 可以使用的不同地圖資料囉! ![](https://i.imgur.com/9KNFjxp.jpg) ## Vue leaflet介紹 * [官方網站](https://vue2-leaflet.netlify.app/) * 完整的文件。 * 大多數的leaflet功能都能用 Vue的方式來使用。 * 豐富的插件生態系。 ### 如何安裝 > 只介紹我有用的安裝方式,官網有全部的可使用方式 [所有安裝方式&使用方法](https://vue2-leaflet.netlify.app/quickstart/#cdn) > 還不熟悉看官方文件的萌新,大多數套件和框架,都會有完整的介紹如何安裝和基本使用方式;今天如果接觸到自己不熟悉的套件和框架,建議先從官方的使用說明開始,或是找一個與自己想做的功能類似的範例,下載下來使用和研讀。 :female_mage: 1. NPM ```sh= npm install leaflet vue2-leaflet --save ``` 2. 用 webpack全域註冊自己想要用的 components,[全部 Components頁面](https://vue2-leaflet.netlify.app/components/LTileLayer.html#demo) ```javascript= import Vue from 'vue'; import { LMap, LTileLayer, LMarker } from 'vue2-leaflet'; import 'leaflet/dist/leaflet.css'; Vue.component('l-map', LMap); Vue.component('l-tile-layer', LTileLayer); Vue.component('l-marker', LMarker); ``` ### 如何使用 > 這邊只會介紹我有使用過的 Components;同前述,如未來還有使用到其他 Components,會再補充。 ## LMap > 最基本與核心的組件,用於在畫面上創建地圖和操作,相容所有其他組件。 [LMap](https://vue2-leaflet.netlify.app/components/LMap.html#demo) :::warning 需要注意的是,這個組件把所有其他組件包在裡面,是==必要的==組件:+1: ::: :::info 這個組件只是創建出一個放置地圖svg的框,需要另外加入其他組件才會有地圖出現。 ::: ```javascript= // 這個組件用來決定地圖的大小,使用 inline-style,設定 width和 height。 // 並給定地圖中心點和地圖顯示大小,來初始化地圖。 <l-map style="height: 80%; width: 100%" zoom="3" center="[47.413220, -1.219482]" > // 其他組件 </l-map> ``` ### Props | Prop name | 介紹 | 使用心得 | | -------- | -------- | -------- | | options | leaflet map可用的 options,皆可放入使用。 | 到 [laeflet DOCS](https://leafletjs.com/reference-1.7.1.html#map-example),點 Map底下的 ++Options++,就可以看到可用的 Options了。 | | center | 地圖的中心點,支援 .sync修飾符。 | .sync是用來雙向綁定,今天要動態修改地圖的中心點時,要記得加上此修飾符。 | | maxBounds | 地圖的最大範圍,移動超出範圍,將會被彈回範圍內。 | 這邊要注意的是,當地圖縮放尺度大,顯示的地圖大於設定的 maxBounds時,還是可以看到範圍外的地圖,以及點擊範圍外的地圖,但卻無法拖曳移動,會被彈回。 | | zoom | 地圖的縮放尺度,支援 .sync修飾符。 | zoom的尺度範圍限制為 1~18。 | | minZoom | 地圖的最小縮放尺度。 | - | | maxZoom | 地圖的最大縮放尺度。 | - | ### Events | Event name | 介紹 | 使用心得 | | ----------- | ---- | -------- | | update:zoom | 當改變尺度時觸發。 | 可以得到當前的 zoom大小 | | update:center | 當移動改變地圖中心點時觸發。 | 可以得到中心點 Object,裡面有 lat, lng的 key。 | ## LTileLayer > 從地圖伺服器取得地圖資訊,並根據 L.map設置的寬高、中心點和尺度來顯示地圖。 > [LTileLayer](https://vue2-leaflet.netlify.app/components/LTileLayer.html#demo) :::info 有關於可以用的地圖伺服器和資源,可以參考 [Tile & image layers有哪些地圖資源可以用呢?](#Tile-amp-image-layers有哪些地圖資源可以用呢) 這一段落的說明。 :smiley: ::: :::info 如果要看更多詳細內容介紹,移步到 [leaflet tilelayer](https://leafletjs.com/reference-1.7.1.html#tilelayer),就有更多詳細內容囉。 :mage: ::: ```javascript= // 記得在外面加上 L.map,並給予寬高、中心點和尺度。 <l-map style="height: 350px" :zoom="zoom" :center="center"> <l-tile-layer :url="url"></l-tile-layer> </l-map> ``` ### Props | Prop name | 介紹 | 使用心得 | | -------- | -------- | ------------- | | url | 放置地圖伺服器提供的 URL。 | 詳細介紹請看 [Raster Layers底下的 tilelayer](https://leafletjs.com/reference-1.7.1.html#tilelayer) | | attribution | 大多數的地圖伺服器都要求你放上你目前使用的地圖資源的來源,例: ![](https://i.imgur.com/xbWrTkP.png) 。 | 會顯示在地圖的右下角。 | | visible | 地圖是否顯示。 | 可以搭配 L.map的 update:zoom 來決定地圖是否要顯示。 | ## LMarker > 在地圖上放置一個可供點擊和移動的可客製化標記。 > [LMarker](https://vue2-leaflet.netlify.app/components/LMarker.html#demo) :::info 如果要看更多詳細內容介紹,移步到 [leaflet marker](https://leafletjs.com/reference-1.7.1.html#marker),就有更多詳細內容囉。 :mage: ::: ```javascript= <l-map style="height: 350px" :zoom="zoom" :center="center"> <l-tile-layer :url="url"></l-tile-layer> <l-marker :lat-lng="markerLatLng" ></l-marker> </l-map> ``` ### Props | Prop name | 介紹 | 使用心得 | | --------- | ------------------ | -------- | | latLng | 標記放置的經緯度。 | - | | zIndexOffset | 標記的 z軸位置。沒設置的話,會自動給予緯度的數值。 | - | ### marker icon消失之解決方法 > 方法是參照 [git issue](https://github.com/PaulLeCam/react-leaflet/issues/453)別人的解答。 ```javascript= // 找到你引入 Vue app的 .js檔案,將以下 code複製貼上。 import 'leaflet/dist/leaflet.css'; import L from 'leaflet'; delete L.Icon.Default.prototype._getIconUrl; L.Icon.Default.mergeOptions({ iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'), iconUrl: require('leaflet/dist/images/marker-icon.png'), shadowUrl: require('leaflet/dist/images/marker-shadow.png') }); ``` ### marker icon客製化之方法 > 請參考[LIcon](##LIcon) ## LIcon > 在創建 LMarker標記時,給予圖標。 > [LIcon](https://vue2-leaflet.netlify.app/components/LIcon.html#demo) :::info 如果要看更多詳細內容介紹,移步到 [leaflet icon](https://leafletjs.com/reference-1.7.1.html#icon),就有更多詳細內容囉。 :mage: ::: 1. 在 LMarker裡面放入 LIcon,可以用 icon-url加入你放置的 icon靜態檔案,或是在 LIcon裡面放置你自己的客製化內容。 ```javascript= // icon圖 <l-marker :lat-lng="[47.413220, -1.199482]"> <l-icon :icon-size="dynamicSize" :icon-anchor="dynamicAnchor" icon-url="static/images/baseball-marker.png" > </l-icon> </l-marker> // 客製化內容 <l-marker :lat-lng="[lat, lng]" > <l-icon class-name="cusom-icon" > <div class="custom-name">{{ custom_content }}</div> </l-icon> </l-marker> ``` 2. 直接在 LMarker的 prop加入 icon,並引入 L.icon,根據給予的 option選項,創建 icon實例。 ```javascript= <l-marker :lat-lng="[47.413220, -1.209482]" :icon="icon" > </l-marker> // script data () { return { icon: L.icon({ iconUrl: '/images/baseball-marker.png', // option選項,你的 icon靜態檔 iconSize: [32, 37], // option選項,大小 iconAnchor: [16, 37] // option選項,座標 }) // icon實例, }; }, ``` ## LGeoJson > 解析 GeoJSON,並將其顯示在地圖上。 > [LGeoJson](https://vue2-leaflet.netlify.app/components/LGeoJson.html#demo) :::info 如果要看更多詳細內容介紹,移步到 [leaflet geojson](https://leafletjs.com/reference-1.7.1.html#geojson),就有更多詳細內容囉。 :mage: ::: ```javascript= <l-map style="height: 350px" :zoom="zoom" :center="center"> <l-geo-json :geojson="geojson"></l-geo-json> </l-map> ``` ### Props | Prop name | 介紹 | 使用心得 | | --------- | ---- | -------- | | geojson | 地圖數據。 | 如果想要得到台灣地圖的 geojson,可以到 [國土測繪中心](https://maps.nlsc.gov.tw/),取得開放資料。 | | visible | 地圖是否顯示。 | 可以搭配 L.map的 update:zoom 來決定地圖是否要顯示。 | | optionsStyle | 給予 geojson客製化樣式。 | 可以使用的 options,可以看 [leaflet 提供的 path-option](https://leafletjs.com/reference-1.7.1.html#path-option) | ![](https://i.imgur.com/vitKjsY.png) ## 畫出一個台灣 [Taiwan map DEMO](https://codesandbox.io/s/taiwan-uq325?file=/src/components/leaflet-map.vue) ### 如何得到台灣地圖資訊? 1. 從 [政府資料開放平臺](https://data.gov.tw/dataset/7442)或是 [內證資料開放平臺_國土測繪中心](https://data.moi.gov.tw/MoiOD/Data/DataDetail.aspx?oid=141718DF-0213-48C3-A7F7-AD6222B1D1F2)下載 ==直轄市、縣市界線(TWD97經緯度)SHP格式==。 2. 將檔案放上 [mapshaper](https://mapshaper.org/),線上轉換成 ==GeoJson 格式==。 3. 轉換步驟[參考資料](https://ithelp.ithome.com.tw/articles/10223786)。 ### 如何得到地圖中心點? > LMap提供 @update:center 方法,可以取得目前顯示地圖的中心點經緯度。 ### 如何在縮放的時候,顯示不同地圖? > LMap提供 @update:zoom 方法,如果搭配其他 Components的 visable,來決定到某個 zoom尺度時,你想要顯示的地圖。 ### 我想只顯示台灣地圖的線圖,不想要使用其他地圖伺服器的地圖怎麼辦? > 政府有提供開放資料,請參考 [如何得到台灣地圖資訊?](###如何得到台灣地圖資訊?),使用 LGeojson,放入你的 geojson就可以得到只有線條的台灣地圖;如果你今天想要在只有線條的台灣地圖上,放上縣市名稱,可以先去 [下載台灣鄉鎮市名稱和中心位置資料](https://data.gov.tw/dataset/40281),使用 LMarker 客製化標誌,渲染出各縣市名稱。 ### csv檔案要怎麼讀取? > 可以使用 [fetch](https://www.twblogs.net/a/5d7e091abd9eee5327ffbe96)。 > 用 vue-cli&webpack的話,可以安裝 csv-loader。 - vue-cli: 修改vue.config.js - npm i csv-loader --save ```javascript= chainWebpack: config => { config .module .rule('csv') .test(/\.csv$/) .use('csv-loader') .loader('csv-loader') .options({ dynamicTyping: true, header: true, skipEmptyLines: true }) .end() } ``` - webpack: ```javascript= module: { rule:[ { test: /\.csv$/, loader: 'csv-loader', options: { dynamicTyping: true, header: true, skipEmptyLines: true } }, ] } ``` ### csv讀取成功,但是產生亂碼怎麼辦? > 可能是因為使用 import的方式載入 csv產生。詳細原因應該是轉碼出問題,但如果用 fetch方式載入,會自動轉碼)。 > - 讓excell打開變成中文 - 原本檔案打開長這樣 - ![](https://i.imgur.com/YutDruv.png) - 打開一個新的excel - ![](https://i.imgur.com/uFEXedw.png) - 選擇 UTF-8 - ![](https://i.imgur.com/UC14YZE.png) - 逗點打勾 - ![](https://i.imgur.com/HIeHV6o.png) - 選擇文字 - ![](https://i.imgur.com/X6qXjsF.png) - 選新工作表 - ![](https://i.imgur.com/8eQ6o63.png) - 儲存後打開 - ![](https://i.imgur.com/n8WpOg3.png) - 讓js可以讀到中文 - 右鍵檔案,用==記事本==打開檔案 - 存檔類型 ==所有檔案== - ![](https://i.imgur.com/Kzg8zGi.png) - 編碼 ==UTF-8== - ![](https://i.imgur.com/dWOOAjm.png) - 另存檔案成.csv檔案,js讀取檔案後就不會亂碼了 - ![](https://i.imgur.com/GCslMVB.png) ### 我的地圖載入不正常,但在改變畫面寬高以後就正常,怎麼辦? > leaflet可能會出現渲染不正確問題,在 mouted時,將整個畫面重新調整大小,就可以正確載入了。 > [leaflet render issue](https://github.com/vue-leaflet/Vue2Leaflet/issues/96) ```javascript= mounted () { setTimeout(function() { window.dispatchEvent(new Event('resize')) }, 250); }, ``` ### 我改變了 center,但是地圖沒有變動怎麼辦? > 有些 props支援 .sync雙向綁定,加上去就可以變動了。 > [詳細說明 prop.sync](https://fpjs.fun/vue/component/prop/sync/)