// import L from 'leaflet' import config from '@/utils/map/sub/config' import global from '@/utils/map/sub/global' import store from '@/store/index' import { formatTime } from "@/utils/util.js" // var interval_creatCircleMarker = null // var interval_showTrail = null var togglePlayerFlag = store.state.mapControlPlayer var toggleTooltipFlag = store.state.mapControlTooltip var toggleTrailFlag = store.state.mapControlTrail export default { playerLayerGroup: null, // 玩家标记图层组 trailLayerGroup: null, // 玩家轨迹图层组 init() { this.playerLayerGroup = new L.layerGroup() this.trailLayerGroup = new L.layerGroup() }, // 即将开始地图缩放时触发本方法 onZoomStart(e) { if (togglePlayerFlag) { this.playerLayerGroup.remove() } if (toggleTrailFlag) { this.trailLayerGroup.remove() } }, // 地图发生缩放时触发本方法 onZoom(e) {}, // 地图缩放结束时触发本方法 onZoomEnd(e) { if (toggleTrailFlag) { this.trailLayerGroup.addTo(global.map) } if (togglePlayerFlag) { this.playerLayerGroup.addTo(global.map) this.toggleTooltip(store.state.mapControlTooltip) } }, togglePlayer(flag) { if (flag != null) { togglePlayerFlag = !flag } // console.log("[togglePlayer]", togglePlayerFlag) if (togglePlayerFlag) { this.playerLayerGroup.removeFrom(global.map) } else { this.playerLayerGroup.addTo(global.map) } togglePlayerFlag = !togglePlayerFlag store.commit('setMapControlPlayer', togglePlayerFlag) }, toggleTooltip(flag) { if (flag != null) { toggleTooltipFlag = !flag } else { // if (!togglePlayerFlag) { // this.togglePlayer(true) // toggleTooltipFlag = false // } } for (let i = 0; i < global.storePlayers.length; i++) { var player = global.storePlayers[i] if (player != null && player.marker != null) { // player.marker.toggleTooltip() // let isopen = player.marker.isTooltipOpen() if (toggleTooltipFlag) { player.marker.closeTooltip() } else { player.marker.openTooltip() } } } toggleTooltipFlag = !toggleTooltipFlag store.commit('setMapControlTooltip', toggleTooltipFlag) }, toggleTrail(flag) { if (flag != null) { toggleTrailFlag = !flag } if (toggleTrailFlag) { this.trailLayerGroup.removeFrom(global.map) } else { this.trailLayerGroup.addTo(global.map) } toggleTrailFlag = !toggleTrailFlag store.commit('setMapControlTrail', toggleTrailFlag) }, drawAllPlayers() { // console.log('[drawAllPlayers]', global.players) // if (this.playerLayerGroup != null) // this.playerLayerGroup.clearLayers() for (let i = 0; i < global.players.length; i++) { this.drawOnePlayer(global.players[i].id) // this.drawOnePlayer2(global.players[i].id) } }, drawOnePlayer2(playerId, animate = true) { var that = this var player = global.getPlayerById(playerId) var player_position = global.getPlayerPositionById(playerId) var storePlayer = global.getStorePlayersById(playerId) // console.log(player, player_position) if (player == null || player_position == null) { console.warn('[drawOnePlayer2] 关键数据为空', player, player_position) return } // 首次创建 if (storePlayer == null || storePlayer.marker == null) { // 在地图上创建 marker 并存储用户信息 var playerIcon = L.icon({ iconUrl: 'static/image/marker-icon.png', iconSize: [20, 32.8], iconAnchor: [10, 30] }); var marker = L.marker([player_position.latitude, player_position.longitude], { icon: playerIcon }) .addTo(this.playerLayerGroup) // .addTo(global.map) // .bindPopup("Hello, I'm a Marker!
").openPopup(); .bindTooltip(`${player.name}`, { permanent: true, offset: [0, -30], direction: 'top', interactive: true }) marker.type = 'marker' marker.playerId = player.id // 存储用户信息 marker.animate = animate marker.on('click', function(e) { var playerId = e.target.playerId; // 获取点击的 marker 的用户信息 console.log("Selected player ID: " + playerId); that.handleFocusPlayer(playerId) }); var tooltip = marker.getTooltip() tooltip.playerId = player.id // 存储用户信息 tooltip.animate = animate tooltip.on('click', function(e) { // console.log("[Marker.Tooltip]", e) var playerId = e.target.playerId; // 获取点击的 marker 的用户信息 console.log("[Marker.Tooltip] Selected player ID: " + playerId) that.handleFocusPlayer(playerId) }) // this.playerLayerGroup.addTo(global.map) if (storePlayer == null) { storePlayer = { id: playerId, marker: marker, // 玩家标识 markerLayerGroup: this.playerLayerGroup, trail: null, // 玩家轨迹 trailData: [], // 玩家轨迹信息 interval_creatCircleMarker: null, interval_showTrail: null, } global.storePlayers.push(storePlayer) } else { storePlayer.marker = marker storePlayer.markerLayerGroup = this.playerLayerGroup } } // 非首次创建,直接移动位置 else { if (!toggleTrailFlag) { var marker = storePlayer.marker var curPoint = [player_position.latitude, player_position.longitude] // console.warn('[drawOnePlayer] 更新玩家的标记位置', storePlayer.marker, curPoint) marker.setLatLng(curPoint) } } }, // 创建动画效果函数,用于实现circleMarker的大小和透明度随时间变化 animateCircle(circle, minRadius, maxRadius, step = 1) { var radius = circle.getRadius(); var opacity = circle.options.fillOpacity; var zoomType = 'zoomIn' // zoomIn: 放大 zoomOut: 缩小 var interval_creatCircleMarker = setInterval(function() { if (!circle.animate) { clearInterval(interval_creatCircleMarker) return } // 改变圆形半径和透明度 if (zoomType == 'zoomIn') { radius = radius + step // opacity = opacity - 0.1 } else if (zoomType == 'zoomOut') { radius = radius - step // opacity = opacity - 0.1 } circle.setRadius(radius); circle.setStyle({ fillOpacity: opacity }); if (radius >= maxRadius) { zoomType = 'zoomOut' } else if (radius <= minRadius) { zoomType = 'zoomIn' } }, 50); return interval_creatCircleMarker }, getPopupContent(player) { var popupContent = '
' popupContent += '
' + ' ' + player.name + '' if (player.nextcontrolpoint.sn != '') { popupContent += '   => ' + player.nextcontrolpoint.sn + '' } popupContent += '   百味豆 ' + player.syspoint + '
' popupContent += '
打点 ' + player.effectivenum + '/' + player.totalcontrolnum + '   距离 ' + player.distance + '米   配速 ' + formatTime(player.pace, false) + '
' popupContent += '
' + '心率 ' + player.lasthr + '   平均 ' + player.avghr + '   最大 ' + player.maxhr + '
' popupContent += '
Cal ' + Math.round(player.calorie / 1000) + '   Ck ' + player.ck + '   Ei ' + Math.round(player.ei * 100) / 100 + '
' popupContent += '
' return popupContent }, drawOnePlayer(playerId, animate = true) { var that = this var player = global.getPlayerById(playerId) var player_position = global.getPlayerPositionById(playerId) var storePlayer = global.getStorePlayersById(playerId) // console.log('[drawOnePlayer]', player, player_position) if (player == null) { console.warn('[drawOnePlayer] 玩家数据为空', player) return } if (player_position == null) { // console.log('[drawOnePlayer] 玩家位置数据为空', player_position) return } var popupContent = this.getPopupContent(player) // 首次创建 if (storePlayer == null || storePlayer.marker == null) { // console.log('[drawOnePlayer] storePlayer == null', playerId) var playerColor = this.getPlayerColor(playerId) var options = config.gStyle.marker.default options.fillColor = playerColor options.stroke = config.gStyle.common.stroke options.color = config.gStyle.common.color // console.log('[drawOnePlayer] options', options) var marker = L.circleMarker([player_position.latitude, player_position.longitude], options) .addTo(this.playerLayerGroup) .bindPopup(popupContent) .bindTooltip(`${player.name}`, config.gStyle.marker.tooltip) marker.type = 'circleMarker' marker.playerId = player.id // 存储用户信息 marker.animate = animate marker.on('click', function(e) { // console.log("[Marker]", e) var playerId = e.target.playerId; // 获取点击的 marker 的用户信息 console.log("[Marker] Selected player ID: " + playerId) that.handleFocusPlayer(playerId) }) var tooltip = marker.getTooltip() tooltip.playerId = player.id // 存储用户信息 tooltip.animate = animate tooltip.on('click', function(e) { // console.log("[Marker.Tooltip]", e) var playerId = e.target.playerId; // 获取点击的 marker 的用户信息 console.log("[Marker.Tooltip] Selected player ID: " + playerId) that.handleFocusPlayer(playerId) }) var interval_creatCircleMarker = null if (animate) { interval_creatCircleMarker = this.animateCircle(marker, 5, 10, 0.5) } // this.playerLayerGroup.addTo(global.map) if (storePlayer == null) { storePlayer = { id: playerId, marker: marker, // 玩家标识 markerLayerGroup: this.playerLayerGroup, trail: null, // 玩家轨迹 外层描边轨迹 trail2: null, // 玩家轨迹 内层填充轨迹 trailLayerGroup: null, trailData: [], // 玩家轨迹信息 interval_creatCircleMarker: interval_creatCircleMarker, interval_showTrail: null, } global.storePlayers.push(storePlayer) } else { storePlayer.marker = marker storePlayer.markerLayerGroup = this.playerLayerGroup storePlayer.interval_creatCircleMarker = interval_creatCircleMarker } } // 非首次创建,直接移动位置 else { if (!toggleTrailFlag) { var marker = storePlayer.marker var curPoint = [player_position.latitude, player_position.longitude] // console.log('[drawOnePlayer] 更新玩家的标记位置', storePlayer.marker, curPoint) marker.setLatLng(curPoint) marker.bringToFront() marker.setPopupContent(popupContent) } } }, handleFocusPlayer(playerId) { console.log("[handleFocusPlayer] 当前选中玩家ID: " + playerId) if (global.focusPlayerId > 0) { // 先把之前选中的目标恢复成默认状态 var unfocusPlayer = global.getStorePlayersById(global.focusPlayerId) // console.log("unfocusPlayer", unfocusPlayer) var playerColor = this.getPlayerColor(global.focusPlayerId) if (unfocusPlayer != null && unfocusPlayer.marker != null && unfocusPlayer.marker.type == 'circleMarker') { var options = config.gStyle.marker.default options.fillColor = playerColor unfocusPlayer.marker.setStyle(options) } if (unfocusPlayer != null && unfocusPlayer.trail != null) { var options = config.gStyle.trail.default options.color = playerColor unfocusPlayer.trail2.setStyle(options) } } global.focusPlayerId = playerId global.getCaller().focusPlayerId = playerId var focusPlayer = global.getStorePlayersById(global.focusPlayerId) // console.log("focusPlayer", focusPlayer) if (focusPlayer != null && focusPlayer.trail != null) { var options = config.gStyle.trail.focus focusPlayer.trail2.setStyle(options) focusPlayer.trail.bringToFront() focusPlayer.trail2.bringToFront() } if (focusPlayer != null && focusPlayer.marker != null && focusPlayer.marker.type == 'circleMarker') { var options = config.gStyle.marker.focus options.stroke = config.gStyle.common.stroke options.color = config.gStyle.common.color focusPlayer.marker.setStyle(options) focusPlayer.marker.openPopup() focusPlayer.marker.bringToFront() } }, drawAllTrails(duration) { // if (this.trailLayerGroup != null) // this.trailLayerGroup.clearLayers() for (let i = 0; i < global.players.length; i++) { this.drawOneTrail(global.players[i].id, duration) } }, // 显示运动轨迹 duration:毫秒 drawOneTrail(playerId, duration) { var player = global.getPlayerById(playerId) var player_position = global.getPlayerPositionById(playerId) var storePlayer = global.getStorePlayersById(playerId) // console.log('[drawOneTrail] param', player, player_position, storePlayer) if (player == null) { console.warn('[drawOneTrail] 玩家数据为空', player) return } if (player_position == null) { // console.log('[drawOneTrail] 玩家位置数据为空', player_position) return } if (storePlayer == null || storePlayer.trail == null) { // console.warn('[drawOneTrail] 轨迹数据为空', player, storePlayer) var trail = null var trail2 = null var curPoint = [player_position.latitude, player_position.longitude, new Date()] // console.log('[drawOneTrail] curPoint', curPoint) var trailData = null var options = config.gStyle.trail.default // 获取Vuex中暂存的用户数据,用于页面重载后的数据恢复 var holdPlayerData = global.fetchPlayersDataById(playerId) // console.warn("[drawOneTrail] holdPlayerData", holdPlayerData) if (holdPlayerData != null && holdPlayerData.trailData != null && holdPlayerData.trailData.length > 0) { // console.warn("[drawOneTrail] 加载暂存轨迹数据", holdPlayerData.trailData) // concat方法连接a、b两个数组后,a、b两个数组的数据不变,同时会返回一个新的数组 trailData = holdPlayerData.trailData.concat([curPoint]) // console.warn("[drawOneTrail] 轨迹数据", trailData) } else { trailData = [curPoint] } // 外层描边轨迹 if (config.gStyle.common.stroke) { options.weight = 6.9 } else { options.weight = 0 } options.color = config.gStyle.common.color trail = L.polyline(trailData, options) .addTo(this.trailLayerGroup) // console.log('[drawOneTrail] trail', trail) // 内层填充轨迹 var playerColor = this.getPlayerColor(playerId) options.weight = 3.9 options.color = playerColor // options.fillColor = playerColor trail2 = L.polyline(trailData, options) .addTo(this.trailLayerGroup) if (storePlayer == null) { storePlayer = { id: playerId, marker: null, // 玩家标识 markerLayerGroup: null, trail: trail, // 玩家轨迹 外层描边轨迹 trail2: trail2, // 玩家轨迹 内层填充轨迹 trailLayerGroup: this.trailLayerGroup, trailData: trailData, // 玩家轨迹信息 interval_creatCircleMarker: null, interval_showTrail: null, } global.storePlayers.push(storePlayer) } else { storePlayer.trail = trail storePlayer.trail2 = trail2 storePlayer.trailLayerGroup = this.trailLayerGroup storePlayer.trailData = trailData } var that = this var interval_showTrail = setInterval(function() { player = global.getPlayerById(playerId) if (player == null) { console.warn('[drawOneTrail] 玩家数据为空 (已完赛或已退赛)', player) clearInterval(interval_showTrail) storePlayer.interval_showTrail = null return } // 去除过期的历史轨迹 if (duration > 0) { var now = new Date() storePlayer.trailData = storePlayer.trailData.filter(function(point) { return (now - point[2]) < duration }); } player_position = global.getPlayerPositionById(playerId) if (player_position == null || player_position.latitude == null || player_position.longitude == null) { console.warn('[drawOneTrail] 玩家位置信息为空 playerId:' + playerId) return } curPoint = [player_position.latitude, player_position.longitude, new Date()] storePlayer.trailData.push(curPoint) // storePlayer.trailData.push(curPoint.slice(0, 2)) if (toggleTrailFlag) { // console.log('interval_showTrail', storePlayer.trailData) trail.setLatLngs(storePlayer.trailData); trail2.setLatLngs(storePlayer.trailData); if (storePlayer.marker != null) { if (toggleTrailFlag) { // console.warn('[drawOneTrail] 更新玩家的标记位置', storePlayer.marker, curPoint) storePlayer.marker.setLatLng(curPoint.slice(0, 2)) // 更新玩家的标记位置 storePlayer.marker.bringToFront() var popupContent = that.getPopupContent(player) storePlayer.marker.setPopupContent(popupContent) } } // global.map.setView(point.slice(0, 2), 18); //地图中心跟踪最新位置 } }, 500); storePlayer.interval_showTrail = interval_showTrail } else { // console.log('[drawOneTrail] 更新玩家轨迹', storePlayer, storePlayer.trail) } }, getPlayerColor(playerId) { var colorIndex = playerId % 10 return config.playerColorList[colorIndex] }, // // duration: 轨迹保存时间 为0表示保存全部轨迹 // getCurPos(lastpos, duration, player_trail) { // // console.log(lastpos, pointsT) // var now = +new Date(); // if (duration > 0) { // player_trail.points = player_trail.points.filter(function(point) { // return now - point[2] < duration; // }); // } // var step = 0.00001 // var t = 10 // var point = null // if (player_trail.pointsT < 20 * t) // point = [lastpos[0] + Math.random() * step, lastpos[1] + Math.random() * step, now]; // else if (player_trail.pointsT >= 20 * t && player_trail.pointsT < 40 * t) // point = [lastpos[0] - Math.random() * step, lastpos[1] + Math.random() * step, now]; // else if (player_trail.pointsT >= 40 * t && player_trail.pointsT < 60 * t) // point = [lastpos[0] - Math.random() * step, lastpos[1] - Math.random() * step, now]; // else if (player_trail.pointsT >= 60 * t && player_trail.pointsT < 80 * t) // point = [lastpos[0] + Math.random() * step, lastpos[1] - Math.random() * step, now]; // // point = [point[0] - Math.random() * 0.00001, point[1] - Math.random() * 0.00001, now]; // player_trail.pointsT++ // if (player_trail.pointsT >= 80 * t) // player_trail.pointsT = 0 // player_trail.points.push(point); // return point // }, free() { for (let i = 0; i < global.storePlayers.length; i++) { var storePlayer = global.storePlayers[i] if (storePlayer.interval_creatCircleMarker != null) { clearInterval(storePlayer.interval_creatCircleMarker) } if (storePlayer.interval_creatCircleMarker != null) { clearInterval(storePlayer.interval_showTrail) } } } }