需求:在圖片上標點了,需要根據標記點在圖片上進行回顯功能,并且不會根據窗口大小導致標記點移位
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>
文章到此結束,希望對你有所幫助~