|
@@ -101,10 +101,10 @@
|
|
|
<el-button size="small" :icon="ZoomOut" @click="zoomOut">缩小</el-button>
|
|
<el-button size="small" :icon="ZoomOut" @click="zoomOut">缩小</el-button>
|
|
|
<el-button size="small" :icon="Location" @click="fitBounds">重置</el-button>
|
|
<el-button size="small" :icon="Location" @click="fitBounds">重置</el-button>
|
|
|
</el-button-group>
|
|
</el-button-group>
|
|
|
- <div class="coordinate-info">坐标: {{ currentLng.toFixed(4) }}, {{ currentLat.toFixed(4) }}</div>
|
|
|
|
|
|
|
+ <div class="coordinate-info">坐标: {{ currentLng.toFixed(4) }}, {{ currentLat.toFixed(4) }}<span class="map-hint"> · 放大地图查看管段标签</span></div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="map-wrapper">
|
|
<div class="map-wrapper">
|
|
|
- <div id="riskAssessmentBaiduMap" class="map-div"></div>
|
|
|
|
|
|
|
+ <div id="riskAssessmentTdtMap" class="map-div"></div>
|
|
|
<div v-if="mapError" class="map-error">{{ mapError }}</div>
|
|
<div v-if="mapError" class="map-error">{{ mapError }}</div>
|
|
|
<!-- 悬浮信息卡 -->
|
|
<!-- 悬浮信息卡 -->
|
|
|
<div v-if="hoverPipeline" class="hover-card" :style="{ top: hoverY + 'px', left: hoverX + 'px' }">
|
|
<div v-if="hoverPipeline" class="hover-card" :style="{ top: hoverY + 'px', left: hoverX + 'px' }">
|
|
@@ -157,6 +157,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
|
|
+import { ensureTdtMap } from '@/utils/mapApi'
|
|
|
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
|
|
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
|
|
|
import { MapLocation, Search, Refresh, FullScreen, Location, ZoomIn, ZoomOut } from '@element-plus/icons-vue'
|
|
import { MapLocation, Search, Refresh, FullScreen, Location, ZoomIn, ZoomOut } from '@element-plus/icons-vue'
|
|
|
import { ElMessage } from 'element-plus'
|
|
import { ElMessage } from 'element-plus'
|
|
@@ -165,7 +166,7 @@ import { convertPipeline, convertPoints, convertCoord } from '@/utils/coordTrans
|
|
|
import { getGisPipeLines } from '@/api/pipeNetwork/basic'
|
|
import { getGisPipeLines } from '@/api/pipeNetwork/basic'
|
|
|
import { getGasRiskAssessments } from '@/api/pipeNetwork/hazard'
|
|
import { getGasRiskAssessments } from '@/api/pipeNetwork/hazard'
|
|
|
|
|
|
|
|
-// ==================== 百度地图初始化 ====================
|
|
|
|
|
|
|
+// ==================== 天地图初始化 ====================
|
|
|
const MAP_CENTER = { lng: 110.386, lat: 28.445 }
|
|
const MAP_CENTER = { lng: 110.386, lat: 28.445 }
|
|
|
const MAP_DEFAULT_ZOOM = 14
|
|
const MAP_DEFAULT_ZOOM = 14
|
|
|
|
|
|
|
@@ -178,30 +179,32 @@ const overlayStore = {
|
|
|
high: [], medium: [], low: [], hazard: [], target: []
|
|
high: [], medium: [], low: [], hazard: [], target: []
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function waitForBMapGL() {
|
|
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
|
|
- let attempts = 0
|
|
|
|
|
- const timer = setInterval(() => {
|
|
|
|
|
- attempts++
|
|
|
|
|
- if (window.BMapGL) { clearInterval(timer); resolve(window.BMapGL) }
|
|
|
|
|
- if (attempts > 150) { clearInterval(timer); reject(new Error('百度地图API加载超时')) }
|
|
|
|
|
- }, 200)
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
|
|
+/** 管段标签独立成层:低缩放/密集区域不逐条渲染,按风险等级优先做屏幕网格抽稀 */
|
|
|
|
|
+const RISK_COLOR = { high: '#f56c6c', medium: '#e6a23c', low: '#67c23a' }
|
|
|
|
|
+const RISK_TEXT_COLOR = { high: '#b91c1c', medium: '#b45309', low: '#15803d' }
|
|
|
|
|
+const RISK_PRIORITY = { high: 0, medium: 1, low: 2 }
|
|
|
|
|
+const LABEL_FONT = "'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif"
|
|
|
|
|
+const LABEL_MIN_ZOOM = 15
|
|
|
|
|
+const LABEL_CELL = { x: 120, y: 44 }
|
|
|
|
|
+const pipelineLabels = []
|
|
|
|
|
+let labelTimer = null
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
|
|
|
function initMap() {
|
|
function initMap() {
|
|
|
- const BMapGL = window.BMapGL
|
|
|
|
|
- const el = document.getElementById('riskAssessmentBaiduMap')
|
|
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
|
|
+ const el = document.getElementById('riskAssessmentTdtMap')
|
|
|
if (!el) return
|
|
if (!el) return
|
|
|
- mapInstance = new BMapGL.Map(el, { enableMapClick: true })
|
|
|
|
|
|
|
+ mapInstance = new TdtMap.Map(el, { enableMapClick: true })
|
|
|
const [clng, clat] = convertCoord(MAP_CENTER.lng, MAP_CENTER.lat)
|
|
const [clng, clat] = convertCoord(MAP_CENTER.lng, MAP_CENTER.lat)
|
|
|
- mapInstance.centerAndZoom(new BMapGL.Point(clng, clat), MAP_DEFAULT_ZOOM)
|
|
|
|
|
|
|
+ mapInstance.centerAndZoom(new TdtMap.Point(clng, clat), MAP_DEFAULT_ZOOM)
|
|
|
mapInstance.enableScrollWheelZoom(true)
|
|
mapInstance.enableScrollWheelZoom(true)
|
|
|
- mapInstance.setMapStyleV2({ styleId: 'a0f4e6e6f9e7a6c5d8e7f7e7f7e7f7e5' })
|
|
|
|
|
mapInstance.addEventListener('mousemove', (e) => {
|
|
mapInstance.addEventListener('mousemove', (e) => {
|
|
|
currentLng.value = e.latlng.lng
|
|
currentLng.value = e.latlng.lng
|
|
|
currentLat.value = e.latlng.lat
|
|
currentLat.value = e.latlng.lat
|
|
|
})
|
|
})
|
|
|
|
|
+ mapInstance.addEventListener('zoomend', scheduleLabels)
|
|
|
|
|
+ mapInstance.addEventListener('moveend', scheduleLabels)
|
|
|
renderAllOverlays()
|
|
renderAllOverlays()
|
|
|
// 风险接口和地图接口是并行加载的,若数据先返回,这里补一次按真实管线范围定位。
|
|
// 风险接口和地图接口是并行加载的,若数据先返回,这里补一次按真实管线范围定位。
|
|
|
fitBounds()
|
|
fitBounds()
|
|
@@ -367,6 +370,7 @@ async function loadRiskData() {
|
|
|
|
|
|
|
|
// ==================== 地图覆盖物渲染 ====================
|
|
// ==================== 地图覆盖物渲染 ====================
|
|
|
function clearOverlays() {
|
|
function clearOverlays() {
|
|
|
|
|
+ clearPipelineLabels()
|
|
|
Object.values(overlayStore).forEach(arr => {
|
|
Object.values(overlayStore).forEach(arr => {
|
|
|
arr.forEach(o => { try { mapInstance.removeOverlay(o) } catch {} })
|
|
arr.forEach(o => { try { mapInstance.removeOverlay(o) } catch {} })
|
|
|
arr.length = 0
|
|
arr.length = 0
|
|
@@ -378,14 +382,14 @@ function addToStore(layer, overlay) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function renderPipelines() {
|
|
function renderPipelines() {
|
|
|
- const BMapGL = window.BMapGL
|
|
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
filteredPipelines.value.forEach(p => {
|
|
filteredPipelines.value.forEach(p => {
|
|
|
if (!Array.isArray(p.path) || p.path.length < 2) return
|
|
if (!Array.isArray(p.path) || p.path.length < 2) return
|
|
|
const layerKey = p.riskLevel
|
|
const layerKey = p.riskLevel
|
|
|
- const points = p.path.map(c => { const [lng, lat] = convertCoord(c[0], c[1]); return new BMapGL.Point(lng, lat) })
|
|
|
|
|
|
|
+ const points = p.path.map(c => { const [lng, lat] = convertCoord(c[0], c[1]); return new TdtMap.Point(lng, lat) })
|
|
|
const color = p.riskLevel === 'high' ? '#f56c6c' : p.riskLevel === 'medium' ? '#e6a23c' : '#67c23a'
|
|
const color = p.riskLevel === 'high' ? '#f56c6c' : p.riskLevel === 'medium' ? '#e6a23c' : '#67c23a'
|
|
|
const weight = p.riskLevel === 'high' ? 6 : p.riskLevel === 'medium' ? 5 : 4
|
|
const weight = p.riskLevel === 'high' ? 6 : p.riskLevel === 'medium' ? 5 : 4
|
|
|
- const polyline = new BMapGL.Polyline(points, {
|
|
|
|
|
|
|
+ const polyline = new TdtMap.Polyline(points, {
|
|
|
strokeColor: color, strokeWeight: weight, strokeOpacity: 0.8
|
|
strokeColor: color, strokeWeight: weight, strokeOpacity: 0.8
|
|
|
})
|
|
})
|
|
|
mapInstance.addOverlay(polyline)
|
|
mapInstance.addOverlay(polyline)
|
|
@@ -405,49 +409,29 @@ function renderPipelines() {
|
|
|
hoverPipeline.value = null
|
|
hoverPipeline.value = null
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- // 管线名称标签
|
|
|
|
|
- const mid = Math.floor(points.length / 2)
|
|
|
|
|
- const scoreLabel = new BMapGL.Label(p.riskScore + '分', {
|
|
|
|
|
- position: points[mid],
|
|
|
|
|
- offset: new BMapGL.Size(0, -16)
|
|
|
|
|
- })
|
|
|
|
|
- scoreLabel.setStyle({
|
|
|
|
|
- color: '#fff', fontSize: '11px', fontWeight: 'bold', padding: '2px 8px',
|
|
|
|
|
- backgroundColor: color, borderRadius: '10px', border: 'none', whiteSpace: 'nowrap'
|
|
|
|
|
- })
|
|
|
|
|
- mapInstance.addOverlay(scoreLabel)
|
|
|
|
|
- addToStore(layerKey, scoreLabel)
|
|
|
|
|
-
|
|
|
|
|
- const nameLabel = new BMapGL.Label(p.name, {
|
|
|
|
|
- position: points[mid],
|
|
|
|
|
- offset: new BMapGL.Size(0, 4)
|
|
|
|
|
- })
|
|
|
|
|
- nameLabel.setStyle({
|
|
|
|
|
- color: '#333', fontSize: '10px', padding: '1px 4px',
|
|
|
|
|
- backgroundColor: 'rgba(255,255,255,0.85)', borderRadius: '2px', border: 'none', whiteSpace: 'nowrap'
|
|
|
|
|
- })
|
|
|
|
|
- mapInstance.addOverlay(nameLabel)
|
|
|
|
|
- addToStore(layerKey, nameLabel)
|
|
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function renderHazardPoints() {
|
|
function renderHazardPoints() {
|
|
|
- const BMapGL = window.BMapGL
|
|
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
hazardPoints.value.forEach(h => {
|
|
hazardPoints.value.forEach(h => {
|
|
|
const [hlng, hlat] = convertCoord(h.lng, h.lat)
|
|
const [hlng, hlat] = convertCoord(h.lng, h.lat)
|
|
|
- const pt = new BMapGL.Point(hlng, hlat)
|
|
|
|
|
- const label = new BMapGL.Label(h.name, {
|
|
|
|
|
|
|
+ const pt = new TdtMap.Point(hlng, hlat)
|
|
|
|
|
+ const label = new TdtMap.Label(h.name, {
|
|
|
position: pt,
|
|
position: pt,
|
|
|
- offset: new BMapGL.Size(0, -18)
|
|
|
|
|
|
|
+ offset: new TdtMap.Size(0, -18)
|
|
|
})
|
|
})
|
|
|
label.setStyle({
|
|
label.setStyle({
|
|
|
- color: '#fff', fontSize: '10px', padding: '3px 8px',
|
|
|
|
|
- backgroundColor: '#9b59b6', borderRadius: '3px', border: 'none', whiteSpace: 'nowrap'
|
|
|
|
|
|
|
+ fontFamily: LABEL_FONT, fontSize: '12px', fontWeight: 600,
|
|
|
|
|
+ color: '#fff', padding: '3px 9px', textShadow: '0 1px 1px rgba(0,0,0,.4)',
|
|
|
|
|
+ backgroundColor: '#8b46a8', borderRadius: '4px',
|
|
|
|
|
+ border: '1px solid rgba(255,255,255,.85)',
|
|
|
|
|
+ boxShadow: '0 2px 6px rgba(15,23,42,.3)', whiteSpace: 'nowrap'
|
|
|
})
|
|
})
|
|
|
mapInstance.addOverlay(label)
|
|
mapInstance.addOverlay(label)
|
|
|
addToStore('hazard', label)
|
|
addToStore('hazard', label)
|
|
|
|
|
|
|
|
- const marker = new BMapGL.Marker(pt)
|
|
|
|
|
|
|
+ const marker = new TdtMap.Marker(pt)
|
|
|
mapInstance.addOverlay(marker)
|
|
mapInstance.addOverlay(marker)
|
|
|
addToStore('hazard', marker)
|
|
addToStore('hazard', marker)
|
|
|
|
|
|
|
@@ -466,22 +450,25 @@ function renderHazardPoints() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function renderTargetPoints() {
|
|
function renderTargetPoints() {
|
|
|
- const BMapGL = window.BMapGL
|
|
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
targetPoints.value.forEach(t => {
|
|
targetPoints.value.forEach(t => {
|
|
|
const [tlng, tlat] = convertCoord(t.lng, t.lat)
|
|
const [tlng, tlat] = convertCoord(t.lng, t.lat)
|
|
|
- const pt = new BMapGL.Point(tlng, tlat)
|
|
|
|
|
- const label = new BMapGL.Label(t.name, {
|
|
|
|
|
|
|
+ const pt = new TdtMap.Point(tlng, tlat)
|
|
|
|
|
+ const label = new TdtMap.Label(t.name, {
|
|
|
position: pt,
|
|
position: pt,
|
|
|
- offset: new BMapGL.Size(0, -18)
|
|
|
|
|
|
|
+ offset: new TdtMap.Size(0, -18)
|
|
|
})
|
|
})
|
|
|
label.setStyle({
|
|
label.setStyle({
|
|
|
- color: '#fff', fontSize: '10px', padding: '3px 8px',
|
|
|
|
|
- backgroundColor: '#409eff', borderRadius: '3px', border: 'none', whiteSpace: 'nowrap'
|
|
|
|
|
|
|
+ fontFamily: LABEL_FONT, fontSize: '12px', fontWeight: 600,
|
|
|
|
|
+ color: '#fff', padding: '3px 9px', textShadow: '0 1px 1px rgba(0,0,0,.4)',
|
|
|
|
|
+ backgroundColor: '#1d6fd0', borderRadius: '4px',
|
|
|
|
|
+ border: '1px solid rgba(255,255,255,.85)',
|
|
|
|
|
+ boxShadow: '0 2px 6px rgba(15,23,42,.3)', whiteSpace: 'nowrap'
|
|
|
})
|
|
})
|
|
|
mapInstance.addOverlay(label)
|
|
mapInstance.addOverlay(label)
|
|
|
addToStore('target', label)
|
|
addToStore('target', label)
|
|
|
|
|
|
|
|
- const marker = new BMapGL.Marker(pt)
|
|
|
|
|
|
|
+ const marker = new TdtMap.Marker(pt)
|
|
|
mapInstance.addOverlay(marker)
|
|
mapInstance.addOverlay(marker)
|
|
|
addToStore('target', marker)
|
|
addToStore('target', marker)
|
|
|
|
|
|
|
@@ -499,6 +486,80 @@ function renderTargetPoints() {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function escapeLabel(value) {
|
|
|
|
|
+ return String(value ?? '').replace(/[&<>"']/g, ch => ({
|
|
|
|
|
+ '&': '&', '<': '<', '>': '>', '"': '"', "'": '''
|
|
|
|
|
+ }[ch]))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function pipelineLabelText(pipeline, count) {
|
|
|
|
|
+ const name = escapeLabel(pipeline.name || pipeline.code || '管段')
|
|
|
|
|
+ const score = Number.isFinite(Number(pipeline.riskScore)) ? pipeline.riskScore + '分' : '—'
|
|
|
|
|
+ const scoreColor = RISK_TEXT_COLOR[pipeline.riskLevel] || RISK_TEXT_COLOR.low
|
|
|
|
|
+ const more = count > 1
|
|
|
|
|
+ ? '<span style="margin-left:6px;padding:0 5px;border-radius:8px;background:#e2e8f0;color:#334155;font-size:11px">+' + (count - 1) + '</span>'
|
|
|
|
|
+ : ''
|
|
|
|
|
+ return '<span style="color:#111827">' + name + '</span>'
|
|
|
|
|
+ + '<span style="margin-left:6px;color:' + scoreColor + '">' + score + '</span>'
|
|
|
|
|
+ + more
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function clearPipelineLabels() {
|
|
|
|
|
+ pipelineLabels.forEach(label => { try { mapInstance.removeOverlay(label) } catch {} })
|
|
|
|
|
+ pipelineLabels.length = 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/** 只在放大后或高/中风险时显示标签;同一屏幕网格只保留一个,其余合并为 +N */
|
|
|
|
|
+function renderPipelineLabels() {
|
|
|
|
|
+ if (!mapInstance || !window.TdtMap) return
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
|
|
+ clearPipelineLabels()
|
|
|
|
|
+ const zoom = Number(mapInstance.getZoom?.() || 0)
|
|
|
|
|
+ const visible = new Set(visibleLayers.value)
|
|
|
|
|
+ const candidates = filteredPipelines.value
|
|
|
|
|
+ .filter(p => visible.has(p.riskLevel) && Array.isArray(p.path) && p.path.length >= 2)
|
|
|
|
|
+ .filter(p => p.riskLevel !== 'low' || zoom >= LABEL_MIN_ZOOM)
|
|
|
|
|
+ .sort((a, b) => (RISK_PRIORITY[a.riskLevel] ?? 9) - (RISK_PRIORITY[b.riskLevel] ?? 9))
|
|
|
|
|
+
|
|
|
|
|
+ const cells = new Map()
|
|
|
|
|
+ candidates.forEach(p => {
|
|
|
|
|
+ const mid = p.path[Math.floor(p.path.length / 2)]
|
|
|
|
|
+ const [lng, lat] = convertCoord(Number(mid?.[0]), Number(mid?.[1]))
|
|
|
|
|
+ if (!Number.isFinite(lng) || !Number.isFinite(lat)) return
|
|
|
|
|
+ const point = new TdtMap.Point(lng, lat)
|
|
|
|
|
+ const pixel = mapInstance.pointToPixel(point)
|
|
|
|
|
+ if (!Number.isFinite(pixel?.x) || !Number.isFinite(pixel?.y)) return
|
|
|
|
|
+ const key = Math.floor(pixel.x / LABEL_CELL.x) + '_' + Math.floor(pixel.y / LABEL_CELL.y)
|
|
|
|
|
+ const hit = cells.get(key)
|
|
|
|
|
+ if (hit) {
|
|
|
|
|
+ hit.count += 1
|
|
|
|
|
+ hit.label.setContent(pipelineLabelText(hit.pipeline, hit.count))
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const label = new TdtMap.Label(pipelineLabelText(p, 1), {
|
|
|
|
|
+ position: point,
|
|
|
|
|
+ offset: new TdtMap.Size(0, -18)
|
|
|
|
|
+ })
|
|
|
|
|
+ label.setStyle({
|
|
|
|
|
+ fontFamily: LABEL_FONT, fontSize: '12px', fontWeight: 600, lineHeight: '18px',
|
|
|
|
|
+ color: '#111827', padding: '3px 9px',
|
|
|
|
|
+ backgroundColor: 'rgba(255,255,255,0.97)',
|
|
|
|
|
+ border: '1px solid #cbd5e1',
|
|
|
|
|
+ borderLeft: '3px solid ' + (RISK_COLOR[p.riskLevel] || RISK_COLOR.low),
|
|
|
|
|
+ borderRadius: '4px', boxShadow: '0 2px 6px rgba(15,23,42,.28)',
|
|
|
|
|
+ whiteSpace: 'nowrap', pointerEvents: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ mapInstance.addOverlay(label)
|
|
|
|
|
+ pipelineLabels.push(label)
|
|
|
|
|
+ cells.set(key, { label, pipeline: p, count: 1 })
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function scheduleLabels() {
|
|
|
|
|
+ clearTimeout(labelTimer)
|
|
|
|
|
+ labelTimer = setTimeout(renderPipelineLabels, 120)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function renderAllOverlays() {
|
|
function renderAllOverlays() {
|
|
|
clearOverlays()
|
|
clearOverlays()
|
|
|
renderPipelines()
|
|
renderPipelines()
|
|
@@ -517,6 +578,7 @@ function onLayerChange() {
|
|
|
} catch {}
|
|
} catch {}
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
+ scheduleLabels()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function onScoreFilter() {
|
|
function onScoreFilter() {
|
|
@@ -534,25 +596,25 @@ function zoomOut() {
|
|
|
|
|
|
|
|
function fitBounds() {
|
|
function fitBounds() {
|
|
|
if (mapInstance) {
|
|
if (mapInstance) {
|
|
|
- const BMapGL = window.BMapGL
|
|
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
const coordinates = filteredPipelines.value
|
|
const coordinates = filteredPipelines.value
|
|
|
.flatMap(p => Array.isArray(p.path) ? p.path : [])
|
|
.flatMap(p => Array.isArray(p.path) ? p.path : [])
|
|
|
.filter(c => Number.isFinite(Number(c?.[0])) && Number.isFinite(Number(c?.[1])))
|
|
.filter(c => Number.isFinite(Number(c?.[0])) && Number.isFinite(Number(c?.[1])))
|
|
|
if (coordinates.length >= 2) {
|
|
if (coordinates.length >= 2) {
|
|
|
const points = coordinates.map(c => {
|
|
const points = coordinates.map(c => {
|
|
|
const [lng, lat] = convertCoord(Number(c[0]), Number(c[1]))
|
|
const [lng, lat] = convertCoord(Number(c[0]), Number(c[1]))
|
|
|
- return new BMapGL.Point(lng, lat)
|
|
|
|
|
|
|
+ return new TdtMap.Point(lng, lat)
|
|
|
})
|
|
})
|
|
|
try {
|
|
try {
|
|
|
mapInstance.setViewport(points, { margins: [40, 40, 40, 40], zoomFactor: -1 })
|
|
mapInstance.setViewport(points, { margins: [40, 40, 40, 40], zoomFactor: -1 })
|
|
|
} catch {
|
|
} catch {
|
|
|
- // 兼容旧版百度地图 GL 不支持 viewportOptions 的情况。
|
|
|
|
|
|
|
+ // 兼容部分地图视口参数不支持的情况。
|
|
|
mapInstance.setViewport(points)
|
|
mapInstance.setViewport(points)
|
|
|
}
|
|
}
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
const [clng, clat] = convertCoord(MAP_CENTER.lng, MAP_CENTER.lat)
|
|
const [clng, clat] = convertCoord(MAP_CENTER.lng, MAP_CENTER.lat)
|
|
|
- mapInstance.centerAndZoom(new BMapGL.Point(clng, clat), MAP_DEFAULT_ZOOM)
|
|
|
|
|
|
|
+ mapInstance.centerAndZoom(new TdtMap.Point(clng, clat), MAP_DEFAULT_ZOOM)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -569,9 +631,9 @@ function locateArea() {
|
|
|
}
|
|
}
|
|
|
const area = areas[quickLocation.value]
|
|
const area = areas[quickLocation.value]
|
|
|
if (area && mapInstance) {
|
|
if (area && mapInstance) {
|
|
|
- const BMapGL = window.BMapGL
|
|
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
const [alng, alat] = convertCoord(area.lng, area.lat)
|
|
const [alng, alat] = convertCoord(area.lng, area.lat)
|
|
|
- mapInstance.centerAndZoom(new BMapGL.Point(alng, alat), area.zoom)
|
|
|
|
|
|
|
+ mapInstance.centerAndZoom(new TdtMap.Point(alng, alat), area.zoom)
|
|
|
ElMessage.success('已定位到: ' + quickLocation.value)
|
|
ElMessage.success('已定位到: ' + quickLocation.value)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -582,10 +644,10 @@ function locateSearch() {
|
|
|
p.name.includes(searchKeyword.value) || p.code.includes(searchKeyword.value)
|
|
p.name.includes(searchKeyword.value) || p.code.includes(searchKeyword.value)
|
|
|
)
|
|
)
|
|
|
if (found && mapInstance) {
|
|
if (found && mapInstance) {
|
|
|
- const BMapGL = window.BMapGL
|
|
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
const mid = found.path[Math.floor(found.path.length / 2)]
|
|
const mid = found.path[Math.floor(found.path.length / 2)]
|
|
|
const [mlng, mlat] = convertCoord(mid[0], mid[1])
|
|
const [mlng, mlat] = convertCoord(mid[0], mid[1])
|
|
|
- mapInstance.centerAndZoom(new BMapGL.Point(mlng, mlat), 16)
|
|
|
|
|
|
|
+ mapInstance.centerAndZoom(new TdtMap.Point(mlng, mlat), 16)
|
|
|
currentPipeline.value = found
|
|
currentPipeline.value = found
|
|
|
detailDrawerVisible.value = true
|
|
detailDrawerVisible.value = true
|
|
|
ElMessage.success(`已定位到: ${found.name}`)
|
|
ElMessage.success(`已定位到: ${found.name}`)
|
|
@@ -596,7 +658,7 @@ function locateSearch() {
|
|
|
|
|
|
|
|
function locatePipeline() {
|
|
function locatePipeline() {
|
|
|
if (!mapInstance || !currentPipeline.value) return
|
|
if (!mapInstance || !currentPipeline.value) return
|
|
|
- const BMapGL = window.BMapGL
|
|
|
|
|
|
|
+ const TdtMap = window.TdtMap
|
|
|
const item = currentPipeline.value
|
|
const item = currentPipeline.value
|
|
|
let lng, lat
|
|
let lng, lat
|
|
|
if (item.path) {
|
|
if (item.path) {
|
|
@@ -608,7 +670,7 @@ function locatePipeline() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
const [llng, llat] = convertCoord(lng, lat)
|
|
const [llng, llat] = convertCoord(lng, lat)
|
|
|
- mapInstance.centerAndZoom(new BMapGL.Point(llng, llat), 16)
|
|
|
|
|
|
|
+ mapInstance.centerAndZoom(new TdtMap.Point(llng, llat), 16)
|
|
|
detailDrawerVisible.value = false
|
|
detailDrawerVisible.value = false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -671,14 +733,15 @@ onMounted(async () => {
|
|
|
window.addEventListener('mousemove', onWindowMouseMove)
|
|
window.addEventListener('mousemove', onWindowMouseMove)
|
|
|
loadRiskData()
|
|
loadRiskData()
|
|
|
try {
|
|
try {
|
|
|
- await waitForBMapGL()
|
|
|
|
|
|
|
+ await ensureTdtMap()
|
|
|
nextTick(() => initMap())
|
|
nextTick(() => initMap())
|
|
|
} catch {
|
|
} catch {
|
|
|
- mapError.value = '百度地图加载失败,请刷新页面重试'
|
|
|
|
|
|
|
+ mapError.value = '天地图加载失败,请刷新页面重试'
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
onBeforeUnmount(() => {
|
|
|
|
|
+ clearTimeout(labelTimer)
|
|
|
window.removeEventListener('mousemove', onWindowMouseMove)
|
|
window.removeEventListener('mousemove', onWindowMouseMove)
|
|
|
if (chartInstance) {
|
|
if (chartInstance) {
|
|
|
chartInstance.dispose()
|
|
chartInstance.dispose()
|
|
@@ -887,6 +950,10 @@ function onWindowMouseMove(e) {
|
|
|
color: #909399;
|
|
color: #909399;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.map-hint {
|
|
|
|
|
+ color: #b0b6c2;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.map-wrapper {
|
|
.map-wrapper {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
position: relative;
|
|
position: relative;
|