vue2通过leaflet实现图片点位回显功能
需求:在图片上标点了,需要根据标记点在图片上进行回显功能,并且不会根据窗口大小导致标记点移位
1.效果
2.下载插件
用到的是leaflet插件:一个交互式地图 JavaScript 库,我下载是 "leaflet": "^1.9.4"
npm install leaflet
引入到项目
icon是自带的图标
import icon from 'leaflet/dist/images/marker-icon.png';
import * as L from 'leaflet';
import 'leaflet/dist/leaflet.css';
3.主要代码详解
图片加载后需要创建map对象,注意!!如果后端传的点数据是根据图片原有大小比如图片尺寸800*800,x:20,y:20,就是在800像素上的xy的值那么直接设置leftmap的unproject为图片本身的尺寸即可
var south_west = that.leftMap.unproject([0, img_original_height], 1); //西南var north_east = that.leftMap.unproject([img_original_width, 0], 1);
如果图片原尺寸为800*800,后端传来尺寸为400*400,x:10,y:10,需要设置如下代码
var style = window.getComputedStyle(document.getElementById("roc_map"));var map_height = parseFloat(style.height); var south_west = that.leftMap.unproject([0, map_height], 1); //西南var north_east = that.leftMap.unproject([img_original_width / this_ratio, 0],1);
创建点:draggable:是否拖拽L.marker上面的这些代码全部都是坐标转换的,就是为了应对原有尺寸和后端尺寸不对应的问题
// 1. 获取旧图片尺寸(pointArr中保存的width/height)const oldWidth = obj_.width; // 例如 1036const oldHeight = obj_.height; // 例如 582// 3. 根据地理边界 this_bounds 计算实际的地理坐标const boundsWidth = this_bounds.getEast() - this_bounds.getWest();const boundsHeight = this_bounds.getNorth() - this_bounds.getSouth();const lng = this_bounds.getWest() + (boundsWidth / oldWidth) * obj_.x;const lat = this_bounds.getNorth() - (+boundsHeight / oldHeight) * obj_.y; // Y轴取反const DefaultIcon = L.icon({iconUrl: icon,iconAnchor: [10, 41]});// 4. 创建标记点(Leaflet的Y轴需要取反)const marker = L.marker([lat, lng], {draggable: false,title: obj_.name,icon: DefaultIcon}).addTo(that.leftMap);
创建点弹窗,弹窗样式自行设计
const popup = L.popup().setContent('加载中...');marker.bindPopup(popup);
4.完整代码
<!--* @Description:* @Author: 请叫我欧皇!* @Date: 2025-04-28 14:58:23* @FilePath: \vue-secondMenu-test-master\src\page\test4\zongti\02.leftjs.vue
-->
<template><div class="leaflet-box"><div id="roc_map" class="map"></div></div>
</template><script>
import icon from 'leaflet/dist/images/marker-icon.png';
import * as L from 'leaflet';
import 'leaflet/dist/leaflet.css';
export default {data() {return {pointArr: [{x: 80,y: 50,name: '测试111',group: ['测试111'],point_id: 1,sn: '123456789',width: 800,height: 572},{x: 200,y: 0,name: '测试222',group: ['测试222'],point_id: 2,sn: '123456789',width: 800,height: 572},{x: 200,y: 200,name: '测试333',group: ['测试222'],point_id: 3,sn: '123456789',width: 800,height: 572}],leftMap: null};},mounted() {this.initLeaflet();},methods: {initLeaflet() {let that = this;let pointArr = this.pointArr;var mark_map = {};var this_img = new Image();let imgs = 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg';// this_img.src = "../images/01.jpg";this_img.src = imgs;this_img.onload = function () {var img_original_width = this_img.width,img_original_height = this_img.height;// 在初始化地图前检查是否已存在地图实例if (that.leftMap) {that.leftMap.remove(); // 移除旧地图that.leftMap = null;}that.leftMap = new L.Map('roc_map', {minZoom: 1,maxZoom: 4,center: [0, 0],zoom: 1,crs: L.CRS.Simple,zoomControl: false,attributionControl: false// zoomControl: false, // 禁用默认的缩放控件});var south_west = that.leftMap.unproject([0, img_original_height], 1); //西南var north_east = that.leftMap.unproject([img_original_width, 0], 1);var this_bounds = new L.LatLngBounds(south_west, north_east);L.imageOverlay(imgs, this_bounds).addTo(that.leftMap);that.leftMap.fitBounds(this_bounds);init_p();// init_grid_2();function init_p() {for (var i = 0; i < pointArr.length; i++) {let obj_ = pointArr[i];// 1. 获取旧图片尺寸(pointArr中保存的width/height)const oldWidth = obj_.width; // 例如 1036const oldHeight = obj_.height; // 例如 582// 3. 根据地理边界 this_bounds 计算实际的地理坐标const boundsWidth = this_bounds.getEast() - this_bounds.getWest();const boundsHeight = this_bounds.getNorth() - this_bounds.getSouth();const lng = this_bounds.getWest() + (boundsWidth / oldWidth) * obj_.x;const lat = this_bounds.getNorth() - (+boundsHeight / oldHeight) * obj_.y; // Y轴取反const DefaultIcon = L.icon({iconUrl: icon,iconAnchor: [10, 41]});// 4. 创建标记点(Leaflet的Y轴需要取反)const marker = L.marker([lat, lng], {draggable: false,title: obj_.name,icon: DefaultIcon}).addTo(that.leftMap);const popup = L.popup().setContent('加载中...');marker.bindPopup(popup);// 最新监测时间:2025-12-23 00:00:00 累计变化量X:1234.45mm 累计变化量Y:12345.567mm// .bindPopup(that.getBindPopup(obj_))marker.on('click', async function (e) {that.sendPointInfo = { ...obj_ };// Show loading messagemarker.bindPopup("<div style='width:260px;height:150px;font-size:12px' class='popup'>加载中...</div>").openPopup();try {const popupContent = `<div style='width:260px;height:150px;font-size:13px' class='popup'><div class="title">点编号:${obj_.name}</div><ul><li>sn:${obj_.sn}</li></ul></div>`;popup.setContent(popupContent);// }} catch (error) {popup.setContent('请求数据时出错');}});mark_map[obj_.point_id] = marker;}}};}}
};
</script><style lang="scss" scoped>
.leaflet-box {width: 100%;height: 800px;.map {width: 50%;height: 70%;margin: 40px;}
}
</style>
文章到此结束,希望对你有所帮助~