|
|
@@ -5,7 +5,7 @@
|
|
|
<script setup>
|
|
|
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
|
import { convertCoord } from '@/utils/coordTransform'
|
|
|
-import { getMonitoringPointColor } from '@/utils/gisMapColors'
|
|
|
+import { getMonitoringPointColor, getMonitoringPointIcon } from '@/utils/gisMapColors'
|
|
|
|
|
|
const props = defineProps({
|
|
|
points: { type: Array, default: () => [] },
|
|
|
@@ -82,37 +82,45 @@ function clearScene() {
|
|
|
overlays = []
|
|
|
}
|
|
|
|
|
|
-function markerHtml(color, name) {
|
|
|
- const size = props.markerSize
|
|
|
- const nameHtml = props.showMarkerName && name ? `<div class="marker-text">${escapeHtml(name)}</div>` : ''
|
|
|
- return `<div class="marker-wrap" style="cursor:pointer"><div style="width:${size}px;height:${size}px;background:${color};border-radius:50%;border:3px solid #fff;box-shadow:0 2px 8px rgba(0,0,0,0.25);margin:0 auto;"></div>${nameHtml}</div>`
|
|
|
-}
|
|
|
-
|
|
|
-function escapeHtml(value) {
|
|
|
- return String(value ?? '')
|
|
|
- .replaceAll('&', '&')
|
|
|
- .replaceAll('<', '<')
|
|
|
- .replaceAll('>', '>')
|
|
|
- .replaceAll('"', '"')
|
|
|
- .replaceAll("'", ''')
|
|
|
+function createMarkerIcon(BMapGL, iconUrl, size) {
|
|
|
+ const icon = new BMapGL.Icon(iconUrl, new BMapGL.Size(size, size), {
|
|
|
+ anchor: new BMapGL.Size(size / 2, size),
|
|
|
+ imageSize: new BMapGL.Size(size, size)
|
|
|
+ })
|
|
|
+ return icon
|
|
|
}
|
|
|
|
|
|
function addPointMarker(BMapGL, point) {
|
|
|
if (!Number.isFinite(Number(point.lng)) || !Number.isFinite(Number(point.lat))) return
|
|
|
const [lng, lat] = convertCoord(point.lng, point.lat)
|
|
|
const color = point.color || getMonitoringPointColor(point)
|
|
|
+ const iconUrl = point.iconUrl || getMonitoringPointIcon(point)
|
|
|
const name = point.name || point.equipmentName || point.facilityName || point.label || ''
|
|
|
- const label = new BMapGL.Label(markerHtml(color, name), {
|
|
|
- position: new BMapGL.Point(lng, lat),
|
|
|
- offset: new BMapGL.Size(-props.markerSize / 2 - 3, -props.markerSize - 8)
|
|
|
+ const position = new BMapGL.Point(lng, lat)
|
|
|
+ const marker = new BMapGL.Marker(position, {
|
|
|
+ icon: createMarkerIcon(BMapGL, iconUrl, props.markerSize),
|
|
|
+ enableDragging: false
|
|
|
})
|
|
|
- label.setStyle({ border: 'none', background: 'transparent', padding: '0' })
|
|
|
- label.addEventListener('click', (event) => {
|
|
|
+ marker.addEventListener('click', (event) => {
|
|
|
event?.domEvent?.stopPropagation?.()
|
|
|
emit('point-click', point)
|
|
|
})
|
|
|
- mapInstance.addOverlay(label)
|
|
|
- overlays.push(label)
|
|
|
+ mapInstance.addOverlay(marker)
|
|
|
+ overlays.push(marker)
|
|
|
+
|
|
|
+ if (props.showMarkerName && name) {
|
|
|
+ const label = new BMapGL.Label(`<div class="marker-text">${escapeHtml(name)}</div>`, {
|
|
|
+ position,
|
|
|
+ offset: new BMapGL.Size(-90, -props.markerSize - 28)
|
|
|
+ })
|
|
|
+ label.setStyle({ border: 'none', background: 'transparent', padding: '0' })
|
|
|
+ label.addEventListener('click', (event) => {
|
|
|
+ event?.domEvent?.stopPropagation?.()
|
|
|
+ emit('point-click', point)
|
|
|
+ })
|
|
|
+ mapInstance.addOverlay(label)
|
|
|
+ overlays.push(label)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function addLine(BMapGL, line) {
|
|
|
@@ -221,14 +229,35 @@ defineExpose({
|
|
|
}
|
|
|
|
|
|
.marker-text {
|
|
|
- margin-top: 4px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ width: 180px;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ padding: 2px 6px;
|
|
|
+ overflow: hidden;
|
|
|
color: #22405c;
|
|
|
+ background: rgba(255, 255, 255, 0.92);
|
|
|
+ border: 1px solid rgba(118, 151, 181, 0.32);
|
|
|
+ border-radius: 4px;
|
|
|
+ box-shadow: 0 2px 6px rgba(31, 74, 121, 0.12);
|
|
|
font-size: 12px;
|
|
|
+ line-height: 16px;
|
|
|
font-weight: 600;
|
|
|
text-align: center;
|
|
|
+ text-overflow: ellipsis;
|
|
|
white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
+.marker-wrap {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.marker-icon {
|
|
|
+ display: block;
|
|
|
+ object-fit: contain;
|
|
|
+}
|
|
|
+
|
|
|
.pipe-label {
|
|
|
color: #2563eb;
|
|
|
font-size: 12px;
|