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