Commit 48d35bd1 authored by 高晓帆's avatar 高晓帆

fix

parent 0152b21d
{
"SERVICE_IP": "172.16.0.118:1234",
"MAP_CENTER": [39.74441007068,111.24544532751],
"version": "1.1.4"
}
\ No newline at end of file
{
"SERVICE_IP": "172.16.0.118:1234",
"MAP_CENTER": [39.74441007068,111.24544532751],
"version": "1.1.4"
}
\ No newline at end of file
/**
* 关于deck.gl的二次封装,由于很多功能使用起来不方便,因此进行二次封装
* gaoxf
*/
import { Deck } from '@deck.gl/core';
import { GeoJsonLayer } from '@deck.gl/layers';
import {ScenegraphLayer} from '@deck.gl/mesh-layers';
export default class DeckNew{
constructor(props){
this.deck=new Deck({...props,_animation:true})
this.initProps={initialViewState:props.initialViewState};
this.mapLayers=[];
this.markerLayers=[];
this.createGeoJsonLayer=this.createGeoJsonLayer.bind(this);
}
createGeoJsonLayer(result,attribute,layerName){
let layer = new GeoJsonLayer({
id: layerName,
data: this.convert(result),
stroked: true,
filled: true,
extruded: false,
wireframe: true,
getElevation: 0,
pickable: true,
...attribute,
});
this.removeLayer('map',layerName)
this.mapLayers.push(layer)
this.layerSort()
this.deck.setProps({
layers:[...this.markerLayers,...this.mapLayers]
})
}
createCarModel(data,layerName){
const layer = new ScenegraphLayer({
id: layerName,
data,
pickable: true,
scenegraph: 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BoxAnimated/glTF-Binary/BoxAnimated.glb',
getPosition: d => d.coordinates,
// getOrientation: d => [0, Math.random() * 180, 90],
// _animations: {
// '*': {speed: 5}
// },
sizeScale: 10,
_lighting: 'pbr',
getTranslation:[0,0,5],
getOrientation:f=>{
// console.log(f)
return [0,f.rotate*180/Math.PI,0]
}
});
this.removeLayer('marker',layerName)
this.markerLayers.push(layer)
this.deck.setProps({
layers:[...this.markerLayers,...this.mapLayers]
})
}
setRotation(rotate){
this.initProps.viewState.bearing=rotate;
this.deck.setProps({...this.initProps})
}
flyTo(coor){
this.initProps.initialViewState.longitude=coor[0];
this.initProps.initialViewState.latitude=coor[1];
this.initProps.initialViewState.zoom=18
this.deck.setProps({initialViewState:{latitude: document.location.mapCenter[0],
longitude: document.location.mapCenter[1],
zoom: 18,
maxZoom: 20,
pitch: 0,
bearing: 0}})
}
//根据页面中图层的顺序排序
layerSort() {
//图层的顺序
let obj = ['lane','centerLine','electronicFence','obstacles','staticobjs','dumparea','parkspot','barricade', 'diggingworkarea', 'runablearea']
let newArray = []
obj.forEach(item => {
this.mapLayers.forEach(m => {
if(item==m.id){
newArray.push(m)
}
})
})
this.mapLayers=newArray.reverse();
}
//根据图层名字从图层数组中移除对应图层
removeLayer(type,layerName){
if(type=='marker'){
this.markerLayers.forEach((item,index)=>{
if(item.id==layerName){
this.markerLayers.splice(index,1)
}
})
}else{
this.mapLayers.forEach((item,index)=>{
if(item.id==layerName){
this.mapLayers.splice(index,1)
}
})
}
}
remove(){
this.deck.setProps({
layers:[]
})
}
convert(obj) {
let { features } = obj;
for (let i = 0; i < features.length; i++) {
let { geometry } = features[i];
let { coordinates, type } = geometry;
for (let j = 0; j < coordinates.length; j++) {
if (type == "Polygon") {
for (let k = 0; k < coordinates[j].length; k++) {
if (coordinates[j][k].length > 2) {
coordinates[j][k] = coordinates[j][k].slice(0, 2)
}
}
} else {
if (coordinates[j].length > 2) {
coordinates[j] = coordinates[j].slice(0, 2)
}
}
}
}
return obj
}
convertColor(color,opacity) {
if(color.indexOf('rgba')>-1){
let colors=color.replace('rgba','').replace('(','').replace(')','').split(',').map(m=>parseInt(m))
return [...colors.slice(0,3),opacity?opacity*225:225]
}
return [...color.match(/[0-9a-f]{2}/g).map(x => parseInt(x, 16)),opacity?opacity*225:225]
}
}
/**
* 关于deck.gl的二次封装,由于很多功能使用起来不方便,因此进行二次封装
* gaoxf
*/
import { Deck } from '@deck.gl/core';
import { GeoJsonLayer } from '@deck.gl/layers';
import {ScenegraphLayer} from '@deck.gl/mesh-layers';
export default class DeckNew{
constructor(props){
this.deck=new Deck({...props,_animation:true})
this.initProps={initialViewState:props.initialViewState};
this.mapLayers=[];
this.markerLayers=[];
this.createGeoJsonLayer=this.createGeoJsonLayer.bind(this);
}
createGeoJsonLayer(result,attribute,layerName){
let layer = new GeoJsonLayer({
id: layerName,
data: this.convert(result),
stroked: true,
filled: true,
extruded: false,
wireframe: true,
getElevation: 0,
pickable: true,
...attribute,
});
this.removeLayer('map',layerName)
this.mapLayers.push(layer)
this.layerSort()
this.deck.setProps({
layers:[...this.markerLayers,...this.mapLayers]
})
}
createCarModel(data,layerName){
const layer = new ScenegraphLayer({
id: layerName,
data,
pickable: true,
scenegraph: 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BoxAnimated/glTF-Binary/BoxAnimated.glb',
getPosition: d => d.coordinates,
// getOrientation: d => [0, Math.random() * 180, 90],
// _animations: {
// '*': {speed: 5}
// },
sizeScale: 10,
_lighting: 'pbr',
getTranslation:[0,0,5],
getOrientation:f=>{
// console.log(f)
return [0,f.rotate*180/Math.PI,0]
}
});
this.removeLayer('marker',layerName)
this.markerLayers.push(layer)
this.deck.setProps({
layers:[...this.markerLayers,...this.mapLayers]
})
}
setRotation(rotate){
this.initProps.viewState.bearing=rotate;
this.deck.setProps({...this.initProps})
}
flyTo(coor){
this.initProps.initialViewState.longitude=coor[0];
this.initProps.initialViewState.latitude=coor[1];
this.initProps.initialViewState.zoom=18
this.deck.setProps({initialViewState:{latitude: document.location.mapCenter[0],
longitude: document.location.mapCenter[1],
zoom: 18,
maxZoom: 20,
pitch: 0,
bearing: 0}})
}
//根据页面中图层的顺序排序
layerSort() {
//图层的顺序
let obj = ['lane','centerLine','electronicFence','obstacles','staticobjs','dumparea','parkspot','barricade', 'diggingworkarea', 'runablearea']
let newArray = []
obj.forEach(item => {
this.mapLayers.forEach(m => {
if(item==m.id){
newArray.push(m)
}
})
})
this.mapLayers=newArray.reverse();
}
//根据图层名字从图层数组中移除对应图层
removeLayer(type,layerName){
if(type=='marker'){
this.markerLayers.forEach((item,index)=>{
if(item.id==layerName){
this.markerLayers.splice(index,1)
}
})
}else{
this.mapLayers.forEach((item,index)=>{
if(item.id==layerName){
this.mapLayers.splice(index,1)
}
})
}
}
remove(){
this.deck.setProps({
layers:[]
})
}
convert(obj) {
let { features } = obj;
for (let i = 0; i < features.length; i++) {
let { geometry } = features[i];
let { coordinates, type } = geometry;
for (let j = 0; j < coordinates.length; j++) {
if (type == "Polygon") {
for (let k = 0; k < coordinates[j].length; k++) {
if (coordinates[j][k].length > 2) {
coordinates[j][k] = coordinates[j][k].slice(0, 2)
}
}
} else {
if (coordinates[j].length > 2) {
coordinates[j] = coordinates[j].slice(0, 2)
}
}
}
}
return obj
}
convertColor(color,opacity) {
if(color.indexOf('rgba')>-1){
let colors=color.replace('rgba','').replace('(','').replace(')','').split(',').map(m=>parseInt(m))
return [...colors.slice(0,3),opacity?opacity*225:225]
}
return [...color.match(/[0-9a-f]{2}/g).map(x => parseInt(x, 16)),opacity?opacity*225:225]
}
}
<template>
<div class="map-contain">
<div id="map" ref="root"></div>
<img src="/image/compass.png" class="compass" ref="compass" :style="`transform: rotateZ(${compassRotationAngle}rad)`" alt="" @click="changeCompass">
<div class="navigate-preview">
<img src="/image/navigate.png" class="navigate" @click="changeNavigate" alt="" />
</div>
</div>
</template>
<script setup>
import { markRaw, onMounted, watch, ref, computed, onBeforeUnmount, nextTick } from 'vue'
import { useMapStore } from '@/store/MapStore.js'
import { useVehicleStore } from '@/store/VehicleStore'
import { storeToRefs } from 'pinia'
import { vehicleScale } from '../js/tools'
import L from 'leaflet'
import 'leaflet-rotate'
import '@/tools/Leaflet.LayerGroup.Collision'
import * as turf from '@turf/turf'
const safe_color = '#FFA500'
const BASE_RAD = 1.5707963267948966
const MAP_ZOOM = 18
const LAYER_PROPOITY = {
runablearea: 1,
staticobjs: 2,
diggingarea: 3,
diggingworkarea: 3,
dumparea: 4,
barricade: 5,
electronicFence: 6,
wetArea: 7,
lane: 8,
obstacles: 9,
stationarea: 10,
parkspot: 11,
lanenode: 12,
currPathinfo: 13,
nextPathinfo: 14,
avoidancePath: 15,
traj: 16,
obstacle: 17
}
const vehicles = {}
let ismousedown = false
let ismousemove = false
let resetTime = null
let obstaclePolygons = []
let dynamicPaths=[]
const reNavigateTime = 10 * 1000
const props = defineProps({
isShowBasic: Boolean,
clearSinglePointEnable: Boolean,
reloadData: Boolean
})
let map = markRaw({})
let currentPosition = markRaw([])
const root = ref(null)
const mapLayers = markRaw({})
const safeObjects = markRaw({})
const safeTrajs = markRaw({})
const singlePaths = markRaw([])
const navigate = ref(true)
const currentRotation = ref(0)
const markerLayerGroupLists = markRaw({})
const isSinglePreview = ref(false)
const compassRotationAngle = ref(0)
const compass = ref(null)
const mapStore = useMapStore()
const mapStoreToRefs = storeToRefs(mapStore)
const {
lanenode,
lane,
runablearea,
centerline,
obstacles,
diggingworkarea,
dumparea,
barricade,
stationarea,
parkspot,
staticobjs,
electronicFence,
morepoint, // 单机循迹单路径
morepath, // 单机循迹多路径
nextPathinfo,
currPathinfo,
nextPathAvailable,
avoidancePath, // 绕障路径
obstacleData,
dynamicPathinfo, // 车辆动态路权信息
} = mapStoreToRefs
const vehicleStore = useVehicleStore()
const vehicleStoreToRefs = storeToRefs(vehicleStore)
const { vehiclesPositioninfo, safeObj, trajObj, paraminfo, deleteVehicles } = vehicleStoreToRefs
const deviceId = computed(() => {
return paraminfo.value.deviceId
})
const emits = defineEmits(['handleSend'])
onMounted(() => {
map = L.map(root.value, {
center: document.location.mapCenter,
zoom: 14,
zoomControl: false,
minZoom: 10,
maxZoom: 21,
rotate: true,
touchRotate: true
})
map.on('zoomend', () => {
let zoom = map.getZoom()
let { iconSize, iconAnchor } = vehicleScale(zoom)
for (let vehicle in vehicles) {
let icon = vehicles[vehicle].getIcon()
let { iconUrl } = icon.options
let newIcon = L.icon({
iconUrl,
iconSize,
iconAnchor
})
vehicles[vehicle].setIcon(newIcon)
}
})
let mapDom = root.value
mapDom.addEventListener('mousedown', () => {
changeMouseDown()
})
mapDom.addEventListener('mousemove', (evt) => {
changeMouseMove()
})
mapDom.addEventListener('mouseup', (evt) => {
changeMouseUp()
})
emits('handleSend', {
type: 'syncMapVersion',
msg: {}
})
})
function changeNavigate() {
navigate.value = true
dealMapRotate(currentRotation.value, currentPosition, map.getZoom())
}
// 指南针
function changeCompass() {
dealVehicleRotate(0)
currentRotation.value = BASE_RAD
if (navigate.value) {
setTimeout(() => {
dealVehicleRotate()
}, 3 * 1000)
}
}
function changeMouseDown() {
ismousedown = true
}
function changeMouseMove() {
if (ismousedown) {
ismousemove = true
if (resetTime) {
window.clearTimeout(resetTime)
resetTime = null
}
}
}
function changeMouseUp() {
if (!currentPosition) return
if (ismousedown && ismousemove) {
navigate.value = false
resetTime = window.setTimeout(() => {
if (!navigate.value) {
navigate.value = true
dealVehicleRotate()
currentRotation.value = BASE_RAD
}
}, reNavigateTime)
ismousedown = false
ismousemove = false
}
}
function dealVehicleRotate(rotate) {
let keys = Object.keys(vehicles)
let target = keys.find(item => item === deviceId.value)
let currentTarget = vehicles[target]
let vehicleHeading = BASE_RAD
let currentOldHeading = currentTarget && currentTarget.options.vehicleHeading
if (typeof rotate === 'number') {
dealMapRotate(0, currentPosition, map.getZoom())
currentTarget.setRotation(-currentOldHeading + vehicleHeading)
} else {
vehicleHeading = currentOldHeading
currentRotation.value = vehicleHeading
dealMapRotate(vehicleHeading, currentPosition, map.getZoom())
currentTarget.setRotation(0)
}
for (let key in vehicles) {
if (key !== deviceId.value) {
let oldHeading = vehicles[key].options['vehicleHeading']
vehicles[key].setRotation(-oldHeading + vehicleHeading)
}
}
}
function dealMapLayer(value, color, layerName) {
if (!value || !map) return
let result = JSON.parse(value)
if (!result) return
if (mapLayers[layerName]) {
map.removeLayer(mapLayers[layerName])
delete mapLayers[layerName]
}
let layer = L.geoJSON(result, {
style: function (feature) {
if(layerName === 'barricade'){
return {
color: '#0066ff',
opacity: 1,
width:5
}
}else{
return {
color: layerName === 'lane' ? '#eee' : feature.properties.color,
opacity: layerName === 'lane' ? .5 : 1,
fillColor: layerName === 'electronicFence'
? feature.properties.color
: color ? color : feature.properties.color,
fillOpacity: layerName === 'runablearea' ? .5 : .7
}
}
},
})
mapLayers[layerName] = layer.addTo(map)
let bottomLayerOne = mapLayers['diggingworkarea']
let bottomLayerTwo = mapLayers['runablearea']
let bottomLayerThree = mapLayers['barricade']
bottomLayerThree && bottomLayerThree.bringToFront()
bottomLayerOne && bottomLayerOne.bringToBack()
bottomLayerTwo && bottomLayerTwo.bringToBack()
mapStore.setData(layerName, null)
}
function dealMapPath(value, layerName, color) {
if (mapLayers[layerName]) {
map.removeLayer(mapLayers[layerName])
delete mapLayers[layerName]
}
if (mapLayers[`${layerName}Buffer`]) {
map.removeLayer(mapLayers[`${layerName}Buffer`])
delete mapLayers[`${layerName}Buffer`]
}
if (value && value.length) {
let data = JSON.parse(JSON.stringify(value))
let path = L.polyline(data, {
color: '#ffff00',
opacity: 1,
className: 'middle-line',
fillColor: '#ffff00',
fillOpacity: 1,
}).addTo(map)
mapLayers[layerName] = path
let bufferLine = turf.buffer(path.toGeoJSON(), 6.5, { units: "meters" })
mapLayers[`${layerName}Buffer`] = L.geoJSON(bufferLine, {
style: function () { return { color, fillOpacity: .6 } },
}).addTo(map)
mapLayers[`${layerName}Buffer`].bringToFront()
}
}
function deleteMarker(features, layerName) {
Object.keys(markerLayerGroupLists).forEach(item => {
if(item.includes(layerName)){
map.removeLayer(markerLayerGroupLists[item])
}
})
let marker = Object.keys(markerLayerGroupLists).filter(item => item.includes(layerName))
for (let i = 0; i < marker.length; i++) {
let item = marker[i]
let isIn = features.find(f => `${layerName}${f.properties.id}` === item)
if (isIn) continue
if (item.includes('point')) continue
let id = item.replace(`${layerName}`, '')
let icon = L.divIcon({
html: `<span class="icon-node-name"></span>`,
className: 'icon-node',
})
markerLayerGroupLists[`${layerName}${id}`].setIcon(icon)
}
}
function dealDivIcon(value, layerName) {
if (!value || !map) return
let result = JSON.parse(value)
if (!result) return
const { features } = result
deleteMarker(features, layerName)
let markerLayerGroup = L.LayerGroup.collision({ margin: 5 })
for (let i = 0; i < features.length; i++) {
let feature = features[i]
let { name, id } = feature.properties
let { coordinates } = feature.geometry
let markerCoor = null
if (layerName === 'lanenode') {
markerCoor = [coordinates[1], coordinates[0]]
} else {
let center = turf.center(feature)
markerCoor = [center.geometry.coordinates[1], center.geometry.coordinates[0]]
}
let icon = L.divIcon({
html: `<span class="icon-node-name">${name}</span>`,
className: 'icon-node',
})
if (markerLayerGroupLists[`${layerName}${id}`]) {
markerLayerGroupLists[`${layerName}${id}`].setIcon(icon)
} else {
let nameMarker = L.marker(markerCoor, { icon, zIndexOffset: -100 })
markerLayerGroup.addLayer(nameMarker)
markerLayerGroupLists[`${layerName}${id}`] = nameMarker
}
markerLayerGroupLists[`${layerName}${id}point`] = L.marker(markerCoor, {
icon: L.icon({
iconUrl: '/image/bluePoint.png',
iconSize: [12, 12],
iconAnchor: [6, 6],
}),
zIndexOffset: -100,
}).addTo(map)
}
markerLayerGroup.addTo(map)
mapStore.setData(layerName, null)
}
function removeLayer(obj, vehicleID) {
if (obj[vehicleID]) {
for (let item in obj[vehicleID]) {
map.removeLayer(obj[vehicleID][item])
}
}
}
function adjustmentLayer() {
mapLayers['currentPath'] && mapLayers['currentPath'].bringToFront()
mapLayers['nextPath'] && mapLayers['nextPath'].bringToFront()
for (let key in safeObjects) {
let safeLayer = safeObjects[key]
for (let lkey in safeLayer) {
lkey && safeLayer[lkey].bringToFront()
}
}
for (let key in safeTrajs) {
safeTrajs[key] && safeTrajs[key]['pathBuffer'] && safeTrajs[key]['pathBuffer'].bringToFront()
}
}
function dealSafe(vehicleID, safe) {
if (!map) return
const { enable, data, dealedData, vehicleType, vehicleLatitude, vehicleLongtitude } = safe
removeLayer(safeObjects, vehicleID)
safeObjects[vehicleID] = {}
if (!enable) return
let safeType = [1, 20, 21].includes(vehicleType) ? 'circle' : 'rectangle'
let zIndex = 16
for (let i = 0; i < dealedData.length; i++) {
let item = JSON.parse(JSON.stringify(dealedData[i]))
let layer = safeType === 'rectangle' ? L.polygon(item, { color: safe_color, weight: 1 }) : L.circle([vehicleLatitude, vehicleLongtitude], { radius: data[i], color: safe_color })
safeObjects[vehicleID][i] = layer.addTo(map)
safeObjects[vehicleID][i].bringToFront()
}
}
function dealTraj(vehicleID, traj) {
if (!traj || !map) return
const { trajPathWid, radius, dealedData, vehicleType, vehicleLatitude, vehicleLongtitude } = traj
removeLayer(safeTrajs, vehicleID)
safeTrajs[vehicleID] = {}
// if (!dealedData) return
// if ((dealedData && !dealedData.length) || !radius)) return
if([1, 20, 21].includes(vehicleType && !radius)) return;
const zIndex = LAYER_PROPOITY['traj']
if ([1, 20, 21].includes(vehicleType) && radius) {
let layer = L.circle([vehicleLatitude, vehicleLongtitude], { radius, color: '#FFA500' })
safeTrajs[vehicleID]['circle'] = layer.addTo(map)
safeTrajs[vehicleID]['circle'].bringToFront()
} else {
if(dealedData && !dealedData.length) return;
let path = L.polyline(JSON.parse(JSON.stringify(dealedData)), {})
safeTrajs[vehicleID]['path'] = path
let bufferLine = turf.buffer(path.toGeoJSON(), trajPathWid / 2, { units: "meters" })
let layer = L.geoJSON(bufferLine, {
style: function () {
return {
color: safe_color,
fillOpacity: .4
}
},
})
safeTrajs[vehicleID]['pathBuffer'] = layer.addTo(map)
safeTrajs[vehicleID]['pathBuffer'].bringToFront()
}
}
function rotateVehicles(vehicleHeading) {
for (let key in vehicles) {
if (key !== deviceId.value) {
let oldHeading = vehicles[key].options['vehicleHeading']
vehicles[key].setRotation(-oldHeading + vehicleHeading)
}
}
}
function dealMapRotate(rotationAngle, center, zoom) {
let rotate = 0
if (rotationAngle) {
rotate = turf.radiansToDegrees(rotationAngle - BASE_RAD)
}
if (compass.value) {
compassRotationAngle.value = rotationAngle
map.setBearing(rotate)
}
center && center.length && map.flyTo(center, zoom, {animate: false})
}
function dealVehiclePosition(value) {
if (!map || !value.length) return
let zoom = map.getZoom()
let { iconSize, iconAnchor } = vehicleScale(zoom)
for (let i = 0; i < value.length; i++) {
const item = value[i]
const { vehicleLatitude, vehicleLongtitude, vehicleHeading, vehicleID, image } = item
let vehiclePosition = [vehicleLatitude, vehicleLongtitude]
if (vehicles[vehicleID]) {
let beforeIconUrl = vehicles[vehicleID].getIcon().options
? vehicles[vehicleID].getIcon().options.iconUrl
: vehicles[vehicleID].getIcon().iconUrl
if (!beforeIconUrl.includes(image)) {
let newIcon = L.icon({
iconUrl: `/image/${image}.png`,
iconSize,
iconAnchor
})
vehicles[vehicleID].setIcon(newIcon)
}
vehicles[vehicleID].setLatLng(vehiclePosition)
} else {
let icon = L.icon({
iconUrl: `/image/${image}.png`,
iconSize,
iconAnchor,
})
vehicles[vehicleID] = L.marker(vehiclePosition, {
icon: icon,
draggable: false,
rotationOrigin: 'center',
rotationAngle: 0,
zIndexOffset: 999
}).addTo(map)
vehicles[vehicleID].bindTooltip(`${vehicleID}`, {
permanent: true,
direction: 'center',
}).openTooltip()
}
vehicles[vehicleID].options = Object.assign({}, vehicles[vehicleID].options, {
vehicleHeading,
vehicleLongtitude,
vehicleLatitude
})
if (vehicleID === deviceId.value) {
currentPosition = vehiclePosition
if (navigate.value) {
if (vehicleHeading !== currentRotation.value) {
rotateVehicles(vehicleHeading)
}
currentRotation.value = vehicleHeading
dealMapRotate(vehicleHeading, vehiclePosition, zoom <= MAP_ZOOM ? MAP_ZOOM : zoom)
vehicles[vehicleID].setRotation(0)
} else {
// 再不旋转地图的情况下,需要旋转车辆本身(弧度)
vehicles[vehicleID].setRotation(-vehicleHeading + currentRotation.value)
}
} else {
// 非本车
vehicles[vehicleID].setRotation(-vehicleHeading + currentRotation.value)
}
}
}
function dealSingleDatas(datas) {
const { color, coor } = datas
let path = L.polyline(coor, {
color,
}).addTo(map)
singlePaths.push(path)
}
function dealObtacleData(value) {
if (obstaclePolygons.length) {
obstaclePolygons.forEach(item => map.removeLayer(item))
obstaclePolygons = []
}
if (value && value.length) {
for (let i = 0; i < value.length; i++) {
let obstacle = value[i]
let { typeColor, coordinate, centerLon, centerLat, centerRadius, centerColor } = obstacle
let obstaclePolygon = L.polygon(JSON.parse(JSON.stringify(coordinate)), { color: typeColor }).addTo(map)
let point = turf.point([centerLon, centerLat])
let obstacleBuffer = turf.buffer(point, centerRadius, { units: "meters" })
let obstacleCircle = L.geoJSON(obstacleBuffer, {
style: () => {
return {
color: centerColor,
fillOpacity: .5
}
}
}).addTo(map)
obstaclePolygons.push(obstacleCircle)
obstaclePolygons.push(obstaclePolygon)
}
}
}
function dealDynamicDatas(datas) {
let name='dynamicLine';
if (mapLayers[name]) {
map.removeLayer(mapLayers[name])
delete mapLayers[name]
}
// if (dynamicPaths.length) {
// dynamicPaths.forEach(item => map.removeLayer(item))
// dynamicPaths = []
// }
const { color, path } = datas
let pathNew = L.polyline(path, {
color,
opacity:0.3,
weight:30,
}).addTo(map)
mapLayers[name] = pathNew
mapLayers[name].bringToFront()
// dynamicPaths.push(pathNew)
}
// 直接监听props.isShowBasic 不会触发
watch(() => props.isShowBasic, () => {
nextTick(() => {
map.invalidateSize(true)
})
})
watch(lanenode, (value) => {
dealDivIcon(value, 'lanenode', '#ff0000')
}, {immediate: true, deep: true})
watch(lane, (value) => {
dealMapLayer(value, '#fff', 'lane')
}, {immediate: true, deep: true})
watch(runablearea, (value) => {
dealMapLayer(value, '#98a0a0', 'runablearea')
}, {immediate: true, deep: true})
watch(centerline, (value) => {
dealMapLayer(value, '#eee', 'centerline')
}, {immediate: true, deep: true})
watch(obstacles, (value) => {
dealDivIcon(value, 'obstacles')
dealMapLayer(value, '#6f9bdd', 'obstacles')
}, {immediate: true, deep: true})
watch(diggingworkarea, (value) => {
dealDivIcon(value, 'diggingworkarea')
dealMapLayer(value, '#886e26', 'diggingworkarea')
}, {immediate: true, deep: true})
watch(dumparea, (value) => {
dealDivIcon(value, 'dumparea')
dealMapLayer(value, '#886e26', 'dumparea')
}, {immediate: true, deep: true})
watch(barricade, (value) => {
dealMapLayer(value, '#0000ff', 'barricade')
}, {immediate: true, deep: true})
watch(stationarea, (value) => {
dealDivIcon(value, 'stationarea')
dealMapLayer(value, '#90ee90', 'stationarea')
}, {immediate: true, deep: true})
watch(parkspot, (value) => {
dealDivIcon(value, 'parkspot')
dealMapLayer(value, '#7e8185', 'parkspot')
}, {immediate: true, deep: true})
watch(staticobjs, (value) => {
dealMapLayer(value, '#98a0a0', 'staticobjs')
}, {immediate: true, deep: true})
watch(electronicFence, (value) => {
dealDivIcon(value, 'electronicFence')
dealMapLayer(value, '#d51d20', 'electronicFence')
}, {immediate: true, deep: true})
watch(nextPathinfo, (value) => {
dealMapPath(value, 'nextPath', nextPathAvailable.value === 1 ? '#19ae19' : '#8B4513')
adjustmentLayer()
}, {immediate: true, deep: true})
watch(currPathinfo, (value) => {
dealMapPath(value, 'currentPath', '#19ae19')
adjustmentLayer()
}, {immediate: true, deep: true})
watch(avoidancePath, (value) => {
dealMapPath(value, 'avoidancePath', 'blue')
}, {immediate: true, deep: true})
watch(vehiclesPositioninfo, (value) => {
dealVehiclePosition(value)
}, {
immediate: true,
deep: true
})
watch(safeObj, (value) => {
Object.keys(value).forEach(item => {
dealSafe(item, value[item])
})
}, {
immediate: true,
deep: true
})
watch(trajObj, (value) => {
Object.keys(value).forEach(item => {
dealTraj(item, value[item])
})
}, {
immediate: true,
deep: true
})
watch(obstacleData, (value) => {
dealObtacleData(value)
}, {immediate: true, deep: true})
watch(deleteVehicles, (data) => {
if (!map) return
if (data && data.length) {
data.forEach(item => {
map.removeLayer(vehicles[item])
removeLayer(safeTrajs, item)
removeLayer(safeObjects, item)
delete vehicles[item]
})
}
}, {
immediate: true
})
watch(() => props.clearSinglePointEnable, (enable) => {
if (!enable) return
isSinglePreview.value = true
singlePaths.forEach(item => map.removeLayer(item))
}, {deep: true})
watch([morepoint, morepath], (pointData, pathData) => {
if (isSinglePreview.value && (pointData || pathData)) {
let datas = pointData.concat(pathData)
for (let i = 0; i < datas.length; i++) {
dealSingleDatas(datas[i])
}
}
}, {deep: true})
watch(dynamicPathinfo, (pathData) => {
if (pathData.length>0) {
for(let i=0;i<pathData.length;i++) {
dealDynamicDatas(pathData[i])
}
}
}, {deep: true})
watch(deviceId, (value) => {
if (value && map) {
dealMapRotate(currentRotation.value, currentPosition, map.getZoom())
}
}, {deep: true})
function doUnmount() {
Object.keys(mapLayers).map(layer => map.removeLayer(mapLayers[layer]))
let mapDom = root.value
mapDom.removeEventListener('mousedown', changeMouseDown)
mapDom.removeEventListener('mousemove', changeMouseMove)
mapDom.removeEventListener('mouseup', changeMouseUp)
map.remove()
map = null
}
watch(() => props.reloadData, (value) => {
if (value) {
doUnmount()
}
})
onBeforeUnmount(() => {
doUnmount()
})
</script>
<style lang="less" scope>
.map-contain {
height: 100%;
overflow: hidden;
}
#map {
width: 200%;
height: 200%;
top: -50%;
left: -50%;
background: #171A23;
position: relative;
}
.navigate-preview {
background: #4A75A9;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.25);
border-radius: 10px;
opacity: 1;
display: flex;
align-items: center;
justify-content: center;
}
.compass,
.navigate-preview {
position: absolute;
width: 4vw;
height: 4vw;
z-index: 999;
}
.compass {
bottom: 88px;
max-width: 60px;
max-height: 60px;
}
.navigate-preview {
bottom: 24px;
max-width: 60px;
max-height: 60px;
}
</style>
<style lang="less">
.icon-node {
width: 120px !important;
white-space: nowrap;
color: #676565;
// padding-left: -2em !important;
z-index: 1;
font-size: 12px !important;
font-family: "Open Sans Regular", "Arial Unicode MS Regular", sans-serif;
text-transform: uppercase;
text-align: center;
-webkit-text-stroke-display: block;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: rgba(33, 33, 33, 0.8);
}
@media screen and (min-width: 1700px) {
.icon-node {
font-size: 18px !important;
}
}
.icon-node-name {
display: inline-block;
transform: scale(.6);
padding-left: -20px !important;
}
.hide {
display: none !important;
}
.middle-line {
// 为svg设置虚线,数字越大,虚线段越长,
// 设置2个参数,参数1: 虚线的长度 参数2: 虚线和虚线之间的间隔, 如果只设置一个参数,说明两个值一样大小
stroke-dasharray: 15 20;
z-index: 999;
}
.leaflet-tooltip {
color: #fff !important;
background-color: rgba(255, 255, 255, 0) !important;
border: 0 !important;
box-shadow: rgba(0, 0, 0, 0);
font-size: 12px !important;
}
.leaflet-control-attribution {
display: none !important;
}</style>
\ No newline at end of file
<template>
<div class="map-contain">
<div id="map" ref="root"></div>
<img src="/image/compass.png" class="compass" ref="compass" :style="`transform: rotateZ(${compassRotationAngle}rad)`" alt="" @click="changeCompass">
<div class="navigate-preview">
<img src="/image/navigate.png" class="navigate" @click="changeNavigate" alt="" />
</div>
</div>
</template>
<script setup>
import { markRaw, onMounted, watch, ref, computed, onBeforeUnmount, nextTick } from 'vue'
import { useMapStore } from '@/store/MapStore.js'
import { useVehicleStore } from '@/store/VehicleStore'
import { storeToRefs } from 'pinia'
import { vehicleScale } from '../js/tools'
import L from 'leaflet'
import 'leaflet-rotate'
import '@/tools/Leaflet.LayerGroup.Collision'
import * as turf from '@turf/turf'
const safe_color = '#FFA500'
const BASE_RAD = 1.5707963267948966
const MAP_ZOOM = 18
const LAYER_PROPOITY = {
runablearea: 1,
staticobjs: 2,
diggingarea: 3,
diggingworkarea: 3,
dumparea: 4,
barricade: 5,
electronicFence: 6,
wetArea: 7,
lane: 8,
obstacles: 9,
stationarea: 10,
parkspot: 11,
lanenode: 12,
currPathinfo: 13,
nextPathinfo: 14,
avoidancePath: 15,
traj: 16,
obstacle: 17
}
const vehicles = {}
let ismousedown = false
let ismousemove = false
let resetTime = null
let obstaclePolygons = []
let dynamicPaths=[]
const reNavigateTime = 10 * 1000
const props = defineProps({
isShowBasic: Boolean,
clearSinglePointEnable: Boolean,
reloadData: Boolean
})
let map = markRaw({})
let currentPosition = markRaw([])
const root = ref(null)
const mapLayers = markRaw({})
const safeObjects = markRaw({})
const safeTrajs = markRaw({})
const singlePaths = markRaw([])
const navigate = ref(true)
const currentRotation = ref(0)
const markerLayerGroupLists = markRaw({})
const isSinglePreview = ref(false)
const compassRotationAngle = ref(0)
const compass = ref(null)
const mapStore = useMapStore()
const mapStoreToRefs = storeToRefs(mapStore)
const {
lanenode,
lane,
runablearea,
centerline,
obstacles,
diggingworkarea,
dumparea,
barricade,
stationarea,
parkspot,
staticobjs,
electronicFence,
morepoint, // 单机循迹单路径
morepath, // 单机循迹多路径
nextPathinfo,
currPathinfo,
nextPathAvailable,
avoidancePath, // 绕障路径
obstacleData,
dynamicPathinfo, // 车辆动态路权信息
} = mapStoreToRefs
const vehicleStore = useVehicleStore()
const vehicleStoreToRefs = storeToRefs(vehicleStore)
const { vehiclesPositioninfo, safeObj, trajObj, paraminfo, deleteVehicles } = vehicleStoreToRefs
const deviceId = computed(() => {
return paraminfo.value.deviceId
})
const emits = defineEmits(['handleSend'])
onMounted(() => {
map = L.map(root.value, {
center: document.location.mapCenter,
zoom: 14,
zoomControl: false,
minZoom: 10,
maxZoom: 21,
rotate: true,
touchRotate: true
})
map.on('zoomend', () => {
let zoom = map.getZoom()
let { iconSize, iconAnchor } = vehicleScale(zoom)
for (let vehicle in vehicles) {
let icon = vehicles[vehicle].getIcon()
let { iconUrl } = icon.options
let newIcon = L.icon({
iconUrl,
iconSize,
iconAnchor
})
vehicles[vehicle].setIcon(newIcon)
}
})
let mapDom = root.value
mapDom.addEventListener('mousedown', () => {
changeMouseDown()
})
mapDom.addEventListener('mousemove', (evt) => {
changeMouseMove()
})
mapDom.addEventListener('mouseup', (evt) => {
changeMouseUp()
})
emits('handleSend', {
type: 'syncMapVersion',
msg: {}
})
})
function changeNavigate() {
navigate.value = true
dealMapRotate(currentRotation.value, currentPosition, map.getZoom())
}
// 指南针
function changeCompass() {
dealVehicleRotate(0)
currentRotation.value = BASE_RAD
if (navigate.value) {
setTimeout(() => {
dealVehicleRotate()
}, 3 * 1000)
}
}
function changeMouseDown() {
ismousedown = true
}
function changeMouseMove() {
if (ismousedown) {
ismousemove = true
if (resetTime) {
window.clearTimeout(resetTime)
resetTime = null
}
}
}
function changeMouseUp() {
if (!currentPosition) return
if (ismousedown && ismousemove) {
navigate.value = false
resetTime = window.setTimeout(() => {
if (!navigate.value) {
navigate.value = true
dealVehicleRotate()
currentRotation.value = BASE_RAD
}
}, reNavigateTime)
ismousedown = false
ismousemove = false
}
}
function dealVehicleRotate(rotate) {
let keys = Object.keys(vehicles)
let target = keys.find(item => item === deviceId.value)
let currentTarget = vehicles[target]
let vehicleHeading = BASE_RAD
let currentOldHeading = currentTarget && currentTarget.options.vehicleHeading
if (typeof rotate === 'number') {
dealMapRotate(0, currentPosition, map.getZoom())
currentTarget.setRotation(-currentOldHeading + vehicleHeading)
} else {
vehicleHeading = currentOldHeading
currentRotation.value = vehicleHeading
dealMapRotate(vehicleHeading, currentPosition, map.getZoom())
currentTarget.setRotation(0)
}
for (let key in vehicles) {
if (key !== deviceId.value) {
let oldHeading = vehicles[key].options['vehicleHeading']
vehicles[key].setRotation(-oldHeading + vehicleHeading)
}
}
}
function dealMapLayer(value, color, layerName) {
if (!value || !map) return
let result = JSON.parse(value)
if (!result) return
if (mapLayers[layerName]) {
map.removeLayer(mapLayers[layerName])
delete mapLayers[layerName]
}
let layer = L.geoJSON(result, {
style: function (feature) {
if(layerName === 'barricade'){
return {
color: '#0066ff',
opacity: 1,
width:5
}
}else{
return {
color: layerName === 'lane' ? '#eee' : feature.properties.color,
opacity: layerName === 'lane' ? .5 : 1,
fillColor: layerName === 'electronicFence'
? feature.properties.color
: color ? color : feature.properties.color,
fillOpacity: layerName === 'runablearea' ? .5 : .7
}
}
},
})
mapLayers[layerName] = layer.addTo(map)
let bottomLayerOne = mapLayers['diggingworkarea']
let bottomLayerTwo = mapLayers['runablearea']
let bottomLayerThree = mapLayers['barricade']
bottomLayerThree && bottomLayerThree.bringToFront()
bottomLayerOne && bottomLayerOne.bringToBack()
bottomLayerTwo && bottomLayerTwo.bringToBack()
mapStore.setData(layerName, null)
}
function dealMapPath(value, layerName, color) {
if (mapLayers[layerName]) {
map.removeLayer(mapLayers[layerName])
delete mapLayers[layerName]
}
if (mapLayers[`${layerName}Buffer`]) {
map.removeLayer(mapLayers[`${layerName}Buffer`])
delete mapLayers[`${layerName}Buffer`]
}
if (value && value.length) {
let data = JSON.parse(JSON.stringify(value))
let path = L.polyline(data, {
color: '#ffff00',
opacity: 1,
className: 'middle-line',
fillColor: '#ffff00',
fillOpacity: 1,
}).addTo(map)
mapLayers[layerName] = path
let bufferLine = turf.buffer(path.toGeoJSON(), 6.5, { units: "meters" })
mapLayers[`${layerName}Buffer`] = L.geoJSON(bufferLine, {
style: function () { return { color, fillOpacity: .6 } },
}).addTo(map)
mapLayers[`${layerName}Buffer`].bringToFront()
}
}
function deleteMarker(features, layerName) {
Object.keys(markerLayerGroupLists).forEach(item => {
if(item.includes(layerName)){
map.removeLayer(markerLayerGroupLists[item])
}
})
let marker = Object.keys(markerLayerGroupLists).filter(item => item.includes(layerName))
for (let i = 0; i < marker.length; i++) {
let item = marker[i]
let isIn = features.find(f => `${layerName}${f.properties.id}` === item)
if (isIn) continue
if (item.includes('point')) continue
let id = item.replace(`${layerName}`, '')
let icon = L.divIcon({
html: `<span class="icon-node-name"></span>`,
className: 'icon-node',
})
markerLayerGroupLists[`${layerName}${id}`].setIcon(icon)
}
}
function dealDivIcon(value, layerName) {
if (!value || !map) return
let result = JSON.parse(value)
if (!result) return
const { features } = result
deleteMarker(features, layerName)
let markerLayerGroup = L.LayerGroup.collision({ margin: 5 })
for (let i = 0; i < features.length; i++) {
let feature = features[i]
let { name, id } = feature.properties
let { coordinates } = feature.geometry
let markerCoor = null
if (layerName === 'lanenode') {
markerCoor = [coordinates[1], coordinates[0]]
} else {
let center = turf.center(feature)
markerCoor = [center.geometry.coordinates[1], center.geometry.coordinates[0]]
}
let icon = L.divIcon({
html: `<span class="icon-node-name">${name}</span>`,
className: 'icon-node',
})
if (markerLayerGroupLists[`${layerName}${id}`]) {
markerLayerGroupLists[`${layerName}${id}`].setIcon(icon)
} else {
let nameMarker = L.marker(markerCoor, { icon, zIndexOffset: -100 })
markerLayerGroup.addLayer(nameMarker)
markerLayerGroupLists[`${layerName}${id}`] = nameMarker
}
markerLayerGroupLists[`${layerName}${id}point`] = L.marker(markerCoor, {
icon: L.icon({
iconUrl: '/image/bluePoint.png',
iconSize: [12, 12],
iconAnchor: [6, 6],
}),
zIndexOffset: -100,
}).addTo(map)
}
markerLayerGroup.addTo(map)
mapStore.setData(layerName, null)
}
function removeLayer(obj, vehicleID) {
if (obj[vehicleID]) {
for (let item in obj[vehicleID]) {
map.removeLayer(obj[vehicleID][item])
}
}
}
function adjustmentLayer() {
mapLayers['currentPath'] && mapLayers['currentPath'].bringToFront()
mapLayers['nextPath'] && mapLayers['nextPath'].bringToFront()
for (let key in safeObjects) {
let safeLayer = safeObjects[key]
for (let lkey in safeLayer) {
lkey && safeLayer[lkey].bringToFront()
}
}
for (let key in safeTrajs) {
safeTrajs[key] && safeTrajs[key]['pathBuffer'] && safeTrajs[key]['pathBuffer'].bringToFront()
}
}
function dealSafe(vehicleID, safe) {
if (!map) return
const { enable, data, dealedData, vehicleType, vehicleLatitude, vehicleLongtitude } = safe
removeLayer(safeObjects, vehicleID)
safeObjects[vehicleID] = {}
if (!enable) return
let safeType = [1, 20, 21].includes(vehicleType) ? 'circle' : 'rectangle'
let zIndex = 16
for (let i = 0; i < dealedData.length; i++) {
let item = JSON.parse(JSON.stringify(dealedData[i]))
let layer = safeType === 'rectangle' ? L.polygon(item, { color: safe_color, weight: 1 }) : L.circle([vehicleLatitude, vehicleLongtitude], { radius: data[i], color: safe_color })
safeObjects[vehicleID][i] = layer.addTo(map)
safeObjects[vehicleID][i].bringToFront()
}
}
function dealTraj(vehicleID, traj) {
if (!traj || !map) return
const { trajPathWid, radius, dealedData, vehicleType, vehicleLatitude, vehicleLongtitude } = traj
removeLayer(safeTrajs, vehicleID)
safeTrajs[vehicleID] = {}
// if (!dealedData) return
// if ((dealedData && !dealedData.length) || !radius)) return
if([1, 20, 21].includes(vehicleType && !radius)) return;
const zIndex = LAYER_PROPOITY['traj']
if ([1, 20, 21].includes(vehicleType) && radius) {
let layer = L.circle([vehicleLatitude, vehicleLongtitude], { radius, color: '#FFA500' })
safeTrajs[vehicleID]['circle'] = layer.addTo(map)
safeTrajs[vehicleID]['circle'].bringToFront()
} else {
if(dealedData && !dealedData.length) return;
if(dealedData=='undefined') return;
let path = L.polyline(JSON.parse(JSON.stringify(dealedData)), {})
safeTrajs[vehicleID]['path'] = path
let bufferLine = turf.buffer(path.toGeoJSON(), trajPathWid / 2, { units: "meters" })
let layer = L.geoJSON(bufferLine, {
style: function () {
return {
color: safe_color,
fillOpacity: .4
}
},
})
safeTrajs[vehicleID]['pathBuffer'] = layer.addTo(map)
safeTrajs[vehicleID]['pathBuffer'].bringToFront()
}
}
function rotateVehicles(vehicleHeading) {
for (let key in vehicles) {
if (key !== deviceId.value) {
let oldHeading = vehicles[key].options['vehicleHeading']
vehicles[key].setRotation(-oldHeading + vehicleHeading)
}
}
}
function dealMapRotate(rotationAngle, center, zoom) {
let rotate = 0
if (rotationAngle) {
rotate = turf.radiansToDegrees(rotationAngle - BASE_RAD)
}
if (compass.value) {
compassRotationAngle.value = rotationAngle
map.setBearing(rotate)
}
center && center.length && map.flyTo(center, zoom, {animate: false})
}
function dealVehiclePosition(value) {
if (!map || !value.length) return
let zoom = map.getZoom()
let { iconSize, iconAnchor } = vehicleScale(zoom)
for (let i = 0; i < value.length; i++) {
const item = value[i]
const { vehicleLatitude, vehicleLongtitude, vehicleHeading, vehicleID, image } = item
let vehiclePosition = [vehicleLatitude, vehicleLongtitude]
if (vehicles[vehicleID]) {
let beforeIconUrl = vehicles[vehicleID].getIcon().options
? vehicles[vehicleID].getIcon().options.iconUrl
: vehicles[vehicleID].getIcon().iconUrl
if (!beforeIconUrl.includes(image)) {
let newIcon = L.icon({
iconUrl: `/image/${image}.png`,
iconSize,
iconAnchor
})
vehicles[vehicleID].setIcon(newIcon)
}
vehicles[vehicleID].setLatLng(vehiclePosition)
} else {
let icon = L.icon({
iconUrl: `/image/${image}.png`,
iconSize,
iconAnchor,
})
vehicles[vehicleID] = L.marker(vehiclePosition, {
icon: icon,
draggable: false,
rotationOrigin: 'center',
rotationAngle: 0,
zIndexOffset: 999
}).addTo(map)
vehicles[vehicleID].bindTooltip(`${vehicleID}`, {
permanent: true,
direction: 'center',
}).openTooltip()
}
vehicles[vehicleID].options = Object.assign({}, vehicles[vehicleID].options, {
vehicleHeading,
vehicleLongtitude,
vehicleLatitude
})
if (vehicleID === deviceId.value) {
currentPosition = vehiclePosition
if (navigate.value) {
if (vehicleHeading !== currentRotation.value) {
rotateVehicles(vehicleHeading)
}
currentRotation.value = vehicleHeading
dealMapRotate(vehicleHeading, vehiclePosition, zoom <= MAP_ZOOM ? MAP_ZOOM : zoom)
vehicles[vehicleID].setRotation(0)
} else {
// 再不旋转地图的情况下,需要旋转车辆本身(弧度)
vehicles[vehicleID].setRotation(-vehicleHeading + currentRotation.value)
}
} else {
// 非本车
vehicles[vehicleID].setRotation(-vehicleHeading + currentRotation.value)
}
}
}
function dealSingleDatas(datas) {
const { color, coor } = datas
let path = L.polyline(coor, {
color,
}).addTo(map)
singlePaths.push(path)
}
function dealObtacleData(value) {
if (obstaclePolygons.length) {
obstaclePolygons.forEach(item => map.removeLayer(item))
obstaclePolygons = []
}
if (value && value.length) {
for (let i = 0; i < value.length; i++) {
let obstacle = value[i]
let { typeColor, coordinate, centerLon, centerLat, centerRadius, centerColor } = obstacle
let obstaclePolygon = L.polygon(JSON.parse(JSON.stringify(coordinate)), { color: typeColor }).addTo(map)
let point = turf.point([centerLon, centerLat])
let obstacleBuffer = turf.buffer(point, centerRadius, { units: "meters" })
let obstacleCircle = L.geoJSON(obstacleBuffer, {
style: () => {
return {
color: centerColor,
fillOpacity: .5
}
}
}).addTo(map)
obstaclePolygons.push(obstacleCircle)
obstaclePolygons.push(obstaclePolygon)
}
}
}
function dealDynamicDatas(datas) {
let name='dynamicLine';
if (mapLayers[name]) {
map.removeLayer(mapLayers[name])
delete mapLayers[name]
}
// if (dynamicPaths.length) {
// dynamicPaths.forEach(item => map.removeLayer(item))
// dynamicPaths = []
// }
const { color, path } = datas
let pathNew = L.polyline(path, {
color,
opacity:0.3,
weight:30,
}).addTo(map)
mapLayers[name] = pathNew
mapLayers[name].bringToFront()
// dynamicPaths.push(pathNew)
}
// 直接监听props.isShowBasic 不会触发
watch(() => props.isShowBasic, () => {
nextTick(() => {
map.invalidateSize(true)
})
})
watch(lanenode, (value) => {
dealDivIcon(value, 'lanenode', '#ff0000')
}, {immediate: true, deep: true})
watch(lane, (value) => {
dealMapLayer(value, '#fff', 'lane')
}, {immediate: true, deep: true})
watch(runablearea, (value) => {
dealMapLayer(value, '#98a0a0', 'runablearea')
}, {immediate: true, deep: true})
watch(centerline, (value) => {
dealMapLayer(value, '#eee', 'centerline')
}, {immediate: true, deep: true})
watch(obstacles, (value) => {
dealDivIcon(value, 'obstacles')
dealMapLayer(value, '#6f9bdd', 'obstacles')
}, {immediate: true, deep: true})
watch(diggingworkarea, (value) => {
dealDivIcon(value, 'diggingworkarea')
dealMapLayer(value, '#886e26', 'diggingworkarea')
}, {immediate: true, deep: true})
watch(dumparea, (value) => {
dealDivIcon(value, 'dumparea')
dealMapLayer(value, '#886e26', 'dumparea')
}, {immediate: true, deep: true})
watch(barricade, (value) => {
dealMapLayer(value, '#0000ff', 'barricade')
}, {immediate: true, deep: true})
watch(stationarea, (value) => {
dealDivIcon(value, 'stationarea')
dealMapLayer(value, '#90ee90', 'stationarea')
}, {immediate: true, deep: true})
watch(parkspot, (value) => {
dealDivIcon(value, 'parkspot')
dealMapLayer(value, '#7e8185', 'parkspot')
}, {immediate: true, deep: true})
watch(staticobjs, (value) => {
dealMapLayer(value, '#98a0a0', 'staticobjs')
}, {immediate: true, deep: true})
watch(electronicFence, (value) => {
dealDivIcon(value, 'electronicFence')
dealMapLayer(value, '#d51d20', 'electronicFence')
}, {immediate: true, deep: true})
watch(nextPathinfo, (value) => {
dealMapPath(value, 'nextPath', nextPathAvailable.value === 1 ? '#19ae19' : '#8B4513')
adjustmentLayer()
}, {immediate: true, deep: true})
watch(currPathinfo, (value) => {
dealMapPath(value, 'currentPath', '#19ae19')
adjustmentLayer()
}, {immediate: true, deep: true})
watch(avoidancePath, (value) => {
dealMapPath(value, 'avoidancePath', 'blue')
}, {immediate: true, deep: true})
watch(vehiclesPositioninfo, (value) => {
dealVehiclePosition(value)
}, {
immediate: true,
deep: true
})
watch(safeObj, (value) => {
Object.keys(value).forEach(item => {
dealSafe(item, value[item])
})
}, {
immediate: true,
deep: true
})
watch(trajObj, (value) => {
Object.keys(value).forEach(item => {
dealTraj(item, value[item])
})
}, {
immediate: true,
deep: true
})
watch(obstacleData, (value) => {
dealObtacleData(value)
}, {immediate: true, deep: true})
watch(deleteVehicles, (data) => {
if (!map) return
if (data && data.length) {
data.forEach(item => {
map.removeLayer(vehicles[item])
removeLayer(safeTrajs, item)
removeLayer(safeObjects, item)
delete vehicles[item]
})
}
}, {
immediate: true
})
watch(() => props.clearSinglePointEnable, (enable) => {
if (!enable) return
isSinglePreview.value = true
singlePaths.forEach(item => map.removeLayer(item))
}, {deep: true})
watch([morepoint, morepath], (pointData, pathData) => {
if (isSinglePreview.value && (pointData || pathData)) {
let datas = pointData.concat(pathData)
for (let i = 0; i < datas.length; i++) {
dealSingleDatas(datas[i])
}
}
}, {deep: true})
watch(dynamicPathinfo, (pathData) => {
if (pathData.length>0) {
for(let i=0;i<pathData.length;i++) {
dealDynamicDatas(pathData[i])
}
}
}, {deep: true})
watch(deviceId, (value) => {
if (value && map) {
dealMapRotate(currentRotation.value, currentPosition, map.getZoom())
}
}, {deep: true})
function doUnmount() {
Object.keys(mapLayers).map(layer => map.removeLayer(mapLayers[layer]))
let mapDom = root.value
mapDom.removeEventListener('mousedown', changeMouseDown)
mapDom.removeEventListener('mousemove', changeMouseMove)
mapDom.removeEventListener('mouseup', changeMouseUp)
map.remove()
map = null
}
watch(() => props.reloadData, (value) => {
if (value) {
doUnmount()
}
})
onBeforeUnmount(() => {
doUnmount()
})
</script>
<style lang="less" scope>
.map-contain {
height: 100%;
overflow: hidden;
}
#map {
width: 200%;
height: 200%;
top: -50%;
left: -50%;
background: #171A23;
position: relative;
}
.navigate-preview {
background: #4A75A9;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.25);
border-radius: 10px;
opacity: 1;
display: flex;
align-items: center;
justify-content: center;
}
.compass,
.navigate-preview {
position: absolute;
width: 4vw;
height: 4vw;
z-index: 999;
}
.compass {
bottom: 88px;
max-width: 60px;
max-height: 60px;
}
.navigate-preview {
bottom: 24px;
max-width: 60px;
max-height: 60px;
}
</style>
<style lang="less">
.icon-node {
width: 120px !important;
white-space: nowrap;
color: #676565;
// padding-left: -2em !important;
z-index: 1;
font-size: 12px !important;
font-family: "Open Sans Regular", "Arial Unicode MS Regular", sans-serif;
text-transform: uppercase;
text-align: center;
-webkit-text-stroke-display: block;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: rgba(33, 33, 33, 0.8);
}
@media screen and (min-width: 1700px) {
.icon-node {
font-size: 18px !important;
}
}
.icon-node-name {
display: inline-block;
transform: scale(.6);
padding-left: -20px !important;
}
.hide {
display: none !important;
}
.middle-line {
// 为svg设置虚线,数字越大,虚线段越长,
// 设置2个参数,参数1: 虚线的长度 参数2: 虚线和虚线之间的间隔, 如果只设置一个参数,说明两个值一样大小
stroke-dasharray: 15 20;
z-index: 999;
}
.leaflet-tooltip {
color: #fff !important;
background-color: rgba(255, 255, 255, 0) !important;
border: 0 !important;
box-shadow: rgba(0, 0, 0, 0);
font-size: 12px !important;
}
.leaflet-control-attribution {
display: none !important;
}</style>
\ No newline at end of file
<template>
<div class="map-contain">
<div id="map" ref="root"></div>
<img src="/image/compass.png" class="compass" ref="compass" :style="`transform: rotateZ(${compassRotationAngle}rad)`" alt="" @click="changeCompass">
<div class="navigate-preview">
<img src="/image/navigate.png" class="navigate" @click="changeNavigate" alt="" />
</div>
</div>
</template>
<script setup>
import { markRaw, onMounted, watch, ref, computed, onBeforeUnmount, nextTick } from 'vue'
import { useMapStore } from '@/store/MapStore.js'
import { useVehicleStore } from '@/store/VehicleStore'
import { storeToRefs } from 'pinia'
import { vehicleScale } from '../js/tools'
import L from 'leaflet'
import 'leaflet-rotate'
import '@/tools/Leaflet.LayerGroup.Collision'
import * as turf from '@turf/turf'
const safe_color = '#FFA500'
const BASE_RAD = 1.5707963267948966
const MAP_ZOOM = 18
const LAYER_PROPOITY = {
runablearea: 1,
staticobjs: 2,
diggingarea: 3,
diggingworkarea: 3,
dumparea: 4,
barricade: 5,
electronicFence: 6,
wetArea: 7,
lane: 8,
obstacles: 9,
stationarea: 10,
parkspot: 11,
lanenode: 12,
currPathinfo: 13,
nextPathinfo: 14,
avoidancePath: 15,
traj: 16,
obstacle: 17
}
const vehicles = {}
let ismousedown = false
let ismousemove = false
let resetTime = null
let obstaclePolygons = []
let dynamicPaths=[]
const reNavigateTime = 10 * 1000
const props = defineProps({
isShowBasic: Boolean,
clearSinglePointEnable: Boolean,
reloadData: Boolean
})
let map = markRaw({})
let currentPosition = markRaw([])
const root = ref(null)
const mapLayers = markRaw({})
const safeObjects = markRaw({})
const safeTrajs = markRaw({})
const singlePaths = markRaw([])
const navigate = ref(true)
const currentRotation = ref(0)
const markerLayerGroupLists = markRaw({})
const isSinglePreview = ref(false)
const compassRotationAngle = ref(0)
const compass = ref(null)
const mapStore = useMapStore()
const mapStoreToRefs = storeToRefs(mapStore)
const {
lanenode,
lane,
runablearea,
centerline,
obstacles,
diggingworkarea,
dumparea,
barricade,
stationarea,
parkspot,
staticobjs,
electronicFence,
morepoint, // 单机循迹单路径
morepath, // 单机循迹多路径
nextPathinfo,
currPathinfo,
nextPathAvailable,
avoidancePath, // 绕障路径
obstacleData,
dynamicPathinfo, // 车辆动态路权信息
} = mapStoreToRefs
const vehicleStore = useVehicleStore()
const vehicleStoreToRefs = storeToRefs(vehicleStore)
const { vehiclesPositioninfo, safeObj, trajObj, paraminfo, deleteVehicles } = vehicleStoreToRefs
const deviceId = computed(() => {
return paraminfo.value.deviceId
})
const emits = defineEmits(['handleSend'])
onMounted(() => {
map = L.map(root.value, {
center: document.location.mapCenter,
zoom: 14,
zoomControl: false,
minZoom: 10,
maxZoom: 21,
rotate: true,
touchRotate: true
})
map.on('zoomend', () => {
let zoom = map.getZoom()
let { iconSize, iconAnchor } = vehicleScale(zoom)
for (let vehicle in vehicles) {
let icon = vehicles[vehicle].getIcon()
let { iconUrl } = icon.options
let newIcon = L.icon({
iconUrl,
iconSize,
iconAnchor
})
vehicles[vehicle].setIcon(newIcon)
}
})
let mapDom = root.value
mapDom.addEventListener('mousedown', () => {
changeMouseDown()
})
mapDom.addEventListener('mousemove', (evt) => {
changeMouseMove()
})
mapDom.addEventListener('mouseup', (evt) => {
changeMouseUp()
})
emits('handleSend', {
type: 'syncMapVersion',
msg: {}
})
})
function changeNavigate() {
navigate.value = true
dealMapRotate(currentRotation.value, currentPosition, map.getZoom())
}
// 指南针
function changeCompass() {
dealVehicleRotate(0)
currentRotation.value = BASE_RAD
if (navigate.value) {
setTimeout(() => {
dealVehicleRotate()
}, 3 * 1000)
}
}
function changeMouseDown() {
ismousedown = true
}
function changeMouseMove() {
if (ismousedown) {
ismousemove = true
if (resetTime) {
window.clearTimeout(resetTime)
resetTime = null
}
}
}
function changeMouseUp() {
if (!currentPosition) return
if (ismousedown && ismousemove) {
navigate.value = false
resetTime = window.setTimeout(() => {
if (!navigate.value) {
navigate.value = true
dealVehicleRotate()
currentRotation.value = BASE_RAD
}
}, reNavigateTime)
ismousedown = false
ismousemove = false
}
}
function dealVehicleRotate(rotate) {
let keys = Object.keys(vehicles)
let target = keys.find(item => item === deviceId.value)
let currentTarget = vehicles[target]
let vehicleHeading = BASE_RAD
let currentOldHeading = currentTarget && currentTarget.options.vehicleHeading
if (typeof rotate === 'number') {
dealMapRotate(0, currentPosition, map.getZoom())
currentTarget.setRotation(-currentOldHeading + vehicleHeading)
} else {
vehicleHeading = currentOldHeading
currentRotation.value = vehicleHeading
dealMapRotate(vehicleHeading, currentPosition, map.getZoom())
currentTarget.setRotation(0)
}
for (let key in vehicles) {
if (key !== deviceId.value) {
let oldHeading = vehicles[key].options['vehicleHeading']
vehicles[key].setRotation(-oldHeading + vehicleHeading)
}
}
}
function dealMapLayer(value, color, layerName) {
if (!value || !map) return
let result = JSON.parse(value)
if (!result) return
if (mapLayers[layerName]) {
map.removeLayer(mapLayers[layerName])
delete mapLayers[layerName]
}
let layer = L.geoJSON(result, {
style: function (feature) {
if(layerName === 'barricade'){
return {
color: '#0066ff',
opacity: 1,
width:5
}
}else{
return {
color: layerName === 'lane' ? '#eee' : feature.properties.color,
opacity: layerName === 'lane' ? .5 : 1,
fillColor: layerName === 'electronicFence'
? feature.properties.color
: color ? color : feature.properties.color,
fillOpacity: layerName === 'runablearea' ? .5 : .7
}
}
},
})
mapLayers[layerName] = layer.addTo(map)
let bottomLayerOne = mapLayers['diggingworkarea']
let bottomLayerTwo = mapLayers['runablearea']
let bottomLayerThree = mapLayers['barricade']
bottomLayerThree && bottomLayerThree.bringToFront()
bottomLayerOne && bottomLayerOne.bringToBack()
bottomLayerTwo && bottomLayerTwo.bringToBack()
mapStore.setData(layerName, null)
}
function dealMapPath(value, layerName, color) {
if (mapLayers[layerName]) {
map.removeLayer(mapLayers[layerName])
delete mapLayers[layerName]
}
if (mapLayers[`${layerName}Buffer`]) {
map.removeLayer(mapLayers[`${layerName}Buffer`])
delete mapLayers[`${layerName}Buffer`]
}
if (value && value.length) {
let data = JSON.parse(JSON.stringify(value))
let path = L.polyline(data, {
color: '#ffff00',
opacity: 1,
className: 'middle-line',
fillColor: '#ffff00',
fillOpacity: 1,
}).addTo(map)
mapLayers[layerName] = path
let bufferLine = turf.buffer(path.toGeoJSON(), 6.5, { units: "meters" })
mapLayers[`${layerName}Buffer`] = L.geoJSON(bufferLine, {
style: function () { return { color, fillOpacity: .6 } },
}).addTo(map)
mapLayers[`${layerName}Buffer`].bringToFront()
}
}
function deleteMarker(features, layerName) {
Object.keys(markerLayerGroupLists).forEach(item => {
if(item.includes(layerName)){
map.removeLayer(markerLayerGroupLists[item])
}
})
let marker = Object.keys(markerLayerGroupLists).filter(item => item.includes(layerName))
for (let i = 0; i < marker.length; i++) {
let item = marker[i]
let isIn = features.find(f => `${layerName}${f.properties.id}` === item)
if (isIn) continue
if (item.includes('point')) continue
let id = item.replace(`${layerName}`, '')
let icon = L.divIcon({
html: `<span class="icon-node-name"></span>`,
className: 'icon-node',
})
markerLayerGroupLists[`${layerName}${id}`].setIcon(icon)
}
}
function dealDivIcon(value, layerName) {
if (!value || !map) return
let result = JSON.parse(value)
if (!result) return
const { features } = result
deleteMarker(features, layerName)
let markerLayerGroup = L.LayerGroup.collision({ margin: 5 })
for (let i = 0; i < features.length; i++) {
let feature = features[i]
let { name, id } = feature.properties
let { coordinates } = feature.geometry
let markerCoor = null
if (layerName === 'lanenode') {
markerCoor = [coordinates[1], coordinates[0]]
} else {
let center = turf.center(feature)
markerCoor = [center.geometry.coordinates[1], center.geometry.coordinates[0]]
}
let icon = L.divIcon({
html: `<span class="icon-node-name">${name}</span>`,
className: 'icon-node',
})
if (markerLayerGroupLists[`${layerName}${id}`]) {
markerLayerGroupLists[`${layerName}${id}`].setIcon(icon)
} else {
let nameMarker = L.marker(markerCoor, { icon, zIndexOffset: -100 })
markerLayerGroup.addLayer(nameMarker)
markerLayerGroupLists[`${layerName}${id}`] = nameMarker
}
markerLayerGroupLists[`${layerName}${id}point`] = L.marker(markerCoor, {
icon: L.icon({
iconUrl: '/image/bluePoint.png',
iconSize: [12, 12],
iconAnchor: [6, 6],
}),
zIndexOffset: -100,
}).addTo(map)
}
markerLayerGroup.addTo(map)
mapStore.setData(layerName, null)
}
function removeLayer(obj, vehicleID) {
if (obj[vehicleID]) {
for (let item in obj[vehicleID]) {
map.removeLayer(obj[vehicleID][item])
}
}
}
function adjustmentLayer() {
mapLayers['currentPath'] && mapLayers['currentPath'].bringToFront()
mapLayers['nextPath'] && mapLayers['nextPath'].bringToFront()
for (let key in safeObjects) {
let safeLayer = safeObjects[key]
for (let lkey in safeLayer) {
lkey && safeLayer[lkey].bringToFront()
}
}
for (let key in safeTrajs) {
safeTrajs[key] && safeTrajs[key]['pathBuffer'] && safeTrajs[key]['pathBuffer'].bringToFront()
}
}
function dealSafe(vehicleID, safe) {
if (!map) return
const { enable, data, dealedData, vehicleType, vehicleLatitude, vehicleLongtitude } = safe
removeLayer(safeObjects, vehicleID)
safeObjects[vehicleID] = {}
if (!enable) return
let safeType = [1, 20, 21].includes(vehicleType) ? 'circle' : 'rectangle'
let zIndex = 16
for (let i = 0; i < dealedData.length; i++) {
let item = JSON.parse(JSON.stringify(dealedData[i]))
let layer = safeType === 'rectangle' ? L.polygon(item, { color: safe_color, weight: 1 }) : L.circle([vehicleLatitude, vehicleLongtitude], { radius: data[i], color: safe_color })
safeObjects[vehicleID][i] = layer.addTo(map)
safeObjects[vehicleID][i].bringToFront()
}
}
function dealTraj(vehicleID, traj) {
if (!traj || !map) return
const { trajPathWid, radius, dealedData, vehicleType, vehicleLatitude, vehicleLongtitude } = traj
removeLayer(safeTrajs, vehicleID)
safeTrajs[vehicleID] = {}
// if (!dealedData) return
// if ((dealedData && !dealedData.length) || !radius)) return
if([1, 20, 21].includes(vehicleType && !radius)) return;
const zIndex = LAYER_PROPOITY['traj']
if ([1, 20, 21].includes(vehicleType) && radius) {
let layer = L.circle([vehicleLatitude, vehicleLongtitude], { radius, color: '#FFA500' })
safeTrajs[vehicleID]['circle'] = layer.addTo(map)
safeTrajs[vehicleID]['circle'].bringToFront()
} else {
if(dealedData && !dealedData.length) return;
if(dealedData=='undefined') return;
let path = L.polyline(JSON.parse(JSON.stringify(dealedData)), {})
safeTrajs[vehicleID]['path'] = path
let bufferLine = turf.buffer(path.toGeoJSON(), trajPathWid / 2, { units: "meters" })
let layer = L.geoJSON(bufferLine, {
style: function () {
return {
color: safe_color,
fillOpacity: .4
}
},
})
safeTrajs[vehicleID]['pathBuffer'] = layer.addTo(map)
safeTrajs[vehicleID]['pathBuffer'].bringToFront()
}
}
function rotateVehicles(vehicleHeading) {
for (let key in vehicles) {
if (key !== deviceId.value) {
let oldHeading = vehicles[key].options['vehicleHeading']
vehicles[key].setRotation(-oldHeading + vehicleHeading)
}
}
}
function dealMapRotate(rotationAngle, center, zoom) {
let rotate = 0
if (rotationAngle) {
rotate = turf.radiansToDegrees(rotationAngle - BASE_RAD)
}
if (compass.value) {
compassRotationAngle.value = rotationAngle
map.setBearing(rotate)
}
center && center.length && map.flyTo(center, zoom, {animate: false})
}
function dealVehiclePosition(value) {
if (!map || !value.length) return
let zoom = map.getZoom()
let { iconSize, iconAnchor } = vehicleScale(zoom)
for (let i = 0; i < value.length; i++) {
const item = value[i]
const { vehicleLatitude, vehicleLongtitude, vehicleHeading, vehicleID, image } = item
let vehiclePosition = [vehicleLatitude, vehicleLongtitude]
if (vehicles[vehicleID]) {
let beforeIconUrl = vehicles[vehicleID].getIcon().options
? vehicles[vehicleID].getIcon().options.iconUrl
: vehicles[vehicleID].getIcon().iconUrl
if (!beforeIconUrl.includes(image)) {
let newIcon = L.icon({
iconUrl: `/image/${image}.png`,
iconSize,
iconAnchor
})
vehicles[vehicleID].setIcon(newIcon)
}
vehicles[vehicleID].setLatLng(vehiclePosition)
} else {
let icon = L.icon({
iconUrl: `/image/${image}.png`,
iconSize,
iconAnchor,
})
vehicles[vehicleID] = L.marker(vehiclePosition, {
icon: icon,
draggable: false,
rotationOrigin: 'center',
rotationAngle: 0,
zIndexOffset: 999
}).addTo(map)
vehicles[vehicleID].bindTooltip(`${vehicleID}`, {
permanent: true,
direction: 'center',
}).openTooltip()
}
vehicles[vehicleID].options = Object.assign({}, vehicles[vehicleID].options, {
vehicleHeading,
vehicleLongtitude,
vehicleLatitude
})
if (vehicleID === deviceId.value) {
currentPosition = vehiclePosition
if (navigate.value) {
if (vehicleHeading !== currentRotation.value) {
rotateVehicles(vehicleHeading)
}
currentRotation.value = vehicleHeading
dealMapRotate(vehicleHeading, vehiclePosition, zoom <= MAP_ZOOM ? MAP_ZOOM : zoom)
vehicles[vehicleID].setRotation(0)
} else {
// 再不旋转地图的情况下,需要旋转车辆本身(弧度)
vehicles[vehicleID].setRotation(-vehicleHeading + currentRotation.value)
}
} else {
// 非本车
vehicles[vehicleID].setRotation(-vehicleHeading + currentRotation.value)
}
}
}
function dealSingleDatas(datas) {
const { color, coor } = datas
let path = L.polyline(coor, {
color,
}).addTo(map)
singlePaths.push(path)
}
function dealObtacleData(value) {
if (obstaclePolygons.length) {
obstaclePolygons.forEach(item => map.removeLayer(item))
obstaclePolygons = []
}
if (value && value.length) {
for (let i = 0; i < value.length; i++) {
let obstacle = value[i]
let { typeColor, coordinate, centerLon, centerLat, centerRadius, centerColor } = obstacle
let obstaclePolygon = L.polygon(JSON.parse(JSON.stringify(coordinate)), { color: typeColor }).addTo(map)
let point = turf.point([centerLon, centerLat])
let obstacleBuffer = turf.buffer(point, centerRadius, { units: "meters" })
let obstacleCircle = L.geoJSON(obstacleBuffer, {
style: () => {
return {
color: centerColor,
fillOpacity: .5
}
}
}).addTo(map)
obstaclePolygons.push(obstacleCircle)
obstaclePolygons.push(obstaclePolygon)
}
}
}
function dealDynamicDatas(datas) {
let name='dynamicLine';
if (mapLayers[name]) {
map.removeLayer(mapLayers[name])
delete mapLayers[name]
}
// if (dynamicPaths.length) {
// dynamicPaths.forEach(item => map.removeLayer(item))
// dynamicPaths = []
// }
const { color, path } = datas
let pathNew = L.polyline(path, {
color,
opacity:0.3,
weight:30,
}).addTo(map)
mapLayers[name] = pathNew
mapLayers[name].bringToFront()
// dynamicPaths.push(pathNew)
}
// 直接监听props.isShowBasic 不会触发
watch(() => props.isShowBasic, () => {
nextTick(() => {
map.invalidateSize(true)
})
})
watch(lanenode, (value) => {
dealDivIcon(value, 'lanenode', '#ff0000')
}, {immediate: true, deep: true})
watch(lane, (value) => {
dealMapLayer(value, '#fff', 'lane')
}, {immediate: true, deep: true})
watch(runablearea, (value) => {
dealMapLayer(value, '#98a0a0', 'runablearea')
}, {immediate: true, deep: true})
watch(centerline, (value) => {
dealMapLayer(value, '#eee', 'centerline')
}, {immediate: true, deep: true})
watch(obstacles, (value) => {
dealDivIcon(value, 'obstacles')
dealMapLayer(value, '#6f9bdd', 'obstacles')
}, {immediate: true, deep: true})
watch(diggingworkarea, (value) => {
dealDivIcon(value, 'diggingworkarea')
dealMapLayer(value, '#886e26', 'diggingworkarea')
}, {immediate: true, deep: true})
watch(dumparea, (value) => {
dealDivIcon(value, 'dumparea')
dealMapLayer(value, '#886e26', 'dumparea')
}, {immediate: true, deep: true})
watch(barricade, (value) => {
dealMapLayer(value, '#0000ff', 'barricade')
}, {immediate: true, deep: true})
watch(stationarea, (value) => {
dealDivIcon(value, 'stationarea')
dealMapLayer(value, '#90ee90', 'stationarea')
}, {immediate: true, deep: true})
watch(parkspot, (value) => {
dealDivIcon(value, 'parkspot')
dealMapLayer(value, '#7e8185', 'parkspot')
}, {immediate: true, deep: true})
watch(staticobjs, (value) => {
dealMapLayer(value, '#98a0a0', 'staticobjs')
}, {immediate: true, deep: true})
watch(electronicFence, (value) => {
dealDivIcon(value, 'electronicFence')
dealMapLayer(value, '#d51d20', 'electronicFence')
}, {immediate: true, deep: true})
watch(nextPathinfo, (value) => {
dealMapPath(value, 'nextPath', nextPathAvailable.value === 1 ? '#19ae19' : '#8B4513')
adjustmentLayer()
}, {immediate: true, deep: true})
watch(currPathinfo, (value) => {
dealMapPath(value, 'currentPath', '#19ae19')
adjustmentLayer()
}, {immediate: true, deep: true})
watch(avoidancePath, (value) => {
dealMapPath(value, 'avoidancePath', 'blue')
}, {immediate: true, deep: true})
watch(vehiclesPositioninfo, (value) => {
dealVehiclePosition(value)
}, {
immediate: true,
deep: true
})
watch(safeObj, (value) => {
Object.keys(value).forEach(item => {
dealSafe(item, value[item])
})
}, {
immediate: true,
deep: true
})
watch(trajObj, (value) => {
Object.keys(value).forEach(item => {
dealTraj(item, value[item])
})
}, {
immediate: true,
deep: true
})
watch(obstacleData, (value) => {
dealObtacleData(value)
}, {immediate: true, deep: true})
watch(deleteVehicles, (data) => {
if (!map) return
if (data && data.length) {
data.forEach(item => {
map.removeLayer(vehicles[item])
removeLayer(safeTrajs, item)
removeLayer(safeObjects, item)
delete vehicles[item]
})
}
}, {
immediate: true
})
watch(() => props.clearSinglePointEnable, (enable) => {
if (!enable) return
isSinglePreview.value = true
singlePaths.forEach(item => map.removeLayer(item))
}, {deep: true})
watch([morepoint, morepath], (pointData, pathData) => {
if (isSinglePreview.value && (pointData || pathData)) {
let datas = pointData.concat(pathData)
for (let i = 0; i < datas.length; i++) {
dealSingleDatas(datas[i])
}
}
}, {deep: true})
watch(dynamicPathinfo, (pathData) => {
if (pathData.length>0) {
for(let i=0;i<pathData.length;i++) {
dealDynamicDatas(pathData[i])
}
}
}, {deep: true})
watch(deviceId, (value) => {
if (value && map) {
dealMapRotate(currentRotation.value, currentPosition, map.getZoom())
}
}, {deep: true})
function doUnmount() {
Object.keys(mapLayers).map(layer => map.removeLayer(mapLayers[layer]))
let mapDom = root.value
mapDom.removeEventListener('mousedown', changeMouseDown)
mapDom.removeEventListener('mousemove', changeMouseMove)
mapDom.removeEventListener('mouseup', changeMouseUp)
map.remove()
map = null
}
watch(() => props.reloadData, (value) => {
if (value) {
doUnmount()
}
})
onBeforeUnmount(() => {
doUnmount()
})
</script>
<style lang="less" scope>
.map-contain {
height: 100%;
overflow: hidden;
}
#map {
width: 200%;
height: 200%;
top: -50%;
left: -50%;
background: #171A23;
position: relative;
}
.navigate-preview {
background: #4A75A9;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.25);
border-radius: 10px;
opacity: 1;
display: flex;
align-items: center;
justify-content: center;
}
.compass,
.navigate-preview {
position: absolute;
width: 4vw;
height: 4vw;
z-index: 999;
}
.compass {
bottom: 88px;
max-width: 60px;
max-height: 60px;
}
.navigate-preview {
bottom: 24px;
max-width: 60px;
max-height: 60px;
}
</style>
<style lang="less">
.icon-node {
width: 120px !important;
white-space: nowrap;
color: #676565;
// padding-left: -2em !important;
z-index: 1;
font-size: 12px !important;
font-family: "Open Sans Regular", "Arial Unicode MS Regular", sans-serif;
text-transform: uppercase;
text-align: center;
-webkit-text-stroke-display: block;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: rgba(33, 33, 33, 0.8);
}
@media screen and (min-width: 1700px) {
.icon-node {
font-size: 18px !important;
}
}
.icon-node-name {
display: inline-block;
transform: scale(.6);
padding-left: -20px !important;
}
.hide {
display: none !important;
}
.middle-line {
// 为svg设置虚线,数字越大,虚线段越长,
// 设置2个参数,参数1: 虚线的长度 参数2: 虚线和虚线之间的间隔, 如果只设置一个参数,说明两个值一样大小
stroke-dasharray: 15 20;
z-index: 999;
}
.leaflet-tooltip {
color: #fff !important;
background-color: rgba(255, 255, 255, 0) !important;
border: 0 !important;
box-shadow: rgba(0, 0, 0, 0);
font-size: 12px !important;
}
.leaflet-control-attribution {
display: none !important;
}</style>
\ No newline at end of file
{
"SERVICE_IP": "172.16.0.114:1234",
"SERVICE_IP": "172.16.0.118:1234",
"MAP_CENTER": [39.74441007068,111.24544532751],
"version": "1.1.4"
}
\ No newline at end of file
......@@ -414,6 +414,7 @@
safeTrajs[vehicleID]['circle'].bringToFront()
} else {
if(dealedData && !dealedData.length) return;
if(dealedData=='undefined') return;
let path = L.polyline(JSON.parse(JSON.stringify(dealedData)), {})
safeTrajs[vehicleID]['path'] = path
let bufferLine = turf.buffer(path.toGeoJSON(), trajPathWid / 2, { units: "meters" })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment