vue+leaflet实现离线地图
此文章以腾讯地图为例,仅供学习使用,代码可能存在一定的问题,欢迎讨论
一.准备工作
1.下载瓦片地图数据
地图下载器可以参考
https://gitee.com/CrimsonHu/java_map_download
此开源项目
下载完成后点击run.bat
运行成功后选择地图进行下载
注意:腾讯地图到第18级,层级选择到第18级就行,格式选择PNG,或者是JPG,我这里选择的是PNG。命名风格选择第四个 /{z}/{x}/{y}.[image]
选择完成之后可以点击下载了,下载的速度与你选择的地图区域和层级有关
2.部署瓦片数据
部署方式随便,可以使用tomcat,nginx,等任意部署方式,只要能将下载的瓦片数据作为静态资源转发出去就行了,我这里是学习使用,所有使用了一种简单的部署方式IIS
1.打开“控制面板”->“程序和功能”->“打开或关闭Windows功能”,勾选Internet Information Services,点击确定即可安装。
2.打开开始菜单,搜索ISS,打开ISS。右键单击“网站”->“添加网站”,设置网站名称和物理路径
物理路径选择到下载的最外层路径即可,端口你选择一个未被占用的端口即可
3.打开“目录预览”功能,之后重新启动
4.验证部署,浏览器输入http://localhost:8044/ 即你部署的端口出来以下页面说明部署成功
3.导入依赖(Leaflet插件安装)
https://leafletjs.cn/
Leaflet的官方网站,详情和其他更多使用方法请参考
npm install leaflet --save
使用npm导入leaflet插件
二.使用
1.坐标标点
废话不多讲先上代码
<template>
<div id="editTMap" class="main_map"></div>
</template>
<script>
//引入依赖,你也可以在main.js中做全局依赖引入
import 'leaflet/dist/leaflet.css';
import L from "leaflet";
export default {
data() {
return {
};
},
mounted() { this.initMap()},
methods: {
initMap(lat = 25.822549, lng = 98.857601) {
// 创建地图实例,将其绑定到 id 参数为 "map" 的 DOM 元素上※
this.map = L.map("editTMap");
// 使用 setView() 方法设置地图中心点坐标(维度,经度)和初始缩放级别※
this.map.setView([lat, lng], 14);
// 创建 Stamen 图层,并添加到地图上※
var stamenLayer = L.tileLayer('http://localhost:8044/{z}/{x}/{y}.jpg', {
attribution: '坐标标点', // 图层属性信息※
minZoom: 12, // 最小缩放级别※
maxZoom: 18 // 最大缩放级别※
}).addTo(this.map)
//标点
this.markerLayer=L.marker([lat, lng], {
//详细说明可参考https://leafletjs.cn/reference.html#icon 官方文档(此处设置可以防止地图放大缩小后,定位出现偏移)
icon: new L.Icon({
className: "lmap-icon",
iconUrl: require('@/assets/icons/flag.png'), //坐标图标(仿照腾讯地图坐标标点,可去阿里图标库下载)
iconSize: [40, 40], //图标大小
iconAnchor: [20, 40], //位移,原点是左上角。X正轴右侧,Y正是下侧
popupAnchor: [-3, -76], //弹出窗口(popup)的坐标,相对于图标锚点而言,将从该点打开。
shadowSize: [68, 95],//阴影图像的大小,单位是像素。
shadowAnchor: [22, 94]//阴影 "tip" 的坐标(相对于其左上角)(如果没有指定,则与iconAnchor相同)。
})
}).addTo(this.map);
//监听坐标变化
this.map.on("click", (evt) => {
console.log(evt.latlng)
console.log("lgtd",evt.latlng.lat)
console.log("lttd", evt.latlng.lng)
//修改坐标位置
this.markerLayer.setLatLng(evt.latlng)
});
},
},
};
</script>
<style lang="scss" scoped>
/* 设置地图容器的高度和宽度 */
.main_map {
height: calc(100vh - 50px) !important;
width: 100%;
}
</style>
运行效果
监听坐标变化
如果你使用了el-drag-dialog等弹出组件的话,在关闭弹窗时要记得释放this.map,否则在你下次打开的时候会报错
handleClose() {
if(this.map){
this.map.remove();
}
},
清除标点的方法
this.markerLayer.remove();
如果是多个点位标注的话,可以使用数据进行标注和清除
2.多点标注点击图标弹出详情
代码如下
<template>
<div id="editTMap" class="main_map"></div>
</template>
<script>
//引入依赖,你也可以在main.js中做全局依赖引入
import 'leaflet/dist/leaflet.css';
import L from "leaflet";
export default {
data() {
return {
list: [],
scenicMarker: null,
scenicMarkerlist: []
};
},
mounted() { this.initMap() },
methods: {
initMap(lat = 25.822549, lng = 98.857601) {
// 创建地图实例,将其绑定到 id 参数为 "map" 的 DOM 元素上※
this.map = L.map("editTMap");
// 使用 setView() 方法设置地图中心点坐标(维度,经度)和初始缩放级别※
this.map.setView([lat, lng], 14);
// 创建 Stamen 图层,并添加到地图上※
var stamenLayer = L.tileLayer('http://localhost:8044/{z}/{x}/{y}.jpg', {
attribution: '坐标标点', // 图层属性信息※
minZoom: 12, // 最小缩放级别※
maxZoom: 18 // 最大缩放级别※
}).addTo(this.map)
//标点(list是你的坐标集)
list.map((item) => {
if (item.lgtd) {
var scenicMarker = L.marker([item.lgtd, item.lttd], {
icon: new L.Icon({
className: "lmap-icon",
iconUrl: require('@/assets/images/home/mapld.png'),
iconSize: [40, 40],
iconAnchor: [20, 40],
popupAnchor: [-3, -76],
shadowSize: [68, 95],
shadowAnchor: [22, 94],
propertiesss: item//可以携带在图标的对象(比如说需要点击图标需要弹出详情,propertiesss自定义可以叫任何名称)
})
}).addTo(this.map);
this.scenicMarkerlist.push(scenicMarker)
scenicMarker.on("click", this.scenicClick);
}
});
},
//清除坐标集
removeMarker() {
for (let i = 0; i < this.scenicMarkerlist.length; i++) {
this.scenicMarkerlist[i].remove();
}
},
//点击事件
scenicClick(evt) {
//获取我图标里存的对象propertiesss
console.log("propertiesss",evt.target.options.icon.options.propertiesss)
},
},
};
</script>
<style lang="scss" scoped>
/* 设置地图容器的高度和宽度 */
.main_map {
height: calc(100vh - 50px) !important;
width: 100%;
}
</style>