<template>
|
<div class="f-map" id="map">
|
<div id="fmapDiv"></div>
|
</div>
|
</template>
|
<script>
|
import fengmap from "fengmap";
|
import { updatePos } from "../../../api/map";
|
|
import Wfs from "@/components/player/wfs";
|
|
const FengMapDataPath = "/apps/visual";
|
|
var ctlOpt = new fengmap.controlOptions({
|
//默认在右上角
|
position: fengmap.controlPositon.RIGHT_TOP,
|
//默认显示楼层的个数
|
showBtnCount: 8,
|
//初始是否是多层显示,默认单层显示
|
allLayer: false,
|
//位置x,y的偏移量
|
offset: {
|
x: 0,
|
y: 0
|
},
|
imgURL: FengMapDataPath + "/mapImgs/"
|
});
|
var map = null;
|
var imgMarkerLayer = null;
|
var zoomControl = null;
|
var toolControl = null;
|
var imgMarkerArray = [];
|
//定义二维/三维模式变量
|
var planarFlag = false;
|
let clickMarker = null;
|
|
export default {
|
name: "Fmap",
|
components: {},
|
props: {
|
defaultMapScaleLevel: {
|
type: Number,
|
default: 19
|
}
|
},
|
data() {
|
return {
|
mapDom: null
|
};
|
},
|
watch: {
|
mapDom: {
|
handler: function (newVal, oldVal) {
|
if (newVal !== null) {
|
console.log(newVal, '地图是否渲染好', oldVal)
|
}
|
},
|
deep: true
|
}
|
},
|
created() { },
|
methods: {
|
async updateCamPos(obj) {
|
let res = await updatePos(obj);
|
return res
|
// console.info("updateCamPos", res);
|
},
|
initMap() {
|
const _this = this;
|
const mapId = "basicyuyingschool-2";
|
const appName = "育英中学";
|
const defaultThemeName = "2001";
|
const key = "a7ab1be10d3893766eb90e22ee101616";
|
// console.log('初始化地图')
|
map = new fengmap.FMMap({
|
container: document.querySelector("#fmapDiv"),
|
mapServerURL: FengMapDataPath + '/fengmap/data/' + mapId,
|
mapThemeURL: FengMapDataPath + '/fengmap/data/theme',
|
defaultThemeName: defaultThemeName,
|
compassSize: 48, //指北针大小默认设置
|
appName: appName,
|
key: key,
|
defaultFocusGroup: 3,
|
defaultVisibleGroups: [3],
|
modelHoverEffect: true,
|
//初始二维/三维状态,默认3D显示
|
defaultViewMode: fengmap.FMViewMode.MODE_3D,
|
defaultMapScaleLevel: _this.defaultMapScaleLevel
|
});
|
// map.hoverFilterFunction = (event)=>{
|
// console.log('event:', event);
|
// if(event.nodeType == fengmap.FMNodeType.MODEL && event.typeID == "300000"){
|
// return false;
|
// }
|
// return true;
|
// };
|
map.openMapById(mapId); //打开场景id=1的模型
|
|
map.on("loadComplete", function () {
|
new fengmap.scrollGroupsControl(map, ctlOpt);
|
|
// map.showCompass = true;
|
// //点击指北针事件, 使角度归0
|
// map.on('mapClickCompass', function () {
|
// map.rotateTo({
|
// //设置角度
|
// to: 0,
|
// //动画持续时间,默认为。3秒
|
// duration: .3,
|
// callback: function () { //回调函数
|
// console.log('rotateTo complete!');
|
// }
|
// })
|
// });
|
_this.findMapEvent()
|
var zoomCtlOpt = {
|
//设置显示的位置为左上角
|
position: fengmap.FMControlPosition.LEFT_TOP,
|
//位置x,y的偏移量
|
offset: {
|
x: 10,
|
y: 110
|
},
|
imgURL: FengMapDataPath + "/mapImgs/"
|
};
|
//创建放大缩小控件
|
zoomControl = new fengmap.FMZoomControl(map, zoomCtlOpt);
|
//创建3D按钮控件
|
var toolCtlOpt = {
|
position: fengmap.FMControlPosition.LEFT_TOP,
|
//位置x,y的偏移量
|
offset: {
|
x: 10,
|
y: 89
|
},
|
imgURL: FengMapDataPath + "/mapImgs/",
|
//初始化2D模式
|
init2D: false,
|
//当楼层切换按钮存在时,设置初始默认-false表示显示单层状态,true表示显示多层状态,.
|
initGroups: false,
|
//设置为false表示不显示,即只显示2D,3D切换按钮
|
groupsButtonNeeded: false,
|
//设置为false表示不显示,即只显示楼层切换按钮
|
viewModeButtonNeeded: true
|
};
|
// toolControl = new fengmap.FMToolControl(map, toolCtlOpt);
|
//判断map是否为null
|
if (map !== null) {
|
_this.mapDom = true
|
_this.$nextTick(() => {
|
console.log('emit')
|
_this.$emit('initPosCameras')
|
})
|
}
|
//注册地图级别变化事件
|
map.on("scaleLevelChanged", function () {
|
console.log("当前级别:", map.scaleLevel, map.mapScale);
|
if (map.scaleLevel < 20) {
|
imgMarkerArray.map(i => {
|
_this.controlShow(i, false)
|
})
|
} else {
|
imgMarkerArray.map(i => {
|
_this.controlShow(i, true)
|
})
|
}
|
// if(map.mapScale > 829.18365262){
|
// imgMarkerArray.map(i=>{
|
// _this.controlShow(i,false)
|
// })
|
// }
|
// if(map.mapScale < 872.8248974){
|
// imgMarkerArray.map(i=>{
|
// _this.controlShow(i,true)
|
// })
|
// }
|
});
|
map.on("mapHoverNode", function (e) {
|
console.info("mapHoverNode");
|
});
|
});
|
map.on("scaleLevelChanged", function (event) {
|
// console.log(event,'scaleLevelChanged')
|
});
|
map.on("focusGroupIDChanged", event => {
|
console.log(this.MapData.onMapDeviceList, "地图聚焦楼层改变:", map.focusGroupID);
|
var cameras = this.MapData.onMapDeviceList;
|
this.initPosCameras(cameras);
|
});
|
map.on("mapClickNode", function (event) {
|
let target = event.target;
|
if (!target) {
|
return;
|
}
|
console.log(target, '地图上点击标记点')
|
// _this.changePosFunc()
|
switch (target.nodeType) {
|
case fengmap.FMNodeType.IMAGE_MARKER:
|
_this.moveToMarker(target)
|
let devId = target.devId;
|
imgMarkerArray.forEach(marker => {
|
if (marker.devId == event.target.devId) {
|
// _this.markerJump(marker)
|
let devName = marker.devName;
|
let addr = marker.addr;
|
let rtsp = marker.rtsp;
|
let is_running = marker.is_running;
|
let isGb28181 = marker.type === 1;
|
var markerInfo = {
|
//设置弹框的宽度
|
width: 350,
|
//设置弹框的高度px
|
height: 210,
|
//设置弹框的内容,文本或html页面元素
|
content:
|
`<div class="pop-box">
|
<div class="pop-video">
|
<video id="` + marker.devId + `" controls></video>
|
</div>
|
<div class="pop-msg">
|
<p> 设备类型: ` + (isGb28181 ? "AI摄像机" : "分析摄像机") + `</p>
|
<p> 设备名称: ` + devName + ` </p>
|
<p> 设备位置: ` + addr + ` </p>
|
</div>
|
<div class="pop-btn">
|
<i class="el-icon-lock" id="btn-lock-` + marker.devId + `"></i>
|
<i class="el-icon-delete" id="btn-del-` + marker.devId + `"></i>
|
<i class="el-icon-close" id="btn-close-` + marker.devId + `"></i>
|
</div>
|
</div>`,
|
//关闭回调函数
|
closeCallBack: function () {
|
//信息窗点击关闭操作
|
// console.log("信息窗关闭了!");
|
}
|
};
|
|
var wfs = new Wfs();
|
setTimeout(() => {
|
let wsAddr = `${location.protocol === "https" ? "wss" : "ws"}://${location.host}/ws`;
|
let cameraInfo = {
|
cameraID: marker.devId,
|
rtspUrl: rtsp,
|
isRunning: is_running,
|
isGb28181: isGb28181
|
};
|
|
let camera = document.getElementById(marker.devId);
|
|
wfs.attachMedia(camera, "chX", "H264Raw", wsAddr, cameraInfo);
|
}, 100);
|
//添加弹框到地图上,绑定marker
|
var popMarker = new fengmap.FMPopInfoWindow(
|
map,
|
markerInfo,
|
marker
|
);
|
|
setTimeout(() => {
|
// 关闭弹窗
|
document.querySelector(
|
`#btn-close-${marker.devId}`
|
).onclick = () => {
|
_this.closePop(popMarker, wfs)
|
}
|
// 解锁
|
document.querySelector(
|
`#btn-lock-${marker.devId}`
|
).onclick = () => {
|
_this.lockNode(popMarker)
|
}
|
// 删除节点
|
document.querySelector(
|
`#btn-del-${marker.devId}`
|
).onclick = () => {
|
_this.delNode(popMarker)
|
}
|
}, 100);
|
}
|
if (marker.devId == event.target.devId && !marker.isLock) {
|
_this.clickMarker = marker
|
console.log(_this.clickMarker, '鼠标左键状态')
|
window.addEventListener('mousemove', _this.listenMove, false)
|
window.addEventListener('dbclick', _this.listenDbClick, false)
|
}
|
// if(_this.clickMarker){
|
// console.log('监听事件')
|
// window.addEventListener('mousemove',_this.listenMove,false)
|
// window.addEventListener('dbclick',_this.listenDbClick,false)
|
// }
|
});
|
break;
|
|
default:
|
break;
|
}
|
if (event.target && event.target.devId) {
|
// console.log("cameraId:", event.target.devId);
|
}
|
});
|
},
|
addMarker(cameraId, x, y, devName, addr, runType, rtsp, isRunning, type) {
|
console.info("addMarker", cameraId, x, y);
|
var group = map.getFMGroup(map.focusGroupID);
|
//转换坐标
|
var mapCoord = map.coordScreenToMap(x, y, group.height, false, false);
|
console.info("mCoord", mapCoord);
|
|
console.log("focusGroupID:", map.focusGroupID);
|
if (imgMarkerLayer == null) {
|
imgMarkerLayer = group.getOrCreateLayer("imageMarker");
|
}
|
|
var markerPath = FengMapDataPath + "/mapImgs/ai-map.png";
|
if (runType == -1) {
|
markerPath = FengMapDataPath + "/mapImgs/camera-map.png";
|
}
|
var im = new fengmap.FMImageMarker({
|
x: mapCoord.x,
|
y: mapCoord.y,
|
url: markerPath,
|
size: 32,
|
height: 1
|
});
|
im.devId = cameraId;
|
im.devName = devName;
|
im.addr = addr;
|
im.runType = runType;
|
im.rtsp = rtsp;
|
im.isRunning = isRunning;
|
im.type = type;
|
im.cameraFloor = map.focusGroupID;
|
im.isLock = true;
|
imgMarkerLayer.addMarker(im);
|
imgMarkerLayer.avoid(false);
|
if (map.scaleLevel >= 19) {
|
this.controlShow(im, false)
|
} else {
|
this.controlShow(im, true)
|
}
|
imgMarkerArray.push(im);
|
//将坐标更新到数据库中
|
this.updateCamPos({
|
id: cameraId,
|
floor: map.focusGroupID,
|
longitude: mapCoord.x,
|
latitude: mapCoord.y
|
}).then(res => {
|
this.MapData.refreshDeviceList();
|
}).catch(err => { });
|
},
|
removeMarker(marker) {
|
imgMarkerLayer.removeMarker(marker)
|
},
|
initPosCameras(cameras) {
|
//地图加载的时候
|
// console.info("initPosCameras:", cameras,map);
|
if (cameras != null && cameras instanceof Array) {
|
cameras.forEach(cam => {
|
// console.info("cam imgMarkerArray", cam, imgMarkerArray);
|
if (map.focusGroupID == cam.floor) {
|
var existMarker = null;
|
imgMarkerArray.forEach(m => {
|
if (m.cameraFloor != map.focusGroupID) {
|
m.show = false;
|
} else {
|
// console.info('cameraName',m.devName)
|
m.show = true;
|
}
|
if (m.devId == cam.id) {
|
existMarker = m;
|
}
|
});
|
if (existMarker == null) {
|
var group = map.getFMGroup(map.focusGroupID);
|
if (imgMarkerLayer == null) {
|
imgMarkerLayer = group.getOrCreateLayer("imageMarker");
|
}
|
|
var markerPath = FengMapDataPath + "/mapImgs/ai-map.png";
|
if (cam.run_type == -1) {
|
markerPath = FengMapDataPath + "/mapImgs/camera-map.png";
|
// console.info("监控marker");
|
}
|
|
var im = new fengmap.FMImageMarker({
|
x: cam.longitude,
|
y: cam.latitude,
|
url: markerPath,
|
size: 32,
|
height: 1
|
});
|
im.devId = cam.id;
|
im.devName = cam.name;
|
im.addr = cam.addr;
|
im.isLock = cam.isLock;
|
im.runType = cam.run_type;
|
im.rtsp = cam.rtsp;
|
im.isRunning = cam.is_running;
|
im.type = cam.type;
|
im.cameraFloor = map.focusGroupID;
|
|
imgMarkerLayer.avoid(false);
|
group.avoid(false);
|
imgMarkerLayer.addMarker(im);
|
console.log(map.scaleLevel, 'initPosCameras')
|
if (map.scaleLevel >= 19) {
|
this.controlShow(im, false)
|
} else {
|
this.controlShow(im, true)
|
}
|
imgMarkerArray.push(im);
|
}
|
}
|
});
|
}
|
},
|
closePop(popMarker, wfs) {
|
popMarker.close()
|
if (wfs) {
|
wfs.destroy();
|
}
|
},
|
lockNode(popMarker) {
|
console.log(popMarker.marker, "unlock")
|
if (popMarker.marker.isLock) {
|
this.$set(popMarker.marker, 'isLock', false)
|
} else {
|
this.$set(popMarker.marker, 'isLock', true)
|
}
|
},
|
delNode(markerNode, wfs) {
|
if (markerNode && markerNode.marker) {
|
this.closePop(markerNode, wfs)
|
let res = this.updateCamPos({
|
id: markerNode.marker.devId,
|
floor: -9999,
|
longitude: 0.0,
|
latitude: 0.0
|
}).then(res => {
|
// console.log(res,"del node")
|
if (res.success) {
|
this.removeMarker(markerNode.marker)
|
this.MapData.findOnMap(-9999, false);
|
this.MapData.findOnMap(-9999, true);
|
if (
|
this.MapData.onMapDeviceList &&
|
this.MapData.onMapDeviceList.length !== 0
|
) {
|
this.initPosCameras(this.MapData.onMapDeviceList);
|
}
|
}
|
})
|
|
}
|
},
|
//offsetX:地图偏移X
|
//offsetY:地图偏移Y
|
//im:地图marker
|
//gid:楼层id
|
//height:偏移高度
|
moveMarker(offsetX, offsetY, im, gid, height) {
|
if (im) {
|
console.log(im, '标记点移动前')
|
im.setPosition(im.x + offsetX, im.y + offsetY, gid, height)
|
console.log(im, '标记点移动后')
|
}
|
},
|
//2D/3D切换
|
changeMode(domObj) {
|
if (this.planarFlag) {
|
//切换地图为三维模式
|
if (map) {
|
map.viewMode = fengmap.FMViewMode.MODE_3D;
|
// domObj.classList.remove('planar');
|
}
|
} else {
|
//切换地图为二维模式
|
if (map) {
|
map.viewMode = fengmap.FMViewMode.MODE_2D;
|
// domObj.classList.add('planar');
|
}
|
}
|
this.planarFlag = !this.planarFlag
|
},
|
//地图中心移动到指定点
|
moveToMarker(marker) {
|
console.log(marker, 'moveToMarker', marker.x, marker.y)
|
if (map && marker) {
|
var coord = {
|
x: marker.x,
|
y: marker.y,
|
groupID: marker.groupID
|
};
|
map.moveTo(coord);
|
}
|
},
|
//让标记点跳动
|
markerJump(marker) {
|
let options = {
|
height: 10,
|
times: 5,
|
duration: 0.5,
|
delay: 0.5
|
}
|
if (marker) {
|
marker.jump(options);
|
}
|
},
|
//停止图标标记跳动
|
stopJump(marker) {
|
console.log(marker, '标记点停止跳动')
|
if (marker) {
|
marker.stopJump();
|
}
|
},
|
//循环比较marker,让选中的摄像机跳动
|
reciveNodeId(nodeId) {
|
console.log(nodeId, '标记点跳动', imgMarkerArray)
|
if (nodeId && imgMarkerArray.length !== 0) {
|
imgMarkerArray.map(marker => {
|
if (marker.devId === nodeId) {
|
this.markerJump(marker)
|
} else {
|
this.stopJump(marker)
|
}
|
})
|
}
|
},
|
//屏幕坐标转地图坐标
|
//x:屏幕x值
|
//y:屏幕y值
|
//z:地图高度
|
//isFloat:是否使用屏幕像素坐标系 默认false
|
//giveMeRaw:是否返回三维空间坐标 默认false
|
coordScreenToMap(x, y, z, isFloat = false, giveMeRaw = false) {
|
if (map) {
|
let json = map.coordScreenToMap(x, y, z, isFloat, giveMeRaw)
|
return json
|
}
|
},
|
//监听鼠标移动
|
listenMove(e) {
|
let json = this.coordScreenToMap(e.clientX, e.clientY, this.clickMarker['height'])
|
this.moveMarker(json.x, json.y, this.clickMarker, this.clickMarker.cameraFloor, this.clickMarker.height)
|
},
|
//监听鼠标双击
|
listenDbClick(e) {
|
console.log(e, '双击事件')
|
window.removeEventListener('mousemove', this.listenMove, false)
|
},
|
//添加imagemarker
|
TestaddMarker() {
|
let group = map.getFMGroup(map.focusGroupID);
|
let layer = group.getOrCreateLayer('imageMarker')
|
//图标标注对象,默认位置为该楼层中心点
|
let gpos = group.mapCoord;
|
this.clickMarker = new fengmap.FMImageMarker({
|
//标注x坐标点
|
x: gpos.x,
|
//标注y坐标点
|
y: gpos.y,
|
//设置图片路径
|
url: FengMapDataPath + '/mapImgs/blueImageMarker.png',
|
//设置图片显示尺寸
|
size: 32,
|
//标注高度,大于model的高度
|
height: 1
|
});
|
layer.addMarker(this.clickMarker)
|
},
|
/**
|
* 更新图片位置按钮事件
|
* */
|
changePosFunc() {
|
//marker已存在,设置marker的位置,setPosition ( x, y, gid, height )
|
if (this.clickMarker) {
|
this.clickMarker.setPosition(this.clickMarker.x + 10, this.clickMarker.y + 10, 3, 6);
|
}
|
},
|
/**
|
* 查询地图元素监听事件
|
*/
|
findMapEvent() {
|
// let list = window.getEventListeners(document.querySelector('#fmapDiv'))
|
// console.log(list,'事件列表')
|
},
|
clearData() {
|
map = null;
|
imgMarkerLayer = null;
|
zoomControl = null;
|
toolControl = null;
|
imgMarkerArray = [];
|
planarFlag = false;
|
clickMarker = null;
|
},
|
/**
|
* 控制marker显示状态
|
*/
|
controlShow(marker, bool) {
|
if (marker) {
|
marker.show = bool
|
}
|
}
|
},
|
mounted() {
|
this.initMap(); //初始化map
|
},
|
destroyed() {
|
map.dispose()
|
this.clearData()
|
},
|
};
|
</script>
|
<style lang="scss">
|
.f-map {
|
#fmapDiv {
|
width: 100%;
|
height: 100%;
|
}
|
.fm-control-popmarker {
|
background-color: transparent !important;
|
border: 0px !important;
|
}
|
|
.fm-control-popmarker-closebtn,
|
.fm-control-popmarker-bot,
|
.fm-control-popmarker-top {
|
display: none;
|
}
|
.pop-box {
|
position: absolute;
|
top: -16px;
|
left: 42px;
|
width: 255px;
|
height: 227px;
|
background: rgba(0, 0, 0, 0.51);
|
border: 1px solid rgba(255, 255, 255, 0.26);
|
border-radius: 4px;
|
}
|
.pop-d3 {
|
position: absolute;
|
bottom: -38px;
|
left: 157px;
|
border-width: 18px;
|
border-style: solid;
|
border-color: rgba(0, 0, 0, 0.51) transparent transparent transparent;
|
}
|
.pop-video {
|
width: 235px;
|
height: 132px;
|
margin: 10px;
|
background-color: #000;
|
}
|
.pop-msg {
|
color: #eee;
|
margin: 10px 10px;
|
text-align: left;
|
p {
|
line-height: 18px;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
width: 223px;
|
}
|
}
|
.pop-btn {
|
color: #eee;
|
float: right;
|
margin-top: -11px;
|
margin-right: 8px;
|
font-size: 15px !important;
|
cursor: pointer;
|
}
|
.pop-btn i {
|
margin-left: 10px;
|
}
|
}
|
</style>
|