my-openlayer 1.0.3 → 1.0.5
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/MyOl.d.ts +2 -9
- package/MyOl.js +17 -33
- package/core/DomPoint.d.ts +3 -10
- package/core/DomPoint.js +75 -31
- package/core/EventManager.d.ts +13 -3
- package/core/EventManager.js +77 -18
- package/core/Line.d.ts +2 -0
- package/core/Line.js +3 -1
- package/core/MapBaseLayers.d.ts +32 -2
- package/core/MapBaseLayers.js +91 -23
- package/core/MapTools.d.ts +1 -52
- package/core/MapTools.js +1 -153
- package/core/Point.d.ts +13 -10
- package/core/Point.js +16 -47
- package/core/Polygon.js +1 -1
- package/core/VueTemPoint.d.ts +163 -0
- package/core/VueTemPoint.js +432 -0
- package/core/VueTemplatePoint.d.ts +51 -0
- package/core/VueTemplatePoint.js +529 -0
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/package.json +6 -5
- package/types.d.ts +33 -13
- package/types.js +8 -8
package/MyOl.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import MapTools from "./core/MapTools";
|
|
|
8
8
|
import { ErrorHandler } from './utils/ErrorHandler';
|
|
9
9
|
import { EventManager } from './core/EventManager';
|
|
10
10
|
import { ConfigManager } from './core/ConfigManager';
|
|
11
|
-
import { MapInitType
|
|
11
|
+
import { MapInitType } from './types';
|
|
12
12
|
/**
|
|
13
13
|
* MyOl 地图核心类
|
|
14
14
|
* 提供完整的地图操作功能,包括点、线、面要素管理,底图切换,工具操作等
|
|
@@ -21,7 +21,7 @@ export default class MyOl {
|
|
|
21
21
|
private _point?;
|
|
22
22
|
private _line?;
|
|
23
23
|
private readonly errorHandler;
|
|
24
|
-
private
|
|
24
|
+
private _eventManager?;
|
|
25
25
|
private readonly configManager;
|
|
26
26
|
private readonly options;
|
|
27
27
|
static readonly DefaultOptions: MapInitType;
|
|
@@ -101,13 +101,6 @@ export default class MyOl {
|
|
|
101
101
|
* @param duration 动画持续时间(毫秒)
|
|
102
102
|
*/
|
|
103
103
|
locationAction(longitude: number, latitude: number, zoom?: number, duration?: number): void;
|
|
104
|
-
/**
|
|
105
|
-
* 监听地图事件
|
|
106
|
-
* @param eventType 事件类型
|
|
107
|
-
* @param callback 回调函数
|
|
108
|
-
* @param clickType 点击类型(可选)
|
|
109
|
-
*/
|
|
110
|
-
mapOnEvent(eventType: EventType, callback: (feature?: any, e?: any) => void, clickType?: 'point' | 'line' | 'polygon'): void;
|
|
111
104
|
/**
|
|
112
105
|
* 获取错误处理器实例
|
|
113
106
|
* @returns ErrorHandler 错误处理器
|
package/MyOl.js
CHANGED
|
@@ -46,9 +46,10 @@ class MyOl {
|
|
|
46
46
|
layers: layers,
|
|
47
47
|
controls: this.createControls()
|
|
48
48
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
if (layers.length === 0 || this.options.annotation) {
|
|
50
|
+
this.getMapBaseLayers();
|
|
51
|
+
}
|
|
52
|
+
// 初始化基础事件监听(地图错误等)
|
|
52
53
|
this.initializeEventListeners();
|
|
53
54
|
}
|
|
54
55
|
catch (error) {
|
|
@@ -108,13 +109,14 @@ class MyOl {
|
|
|
108
109
|
* @private
|
|
109
110
|
*/
|
|
110
111
|
initializeEventListeners() {
|
|
112
|
+
const eventManager = this.getEventManager();
|
|
111
113
|
// 地图加载完成事件
|
|
112
|
-
|
|
114
|
+
eventManager.on('rendercomplete', (eventData) => {
|
|
113
115
|
console.debug('地图初始化完成', { map: this.map });
|
|
114
|
-
});
|
|
116
|
+
}, { once: true });
|
|
115
117
|
// 地图错误事件
|
|
116
|
-
|
|
117
|
-
this.errorHandler.handleError(new MyOpenLayersError('地图渲染错误', ErrorType.MAP_ERROR, { error }));
|
|
118
|
+
eventManager.on('error', (eventData) => {
|
|
119
|
+
this.errorHandler.handleError(new MyOpenLayersError('地图渲染错误', ErrorType.MAP_ERROR, { error: eventData.error }));
|
|
118
120
|
});
|
|
119
121
|
}
|
|
120
122
|
/**
|
|
@@ -304,29 +306,6 @@ class MyOl {
|
|
|
304
306
|
throw error;
|
|
305
307
|
}
|
|
306
308
|
}
|
|
307
|
-
/**
|
|
308
|
-
* 监听地图事件
|
|
309
|
-
* @param eventType 事件类型
|
|
310
|
-
* @param callback 回调函数
|
|
311
|
-
* @param clickType 点击类型(可选)
|
|
312
|
-
*/
|
|
313
|
-
mapOnEvent(eventType, callback, clickType) {
|
|
314
|
-
try {
|
|
315
|
-
if (typeof callback !== 'function') {
|
|
316
|
-
throw new Error('回调函数必须是函数类型');
|
|
317
|
-
}
|
|
318
|
-
MapTools.mapOnEvent(this.map, eventType, callback, clickType);
|
|
319
|
-
// 记录事件监听
|
|
320
|
-
console.debug('地图事件监听已添加', {
|
|
321
|
-
eventType,
|
|
322
|
-
clickType
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
catch (error) {
|
|
326
|
-
this.errorHandler.handleError(new MyOpenLayersError(`添加地图事件监听失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.MAP_ERROR, { eventType, clickType }));
|
|
327
|
-
throw error;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
309
|
// ==========================================
|
|
331
310
|
// 管理器访问方法
|
|
332
311
|
// ==========================================
|
|
@@ -342,7 +321,10 @@ class MyOl {
|
|
|
342
321
|
* @returns EventManager 事件管理器
|
|
343
322
|
*/
|
|
344
323
|
getEventManager() {
|
|
345
|
-
|
|
324
|
+
if (!this._eventManager) {
|
|
325
|
+
this._eventManager = new EventManager(this.map);
|
|
326
|
+
}
|
|
327
|
+
return this._eventManager;
|
|
346
328
|
}
|
|
347
329
|
/**
|
|
348
330
|
* 获取配置管理器实例
|
|
@@ -363,8 +345,10 @@ class MyOl {
|
|
|
363
345
|
*/
|
|
364
346
|
destroy() {
|
|
365
347
|
try {
|
|
366
|
-
//
|
|
367
|
-
this.
|
|
348
|
+
// 清理事件监听(仅在已初始化时)
|
|
349
|
+
if (this._eventManager) {
|
|
350
|
+
this._eventManager.clear();
|
|
351
|
+
}
|
|
368
352
|
// 销毁功能模块
|
|
369
353
|
this._point = undefined;
|
|
370
354
|
this._line = undefined;
|
package/core/DomPoint.d.ts
CHANGED
|
@@ -54,13 +54,6 @@ export default class DomPoint {
|
|
|
54
54
|
* @private
|
|
55
55
|
*/
|
|
56
56
|
private createVueApp;
|
|
57
|
-
/**
|
|
58
|
-
* 判断是否为Vue 3
|
|
59
|
-
* @param Vue Vue构造函数
|
|
60
|
-
* @returns 是否为Vue 3
|
|
61
|
-
* @private
|
|
62
|
-
*/
|
|
63
|
-
private isVue3;
|
|
64
57
|
/**
|
|
65
58
|
* 创建覆盖层
|
|
66
59
|
* @returns 覆盖层实例
|
|
@@ -88,11 +81,11 @@ export default class DomPoint {
|
|
|
88
81
|
isVisible(): boolean;
|
|
89
82
|
/**
|
|
90
83
|
* 更新位置
|
|
91
|
-
* @param
|
|
92
|
-
* @param
|
|
84
|
+
* @param lgtd 新经度
|
|
85
|
+
* @param lttd 新纬度
|
|
93
86
|
* @throws 当操作失败时抛出错误
|
|
94
87
|
*/
|
|
95
|
-
updatePosition(
|
|
88
|
+
updatePosition(lgtd: number, lttd: number): void;
|
|
96
89
|
/**
|
|
97
90
|
* 获取当前位置
|
|
98
91
|
* @returns 当前坐标位置
|
package/core/DomPoint.js
CHANGED
|
@@ -2,6 +2,60 @@ import Overlay from 'ol/Overlay';
|
|
|
2
2
|
import { DomPointState } from '../types';
|
|
3
3
|
import { ErrorHandler, ErrorType } from '../utils/ErrorHandler';
|
|
4
4
|
import { ValidationUtils } from '../utils/ValidationUtils';
|
|
5
|
+
// 动态导入Vue
|
|
6
|
+
let Vue = null;
|
|
7
|
+
let isVue3 = false;
|
|
8
|
+
// 检测Vue版本并导入
|
|
9
|
+
async function detectAndImportVue() {
|
|
10
|
+
try {
|
|
11
|
+
// 尝试动态导入Vue
|
|
12
|
+
const vueModule = await import('vue');
|
|
13
|
+
Vue = vueModule.default || vueModule;
|
|
14
|
+
// 检测Vue版本
|
|
15
|
+
if (Vue && (Vue.version?.startsWith('3') || Vue.createApp)) {
|
|
16
|
+
isVue3 = true;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
isVue3 = false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
console.warn('Vue not found. Please ensure Vue is installed in your project.');
|
|
24
|
+
Vue = null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// 同步版本的Vue检测(用于兼容性)
|
|
28
|
+
function detectVueSync() {
|
|
29
|
+
try {
|
|
30
|
+
// 尝试从全局对象获取Vue
|
|
31
|
+
if (typeof window !== 'undefined' && window.Vue) {
|
|
32
|
+
Vue = window.Vue;
|
|
33
|
+
isVue3 = !!(Vue.version?.startsWith('3') || Vue.createApp);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// 如果在Node.js环境中,尝试require
|
|
37
|
+
if (typeof window === 'undefined') {
|
|
38
|
+
try {
|
|
39
|
+
// 使用eval来避免TypeScript编译时的require检查
|
|
40
|
+
const requireFunc = eval('require');
|
|
41
|
+
Vue = requireFunc('vue');
|
|
42
|
+
isVue3 = !!(Vue.version?.startsWith('3') || Vue.createApp);
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
console.warn('Vue not found. Please ensure Vue is installed in your project.');
|
|
46
|
+
Vue = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
console.warn('Failed to detect Vue:', e);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// 初始化Vue导入
|
|
55
|
+
detectVueSync();
|
|
56
|
+
if (!Vue) {
|
|
57
|
+
detectAndImportVue();
|
|
58
|
+
}
|
|
5
59
|
/**
|
|
6
60
|
* DOM点位管理类
|
|
7
61
|
* 用于在地图上添加和管理DOM元素覆盖物
|
|
@@ -23,10 +77,7 @@ export default class DomPoint {
|
|
|
23
77
|
this.map = map;
|
|
24
78
|
this.options = this.mergeDefaultOptions(options);
|
|
25
79
|
this.id = this.generateUniqueId();
|
|
26
|
-
this.position = [
|
|
27
|
-
this.options.longitude ?? this.options.lgtd,
|
|
28
|
-
this.options.latitude ?? this.options.lttd
|
|
29
|
-
];
|
|
80
|
+
this.position = [this.options.lgtd, this.options.lttd];
|
|
30
81
|
// 创建DOM元素
|
|
31
82
|
this.dom = this.createDomElement();
|
|
32
83
|
// 创建Vue应用实例
|
|
@@ -53,13 +104,12 @@ export default class DomPoint {
|
|
|
53
104
|
validateConstructorParams(map, options) {
|
|
54
105
|
ValidationUtils.validateRequired(map, 'Map instance is required');
|
|
55
106
|
ValidationUtils.validateRequired(options, 'Options are required');
|
|
56
|
-
const {
|
|
57
|
-
ValidationUtils.validateRequired(Vue, 'Vue is required in options');
|
|
107
|
+
const { Template, lgtd, lttd } = options;
|
|
58
108
|
ValidationUtils.validateRequired(Template, 'Template is required in options');
|
|
59
|
-
if (typeof
|
|
60
|
-
throw new Error('Longitude and
|
|
109
|
+
if (typeof lgtd !== 'number' || typeof lttd !== 'number') {
|
|
110
|
+
throw new Error('Longitude and lttd must be numbers');
|
|
61
111
|
}
|
|
62
|
-
ValidationUtils.validateCoordinate(
|
|
112
|
+
ValidationUtils.validateCoordinate(lgtd, lttd);
|
|
63
113
|
}
|
|
64
114
|
/**
|
|
65
115
|
* 合并默认配置选项
|
|
@@ -105,9 +155,12 @@ export default class DomPoint {
|
|
|
105
155
|
* @private
|
|
106
156
|
*/
|
|
107
157
|
createVueApp() {
|
|
108
|
-
const {
|
|
158
|
+
const { Template, props } = this.options;
|
|
159
|
+
if (!Vue) {
|
|
160
|
+
throw new Error('Vue is not available. Please ensure Vue is installed in your project.');
|
|
161
|
+
}
|
|
109
162
|
try {
|
|
110
|
-
if (
|
|
163
|
+
if (isVue3) {
|
|
111
164
|
// Vue 3
|
|
112
165
|
this.app = Vue.createApp({
|
|
113
166
|
...Template,
|
|
@@ -127,15 +180,6 @@ export default class DomPoint {
|
|
|
127
180
|
throw new Error(`Failed to create Vue app: ${error}`);
|
|
128
181
|
}
|
|
129
182
|
}
|
|
130
|
-
/**
|
|
131
|
-
* 判断是否为Vue 3
|
|
132
|
-
* @param Vue Vue构造函数
|
|
133
|
-
* @returns 是否为Vue 3
|
|
134
|
-
* @private
|
|
135
|
-
*/
|
|
136
|
-
isVue3(Vue) {
|
|
137
|
-
return !!(Vue.version && Vue.version.startsWith('3')) || !!Vue.createApp;
|
|
138
|
-
}
|
|
139
183
|
/**
|
|
140
184
|
* 创建覆盖层
|
|
141
185
|
* @returns 覆盖层实例
|
|
@@ -188,21 +232,21 @@ export default class DomPoint {
|
|
|
188
232
|
}
|
|
189
233
|
/**
|
|
190
234
|
* 更新位置
|
|
191
|
-
* @param
|
|
192
|
-
* @param
|
|
235
|
+
* @param lgtd 新经度
|
|
236
|
+
* @param lttd 新纬度
|
|
193
237
|
* @throws 当操作失败时抛出错误
|
|
194
238
|
*/
|
|
195
|
-
updatePosition(
|
|
239
|
+
updatePosition(lgtd, lttd) {
|
|
196
240
|
if (this.state === DomPointState.DESTROYED) {
|
|
197
241
|
throw new Error('Cannot update position on destroyed DOM point');
|
|
198
242
|
}
|
|
199
|
-
ValidationUtils.validateCoordinate(
|
|
243
|
+
ValidationUtils.validateCoordinate(lgtd, lttd);
|
|
200
244
|
try {
|
|
201
|
-
this.position = [
|
|
245
|
+
this.position = [lgtd, lttd];
|
|
202
246
|
this.anchor.setPosition(this.position);
|
|
203
247
|
}
|
|
204
248
|
catch (error) {
|
|
205
|
-
this.handleError('Failed to update position', error, {
|
|
249
|
+
this.handleError('Failed to update position', error, { lgtd, lttd });
|
|
206
250
|
throw error;
|
|
207
251
|
}
|
|
208
252
|
}
|
|
@@ -293,17 +337,17 @@ export default class DomPoint {
|
|
|
293
337
|
destroyVueApp() {
|
|
294
338
|
if (this.app) {
|
|
295
339
|
try {
|
|
296
|
-
if (
|
|
297
|
-
// Vue 3
|
|
340
|
+
if (isVue3) {
|
|
341
|
+
// Vue 3: 使用 unmount
|
|
298
342
|
this.app.unmount();
|
|
299
343
|
}
|
|
300
|
-
else
|
|
301
|
-
// Vue 2
|
|
344
|
+
else {
|
|
345
|
+
// Vue 2: 使用 $destroy
|
|
302
346
|
this.app.$destroy();
|
|
303
347
|
}
|
|
304
348
|
}
|
|
305
349
|
catch (error) {
|
|
306
|
-
|
|
350
|
+
this.handleError('Failed to destroy Vue app', error);
|
|
307
351
|
}
|
|
308
352
|
finally {
|
|
309
353
|
this.app = null;
|
package/core/EventManager.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { FeatureLike } from 'ol/Feature';
|
|
|
4
4
|
/**
|
|
5
5
|
* 事件类型定义
|
|
6
6
|
*/
|
|
7
|
-
export type MapEventType = 'click' | 'dblclick' | 'hover' | 'moveend' | 'zoomend' | 'pointermove';
|
|
7
|
+
export type MapEventType = 'click' | 'dblclick' | 'hover' | 'moveend' | 'zoomend' | 'pointermove' | 'rendercomplete' | 'error';
|
|
8
8
|
/**
|
|
9
9
|
* 事件回调函数类型
|
|
10
10
|
*/
|
|
@@ -30,6 +30,7 @@ export declare class EventManager {
|
|
|
30
30
|
private readonly map;
|
|
31
31
|
private listeners;
|
|
32
32
|
private eventCounters;
|
|
33
|
+
private mapEventListeners;
|
|
33
34
|
/**
|
|
34
35
|
* 构造函数
|
|
35
36
|
* @param map OpenLayers地图实例
|
|
@@ -80,10 +81,10 @@ export declare class EventManager {
|
|
|
80
81
|
*/
|
|
81
82
|
private attachMapEvent;
|
|
82
83
|
/**
|
|
83
|
-
*
|
|
84
|
+
* 移除地图事件监听器
|
|
84
85
|
* @param type 事件类型
|
|
85
86
|
*/
|
|
86
|
-
private
|
|
87
|
+
private detachMapEvent;
|
|
87
88
|
/**
|
|
88
89
|
* 处理点击事件
|
|
89
90
|
* @param event 地图浏览器事件
|
|
@@ -107,6 +108,15 @@ export declare class EventManager {
|
|
|
107
108
|
* 处理缩放结束事件
|
|
108
109
|
*/
|
|
109
110
|
private handleZoomEndEvent;
|
|
111
|
+
/**
|
|
112
|
+
* 处理渲染完成事件
|
|
113
|
+
*/
|
|
114
|
+
private handleRenderCompleteEvent;
|
|
115
|
+
/**
|
|
116
|
+
* 处理错误事件
|
|
117
|
+
* @param error 错误对象
|
|
118
|
+
*/
|
|
119
|
+
private handleErrorEvent;
|
|
110
120
|
/**
|
|
111
121
|
* 创建事件数据
|
|
112
122
|
* @param type 事件类型
|
package/core/EventManager.js
CHANGED
|
@@ -11,6 +11,7 @@ export class EventManager {
|
|
|
11
11
|
constructor(map) {
|
|
12
12
|
this.listeners = new Map();
|
|
13
13
|
this.eventCounters = new Map();
|
|
14
|
+
this.mapEventListeners = new Map();
|
|
14
15
|
ErrorHandler.validateMap(map);
|
|
15
16
|
this.map = map;
|
|
16
17
|
this.initializeEventCounters();
|
|
@@ -19,7 +20,7 @@ export class EventManager {
|
|
|
19
20
|
* 初始化事件计数器
|
|
20
21
|
*/
|
|
21
22
|
initializeEventCounters() {
|
|
22
|
-
const eventTypes = ['click', 'dblclick', 'hover', 'moveend', 'zoomend', 'pointermove'];
|
|
23
|
+
const eventTypes = ['click', 'dblclick', 'hover', 'moveend', 'zoomend', 'pointermove', 'rendercomplete', 'error'];
|
|
23
24
|
eventTypes.forEach(type => {
|
|
24
25
|
this.eventCounters.set(type, 0);
|
|
25
26
|
});
|
|
@@ -54,7 +55,11 @@ export class EventManager {
|
|
|
54
55
|
return false;
|
|
55
56
|
}
|
|
56
57
|
this.listeners.delete(id);
|
|
57
|
-
|
|
58
|
+
// 如果该类型没有其他监听器了,移除地图事件监听器
|
|
59
|
+
const remainingListeners = this.getListenerCount(listener.type);
|
|
60
|
+
if (remainingListeners === 0) {
|
|
61
|
+
this.detachMapEvent(listener.type);
|
|
62
|
+
}
|
|
58
63
|
return true;
|
|
59
64
|
}
|
|
60
65
|
/**
|
|
@@ -71,15 +76,19 @@ export class EventManager {
|
|
|
71
76
|
idsToRemove.forEach(id => {
|
|
72
77
|
this.listeners.delete(id);
|
|
73
78
|
});
|
|
74
|
-
|
|
79
|
+
// 移除对应的地图事件监听器
|
|
80
|
+
if (idsToRemove.length > 0) {
|
|
81
|
+
this.detachMapEvent(type);
|
|
82
|
+
}
|
|
75
83
|
}
|
|
76
84
|
/**
|
|
77
85
|
* 清除所有事件监听器
|
|
78
86
|
*/
|
|
79
87
|
clear() {
|
|
80
88
|
this.listeners.clear();
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
// 移除所有地图事件监听器
|
|
90
|
+
this.mapEventListeners.forEach((_, type) => {
|
|
91
|
+
this.detachMapEvent(type);
|
|
83
92
|
});
|
|
84
93
|
}
|
|
85
94
|
/**
|
|
@@ -113,37 +122,64 @@ export class EventManager {
|
|
|
113
122
|
if (existingListeners > 1) {
|
|
114
123
|
return; // 已经附加过该类型的事件
|
|
115
124
|
}
|
|
125
|
+
// 如果已经有地图事件监听器,先移除
|
|
126
|
+
if (this.mapEventListeners.has(type)) {
|
|
127
|
+
this.detachMapEvent(type);
|
|
128
|
+
}
|
|
129
|
+
let eventHandler;
|
|
130
|
+
let target = this.map;
|
|
131
|
+
let eventName;
|
|
116
132
|
switch (type) {
|
|
117
133
|
case 'click':
|
|
118
|
-
|
|
134
|
+
eventHandler = this.handleClickEvent.bind(this);
|
|
135
|
+
eventName = 'click';
|
|
119
136
|
break;
|
|
120
137
|
case 'dblclick':
|
|
121
|
-
|
|
138
|
+
eventHandler = this.handleDblClickEvent.bind(this);
|
|
139
|
+
eventName = 'dblclick';
|
|
122
140
|
break;
|
|
123
141
|
case 'hover':
|
|
124
142
|
case 'pointermove':
|
|
125
|
-
|
|
143
|
+
eventHandler = this.handlePointerMoveEvent.bind(this);
|
|
144
|
+
eventName = 'pointermove';
|
|
126
145
|
break;
|
|
127
146
|
case 'moveend':
|
|
128
|
-
|
|
147
|
+
eventHandler = this.handleMoveEndEvent.bind(this);
|
|
148
|
+
eventName = 'moveend';
|
|
129
149
|
break;
|
|
130
150
|
case 'zoomend':
|
|
131
|
-
|
|
151
|
+
eventHandler = this.handleZoomEndEvent.bind(this);
|
|
152
|
+
target = this.map.getView();
|
|
153
|
+
eventName = 'change:resolution';
|
|
154
|
+
break;
|
|
155
|
+
case 'rendercomplete':
|
|
156
|
+
eventHandler = this.handleRenderCompleteEvent.bind(this);
|
|
157
|
+
eventName = 'rendercomplete';
|
|
158
|
+
this.map.once(eventName, eventHandler);
|
|
159
|
+
this.mapEventListeners.set(type, { handler: eventHandler, target, eventName, isOnce: true });
|
|
160
|
+
return;
|
|
161
|
+
case 'error':
|
|
162
|
+
eventHandler = this.handleErrorEvent.bind(this);
|
|
163
|
+
eventName = 'error';
|
|
132
164
|
break;
|
|
165
|
+
default:
|
|
166
|
+
return;
|
|
133
167
|
}
|
|
168
|
+
target.on(eventName, eventHandler);
|
|
169
|
+
this.mapEventListeners.set(type, { handler: eventHandler, target, eventName, isOnce: false });
|
|
134
170
|
}
|
|
135
171
|
/**
|
|
136
|
-
*
|
|
172
|
+
* 移除地图事件监听器
|
|
137
173
|
* @param type 事件类型
|
|
138
174
|
*/
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
if (
|
|
142
|
-
return;
|
|
175
|
+
detachMapEvent(type) {
|
|
176
|
+
const mapListener = this.mapEventListeners.get(type);
|
|
177
|
+
if (!mapListener) {
|
|
178
|
+
return;
|
|
143
179
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
180
|
+
const { handler, target, eventName } = mapListener;
|
|
181
|
+
target.un(eventName, handler);
|
|
182
|
+
this.mapEventListeners.delete(type);
|
|
147
183
|
}
|
|
148
184
|
/**
|
|
149
185
|
* 处理点击事件
|
|
@@ -192,6 +228,29 @@ export class EventManager {
|
|
|
192
228
|
};
|
|
193
229
|
this.triggerListeners('zoomend', eventData);
|
|
194
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* 处理渲染完成事件
|
|
233
|
+
*/
|
|
234
|
+
handleRenderCompleteEvent() {
|
|
235
|
+
const eventData = {
|
|
236
|
+
type: 'rendercomplete',
|
|
237
|
+
zoom: this.map.getView().getZoom(),
|
|
238
|
+
coordinate: this.map.getView().getCenter()
|
|
239
|
+
};
|
|
240
|
+
this.triggerListeners('rendercomplete', eventData);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 处理错误事件
|
|
244
|
+
* @param error 错误对象
|
|
245
|
+
*/
|
|
246
|
+
handleErrorEvent(error) {
|
|
247
|
+
const eventData = {
|
|
248
|
+
type: 'error',
|
|
249
|
+
originalEvent: error,
|
|
250
|
+
error: error
|
|
251
|
+
};
|
|
252
|
+
this.triggerListeners('error', eventData);
|
|
253
|
+
}
|
|
195
254
|
/**
|
|
196
255
|
* 创建事件数据
|
|
197
256
|
* @param type 事件类型
|
package/core/Line.d.ts
CHANGED
package/core/Line.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Stroke, Style } from "ol/style";
|
|
|
5
5
|
import { Feature } from "ol";
|
|
6
6
|
import MapTools from "./MapTools";
|
|
7
7
|
import { ValidationUtils } from "../utils/ValidationUtils";
|
|
8
|
+
import { EventManager } from "./EventManager";
|
|
8
9
|
/**
|
|
9
10
|
* 线要素管理类
|
|
10
11
|
* 用于在地图上添加和管理线要素,包括普通线要素、河流图层等
|
|
@@ -39,6 +40,7 @@ export default class Line {
|
|
|
39
40
|
};
|
|
40
41
|
ValidationUtils.validateMapInstance(map);
|
|
41
42
|
this.map = map;
|
|
43
|
+
this.eventManager = new EventManager(map);
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* 添加线要素
|
|
@@ -156,7 +158,7 @@ export default class Line {
|
|
|
156
158
|
this.map.addLayer(riverLayer);
|
|
157
159
|
}
|
|
158
160
|
// 设置缩放事件监听
|
|
159
|
-
|
|
161
|
+
this.eventManager.on('moveend', () => {
|
|
160
162
|
this.showRiverLayerByZoom();
|
|
161
163
|
});
|
|
162
164
|
// 初始显示
|
package/core/MapBaseLayers.d.ts
CHANGED
|
@@ -48,6 +48,8 @@ export default class MapBaseLayers {
|
|
|
48
48
|
private layers;
|
|
49
49
|
private readonly errorHandler;
|
|
50
50
|
private currentBaseLayerType;
|
|
51
|
+
private currentAnnotationLayer;
|
|
52
|
+
private currentAnnotationType;
|
|
51
53
|
/**
|
|
52
54
|
* 构造函数
|
|
53
55
|
* @param map OpenLayers地图实例
|
|
@@ -79,12 +81,40 @@ export default class MapBaseLayers {
|
|
|
79
81
|
*/
|
|
80
82
|
private initTiandituLayers;
|
|
81
83
|
/**
|
|
82
|
-
*
|
|
84
|
+
* 加载默认注记图层(cia_c)
|
|
83
85
|
* @param token 天地图token
|
|
84
86
|
* @param baseZIndex 基础层级
|
|
85
87
|
* @private
|
|
86
88
|
*/
|
|
87
|
-
private
|
|
89
|
+
private loadDefaultAnnotationLayer;
|
|
90
|
+
/**
|
|
91
|
+
* 切换注记类别
|
|
92
|
+
* @param annotationType 注记类型 ('cva_c' | 'cia_c' | 'cta_c')
|
|
93
|
+
*/
|
|
94
|
+
switchAnnotationLayer(annotationType: 'cva_c' | 'cia_c' | 'cta_c'): void;
|
|
95
|
+
/**
|
|
96
|
+
* 设置注记图层(私有方法,用于消除代码重复)
|
|
97
|
+
* @param annotationType 注记类型
|
|
98
|
+
* @param token 天地图token
|
|
99
|
+
* @param baseZIndex 基础层级
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
private setAnnotationLayer;
|
|
103
|
+
/**
|
|
104
|
+
* 获取当前注记类型
|
|
105
|
+
* @returns 当前注记类型
|
|
106
|
+
*/
|
|
107
|
+
getCurrentAnnotationType(): string | null;
|
|
108
|
+
/**
|
|
109
|
+
* 显示/隐藏注记图层
|
|
110
|
+
* @param visible 是否可见
|
|
111
|
+
*/
|
|
112
|
+
setAnnotationVisible(visible: boolean): void;
|
|
113
|
+
/**
|
|
114
|
+
* 检查注记图层是否可见
|
|
115
|
+
* @returns 是否可见
|
|
116
|
+
*/
|
|
117
|
+
isAnnotationVisible(): boolean;
|
|
88
118
|
/**
|
|
89
119
|
* 切换底图图层
|
|
90
120
|
* @param type 图层类型
|