fix: 修改地图上圆圈的绘制方式,以修复多个世界中出现重复圆圈的问题

This commit is contained in:
Xu Zhimeng 2023-06-26 17:43:04 +08:00
parent 33c7a82f84
commit 4f36221391
3 changed files with 102 additions and 56 deletions

View File

@ -27,6 +27,13 @@ export default {
list: { list: {
type: Array, type: Array,
required: true required: true
},
markerType: {
type: Number,
default: 1
},
radius: {
type: Number
} }
}, },
data() { data() {
@ -39,6 +46,11 @@ export default {
}, },
mounted() { mounted() {
this.map = this.$parent.getMapInstance() this.map = this.$parent.getMapInstance()
this.map.getView().on('change:resolution', () => {
//
this.changeCircleRadius()
})
this.getStationInfo = debounce(stationInfo => { this.getStationInfo = debounce(stationInfo => {
// //
if (this.isHover) { if (this.isHover) {
@ -47,6 +59,60 @@ export default {
}, 0) }, 0)
}, },
methods: { methods: {
initCircles() {
const circleRadius = this.getRadius() * 2
this.list
.filter(
stationInfo =>
stationInfo.stationType !== MarkerType.NuclearFacility && stationInfo.stationType !== MarkerType.NRL
)
.forEach(stationInfo => {
this.map.addOverlay(this.getCircle(stationInfo, circleRadius))
})
},
getCircle({ lon, lat, stationType, stationId }, circleRadius) {
const circleDiv = document.createElement('div')
circleDiv.className = 'custom-map-circle'
circleDiv.style.width = circleRadius + 'px'
circleDiv.style.height = circleRadius + 'px'
circleDiv.style.borderRadius = '50%'
circleDiv.style.backgroundColor = 'rgba(255, 0, 0, .4)'
return new Overlay({
position: fromLonLat([lon, lat]),
element: circleDiv,
id: `circle_${stationType}_${stationId}`,
positioning: 'center-center',
className: 'circle-overlay'
})
},
//
changeCircleRadius() {
const overlays = this.map.getOverlays().getArray()
const circleOverlays = overlays.filter(item => item.id.indexOf('circle') == 0) // id
const circleRadius = this.getRadius() * 2
circleOverlays.forEach(circle => {
const circleEle = circle.getElement()
circleEle.style.width = circleRadius + 'px'
circleEle.style.height = circleRadius + 'px'
})
},
//
getRadius() {
const metersPerUnit = this.map
.getView()
.getProjection()
.getMetersPerUnit()
const distance = (this.radius * 1000) / metersPerUnit
const resolution = this.map.getView().getResolution()
return distance / resolution
},
// marker // marker
initMarkers() { initMarkers() {
this.list.forEach(stationInfo => { this.list.forEach(stationInfo => {
@ -78,7 +144,7 @@ export default {
return new Overlay({ return new Overlay({
position: fromLonLat([lon, lat]), position: fromLonLat([lon, lat]),
element: img, element: img,
id: `${stationInfo.stationType}_${stationInfo.stationId}`, id: `marker_${stationInfo.stationType}_${stationInfo.stationId}`,
positioning: 'center-center' positioning: 'center-center'
}) })
}, },
@ -107,7 +173,8 @@ export default {
position: fromLonLat([lon, lat]), position: fromLonLat([lon, lat]),
element: rippleDiv, element: rippleDiv,
id: `ripple_${stationType}_${stationId}`, id: `ripple_${stationType}_${stationId}`,
positioning: 'center-center' positioning: 'center-center',
className: 'ripple-overlay'
}) })
}, },
@ -164,6 +231,9 @@ export default {
this.initMapPopup() this.initMapPopup()
this.initMarkers() this.initMarkers()
this.initRipples() this.initRipples()
if (this.markerType == 2) {
this.initCircles()
}
} }
} }
} }
@ -227,10 +297,10 @@ export default {
.custom-ripple { .custom-ripple {
width: 85px; width: 85px;
height: 85px; height: 85px;
z-index: -1;
@duration: 1.8s; @duration: 1.8s;
@delay: 0.9s; @delay: 0.9s;
.inner-ripple-1 { .inner-ripple-1 {
position: absolute; position: absolute;
top: 0; top: 0;
@ -240,6 +310,7 @@ export default {
background-image: radial-gradient(circle, transparent 10%, rgba(15, 148, 28, 0.2) 30%, rgba(15, 148, 28, 0.5) 60%); 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; animation: rippleEffect @duration linear 0s infinite;
} }
.inner-ripple-2 { .inner-ripple-2 {
position: absolute; position: absolute;
top: 0; top: 0;
@ -262,4 +333,9 @@ export default {
opacity: 0; opacity: 0;
} }
} }
.ripple-overlay,
.circle-overlay {
pointer-events: none !important;
}
</style> </style>

View File

@ -473,10 +473,11 @@ export default {
source.clear() // source.clear() //
switch (active) { switch (active) {
case 1: // case 1: //
this.drawCircle() this.emitDrawCircle(2)
this.emitStationChange() this.emitStationChange()
break break
case 2: // case 2: //
this.emitDrawCircle(1)
this.emitFilter() this.emitFilter()
break break
} }
@ -581,9 +582,8 @@ export default {
} }
this.markerList = markerList this.markerList = markerList
this.emitDrawCircle(2)
this.emitStationChange() this.emitStationChange()
this.drawCircle()
} else { } else {
this.dataSource = [] this.dataSource = []
this.markerList = [] this.markerList = []
@ -600,52 +600,8 @@ export default {
}, },
// //
drawCircle() { emitDrawCircle(markerType) {
const source = this.circleLayer.getSource() this.$emit('drawCircle', { markerType, radius: this.radius })
const circleFeatures = []
this.stationList.forEach(stationItem => {
circleFeatures.push(this.getCircle(stationItem))
})
source.addFeatures(circleFeatures)
},
getCircle(stationInfo) {
const { lon, lat } = stationInfo
//
const fill = new Fill({
color: 'rgba(255, 0, 0, .4)' //
})
//
const stroke = new Stroke({
color: 'rgba(255, 0, 0, .4)', //
width: 1 //
})
//
const style = new Style({
fill: fill,
stroke: stroke
})
const circle = new Circle(fromLonLat([lon, lat]), this.getRadius())
const feature = new Feature({
geometry: circle,
style: style
})
feature.setStyle(style)
return feature
},
//
getRadius() {
const metersPerUnit = this.map
.getView()
.getProjection()
.getMetersPerUnit()
const circleRadius = (this.radius * 1000) / metersPerUnit
return circleRadius
}, },
// //

View File

@ -144,8 +144,14 @@
ref="mapRef" ref="mapRef"
token="AAPK2b935e8bbf564ef581ca3c6fcaa5f2a71ZH84cPqqFvyz3KplFRHP8HyAwJJkh6cnpcQ-qkWh5aiyDQsGJbsXglGx0QM2cPm" token="AAPK2b935e8bbf564ef581ca3c6fcaa5f2a71ZH84cPqqFvyz3KplFRHP8HyAwJJkh6cnpcQ-qkWh5aiyDQsGJbsXglGx0QM2cPm"
> >
<MapMarker :list="markerList" @markerClick="onMarkerClick" /> <MapMarker :list="markerList" :marker-type="markerType" :radius="circleRadius" @markerClick="onMarkerClick" />
<MapPane ref="mapPane" :treeData="treeData" @changeMarker="onChangeMarker" @filterMarker="onFilterMarker" /> <MapPane
ref="mapPane"
:treeData="treeData"
@changeMarker="onChangeMarker"
@filterMarker="onFilterMarker"
@drawCircle="onDrawCircle"
/>
</Map> </Map>
</div> </div>
</div> </div>
@ -177,6 +183,8 @@ export default {
dataList: [], // All Data dataList: [], // All Data
followedDataList: [], // followedDataList: [], //
markerList: [], // markerList: [], //
markerType: 1, //
circleRadius: 0,
searchPlacementVisible: false, // searchPlacementVisible: false, //
@ -355,6 +363,12 @@ export default {
this.markerList = markerList this.markerList = markerList
}, },
//
onDrawCircle({ markerType, radius }) {
this.markerType = markerType
this.circleRadius = radius
},
/** /**
* 根据类型筛选地图上的marker列表 * 根据类型筛选地图上的marker列表
*/ */
@ -413,7 +427,7 @@ export default {
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
text-align: center; text-align: center;
color: #00E9FE; color: #00e9fe;
background-color: #021a1d; background-color: #021a1d;
} }
@ -431,7 +445,7 @@ export default {
&-active { &-active {
.ant-collapse-arrow { .ant-collapse-arrow {
transform: translateY(-50%) rotate(-90deg) transform: translateY(-50%) rotate(-90deg);
} }
} }
} }