|
|
@@ -15,6 +15,13 @@
|
|
|
:style="alarmPositionStyle"
|
|
|
class="c-alarm"
|
|
|
/>
|
|
|
+ <AlarmInfo
|
|
|
+ v-for="(item, index) in alarmList.slice(1,5)"
|
|
|
+ :key="item.id"
|
|
|
+ :alarm="item"
|
|
|
+ :style="alarmStyleMap[index]"
|
|
|
+ class="c-alarm--sub"
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
</box>
|
|
|
@@ -22,6 +29,7 @@
|
|
|
|
|
|
<script>
|
|
|
import Box from './Box'
|
|
|
+import { Bounds } from './config'
|
|
|
import DeviceStatus from './DeviceStatus'
|
|
|
import AlarmInfo from './AlarmInfo'
|
|
|
import AMapLoader from '@amap/amap-jsapi-loader'
|
|
|
@@ -46,17 +54,36 @@ export default {
|
|
|
},
|
|
|
city: {
|
|
|
type: String,
|
|
|
- default: '中国'
|
|
|
+ default: '深圳市'
|
|
|
}
|
|
|
},
|
|
|
data () {
|
|
|
this.curMarker = null
|
|
|
this.polylines = null
|
|
|
+ this.alarmStyleMap = [
|
|
|
+ {
|
|
|
+ top: 0,
|
|
|
+ left: 0
|
|
|
+ },
|
|
|
+ {
|
|
|
+ top: 0,
|
|
|
+ left: '720px'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ bottom: 0,
|
|
|
+ left: 0
|
|
|
+ },
|
|
|
+ {
|
|
|
+ bottom: 0,
|
|
|
+ left: '720px'
|
|
|
+ }
|
|
|
+ ]
|
|
|
return {
|
|
|
marks: [],
|
|
|
alarmPosition: [],
|
|
|
isShowAlarm: false,
|
|
|
- alarm: {}
|
|
|
+ alarm: {},
|
|
|
+ alarmList: []
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
@@ -91,46 +118,47 @@ export default {
|
|
|
plugins: ['AMap.DistrictSearch']
|
|
|
}).then(AMap => {
|
|
|
this.$AMap = AMap
|
|
|
-
|
|
|
- const options = {
|
|
|
- subdistrict: 2,
|
|
|
- extensions: 'all',
|
|
|
- level: 'province'
|
|
|
+ /*
|
|
|
+ bounds 里存多个边界区域 配合map 的mask 属性 可只显示该区域
|
|
|
+ 边界区域获取方式
|
|
|
+ 1. new AMap.DistrictSearch 获取省市区 街道无
|
|
|
+ 2. 自定义 手动捡
|
|
|
+ 高德地图 F12 接口获取
|
|
|
+ 点击目标点 出现 蓝色轮廓时 过滤 detail接口 数据 data.spec.mining_shape.shape 获取分号相隔的经纬度字符串
|
|
|
+ 辅助转化函数 str.split(';').map(i=>i.split(',').map(i=>Number))
|
|
|
+ 后续 可以 new AMap.Polyline画轮廓 setFiew 定位轮廓
|
|
|
+ */
|
|
|
+ const bounds = [Bounds.inspur]
|
|
|
+ const mask = []
|
|
|
+ for (let i = 0; i < bounds.length; i++) {
|
|
|
+ mask.push([bounds[i]])
|
|
|
}
|
|
|
|
|
|
- const district = new AMap.DistrictSearch(options)
|
|
|
- // 查询区域
|
|
|
- district.search(this.city, (status, result) => {
|
|
|
- const bounds = result.districtList[0]['boundaries']
|
|
|
- const mask = []
|
|
|
- console.log(result)
|
|
|
- for (let i = 0; i < bounds.length; i++) {
|
|
|
- mask.push([bounds[i]])
|
|
|
- }
|
|
|
-
|
|
|
- // 实例化地图
|
|
|
- const map = new AMap.Map(this.$refs.map, {
|
|
|
- mask,
|
|
|
- // expandZoomRange: true, // 开启显示范围设置
|
|
|
- // zooms: [7, 20], // 最小显示级别为7,最大显示级别为20
|
|
|
- // viewMode: '3D', // 这里特别注意,设置为3D则其它地区不显示
|
|
|
- zoomEnable: true, // 是否可以缩放地图
|
|
|
- // resizeEnable: true
|
|
|
- mapStyle: 'amap://styles/darkblue'
|
|
|
- })
|
|
|
- this.map = map
|
|
|
+ // 实例化地图
|
|
|
+ const map = new AMap.Map(this.$refs.map, {
|
|
|
+ mask,
|
|
|
+ // expandZoomRange: true, // 开启显示范围设置
|
|
|
+ // zooms: [7, 20], // 最小显示级别为7,最大显示级别为20
|
|
|
+ // viewMode: '3D', // 这里特别注意,设置为3D则其它地区不显示
|
|
|
+ zoomEnable: true, // 是否可以缩放地图
|
|
|
+ // resizeEnable: true
|
|
|
+ mapStyle: 'amap://styles/darkblue'
|
|
|
+ })
|
|
|
+ this.map = map
|
|
|
|
|
|
- this.marks = []
|
|
|
- this.$deviceMap = {}
|
|
|
+ this.marks = []
|
|
|
+ this.$deviceMap = {} // 当前地图 有标记点的设备 (可能切换部门变少)
|
|
|
+ this.$alldeviceMap = {} // 警告是全部设备的 可能因为切换部门 地图上没有警告对应设备的标记点无法定位 所以需要一个全部的坐标map
|
|
|
|
|
|
- this.$onlineIcon = new AMap.Icon({
|
|
|
- image: onlineIcon
|
|
|
- })
|
|
|
- this.$offlineIcon = new AMap.Icon({
|
|
|
- image: offlineIcon
|
|
|
- })
|
|
|
+ this.$onlineIcon = new AMap.Icon({
|
|
|
+ image: onlineIcon
|
|
|
+ })
|
|
|
+ this.$offlineIcon = new AMap.Icon({
|
|
|
+ image: offlineIcon
|
|
|
+ })
|
|
|
|
|
|
- this.deviceList.forEach(({ id, longitude, latitude, name, onlineStatus, address, mac }) => {
|
|
|
+ this.deviceList.forEach(
|
|
|
+ ({ id, longitude, latitude, name, onlineStatus, address, mac }) => {
|
|
|
if (longitude && latitude) {
|
|
|
const markObj = new AMap.Marker({
|
|
|
position: [Number(longitude), Number(latitude)],
|
|
|
@@ -140,61 +168,55 @@ export default {
|
|
|
this.marks.push(markObj)
|
|
|
this.$deviceMap[id] = {
|
|
|
onlineStatus,
|
|
|
- markObj, address, mac
|
|
|
+ markObj,
|
|
|
+ address,
|
|
|
+ mac
|
|
|
+ }
|
|
|
+ this.$allDeviceMap[id] = {
|
|
|
+ onlineStatus,
|
|
|
+ markObj,
|
|
|
+ address,
|
|
|
+ mac
|
|
|
}
|
|
|
}
|
|
|
- })
|
|
|
- map.add(this.marks)
|
|
|
-
|
|
|
- const polylines = []
|
|
|
- // 添加描边
|
|
|
- for (let i = 0; i < bounds.length; i += 1) {
|
|
|
- polylines.push(
|
|
|
- new AMap.Polyline({
|
|
|
- path: bounds[i],
|
|
|
- strokeColor: '#182C65',
|
|
|
- strokeWeight: 0,
|
|
|
- map
|
|
|
- })
|
|
|
- )
|
|
|
}
|
|
|
- this.polylines = polylines
|
|
|
- this.resetView()
|
|
|
- map.on('complete', () => {
|
|
|
- map.on('zoomstart', () => {
|
|
|
- this.isShowAlarm = false
|
|
|
- })
|
|
|
- map.on('movestart', () => {
|
|
|
- this.isShowAlarm = false
|
|
|
+ )
|
|
|
+ map.add(this.marks)
|
|
|
+ const polylines = []
|
|
|
+ // 添加描边
|
|
|
+ for (let i = 0; i < bounds.length; i += 1) {
|
|
|
+ polylines.push(
|
|
|
+ new AMap.Polyline({
|
|
|
+ path: bounds[i],
|
|
|
+ strokeColor: '#182C65',
|
|
|
+ strokeWeight: 0,
|
|
|
+ map
|
|
|
})
|
|
|
+ )
|
|
|
+ }
|
|
|
+ this.polylines = polylines
|
|
|
+ this.resetView()
|
|
|
+ map.on('complete', () => {
|
|
|
+ map.on('zoomstart', () => {
|
|
|
+ this.isShowAlarm = false
|
|
|
+ })
|
|
|
+ map.on('movestart', () => {
|
|
|
+ this.isShowAlarm = false
|
|
|
})
|
|
|
-
|
|
|
- // 区级线条
|
|
|
- for (const item of result.districtList[0].districtList) {
|
|
|
- district.search(item.adcode, (status, result) => {
|
|
|
- const bounds = result.districtList[0]['boundaries']
|
|
|
- for (let i = 0; i < bounds.length; i++) {
|
|
|
- new AMap.Polyline({
|
|
|
- path: bounds[i],
|
|
|
- strokeColor: '#182C65',
|
|
|
- strokeWeight: 4,
|
|
|
- map
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
})
|
|
|
})
|
|
|
},
|
|
|
setNewAlarm (alarm) {
|
|
|
- const { markObj: marker, mac, address } = this.$deviceMap[alarm.deviceId]
|
|
|
+ const {
|
|
|
+ markObj: marker,
|
|
|
+ mac,
|
|
|
+ address
|
|
|
+ } = this.$alldeviceMap[alarm.deviceId] || {}
|
|
|
+ this.alarm = { ...alarm, mac, address, status: alarm.status.label }
|
|
|
+ this.alarmList.unshift(this.alarm)
|
|
|
if (!marker) {
|
|
|
return
|
|
|
}
|
|
|
- this.alarm = { ...alarm, mac, address, status: alarm.status.label }
|
|
|
- alarm.status = alarm.status?.label
|
|
|
- alarm.mac = marker._originOpts.mac
|
|
|
- alarm.address = marker._originOpts.address
|
|
|
//
|
|
|
this.map.on('zoomend', this.onSetNewAlarmFitView)
|
|
|
this.map.on('moveend', this.onSetNewAlarmFitView)
|
|
|
@@ -212,70 +234,87 @@ export default {
|
|
|
showAlarm (position) {
|
|
|
this.map.off('zoomend', this.onSetNewAlarmFitView)
|
|
|
this.map.off('moveend', this.onSetNewAlarmFitView)
|
|
|
- const x = this.$refs.map.offsetWidth
|
|
|
+
|
|
|
// const y = this.$refs.map.offsetHeight
|
|
|
- const padding = 40
|
|
|
+
|
|
|
const width = 700 / 2
|
|
|
const height = 420
|
|
|
let left = position[0]
|
|
|
let top = position[1]
|
|
|
- if (left < width) {
|
|
|
- left = 0
|
|
|
- } else if (left + width > x) {
|
|
|
- left = x - width * 2
|
|
|
- } else {
|
|
|
- left -= width
|
|
|
- }
|
|
|
- if (left < padding) {
|
|
|
- left = padding
|
|
|
- }
|
|
|
- if (top - height - padding > 0) {
|
|
|
- top = top - height - padding
|
|
|
- } else {
|
|
|
- top += padding
|
|
|
- }
|
|
|
+ // 弹出框在标记点上方的逻辑
|
|
|
+ // const x = this.$refs.map.offsetWidth
|
|
|
+ // const padding = 40
|
|
|
+ // if (left < width) {
|
|
|
+ // left = 0
|
|
|
+ // } else if (left + width > x) {
|
|
|
+ // left = x - width * 2
|
|
|
+ // } else {
|
|
|
+ // left -= width
|
|
|
+ // }
|
|
|
+ // if (left < padding) {
|
|
|
+ // left = padding
|
|
|
+ // }
|
|
|
+ // if (top - height - padding > 0) {
|
|
|
+ // top = top - height - padding
|
|
|
+ // } else {
|
|
|
+ // top += padding
|
|
|
+ // }
|
|
|
+
|
|
|
+ // 弹出框在标记点中间的逻辑
|
|
|
+ left -= width
|
|
|
+ top -= height / 2
|
|
|
|
|
|
+ //
|
|
|
this.alarmPosition = [`${left}px`, `${top}px`]
|
|
|
this.isShowAlarm = true
|
|
|
},
|
|
|
refreshMarkers () {
|
|
|
const map = {}
|
|
|
const arr = []
|
|
|
- this.deviceList.forEach(({ id, longitude, latitude, name, onlineStatus, address, mac }) => {
|
|
|
- if (longitude && latitude) {
|
|
|
- const device = this.$deviceMap[id]
|
|
|
- if (device) {
|
|
|
- device.onlineStatus = onlineStatus
|
|
|
- device.markObj.setPosition([Number(longitude), Number(latitude)])
|
|
|
- device.markObj.setIcon(onlineStatus === 1 ? this.$onlineIcon : this.$offlineIcon)
|
|
|
- map[id] = device
|
|
|
- delete this.$deviceMap[id]
|
|
|
- } else {
|
|
|
- const markObj = new this.$AMap.Marker({
|
|
|
- position: [Number(longitude), Number(latitude)],
|
|
|
- title: name,
|
|
|
- icon: onlineStatus === 1 ? this.$onlineIcon : this.$offlineIcon
|
|
|
- })
|
|
|
- map[id] = {
|
|
|
- onlineStatus,
|
|
|
- markObj,
|
|
|
- address, mac
|
|
|
+ this.deviceList.forEach(
|
|
|
+ ({ id, longitude, latitude, name, onlineStatus, address, mac }) => {
|
|
|
+ if (longitude && latitude) {
|
|
|
+ const device = this.$deviceMap[id]
|
|
|
+ if (device) {
|
|
|
+ device.onlineStatus = onlineStatus
|
|
|
+ device.markObj.setPosition([Number(longitude), Number(latitude)])
|
|
|
+ device.markObj.setIcon(
|
|
|
+ onlineStatus === 1 ? this.$onlineIcon : this.$offlineIcon
|
|
|
+ )
|
|
|
+ map[id] = device
|
|
|
+ delete this.$deviceMap[id]
|
|
|
+ } else {
|
|
|
+ const markObj = new this.$AMap.Marker({
|
|
|
+ position: [Number(longitude), Number(latitude)],
|
|
|
+ title: name,
|
|
|
+ icon: onlineStatus === 1 ? this.$onlineIcon : this.$offlineIcon
|
|
|
+ })
|
|
|
+ map[id] = {
|
|
|
+ onlineStatus,
|
|
|
+ markObj,
|
|
|
+ address,
|
|
|
+ mac
|
|
|
+ }
|
|
|
+ arr.push(markObj)
|
|
|
}
|
|
|
- arr.push(markObj)
|
|
|
}
|
|
|
}
|
|
|
- })
|
|
|
+ )
|
|
|
if (arr.length) {
|
|
|
this.map.add(arr)
|
|
|
}
|
|
|
- const marks = Object.values(this.$deviceMap).filter(Boolean).map(({ markObj }) => markObj)
|
|
|
+ const marks = Object.values(this.$deviceMap)
|
|
|
+ .filter(Boolean)
|
|
|
+ .map(({ markObj }) => markObj)
|
|
|
if (marks.length) {
|
|
|
this.map.remove(marks)
|
|
|
}
|
|
|
// 重构 $deviceMap 包含 delete 和 add 的
|
|
|
+ this.$deviceMap = {} // 只包含当前地图上的设备(按部门)
|
|
|
for (const key in map) {
|
|
|
if (Object.hasOwnProperty.call(map, key)) {
|
|
|
this.$deviceMap[key] = map[key]
|
|
|
+ this.$alldeviceMap[key] = map[key]
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -290,24 +329,28 @@ export default {
|
|
|
}
|
|
|
.c-alarm {
|
|
|
position: absolute;
|
|
|
- z-index: 9;
|
|
|
+ z-index: 99;
|
|
|
+ &--sub {
|
|
|
+ position: absolute;
|
|
|
+ z-index: 9;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- @keyframes sparkle {
|
|
|
- 0% {
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
- 40% {
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
- 50% {
|
|
|
- opacity: 0;
|
|
|
- }
|
|
|
- 60% {
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
- 100% {
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
+@keyframes sparkle {
|
|
|
+ 0% {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ 40% {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ 50% {
|
|
|
+ opacity: 0;
|
|
|
}
|
|
|
+ 60% {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ 100% {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|