fix: Filter中增加NRL的筛选,Data Quality筛选增加事件,因没有接口,未对接筛选功能,动效改为非核设施才有,修复空值导致的地图图层未清理问题

This commit is contained in:
Xu Zhimeng 2023-06-19 19:52:28 +08:00
parent e82fee46b7
commit 39f407e204
6 changed files with 205 additions and 110 deletions

View File

@ -687,3 +687,19 @@ export const EXPORT_FILE_SUFFIX = ".xlsx";
export function stringIsNull(str) {
return str == null || str === 'null' || str === 'undefined';
}
/**
* 根据给的key拍平数组
* @param {Array<any>} arr
* @param {String} flatKey
* @returns
*/
export function flat(arr, flatKey = 'children') {
return arr.reduce((result, item) => {
result.push(item)
if (item[flatKey]) {
result = result.concat(flat(item[flatKey], flatKey))
}
return result
}, [])
}

View File

@ -12,7 +12,7 @@
<script>
import Overlay from 'ol/Overlay'
import { MarkerIcon } from './markerEnum'
import { MarkerIcon, MarkerType } from './markerEnum'
import { fromLonLat } from 'ol/proj'
import PopupColumns from './markerPopupColumns'
@ -44,13 +44,13 @@ export default {
if (this.isHover) {
this._getStationInfo(stationInfo)
}
}, 500)
}, 0)
},
methods: {
// marker
initMarkers() {
this.list.forEach(eventItem => {
this.map.addOverlay(this.getMarker(eventItem))
this.list.forEach(stationInfo => {
this.map.addOverlay(this.getMarker(stationInfo))
})
},
@ -83,9 +83,14 @@ export default {
},
initRipples() {
this.list.forEach(eventItem => {
this.map.addOverlay(this.getRipple(eventItem))
})
this.list
.filter(
stationInfo =>
stationInfo.stationType !== MarkerType.NuclearFacility && stationInfo.stationType !== MarkerType.NRL
)
.forEach(stationInfo => {
this.map.addOverlay(this.getRipple(stationInfo))
})
},
getRipple({ lon, lat, stationId }) {
@ -109,8 +114,7 @@ export default {
this.popupOverlay = new Overlay({
element: this.$refs.mapPopupRef,
positioning: 'top-center',
id: POPUP_OVERLAY_ID,
offset: [0, 27]
id: POPUP_OVERLAY_ID
})
this.map.addOverlay(this.popupOverlay)
},
@ -118,6 +122,7 @@ export default {
//
async showMapPopup(stationInfo) {
this.popupOverlay.setPosition(fromLonLat([stationInfo.lon, stationInfo.lat]))
this.popupOverlay.setOffset([stationInfo.stationType == MarkerType.NuclearFacility ? 10 : 0, 27])
this.columns = PopupColumns[stationInfo.stationType]
this.popupTitle = stationInfo.stationType
this.isGettingInfo = true
@ -173,16 +178,13 @@ export default {
&::before {
position: absolute;
top: -6px;
top: -17px;
left: 50%;
content: '';
width: 12px;
height: 12px;
border: 1px solid rgba(2, 26, 29, 0.9);
background: rgba(2, 26, 29, 0.9);
transform: translateX(-50%) rotate(45deg) skew(14deg, 14deg);
border-bottom: 0;
border-right: 0;
transform: translateX(-50%);
border: 6px solid transparent;
border-bottom-color: rgba(2, 26, 29, 0.9);
border-bottom-width: 12px;
}
h2 {
@ -233,8 +235,8 @@ export default {
width: 100%;
height: 100%;
border-radius: 50%;
background-image: radial-gradient(circle, transparent 10%, rgba(15, 148, 28, 0.1) 30%, rgba(15, 148, 28, 0.5) 60%);
animation: rippleEffect @duration linear @delay infinite;
background-image: radial-gradient(circle, transparent 10%, rgba(15, 148, 28, 0.2) 30%, rgba(15, 148, 28, 0.5) 60%);
animation: rippleEffect @duration linear 0s infinite;
}
.inner-ripple-2 {
position: absolute;
@ -242,8 +244,9 @@ export default {
width: 100%;
height: 100%;
border-radius: 50%;
background-image: radial-gradient(circle, transparent 10%, rgba(15, 148, 28, 0.1) 30%, rgba(15, 148, 28, 0.5) 60%);
animation: rippleEffect @duration linear @delay * 2 infinite;
transform: scale(0);
background-image: radial-gradient(circle, transparent 10%, rgba(15, 148, 28, 0.2) 30%, rgba(15, 148, 28, 0.5) 60%);
animation: rippleEffect @duration linear @delay infinite;
}
}

View File

@ -99,22 +99,35 @@
</div>
<div class="map-pane-content-main">
<div class="station-filter-list">
<div class="station-filter-item" v-for="filterItem in filterList" :key="filterItem.title">
<div
class="station-filter-item"
v-for="filterItem in filterList"
:key="filterItem.title"
@click="onStationTypeFilterChange(filterItem)"
>
<div class="station-filter-item-main">
<div>
<img :src="filterItem.icon" />
</div>
<span>{{ filterItem.title }}</span>
</div>
<a-checkbox v-model="filterItem.checked" @change="emitTypeFilter"></a-checkbox>
<a-checkbox v-model="filterItem.checked"></a-checkbox>
</div>
</div>
<a-divider style="background-color: #0a544e; margin: 10px 0 0;"></a-divider>
<!-- 数据质量类型 -->
<div class="station-data-quality-list">
<div class="station-data-quality-list-item" v-for="(stateItem, index) in dataQualityList" :key="index">
<img :src="stateItem.icon" alt="" />
<span>{{ stateItem.title }}</span>
<div
class="station-data-quality-list-item"
v-for="(stateItem, index) in dataQualityList"
:key="index"
@click="onDataQualityFilterChange(stateItem)"
>
<div>
<img :src="stateItem.icon" alt="" />
<span>{{ stateItem.title }}</span>
</div>
<a-checkbox v-model="stateItem.checked"></a-checkbox>
</div>
</div>
<!-- 数据质量结束 -->
@ -217,11 +230,10 @@
</template>
<script>
import CustomModal from '@/components/CustomModal/index.vue'
import FilterImage from './filterImage'
import CustomTree from '@/components/CustomTree/index.vue'
import RealTimeDataChart from './RealTimeDataChart.vue'
import { postAction } from '../../../api/manage'
import { MarkerType } from './markerEnum'
import { MarkerType, FilterIcon } from './markerEnum'
import { Vector as VectorLayer } from 'ol/layer'
import VectorSource from 'ol/source/Vector'
@ -235,37 +247,43 @@ const filterList = [
{
title: 'IMS RN Station(P)',
type: MarkerType.ImsRnStationP,
icon: FilterImage.ImsRnStation,
icon: FilterIcon[MarkerType.ImsRnStationP],
checked: true
},
{
title: 'IMS RN Station(G)',
type: MarkerType.ImsRnStationG,
icon: FilterImage.ImsRnStation,
icon: FilterIcon[MarkerType.ImsRnStationG],
checked: true
},
{
title: 'NRL',
type: MarkerType.NRL,
icon: FilterIcon[MarkerType.NRL],
checked: true
},
{
title: 'Nuclear Facilities',
type: MarkerType.NuclearFacility,
icon: FilterImage.NuclearFacility,
icon: FilterIcon[MarkerType.NuclearFacility],
checked: true
},
{
title: 'Groud monitoring station',
type: MarkerType.GroudMonitoringStation,
icon: FilterImage.GroudMonitoringStation,
icon: FilterIcon[MarkerType.GroudMonitoringStation],
checked: true
},
{
title: 'car',
type: MarkerType.Car,
icon: FilterImage.Car,
icon: FilterIcon[MarkerType.Car],
checked: true
},
{
title: 'ship',
type: MarkerType.Ship,
icon: FilterImage.Ship,
icon: FilterIcon[MarkerType.Ship],
checked: true
}
]
@ -274,19 +292,23 @@ const filterList = [
const dataQualityList = [
{
title: 'Excellent data quality',
icon: FilterImage.State1
icon: FilterIcon.State1,
checked: true
},
{
title: 'Good data quality',
icon: FilterImage.State2
icon: FilterIcon.State2,
checked: true
},
{
title: 'Poor data quality',
icon: FilterImage.State3
icon: FilterIcon.State3,
checked: true
},
{
title: 'Signal interruption',
icon: FilterImage.State4
icon: FilterIcon.State4,
checked: true
}
]
@ -432,25 +454,28 @@ export default {
//
onPaneChange(active) {
this.active = active
const source = this.circleLayer.getSource()
source.clear() //
switch (active) {
case 1: //
this.drawCircle()
this.emitStationChange()
break
case 2: //
this.emitTypeFilter()
const source = this.circleLayer.getSource()
source.clear()
this.emitFilter()
break
}
},
// Filter Marker
emitTypeFilter() {
this.$emit(
'changeMarkerByType',
this.filterList.filter(item => item.checked).map(item => item.type)
)
emitFilter() {
const filterType = this.filterList.filter(item => item.checked).map(item => item.type)
const filterDataQuality = this.dataQualityList.filter(item => item.checked).map(item => item.title)
this.$emit('filterMarker', {
filterType,
filterDataQuality
})
},
// Radius Marker
@ -472,6 +497,18 @@ export default {
this.checkedKeys = []
},
// Filter
onStationTypeFilterChange(filterItem) {
filterItem.checked = !filterItem.checked
this.emitFilter()
},
//
onDataQualityFilterChange(stateItem) {
stateItem.checked = !stateItem.checked
this.emitFilter()
},
//
async handleSearchByRadius() {
if (!this.radius) {
@ -483,7 +520,7 @@ export default {
return
}
const stationIds = this.checkedKeys.filter(key => !this.treeData.find(leaf => leaf.stationId == key))
const stationIds = this.checkedKeys.filter(key => -1 == key.toString().indexOf('root_'))
try {
this.isGettingInfomationList = true
const {
@ -495,39 +532,48 @@ export default {
stationIds
})
if (success) {
const data = table.flat()
data.forEach((item, index) => {
item.radius = parseFloat(item.radius).toFixed(3)
item.index = index
})
this.dataSource = data // Infomation
const source = this.circleLayer.getSource()
source.clear() //
this.stationList = [] //
markerList.forEach(markerItem => {
// stationId便marker
if (markerItem.stationId) {
//
markerItem.stationType = MarkerType.ImsRnStationG
this.stationList.push(markerItem)
} else {
//
markerItem.stationType = MarkerType.NuclearFacility
markerItem.lon = markerItem.longitude
markerItem.lat = markerItem.latitude
markerItem.stationId = markerItem.facilityId
if (table) {
const data = table.flat()
data.forEach((item, index) => {
item.radius = parseFloat(item.radius).toFixed(3)
item.index = index
})
this.dataSource = data // Infomation
this.stationList = [] //
markerList.forEach(markerItem => {
// stationId便marker
if (markerItem.stationId) {
//
markerItem.stationType = MarkerType.ImsRnStationG
this.stationList.push(markerItem)
} else {
//
markerItem.stationType = MarkerType.NuclearFacility
markerItem.lon = markerItem.longitude
markerItem.lat = markerItem.latitude
markerItem.stationId = markerItem.facilityId
}
})
if (markerList.length) {
//
const firstMarker = markerList[0]
this.$parent.panTo([firstMarker.lon, firstMarker.lat])
}
})
if (markerList.length) {
//
const firstMarker = markerList[0]
this.$parent.panTo([firstMarker.lon, firstMarker.lat])
this.markerList = markerList
this.emitStationChange()
this.drawCircle()
} else {
this.dataSource = []
this.markerList = []
this.emitStationChange()
}
this.markerList = markerList
this.emitStationChange()
this.drawCircle()
} else {
this.$message.error(message)
}
@ -541,7 +587,6 @@ export default {
//
drawCircle() {
const source = this.circleLayer.getSource()
source.clear()
const circleFeatures = []
this.stationList.forEach(stationItem => {
circleFeatures.push(this.getCircle(stationItem))
@ -816,14 +861,16 @@ export default {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
user-select: none;
&:nth-child(3) {
&:nth-child(4) {
img {
margin-left: -10px;
}
}
&:nth-child(4) {
&:nth-child(5) {
img {
margin-left: -12px;
}
@ -844,6 +891,17 @@ export default {
height: 32px;
display: flex;
align-items: center;
display: flex;
justify-content: space-between;
width: 251px;
cursor: pointer;
user-select: none;
align-items: center;
> div {
display: flex;
align-items: center;
}
span {
margin-left: 12px;

View File

@ -1,23 +0,0 @@
import Car from '@/assets/images/station-operation/car-filter.png'
import GroudMonitoringStation from '@/assets/images/station-operation/groud-monitoring-station-filter.png'
import ImsRnStation from '@/assets/images/station-operation/ims-rn-station-filter.png'
import NuclearFacility from '@/assets/images/station-operation/nuclear-facility-filter.png'
import Ship from '@/assets/images/station-operation/ship-filter.png'
import State1 from '@/assets/images/station-operation/station-state-1.png'
import State2 from '@/assets/images/station-operation/station-state-2.png'
import State3 from '@/assets/images/station-operation/station-state-3.png'
import State4 from '@/assets/images/station-operation/station-state-4.png'
export default {
Car,
GroudMonitoringStation,
ImsRnStation,
NuclearFacility,
Ship,
State1,
State2,
State3,
State4
}

View File

@ -4,21 +4,51 @@ import ImsRnStation from '@/assets/images/station-operation/ims-rn-station.png'
import NuclearFacility from '@/assets/images/station-operation/nuclear-facility.png'
import Ship from '@/assets/images/station-operation/ship.png'
import CarFilter from '@/assets/images/station-operation/car-filter.png'
import GroudMonitoringStationFilter from '@/assets/images/station-operation/groud-monitoring-station-filter.png'
import ImsRnStationFilter from '@/assets/images/station-operation/ims-rn-station-filter.png'
import NuclearFacilityFilter from '@/assets/images/station-operation/nuclear-facility-filter.png'
import ShipFilter from '@/assets/images/station-operation/ship-filter.png'
import State1 from '@/assets/images/station-operation/station-state-1.png'
import State2 from '@/assets/images/station-operation/station-state-2.png'
import State3 from '@/assets/images/station-operation/station-state-3.png'
import State4 from '@/assets/images/station-operation/station-state-4.png'
export const MarkerType = {
Car: 'Car',
GroudMonitoringStation: 'Groud monitoring station',
ImsRnStationP: 'IMS STATION(P)',
ImsRnStationG: 'IMS STATION(G)',
NuclearFacility: 'Nuclear Facility',
Ship: 'Ship'
Ship: 'Ship',
NRL: 'NRL',
}
// 地图上Marker的图标
export const MarkerIcon = {
[MarkerType.Car]: Car,
[MarkerType.GroudMonitoringStation]: GroudMonitoringStation,
[MarkerType.ImsRnStationP]: ImsRnStation,
[MarkerType.ImsRnStationG]: ImsRnStation,
[MarkerType.NuclearFacility]: NuclearFacility,
[MarkerType.Ship]: Ship
}
[MarkerType.Ship]: Ship,
[MarkerType.NRL]: ImsRnStation
}
// 面板Filter的图标
export const FilterIcon = {
[MarkerType.Car]: CarFilter,
[MarkerType.GroudMonitoringStation]: GroudMonitoringStationFilter,
[MarkerType.ImsRnStationP]: ImsRnStationFilter,
[MarkerType.ImsRnStationG]: ImsRnStationFilter,
[MarkerType.NuclearFacility]: NuclearFacilityFilter,
[MarkerType.Ship]: ShipFilter,
[MarkerType.NRL]: ImsRnStationFilter,
State1,
State2,
State3,
State4
}

View File

@ -144,7 +144,7 @@
ref="mapPane"
:treeData="treeData"
@changeMarker="onChangeMarker"
@changeMarkerByType="onChangeMarkerByType"
@filterMarker="onFilterMarker"
/>
</Map>
</div>
@ -256,7 +256,14 @@ export default {
try {
const { success, result, message } = await getAction('/stationOperation/findTree')
if (success) {
result.forEach(item => (item.stationCode = item.code))
result.forEach(item => {
item.stationCode = item.code
item.stationId = `root_${item.stationId}`
item.children.forEach(child => {
child.stationCode = child.code
child.stationId = `${item.stationId}_parent_${child.stationId}`
})
})
this.treeData = result
} else {
this.$message.error(message)
@ -331,10 +338,10 @@ export default {
/**
* 根据类型筛选地图上的marker列表
* @param {Array<string>} typeList
*/
onChangeMarkerByType(typeList) {
this.markerList = this.originalDataList.filter(item => typeList.includes(item.stationType))
onFilterMarker({ filterType, filterDataQuality }) {
console.log('%c [ filterType, filterDataQuality ]-343', 'font-size:13px; background:pink; color:#bf2c9f;', filterType, filterDataQuality)
this.markerList = this.originalDataList.filter(item => filterType.includes(item.stationType))
},
//
@ -500,6 +507,10 @@ export default {
align-items: center;
transition: height 0.3s ease-in-out;
overflow: hidden;
.ant-input-search {
margin-right: 10px;
}
}
&-content {