基于Vue3的Leaflet基础
1. 概述
Leaflet 是一个开源、轻量并且对移动端友好的交互式地图 JavaScript 库,大小仅仅只有 39 KB, 拥有绝大部分开发者所需要的所有地图特性
Leaflet 的官网为:Leaflet - a JavaScript library for interactive maps (leafletjs.com)
Leaflet 的中文站点为:Leaflet - 一个交互式地图 JavaScript 库 (leafletjs.cn)
Vue是一个易学易用,性能出色,适用场景丰富的 Web 前端框架
Vue 的官网为:Vue.js - The Progressive JavaScript Framework | Vue.js (vuejs.org)
Vue 的中文站点为:Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)
本文基于Vue3描述Leaflet的基础入门
2. 环境准备
npm/Node的安装参考:如何安装 Node.js (nodejs.cn)
参考Vue3的官方指导:快速上手 | Vue.js (vuejs.org),使用以下命令创建一个Vite+Vue3的环境:
npm init vue@latest
根据提示配置,直接配置完成(如果不确定选项默认即可)
接下来安装模板所需要的包:
cd <your-project-name> npm install
参考:Download - Leaflet - 一个交互式地图 JavaScript 库 (leafletjs.cn),安装Leaflet:
npm install leaflet
不妨测试一下:
npm run dev
如果顺利的话,打开网址,将会看到一个欢迎界面:
接下来将模板中无用的文件与代码删除
删除初始的组件:
清空App.vue
:
新建一个底图组件Map.vue
:
在App.vue
中引入Map:
<script setup> import Map from './components/Map.vue' </script> <template> <Map></Map> </template> <style scoped> </style>
至此环境准备完成,不妨测试一下,顺利的话将会出现test字样
可选项,设置全局样式,将main.css
中边距和填充设置为0:
3. 加载底图
参考官方示例:Quick Start Guide - Leaflet - a JavaScript library for interactive maps (leafletjs.com),加载一个底图:
<script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' export default{ mounted(){ const map = L.map('map').setView([51.505, -0.09], 13) L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 4, attribution: '© OpenStreetMap' }).addTo(map) } } </script> <template> <div id="map"></div> </template> <style scoped> #map { height: 100vh; width: 100vw; } </style>
结果如下:
4. 加载标注与多边形
参考官方示例:Quick Start Guide - Leaflet - a JavaScript library for interactive maps (leafletjs.com),加载标注、圆与多边形:
<script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' export default{ mounted(){ const map = L.map('map').setView([51.505, -0.09], 13) L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 4, attribution: '© OpenStreetMap' }).addTo(map) const marker = L.marker([51.5, -0.09]).addTo(map) const circle = L.circle([51.508, -0.11], { color: 'red', fillColor: '#f03', fillOpacity: 0.5, radius: 500000 }).addTo(map) const polygon = L.polygon([ [51.509, -0.08], [41.503, -0.06], [51.51, -10.047] ]).addTo(map) } } </script> <template> <div id="map"></div> </template> <style scoped> #map { height: 100vh; width: 100vw; } </style>
结果如下:
5. Popup弹窗
参考官方示例:Quick Start Guide - Leaflet - a JavaScript library for interactive maps (leafletjs.com),加载popup弹窗:
<script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' export default{ mounted(){ const map = L.map('map').setView([51.505, -0.09], 13) L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 4, attribution: '© OpenStreetMap' }).addTo(map) const marker = L.marker([51.5, -0.09]).addTo(map) const circle = L.circle([51.508, -0.11], { color: 'red', fillColor: '#f03', fillOpacity: 0.5, radius: 500000 }).addTo(map) const polygon = L.polygon([ [51.509, -0.08], [41.503, -0.06], [51.51, -10.047] ]).addTo(map) marker.bindPopup("<b>Hello world!</b><br>I am a popup.") circle.bindPopup("I am a circle.") polygon.bindPopup("I am a polygon.") var popup = L.popup() .setLatLng([51.5, -0.09]) .setContent("I am a standalone popup.") .openOn(map); } } </script> <template> <div id="map"></div> </template> <style scoped> #map { height: 100vh; width: 100vw; } </style>
结果如下:
6. 点击事件
参考官方示例:Quick Start Guide - Leaflet - a JavaScript library for interactive maps (leafletjs.com),监听底图点击事件:
<script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' export default{ mounted(){ const map = L.map('map').setView([51.505, -0.09], 13) L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 4, attribution: '© OpenStreetMap' }).addTo(map) const marker = L.marker([51.5, -0.09]).addTo(map) const circle = L.circle([51.508, -0.11], { color: 'red', fillColor: '#f03', fillOpacity: 0.5, radius: 500000 }).addTo(map) const polygon = L.polygon([ [51.509, -0.08], [41.503, -0.06], [51.51, -10.047] ]).addTo(map) marker.bindPopup("<b>Hello world!</b><br>I am a popup.") circle.bindPopup("I am a circle.") polygon.bindPopup("I am a polygon.") var popup = L.popup() .setLatLng([51.5, -0.09]) .setContent("I am a standalone popup.") .openOn(map) function onMapClick(e) { popup .setLatLng(e.latlng) .setContent("You clicked the map at " + e.latlng.toString()) .openOn(map); } map.on('click', onMapClick); } } </script> <template> <div id="map"></div> </template> <style scoped> #map { height: 100vh; width: 100vw; } </style>
结果如下:
7. 加载GeoJSON
这里使用的GeoJSON数据下载自:GeoJSON and KML data for the United States - Eric Celeste (clst.org)
下载地址为:https://eric.clst.org/assets/wiki/uploads/Stuff/gz_2010_us_040_00_20m.json
这里将JSON文件放置于public
目录下
使用Fetch加载GeoJSON并添加到地图:
<script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' export default{ mounted(){ const map = L.map('map').setView([51.505, -0.09], 13) L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 4, attribution: '© OpenStreetMap' }).addTo(map) const marker = L.marker([51.5, -0.09]).addTo(map) const circle = L.circle([51.508, -0.11], { color: 'red', fillColor: '#f03', fillOpacity: 0.5, radius: 500000 }).addTo(map) const polygon = L.polygon([ [51.509, -0.08], [41.503, -0.06], [51.51, -10.047] ]).addTo(map) marker.bindPopup("<b>Hello world!</b><br>I am a popup.") circle.bindPopup("I am a circle.") polygon.bindPopup("I am a polygon.") var popup = L.popup() .setLatLng([51.5, -0.09]) .setContent("I am a standalone popup.") .openOn(map) function onMapClick(e) { popup .setLatLng(e.latlng) .setContent("You clicked the map at " + e.latlng.toString()) .openOn(map); } map.on('click', onMapClick); fetch('/gz_2010_us_040_00_20m.json') .then(response => response.json()) .then(data => { console.log(data) L.geoJSON(data, { style: { "color": "#ff7800", "weight": 5, "opacity": 0.65 } }).addTo(map) }); } } </script> <template> <div id="map"></div> </template> <style scoped> #map { height: 100vh; width: 100vw; } </style>
结果如下:
8. 加载WMS服务
参考官方示例:Using WMS and TMS services - Leaflet - 一个交互式地图 JavaScript 库 (leafletjs.cn),添加WMS服务地图:
<script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' export default{ mounted(){ const map = L.map('map').setView([51.505, -0.09], 13) // L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { // maxZoom: 4, // attribution: '© OpenStreetMap' // }).addTo(map) const marker = L.marker([51.5, -0.09]).addTo(map) const circle = L.circle([51.508, -0.11], { color: 'red', fillColor: '#f03', fillOpacity: 0.5, radius: 500000 }).addTo(map) const polygon = L.polygon([ [51.509, -0.08], [41.503, -0.06], [51.51, -10.047] ]).addTo(map) marker.bindPopup("<b>Hello world!</b><br>I am a popup.") circle.bindPopup("I am a circle.") polygon.bindPopup("I am a polygon.") var popup = L.popup() .setLatLng([51.5, -0.09]) .setContent("I am a standalone popup.") .openOn(map) function onMapClick(e) { popup .setLatLng(e.latlng) .setContent("You clicked the map at " + e.latlng.toString()) .openOn(map); } map.on('click', onMapClick); fetch('/gz_2010_us_040_00_20m.json') .then(response => response.json()) .then(data => { console.log(data) L.geoJSON(data, { style: { "color": "#ff7800", "weight": 5, "opacity": 0.65 } }).addTo(map) }); const wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', { layers: 'SRTM30-Colored-Hillshade', maxZoom: 4, }).addTo(map); } } </script> <template> <div id="map"></div> </template> <style scoped> #map { height: 100vh; width: 100vw; } </style>
结果如下:
9. 参考资料
[1]API 参考 | Vue.js (vuejs.org)
[2]Quick Start Guide - Leaflet - a JavaScript library for interactive maps (leafletjs.com)
[3]Quick Start Guide - Leaflet - 一个交互式地图 JavaScript 库 (leafletjs.cn)
[4]Documentation - Leaflet - 一个交互式地图 JavaScript 库 (leafletjs.cn)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 大模型工具KTransformer的安装
· [计算机/硬件/GPU] 显卡