xt-element-ui 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/components/base/xt-map.md +331 -0
- package/docs/components/base/xt-step-price.md +103 -217
- package/lib/index.common.js +2109 -38
- package/lib/index.css +1 -1
- package/lib/index.umd.js +2109 -38
- package/lib/index.umd.min.js +5 -5
- package/package.json +4 -3
- package/src/components/ex-button/index.js +8 -2
- package/src/components/ex-chart/index.js +6 -0
- package/src/components/ex-date-picker/index.js +8 -2
- package/src/components/ex-icon/index.js +6 -0
- package/src/components/ex-page/index.js +8 -2
- package/src/components/ex-select-tree/index.js +8 -2
- package/src/components/ex-table/index.js +6 -0
- package/src/components/ex-upload/index.js +6 -0
- package/src/components/xt-button/index.js +8 -2
- package/src/components/xt-card/index.js +8 -2
- package/src/components/xt-card-item/index.js +8 -2
- package/src/components/xt-config-provider/index.js +6 -0
- package/src/components/xt-flex-box/index.js +8 -2
- package/src/components/xt-flex-box/style/index.scss +0 -9
- package/src/components/xt-grid-box/index.js +8 -2
- package/src/components/xt-grid-item/index.js +7 -1
- package/src/components/xt-input/index.js +8 -2
- package/src/components/xt-map/adapters/amap.js +235 -0
- package/src/components/xt-map/adapters/baidu.js +254 -0
- package/src/components/xt-map/adapters/base.js +267 -0
- package/src/components/xt-map/adapters/index.js +29 -0
- package/src/components/xt-map/adapters/tianditu.js +242 -0
- package/src/components/xt-map/config/xt-map-config.js +197 -0
- package/src/components/xt-map/index.js +22 -0
- package/src/components/xt-map/index.vue +351 -0
- package/src/components/xt-map/loaders/script-loader.js +114 -0
- package/src/components/xt-map/provider.vue +200 -0
- package/src/components/xt-map/style/index.scss +77 -0
- package/src/components/xt-step-price/index.js +9 -0
- package/src/components/xt-step-price-item/index.js +6 -0
- package/src/components/xt-step-price-item/index.vue +3 -1
- package/src/components/xt-text/index.js +8 -2
- package/src/components/xt-time/index.js +6 -0
- package/src/index.js +6 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 百度地图适配器 (BMap / Baidu)
|
|
3
|
+
* 百度地图 JS API 3.0 支持自定义样式
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { MapAdapterBase } from './base'
|
|
7
|
+
import { hasGlobal } from '../loaders/script-loader'
|
|
8
|
+
|
|
9
|
+
// 百度地图类型映射
|
|
10
|
+
const BAIDU_MAP_TYPES = {
|
|
11
|
+
standard: 'BMAP_NORMAL_MAP',
|
|
12
|
+
satellite: 'BMAP_SATELLITE_MAP',
|
|
13
|
+
hybrid: 'BMAP_HYBRID_MAP',
|
|
14
|
+
traffic: 'BMAP_NORMAL_MAP' // 路况通过图层叠加
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 百度地图自定义样式 ID(主题)
|
|
18
|
+
// light: 官方 normal 样式
|
|
19
|
+
// dark: 午夜蓝 dark 样式
|
|
20
|
+
const BAIDU_STYLES = {
|
|
21
|
+
light: { style: 'normal' },
|
|
22
|
+
dark: { style: 'dark' }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class BaiduAdapter extends MapAdapterBase {
|
|
26
|
+
constructor(container, options = {}) {
|
|
27
|
+
super(container, options)
|
|
28
|
+
this._mapTypeMap = { ...BAIDU_MAP_TYPES }
|
|
29
|
+
this._coordType = options.baiduCoordType || 'bd09ll'
|
|
30
|
+
this._trafficLayer = null
|
|
31
|
+
this._callbackName = null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
getScriptUrl() {
|
|
35
|
+
if (this.apiUrl) return this.apiUrl
|
|
36
|
+
if (!this.apiKey) {
|
|
37
|
+
console.warn('[XtMap] 百度地图需要配置 apiKey (ak)')
|
|
38
|
+
return ''
|
|
39
|
+
}
|
|
40
|
+
// 注意:_callbackName 在 beforeLoadScript 中已注册
|
|
41
|
+
return `https://api.map.baidu.com/api?v=3.0&ak=${encodeURIComponent(this.apiKey)}&callback=${this._callbackName}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 脚本加载前注册百度 SDK 回调函数
|
|
46
|
+
*/
|
|
47
|
+
beforeLoadScript() {
|
|
48
|
+
// 生成唯一 callback 名称,支持多实例
|
|
49
|
+
this._callbackName = `__xt_map_baidu_${Date.now()}_${Math.floor(Math.random() * 100000)}`
|
|
50
|
+
// 注册全局 callback(百度地图 SDK 加载完成后调用)
|
|
51
|
+
if (typeof window !== 'undefined') {
|
|
52
|
+
window[this._callbackName] = () => {
|
|
53
|
+
// 空实现,仅用于触发 Promise resolve
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
isSdkLoaded() {
|
|
59
|
+
return hasGlobal('BMap') && typeof window.BMap === 'function'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async createMap() {
|
|
63
|
+
const BMap = window.BMap
|
|
64
|
+
if (!BMap) throw new Error('[XtMap] 百度地图 SDK 未加载')
|
|
65
|
+
|
|
66
|
+
const mapOptions = {
|
|
67
|
+
enableMapClick: false
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.mapInstance = new BMap.Map(this.container, mapOptions)
|
|
71
|
+
this.mapInstance.centerAndZoom(new BMap.Point(this.center[0], this.center[1]), this.zoom)
|
|
72
|
+
this.mapInstance.enableScrollWheelZoom(true)
|
|
73
|
+
|
|
74
|
+
// 应用地图类型
|
|
75
|
+
this._applyMapType(this.mapType)
|
|
76
|
+
|
|
77
|
+
// 应用主题
|
|
78
|
+
this._applyTheme(this.theme)
|
|
79
|
+
|
|
80
|
+
// 等待地图就绪
|
|
81
|
+
await new Promise((resolve) => setTimeout(resolve, 500))
|
|
82
|
+
|
|
83
|
+
for (const [eventName, handler] of this.eventHandlers.entries()) {
|
|
84
|
+
this._bindEvent(eventName, handler)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
_applyMapType(type) {
|
|
89
|
+
if (!this.mapInstance || !window.BMap) return
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
// 清除路况图层
|
|
93
|
+
if (this._trafficLayer) {
|
|
94
|
+
try {
|
|
95
|
+
this.mapInstance.removeTileLayer(this._trafficLayer)
|
|
96
|
+
} catch (e) {}
|
|
97
|
+
this._trafficLayer = null
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (type === 'satellite') {
|
|
101
|
+
this.mapInstance.setMapType(window.BMAP_SATELLITE_MAP || 1)
|
|
102
|
+
} else if (type === 'hybrid') {
|
|
103
|
+
this.mapInstance.setMapType(window.BMAP_HYBRID_MAP || 2)
|
|
104
|
+
} else if (type === 'traffic') {
|
|
105
|
+
this.mapInstance.setMapType(window.BMAP_NORMAL_MAP || 0)
|
|
106
|
+
// 叠加路况图层
|
|
107
|
+
try {
|
|
108
|
+
const BMap = window.BMap
|
|
109
|
+
this._trafficLayer = new BMap.TrafficLayer()
|
|
110
|
+
this.mapInstance.addTileLayer(this._trafficLayer)
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.warn('[XtMap] 百度地图加载路况图层失败:', e)
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
this.mapInstance.setMapType(window.BMAP_NORMAL_MAP || 0)
|
|
116
|
+
}
|
|
117
|
+
} catch (e) {
|
|
118
|
+
console.warn('[XtMap] 百度地图切换地图类型失败:', e)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
_applyTheme(theme) {
|
|
123
|
+
if (!this.mapInstance || !window.BMap) return
|
|
124
|
+
try {
|
|
125
|
+
// 百度 3.0 通过 setMapStyle 设置主题样式
|
|
126
|
+
const styleConfig = BAIDU_STYLES[theme] || BAIDU_STYLES.light
|
|
127
|
+
if (this.mapInstance.setMapStyleV2) {
|
|
128
|
+
// 新版 API
|
|
129
|
+
this.mapInstance.setMapStyleV2({ styleId: styleConfig.style === 'dark' ? 'midnight' : '' })
|
|
130
|
+
} else if (this.mapInstance.setMapStyle) {
|
|
131
|
+
// 旧版 API
|
|
132
|
+
const styleJson = theme === 'dark' ? this._getDarkStyleJson() : null
|
|
133
|
+
if (styleJson) {
|
|
134
|
+
this.mapInstance.setMapStyle({ styleJson: styleJson })
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (e) {
|
|
138
|
+
console.warn('[XtMap] 百度地图设置主题失败:', e)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 简易百度地图 dark 样式 JSON 配置
|
|
144
|
+
*/
|
|
145
|
+
_getDarkStyleJson() {
|
|
146
|
+
return [
|
|
147
|
+
{ featureType: 'land', elementType: 'geometry', stylers: { color: '#1a1a1a' } },
|
|
148
|
+
{ featureType: 'water', elementType: 'geometry', stylers: { color: '#0a1a2a' } },
|
|
149
|
+
{ featureType: 'green', elementType: 'geometry', stylers: { color: '#0a2a1a' } },
|
|
150
|
+
{ featureType: 'building', elementType: 'geometry', stylers: { color: '#2a2a2a' } },
|
|
151
|
+
{ featureType: 'highway', elementType: 'geometry', stylers: { color: '#3a3a3a' } },
|
|
152
|
+
{ featureType: 'highway', elementType: 'geometry.stroke', stylers: { color: '#4a4a4a' } },
|
|
153
|
+
{ featureType: 'arterial', elementType: 'geometry', stylers: { color: '#333333' } },
|
|
154
|
+
{ featureType: 'arterial', elementType: 'geometry.stroke', stylers: { color: '#3d3d3d' } },
|
|
155
|
+
{ featureType: 'local', elementType: 'geometry', stylers: { color: '#2a2a2a' } },
|
|
156
|
+
{ featureType: 'railway', elementType: 'geometry', stylers: { color: '#3a3a3a' } },
|
|
157
|
+
{ featureType: 'subway', elementType: 'geometry', stylers: { color: '#3a3a3a' } },
|
|
158
|
+
{ featureType: 'boundary', elementType: 'geometry', stylers: { color: '#666666' } },
|
|
159
|
+
{ featureType: 'district', elementType: 'labels.text.fill', stylers: { color: '#888888' } },
|
|
160
|
+
{ featureType: 'poi', elementType: 'labels', stylers: { visibility: 'off' } }
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
_applyCenter(center) {
|
|
165
|
+
if (!this.mapInstance || !window.BMap) return
|
|
166
|
+
try {
|
|
167
|
+
this.mapInstance.centerAndZoom(new window.BMap.Point(center[0], center[1]), this.zoom)
|
|
168
|
+
} catch (e) {
|
|
169
|
+
// 忽略
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
_applyZoom(zoom) {
|
|
174
|
+
if (!this.mapInstance) return
|
|
175
|
+
try {
|
|
176
|
+
this.mapInstance.setZoom(zoom)
|
|
177
|
+
} catch (e) {
|
|
178
|
+
// 忽略
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
getCenter() {
|
|
183
|
+
if (this.mapInstance && this.mapInstance.getCenter) {
|
|
184
|
+
const c = this.mapInstance.getCenter()
|
|
185
|
+
if (c) return [c.lng, c.lat]
|
|
186
|
+
}
|
|
187
|
+
return this.center
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
getZoom() {
|
|
191
|
+
if (this.mapInstance && this.mapInstance.getZoom) {
|
|
192
|
+
return this.mapInstance.getZoom()
|
|
193
|
+
}
|
|
194
|
+
return this.zoom
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
_bindEvent(eventName, handler) {
|
|
198
|
+
if (!this.mapInstance) return
|
|
199
|
+
try {
|
|
200
|
+
const eventMap = {
|
|
201
|
+
click: 'click',
|
|
202
|
+
moveend: 'moveend',
|
|
203
|
+
zoomend: 'zoomend',
|
|
204
|
+
zoomchange: 'zoomend',
|
|
205
|
+
mapmove: 'movestart'
|
|
206
|
+
}
|
|
207
|
+
const nativeEvent = eventMap[eventName] || eventName
|
|
208
|
+
this.mapInstance.addEventListener(nativeEvent, (e) => {
|
|
209
|
+
const normalized = {
|
|
210
|
+
originalEvent: e,
|
|
211
|
+
lnglat: e && e.point ? [e.point.lng, e.point.lat] : null
|
|
212
|
+
}
|
|
213
|
+
handler(normalized)
|
|
214
|
+
})
|
|
215
|
+
} catch (err) {
|
|
216
|
+
console.warn('[XtMap] 百度地图事件绑定失败:', eventName, err)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
_unbindEvent(eventName, handler) {
|
|
221
|
+
if (!this.mapInstance) return
|
|
222
|
+
try {
|
|
223
|
+
this.mapInstance.removeEventListener(eventName, handler)
|
|
224
|
+
} catch (e) {
|
|
225
|
+
// 忽略
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
_applyResize() {
|
|
230
|
+
if (this.mapInstance && this.mapInstance.enableResize) {
|
|
231
|
+
try {
|
|
232
|
+
// 百度地图默认启用 resize,无需手动调用
|
|
233
|
+
if (typeof this.mapInstance.checkResize === 'function') {
|
|
234
|
+
this.mapInstance.checkResize()
|
|
235
|
+
}
|
|
236
|
+
} catch (e) {
|
|
237
|
+
// 忽略
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
destroy() {
|
|
243
|
+
if (this._callbackName && typeof window !== 'undefined') {
|
|
244
|
+
try {
|
|
245
|
+
delete window[this._callbackName]
|
|
246
|
+
} catch (e) {
|
|
247
|
+
// 忽略
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
super.destroy()
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export default BaiduAdapter
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 地图适配器基类
|
|
3
|
+
* 定义统一的 API 接口,各地图引擎(高德/天地图/百度)通过继承/实现该接口完成适配
|
|
4
|
+
*
|
|
5
|
+
* 统一坐标系统:WGS84 (lng, lat) 作为输入输出标准,各适配器内部处理转换
|
|
6
|
+
* 统一地图类型:standard | satellite | hybrid | traffic
|
|
7
|
+
* 统一主题:light | dark
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { loadScript, hasGlobal } from '../loaders/script-loader'
|
|
11
|
+
|
|
12
|
+
// 地图类型 -> 内部常量(各适配器可覆盖转换)
|
|
13
|
+
const DEFAULT_MAP_TYPE_MAP = {
|
|
14
|
+
standard: 'standard',
|
|
15
|
+
satellite: 'satellite',
|
|
16
|
+
hybrid: 'hybrid',
|
|
17
|
+
traffic: 'traffic'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class MapAdapterBase {
|
|
21
|
+
constructor(container, options = {}) {
|
|
22
|
+
this.container = container
|
|
23
|
+
this.options = options
|
|
24
|
+
this.mapInstance = null
|
|
25
|
+
this.mapType = options.mapType || 'standard'
|
|
26
|
+
this.theme = options.theme || 'light'
|
|
27
|
+
this.center = options.center || [116.397428, 39.90923]
|
|
28
|
+
this.zoom = options.zoom || 11
|
|
29
|
+
this.apiKey = options.apiKey || ''
|
|
30
|
+
this.apiUrl = options.apiUrl || null
|
|
31
|
+
this.plugins = options.plugins || []
|
|
32
|
+
this.eventHandlers = new Map()
|
|
33
|
+
this.ready = false
|
|
34
|
+
this._mapTypeMap = { ...DEFAULT_MAP_TYPE_MAP }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 获取 SDK 脚本 URL(各适配器必须实现)
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
getScriptUrl() {
|
|
42
|
+
throw new Error('[XtMap] 子类必须实现 getScriptUrl()')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 检查 SDK 是否已加载
|
|
47
|
+
*/
|
|
48
|
+
isSdkLoaded() {
|
|
49
|
+
throw new Error('[XtMap] 子类必须实现 isSdkLoaded()')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 在脚本加载前执行(可选覆盖)
|
|
54
|
+
* 用于设置 securityJsCode、注册全局 callback 等前置准备
|
|
55
|
+
*/
|
|
56
|
+
beforeLoadScript() {
|
|
57
|
+
// 可选实现 - 各适配器可覆盖
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 创建地图实例(各适配器必须实现)
|
|
62
|
+
*/
|
|
63
|
+
async createMap() {
|
|
64
|
+
throw new Error('[XtMap] 子类必须实现 createMap()')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 加载 SDK 并初始化地图
|
|
69
|
+
*/
|
|
70
|
+
async init() {
|
|
71
|
+
if (!this.container) {
|
|
72
|
+
throw new Error('[XtMap] 缺少容器元素')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!this.isSdkLoaded()) {
|
|
76
|
+
// 1. 脚本加载前执行钩子(设置安全密钥等)
|
|
77
|
+
this.beforeLoadScript()
|
|
78
|
+
|
|
79
|
+
// 2. 获取脚本 URL
|
|
80
|
+
const url = this.getScriptUrl()
|
|
81
|
+
if (!url) {
|
|
82
|
+
throw new Error('[XtMap] 缺少 API URL,请配置 apiKey 或 apiUrl')
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 3. 动态加载脚本
|
|
86
|
+
await loadScript(url)
|
|
87
|
+
|
|
88
|
+
// 4. 等待 SDK 初始化全局对象(部分 SDK 需要等待 callback 或脚本内部初始化完成)
|
|
89
|
+
await this._waitForSdkReady()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 5. 创建地图实例
|
|
93
|
+
await this.createMap()
|
|
94
|
+
this.ready = true
|
|
95
|
+
return this.mapInstance
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 等待 SDK 准备好(部分地图 SDK 需要等待 callback 执行)
|
|
100
|
+
*/
|
|
101
|
+
async _waitForSdkReady() {
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
let attempts = 0
|
|
104
|
+
const maxAttempts = 100
|
|
105
|
+
const check = () => {
|
|
106
|
+
if (this.isSdkLoaded() || attempts >= maxAttempts) {
|
|
107
|
+
resolve()
|
|
108
|
+
} else {
|
|
109
|
+
attempts++
|
|
110
|
+
setTimeout(check, 100)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
check()
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 统一地图类型转换:xt-map 枚举 -> 引擎内部值
|
|
119
|
+
*/
|
|
120
|
+
getNativeMapType(xtType) {
|
|
121
|
+
return this._mapTypeMap[xtType] || this._mapTypeMap.standard
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 设置地图类型
|
|
126
|
+
*/
|
|
127
|
+
setMapType(type) {
|
|
128
|
+
this.mapType = type
|
|
129
|
+
if (this.ready && this.mapInstance) {
|
|
130
|
+
this._applyMapType(type)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 应用地图类型到引擎(各适配器实现)
|
|
136
|
+
*/
|
|
137
|
+
_applyMapType(type) {
|
|
138
|
+
// 可选实现
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 设置主题
|
|
143
|
+
*/
|
|
144
|
+
setTheme(theme) {
|
|
145
|
+
this.theme = theme
|
|
146
|
+
if (this.ready && this.mapInstance) {
|
|
147
|
+
this._applyTheme(theme)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 应用主题到引擎(各适配器实现)
|
|
153
|
+
*/
|
|
154
|
+
_applyTheme(theme) {
|
|
155
|
+
// 可选实现
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 设置中心坐标 [lng, lat]
|
|
160
|
+
*/
|
|
161
|
+
setCenter(center) {
|
|
162
|
+
this.center = center
|
|
163
|
+
if (this.ready && this.mapInstance) {
|
|
164
|
+
this._applyCenter(center)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
_applyCenter(center) {
|
|
169
|
+
// 各适配器实现
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* 设置缩放级别
|
|
174
|
+
*/
|
|
175
|
+
setZoom(zoom) {
|
|
176
|
+
this.zoom = zoom
|
|
177
|
+
if (this.ready && this.mapInstance) {
|
|
178
|
+
this._applyZoom(zoom)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
_applyZoom(zoom) {
|
|
183
|
+
// 各适配器实现
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 获取当前中心坐标
|
|
188
|
+
*/
|
|
189
|
+
getCenter() {
|
|
190
|
+
return this.center
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 获取当前缩放级别
|
|
195
|
+
*/
|
|
196
|
+
getZoom() {
|
|
197
|
+
return this.zoom
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 获取原始地图实例(用于高级自定义操作)
|
|
202
|
+
*/
|
|
203
|
+
getNativeMap() {
|
|
204
|
+
return this.mapInstance
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 绑定事件(统一事件名:click, moveend, zoomend, ready 等)
|
|
209
|
+
*/
|
|
210
|
+
on(eventName, handler) {
|
|
211
|
+
if (typeof handler !== 'function') return
|
|
212
|
+
this.eventHandlers.set(eventName, handler)
|
|
213
|
+
if (this.ready && this.mapInstance) {
|
|
214
|
+
this._bindEvent(eventName, handler)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
_bindEvent(eventName, handler) {
|
|
219
|
+
// 各适配器实现具体事件绑定
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* 解绑事件
|
|
224
|
+
*/
|
|
225
|
+
off(eventName) {
|
|
226
|
+
const handler = this.eventHandlers.get(eventName)
|
|
227
|
+
if (handler && this.ready && this.mapInstance) {
|
|
228
|
+
this._unbindEvent(eventName, handler)
|
|
229
|
+
}
|
|
230
|
+
this.eventHandlers.delete(eventName)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
_unbindEvent(eventName, handler) {
|
|
234
|
+
// 各适配器实现
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* 调整地图大小(容器尺寸变化后调用)
|
|
239
|
+
*/
|
|
240
|
+
resize() {
|
|
241
|
+
if (this.ready && this.mapInstance) {
|
|
242
|
+
this._applyResize()
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
_applyResize() {
|
|
247
|
+
// 各适配器实现
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* 销毁地图
|
|
252
|
+
*/
|
|
253
|
+
destroy() {
|
|
254
|
+
this.eventHandlers.clear()
|
|
255
|
+
if (this.mapInstance && typeof this.mapInstance.destroy === 'function') {
|
|
256
|
+
try {
|
|
257
|
+
this.mapInstance.destroy()
|
|
258
|
+
} catch (e) {
|
|
259
|
+
// 忽略销毁错误
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
this.mapInstance = null
|
|
263
|
+
this.ready = false
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export default MapAdapterBase
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 地图适配器索引
|
|
3
|
+
* 根据 provider 字符串返回对应的适配器构造函数
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AMapAdapter } from './amap'
|
|
7
|
+
import { TiandituAdapter } from './tianditu'
|
|
8
|
+
import { BaiduAdapter } from './baidu'
|
|
9
|
+
|
|
10
|
+
export const adapters = {
|
|
11
|
+
amap: AMapAdapter,
|
|
12
|
+
tianditu: TiandituAdapter,
|
|
13
|
+
baidu: BaiduAdapter
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const getAdapterClass = (provider) => {
|
|
17
|
+
return adapters[provider] || AMapAdapter
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { AMapAdapter, TiandituAdapter, BaiduAdapter }
|
|
21
|
+
export { MapAdapterBase } from './base'
|
|
22
|
+
|
|
23
|
+
export default {
|
|
24
|
+
adapters,
|
|
25
|
+
getAdapterClass,
|
|
26
|
+
AMapAdapter,
|
|
27
|
+
TiandituAdapter,
|
|
28
|
+
BaiduAdapter
|
|
29
|
+
}
|