4 changed files with 199 additions and 2 deletions
@ -0,0 +1,71 @@ |
|||||
|
/** |
||||
|
* 地图助手(最小集) |
||||
|
* maptalks@1.12.x 使用 checkSize 刷新容器尺寸 |
||||
|
*/ |
||||
|
|
||||
|
class MapHelper { |
||||
|
_map = null |
||||
|
_originParent = null |
||||
|
_savedView = null |
||||
|
|
||||
|
setMap(map) { |
||||
|
this._map = map |
||||
|
} |
||||
|
|
||||
|
getMap() { |
||||
|
return this._map |
||||
|
} |
||||
|
|
||||
|
toggleMapMode({ is2D = false, is3D = false } = {}) { |
||||
|
if (!this._map) return |
||||
|
|
||||
|
if (is3D) { |
||||
|
this._map.setPitch(45) |
||||
|
this._map.setBearing(0) |
||||
|
this._map.config('dragRotate', true) |
||||
|
this._map.config('dragPitch', true) |
||||
|
} |
||||
|
|
||||
|
if (is2D) { |
||||
|
this._map.setPitch(0) |
||||
|
this._map.setBearing(0) |
||||
|
this._map.config('dragRotate', false) |
||||
|
this._map.config('dragPitch', false) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
replaceMapContainer(newParent) { |
||||
|
if (!this._map || !newParent) return |
||||
|
|
||||
|
const el = this._map.getContainer() |
||||
|
this._originParent = this._originParent || el.parentNode |
||||
|
this._savedView = { |
||||
|
center: this._map.getCenter(), |
||||
|
zoom: this._map.getZoom(), |
||||
|
pitch: this._map.getPitch(), |
||||
|
bearing: this._map.getBearing(), |
||||
|
} |
||||
|
newParent.appendChild(el) |
||||
|
this._map.checkSize() |
||||
|
} |
||||
|
|
||||
|
restoreMapContainer() { |
||||
|
if (!this._map || !this._originParent) return |
||||
|
|
||||
|
const el = this._map.getContainer() |
||||
|
this._originParent.appendChild(el) |
||||
|
|
||||
|
if (this._savedView) { |
||||
|
this._map.setCenter(this._savedView.center) |
||||
|
this._map.setZoom(this._savedView.zoom) |
||||
|
this._map.setPitch(this._savedView.pitch) |
||||
|
this._map.setBearing(this._savedView.bearing) |
||||
|
} |
||||
|
|
||||
|
this._map.checkSize() |
||||
|
this._originParent = null |
||||
|
this._savedView = null |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default new MapHelper() |
||||
@ -0,0 +1,71 @@ |
|||||
|
<script setup> |
||||
|
import { onMounted, onUnmounted } from 'vue' |
||||
|
import * as maptalks from 'maptalks' |
||||
|
import mapConfig, { createTiandituLayerOptions } from '@/config/map' |
||||
|
import commonRefs from '@/utils/commonRefs' |
||||
|
import mapHelper from '@/core/mapHelper' |
||||
|
import 'maptalks/dist/maptalks.css' |
||||
|
|
||||
|
let map = null |
||||
|
|
||||
|
function initMap() { |
||||
|
const tk = mapConfig.token |
||||
|
if (!tk) { |
||||
|
console.error('[MapLayer] 缺少 APP_TIANDITU_TOKEN,跳过地图初始化') |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
const layers = createTiandituLayerOptions(tk) |
||||
|
const baseLayer = new maptalks.GroupTileLayer('tianditu-base', [ |
||||
|
new maptalks.TileLayer('tdt-img', layers.img), |
||||
|
new maptalks.TileLayer('tdt-cia', layers.cia), |
||||
|
]) |
||||
|
|
||||
|
map = new maptalks.Map('map', { |
||||
|
center: mapConfig.center, |
||||
|
zoom: mapConfig.zoom, |
||||
|
minZoom: 3, |
||||
|
attribution: false, |
||||
|
baseLayer, |
||||
|
}) |
||||
|
|
||||
|
commonRefs.setRef('map', map) |
||||
|
mapHelper.setMap(map) |
||||
|
} |
||||
|
|
||||
|
onMounted(() => { |
||||
|
// 等布局完成后再初始化,避免容器尺寸为 0 |
||||
|
setTimeout(() => { |
||||
|
try { |
||||
|
initMap() |
||||
|
} catch (error) { |
||||
|
console.error('[MapLayer] 地图初始化失败:', error) |
||||
|
} |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
onUnmounted(() => { |
||||
|
if (map) { |
||||
|
map.remove() |
||||
|
commonRefs.removeRef('map') |
||||
|
mapHelper.setMap(null) |
||||
|
map = null |
||||
|
} |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<div id="map" :class="s.root" /> |
||||
|
</template> |
||||
|
|
||||
|
<style lang="less" module="s"> |
||||
|
.root { |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
height: 100%; |
||||
|
z-index: 0; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,54 @@ |
|||||
|
/* |
||||
|
* 公共引用 |
||||
|
* 异步获取引用对象 |
||||
|
*/ |
||||
|
|
||||
|
const refs = Symbol('refs') |
||||
|
const pendingList = Symbol('pendingList') |
||||
|
|
||||
|
class CommonRefs { |
||||
|
[refs] = {} |
||||
|
|
||||
|
[pendingList] = {} |
||||
|
|
||||
|
clearPendingList(key = '') { |
||||
|
if (!key) { |
||||
|
this[pendingList] = {} |
||||
|
} else { |
||||
|
this[pendingList][key] = [] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
setRef(key, ref) { |
||||
|
if (key in this[refs]) return |
||||
|
|
||||
|
this[refs][key] = ref |
||||
|
const { [key]: resolves } = this[pendingList] |
||||
|
;(resolves || []).forEach((resolve, index) => { |
||||
|
if (!resolve) return |
||||
|
resolve(ref) |
||||
|
resolves[index] = undefined // 只作废,不删除
|
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
getRef(key) { |
||||
|
return new Promise((resolve) => { |
||||
|
const { [key]: ref } = this[refs] |
||||
|
if (ref) { |
||||
|
resolve(ref) |
||||
|
} else if (key in this[pendingList]) { |
||||
|
this[pendingList][key].push(resolve) |
||||
|
} else { |
||||
|
this[pendingList][key] = [resolve] |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
removeRef(key) { |
||||
|
if (key in this[refs]) { |
||||
|
delete this[refs][key] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default new CommonRefs() |
||||
Loading…
Reference in new issue