my-openlayer 0.1.18 → 1.0.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/README.md +1114 -213
- package/dist/MyOl.d.ts +99 -31
- package/dist/MyOl.js +338 -106
- package/dist/core/ConfigManager.d.ts +88 -0
- package/dist/core/ConfigManager.js +112 -0
- package/dist/core/DomPoint.d.ts +163 -14
- package/dist/core/DomPoint.js +378 -26
- package/dist/core/EventManager.d.ts +131 -0
- package/dist/core/EventManager.js +257 -0
- package/dist/core/Line.d.ts +99 -12
- package/dist/core/Line.js +216 -57
- package/dist/core/MapBaseLayers.d.ts +187 -19
- package/dist/core/MapBaseLayers.js +453 -122
- package/dist/core/MapTools.d.ts +77 -7
- package/dist/core/MapTools.js +264 -65
- package/dist/core/MeasureHandler.d.ts +13 -6
- package/dist/core/MeasureHandler.js +43 -27
- package/dist/core/Point.d.ts +51 -5
- package/dist/core/Point.js +181 -97
- package/dist/core/Polygon.d.ts +74 -22
- package/dist/core/Polygon.js +294 -125
- package/dist/index.d.ts +18 -10
- package/dist/index.js +17 -10
- package/dist/types.d.ts +200 -14
- package/dist/types.js +11 -1
- package/dist/utils/ErrorHandler.d.ts +102 -0
- package/dist/utils/ErrorHandler.js +191 -0
- package/dist/utils/ValidationUtils.d.ts +162 -0
- package/dist/utils/ValidationUtils.js +308 -0
- package/package.json +5 -6
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { ErrorHandler, ErrorType } from '../utils/ErrorHandler';
|
|
2
|
+
/**
|
|
3
|
+
* 事件管理器类
|
|
4
|
+
* 用于统一管理地图事件的注册、触发和移除
|
|
5
|
+
*/
|
|
6
|
+
export class EventManager {
|
|
7
|
+
/**
|
|
8
|
+
* 构造函数
|
|
9
|
+
* @param map OpenLayers地图实例
|
|
10
|
+
*/
|
|
11
|
+
constructor(map) {
|
|
12
|
+
this.listeners = new Map();
|
|
13
|
+
this.eventCounters = new Map();
|
|
14
|
+
ErrorHandler.validateMap(map);
|
|
15
|
+
this.map = map;
|
|
16
|
+
this.initializeEventCounters();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 初始化事件计数器
|
|
20
|
+
*/
|
|
21
|
+
initializeEventCounters() {
|
|
22
|
+
const eventTypes = ['click', 'dblclick', 'hover', 'moveend', 'zoomend', 'pointermove'];
|
|
23
|
+
eventTypes.forEach(type => {
|
|
24
|
+
this.eventCounters.set(type, 0);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 注册事件监听器
|
|
29
|
+
* @param type 事件类型
|
|
30
|
+
* @param callback 回调函数
|
|
31
|
+
* @param options 选项
|
|
32
|
+
* @returns 事件监听器ID
|
|
33
|
+
*/
|
|
34
|
+
on(type, callback, options) {
|
|
35
|
+
ErrorHandler.validate(typeof callback === 'function', 'Event callback must be a function', { type, callback });
|
|
36
|
+
const id = this.generateListenerId(type);
|
|
37
|
+
const listener = {
|
|
38
|
+
id,
|
|
39
|
+
type,
|
|
40
|
+
callback,
|
|
41
|
+
options
|
|
42
|
+
};
|
|
43
|
+
this.listeners.set(id, listener);
|
|
44
|
+
this.attachMapEvent(type);
|
|
45
|
+
return id;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 移除事件监听器
|
|
49
|
+
* @param id 监听器ID
|
|
50
|
+
*/
|
|
51
|
+
off(id) {
|
|
52
|
+
const listener = this.listeners.get(id);
|
|
53
|
+
if (!listener) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
this.listeners.delete(id);
|
|
57
|
+
this.detachMapEventIfNeeded(listener.type);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 移除指定类型的所有事件监听器
|
|
62
|
+
* @param type 事件类型
|
|
63
|
+
*/
|
|
64
|
+
offAll(type) {
|
|
65
|
+
const idsToRemove = [];
|
|
66
|
+
this.listeners.forEach((listener, id) => {
|
|
67
|
+
if (listener.type === type) {
|
|
68
|
+
idsToRemove.push(id);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
idsToRemove.forEach(id => {
|
|
72
|
+
this.listeners.delete(id);
|
|
73
|
+
});
|
|
74
|
+
this.detachMapEventIfNeeded(type);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 清除所有事件监听器
|
|
78
|
+
*/
|
|
79
|
+
clear() {
|
|
80
|
+
this.listeners.clear();
|
|
81
|
+
this.eventCounters.forEach((_, type) => {
|
|
82
|
+
this.detachMapEventIfNeeded(type);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 获取指定类型的监听器数量
|
|
87
|
+
* @param type 事件类型
|
|
88
|
+
*/
|
|
89
|
+
getListenerCount(type) {
|
|
90
|
+
let count = 0;
|
|
91
|
+
this.listeners.forEach((listener) => {
|
|
92
|
+
if (listener.type === type) {
|
|
93
|
+
count++;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return count;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 生成监听器ID
|
|
100
|
+
* @param type 事件类型
|
|
101
|
+
*/
|
|
102
|
+
generateListenerId(type) {
|
|
103
|
+
const counter = this.eventCounters.get(type) || 0;
|
|
104
|
+
this.eventCounters.set(type, counter + 1);
|
|
105
|
+
return `${type}_${counter + 1}_${Date.now()}`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 附加地图事件
|
|
109
|
+
* @param type 事件类型
|
|
110
|
+
*/
|
|
111
|
+
attachMapEvent(type) {
|
|
112
|
+
const existingListeners = this.getListenerCount(type);
|
|
113
|
+
if (existingListeners > 1) {
|
|
114
|
+
return; // 已经附加过该类型的事件
|
|
115
|
+
}
|
|
116
|
+
switch (type) {
|
|
117
|
+
case 'click':
|
|
118
|
+
this.map.on('click', this.handleClickEvent.bind(this));
|
|
119
|
+
break;
|
|
120
|
+
case 'dblclick':
|
|
121
|
+
this.map.on('dblclick', this.handleDblClickEvent.bind(this));
|
|
122
|
+
break;
|
|
123
|
+
case 'hover':
|
|
124
|
+
case 'pointermove':
|
|
125
|
+
this.map.on('pointermove', this.handlePointerMoveEvent.bind(this));
|
|
126
|
+
break;
|
|
127
|
+
case 'moveend':
|
|
128
|
+
this.map.on('moveend', this.handleMoveEndEvent.bind(this));
|
|
129
|
+
break;
|
|
130
|
+
case 'zoomend':
|
|
131
|
+
this.map.getView().on('change:resolution', this.handleZoomEndEvent.bind(this));
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 分离地图事件(如果不再需要)
|
|
137
|
+
* @param type 事件类型
|
|
138
|
+
*/
|
|
139
|
+
detachMapEventIfNeeded(type) {
|
|
140
|
+
const remainingListeners = this.getListenerCount(type);
|
|
141
|
+
if (remainingListeners > 0) {
|
|
142
|
+
return; // 还有其他监听器需要该事件
|
|
143
|
+
}
|
|
144
|
+
// 注意:OpenLayers 不提供直接移除特定事件监听器的方法
|
|
145
|
+
// 这里只是示例,实际实现可能需要保存事件监听器的引用
|
|
146
|
+
console.warn(`Event type '${type}' detachment not fully implemented`);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 处理点击事件
|
|
150
|
+
* @param event 地图浏览器事件
|
|
151
|
+
*/
|
|
152
|
+
handleClickEvent(event) {
|
|
153
|
+
const eventData = this.createEventData('click', event);
|
|
154
|
+
this.triggerListeners('click', eventData);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 处理双击事件
|
|
158
|
+
* @param event 地图浏览器事件
|
|
159
|
+
*/
|
|
160
|
+
handleDblClickEvent(event) {
|
|
161
|
+
const eventData = this.createEventData('dblclick', event);
|
|
162
|
+
this.triggerListeners('dblclick', eventData);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 处理指针移动事件
|
|
166
|
+
* @param event 地图浏览器事件
|
|
167
|
+
*/
|
|
168
|
+
handlePointerMoveEvent(event) {
|
|
169
|
+
const eventData = this.createEventData('pointermove', event);
|
|
170
|
+
this.triggerListeners('hover', eventData);
|
|
171
|
+
this.triggerListeners('pointermove', eventData);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 处理移动结束事件
|
|
175
|
+
*/
|
|
176
|
+
handleMoveEndEvent() {
|
|
177
|
+
const eventData = {
|
|
178
|
+
type: 'moveend',
|
|
179
|
+
zoom: this.map.getView().getZoom(),
|
|
180
|
+
coordinate: this.map.getView().getCenter()
|
|
181
|
+
};
|
|
182
|
+
this.triggerListeners('moveend', eventData);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 处理缩放结束事件
|
|
186
|
+
*/
|
|
187
|
+
handleZoomEndEvent() {
|
|
188
|
+
const eventData = {
|
|
189
|
+
type: 'zoomend',
|
|
190
|
+
zoom: this.map.getView().getZoom(),
|
|
191
|
+
coordinate: this.map.getView().getCenter()
|
|
192
|
+
};
|
|
193
|
+
this.triggerListeners('zoomend', eventData);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* 创建事件数据
|
|
197
|
+
* @param type 事件类型
|
|
198
|
+
* @param event 原始事件
|
|
199
|
+
*/
|
|
200
|
+
createEventData(type, event) {
|
|
201
|
+
const pixel = this.map.getEventPixel(event.originalEvent);
|
|
202
|
+
const features = this.map.getFeaturesAtPixel(pixel);
|
|
203
|
+
return {
|
|
204
|
+
type,
|
|
205
|
+
originalEvent: event.originalEvent,
|
|
206
|
+
coordinate: event.coordinate,
|
|
207
|
+
pixel,
|
|
208
|
+
features,
|
|
209
|
+
feature: features.length > 0 ? features[0] : undefined
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* 触发监听器
|
|
214
|
+
* @param type 事件类型
|
|
215
|
+
* @param eventData 事件数据
|
|
216
|
+
*/
|
|
217
|
+
triggerListeners(type, eventData) {
|
|
218
|
+
const typeListeners = [];
|
|
219
|
+
this.listeners.forEach((listener) => {
|
|
220
|
+
if (listener.type === type) {
|
|
221
|
+
typeListeners.push(listener);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
typeListeners.forEach((listener) => {
|
|
225
|
+
try {
|
|
226
|
+
// 应用过滤器
|
|
227
|
+
if (listener.options?.filter && !listener.options.filter(eventData)) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
// 执行回调
|
|
231
|
+
listener.callback(eventData);
|
|
232
|
+
// 如果是一次性监听器,移除它
|
|
233
|
+
if (listener.options?.once) {
|
|
234
|
+
this.off(listener.id);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
ErrorHandler.getInstance().createAndHandleError(`Error in event listener: ${error}`, ErrorType.COMPONENT_ERROR, { listener, eventData, error });
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 获取监听器信息(用于调试)
|
|
244
|
+
*/
|
|
245
|
+
getListenersInfo() {
|
|
246
|
+
const result = [];
|
|
247
|
+
this.listeners.forEach((listener) => {
|
|
248
|
+
result.push({
|
|
249
|
+
id: listener.id,
|
|
250
|
+
type: listener.type,
|
|
251
|
+
hasFilter: !!listener.options?.filter,
|
|
252
|
+
isOnce: !!listener.options?.once
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
}
|
package/dist/core/Line.d.ts
CHANGED
|
@@ -1,20 +1,107 @@
|
|
|
1
1
|
import Map from "ol/Map";
|
|
2
2
|
import VectorSource from "ol/source/Vector";
|
|
3
3
|
import VectorLayer from "ol/layer/Vector";
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import { LineOptions, MapJSONData } from "../types";
|
|
5
|
+
/**
|
|
6
|
+
* 河流级别宽度映射配置
|
|
7
|
+
*/
|
|
8
|
+
interface RiverLevelWidthMap {
|
|
9
|
+
[level: number]: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 河流图层配置选项
|
|
13
|
+
*/
|
|
14
|
+
interface RiverLayerOptions extends LineOptions {
|
|
15
|
+
/** 河流级别数量,默认为5 */
|
|
16
|
+
levelCount?: number;
|
|
17
|
+
/** 缩放级别偏移量,默认为8 */
|
|
18
|
+
zoomOffset?: number;
|
|
19
|
+
/** 河流级别宽度映射 */
|
|
20
|
+
levelWidthMap?: RiverLevelWidthMap;
|
|
21
|
+
/** 是否删除同名图层 */
|
|
22
|
+
removeExisting?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 线要素管理类
|
|
26
|
+
* 用于在地图上添加和管理线要素,包括普通线要素、河流图层等
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const lineManager = new Line(map);
|
|
31
|
+
* const layer = lineManager.addLine(geoJsonData, {
|
|
32
|
+
* type: 'road',
|
|
33
|
+
* strokeColor: '#ff0000',
|
|
34
|
+
* strokeWidth: 3
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
6
38
|
export default class Line {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
39
|
+
/** OpenLayers 地图实例 */
|
|
40
|
+
private readonly map;
|
|
41
|
+
/** 河流图层列表 */
|
|
42
|
+
private riverLayerList;
|
|
43
|
+
/** 河流图层显示状态 */
|
|
44
|
+
private riverLayerShow;
|
|
45
|
+
/** 默认河流级别宽度映射 */
|
|
46
|
+
private readonly defaultLevelWidthMap;
|
|
47
|
+
/**
|
|
48
|
+
* 构造函数
|
|
49
|
+
* @param map OpenLayers地图实例
|
|
50
|
+
*/
|
|
11
51
|
constructor(map: Map);
|
|
12
|
-
|
|
13
|
-
|
|
52
|
+
/**
|
|
53
|
+
* 添加线要素
|
|
54
|
+
* @param data GeoJSON格式的线数据
|
|
55
|
+
* @param options 配置项
|
|
56
|
+
* @returns 创建的矢量图层
|
|
57
|
+
*/
|
|
58
|
+
addLine(data: MapJSONData, options?: LineOptions): VectorLayer<VectorSource>;
|
|
59
|
+
/**
|
|
60
|
+
* 添加分级河流图层,根据缩放级别显示不同级别的河流
|
|
61
|
+
* @param fyRiverJson 河流 GeoJSON 数据
|
|
62
|
+
* @param options 河流图层配置选项
|
|
63
|
+
* @throws {Error} 当数据格式无效时抛出错误
|
|
64
|
+
*/
|
|
65
|
+
addRiverLayersByZoom(fyRiverJson: MapJSONData, options?: RiverLayerOptions): void;
|
|
66
|
+
/**
|
|
67
|
+
* 显示或隐藏河流图层
|
|
68
|
+
* @param show 是否显示河流图层
|
|
69
|
+
*/
|
|
14
70
|
showRiverLayer(show: boolean): void;
|
|
71
|
+
/**
|
|
72
|
+
* 根据缩放级别显示对应的河流图层
|
|
73
|
+
* 缩放级别越高,显示的河流级别越详细
|
|
74
|
+
*/
|
|
15
75
|
showRiverLayerByZoom(): void;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
76
|
+
/**
|
|
77
|
+
* 添加按级别显示不同宽度的河流图层
|
|
78
|
+
* @param data 河流 GeoJSON 数据
|
|
79
|
+
* @param options 河流图层配置选项
|
|
80
|
+
* @returns 创建的河流图层
|
|
81
|
+
*/
|
|
82
|
+
addRiverWidthByLevel(data: MapJSONData, options?: RiverLayerOptions): VectorLayer<VectorSource>;
|
|
83
|
+
/**
|
|
84
|
+
* 移除线图层
|
|
85
|
+
* @param layerName 图层名称
|
|
86
|
+
*/
|
|
87
|
+
removeLineLayer(layerName: string): void;
|
|
88
|
+
/**
|
|
89
|
+
* 清除所有河流图层
|
|
90
|
+
*/
|
|
91
|
+
clearRiverLayers(): void;
|
|
92
|
+
/**
|
|
93
|
+
* 获取河流图层显示状态
|
|
94
|
+
* @returns 河流图层是否显示
|
|
95
|
+
*/
|
|
96
|
+
getRiverLayerVisibility(): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* 获取河流图层列表
|
|
99
|
+
* @returns 河流图层数组的副本
|
|
100
|
+
*/
|
|
101
|
+
getRiverLayers(): VectorLayer<VectorSource>[];
|
|
102
|
+
/**
|
|
103
|
+
* 销毁线管理器,清理所有资源
|
|
104
|
+
*/
|
|
105
|
+
destroy(): void;
|
|
20
106
|
}
|
|
107
|
+
export {};
|