my-openlayer 2.3.1 → 2.3.2

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.
@@ -58,20 +58,16 @@ export default class MapBaseLayers {
58
58
  constructor(map: Map, options: MapLayersOptions);
59
59
  /**
60
60
  * 验证构造函数参数
61
- * @param map 地图实例
62
- * @param options 配置选项
63
61
  * @private
64
62
  */
65
63
  private validateConstructorParams;
66
64
  /**
67
65
  * 合并默认配置选项
68
- * @param options 用户配置选项
69
- * @returns 合并后的配置选项
70
66
  * @private
71
67
  */
72
68
  private mergeDefaultOptions;
73
69
  /**
74
- * 初始化图层
70
+ * 初始化图层数据结构
75
71
  * @private
76
72
  */
77
73
  private initializeLayers;
@@ -80,156 +76,158 @@ export default class MapBaseLayers {
80
76
  * @private
81
77
  */
82
78
  private initTiandituLayers;
79
+ /**
80
+ * 初始化注记图层
81
+ * @private
82
+ */
83
+ private initAnnotationLayer;
84
+ /**
85
+ * 设置初始图层状态(默认显示的底图)
86
+ * @private
87
+ */
88
+ private setupInitialState;
89
+ /**
90
+ * 切换底图图层
91
+ * @param type 图层类型
92
+ */
93
+ switchBaseLayer(type: TiandituType | string): this;
94
+ /**
95
+ * 验证是否可以切换到底图
96
+ * @private
97
+ */
98
+ private validateSwitchBaseLayer;
99
+ /**
100
+ * 获取当前底图类型
101
+ */
102
+ getCurrentBaseLayerType(): string | null;
103
+ /**
104
+ * 获取默认底图类型
105
+ * @private
106
+ */
83
107
  private getDefaultBaseLayerType;
84
108
  /**
85
- * 加载默认注记图层(cia_c)
86
- * @param token 天地图token
87
- * @param baseZIndex 基础层级
109
+ * 设置所有底图的可见性
88
110
  * @private
89
111
  */
90
- private loadDefaultAnnotationLayer;
112
+ private setAllBaseLayersVisible;
113
+ /**
114
+ * 设置指定类型图层的可见性
115
+ * @private
116
+ */
117
+ private setLayerTypeVisible;
91
118
  /**
92
119
  * 切换注记类别
93
120
  * @param annotationType 注记类型 ('cva_c' | 'cia_c' | 'cta_c')
94
121
  */
95
- switchAnnotationLayer(annotationType: AnnotationType): void;
122
+ switchAnnotationLayer(annotationType: AnnotationType): this;
96
123
  /**
97
- * 设置注记图层(私有方法,用于消除代码重复)
98
- * @param annotationType 注记类型
99
- * @param token 天地图token
100
- * @param baseZIndex 基础层级
124
+ * 设置注记图层(核心实现)
101
125
  * @private
102
126
  */
103
127
  private setAnnotationLayer;
128
+ /**
129
+ * 移除当前注记图层
130
+ * @private
131
+ */
132
+ private removeCurrentAnnotationLayer;
133
+ /**
134
+ * 更新注记图层层级
135
+ * @private
136
+ */
137
+ private updateAnnotationLayerZIndex;
138
+ /**
139
+ * 加载默认注记图层(cia_c)
140
+ * @private
141
+ */
142
+ private loadDefaultAnnotationLayer;
104
143
  /**
105
144
  * 获取当前注记类型
106
- * @returns 当前注记类型
107
145
  */
108
146
  getCurrentAnnotationType(): string | null;
109
147
  /**
110
148
  * 显示/隐藏注记图层
111
- * @param visible 是否可见
112
149
  */
113
- setAnnotationVisible(visible: boolean): void;
150
+ setAnnotationVisible(visible: boolean): this;
114
151
  /**
115
152
  * 检查注记图层是否可见
116
- * @returns 是否可见
117
153
  */
118
154
  isAnnotationVisible(): boolean;
119
155
  /**
120
- * 切换底图图层
121
- * @param type 图层类型
156
+ * 添加注记图层(实例方法)
122
157
  */
123
- switchBaseLayer(type: TiandituType | string): void;
158
+ addAnnotationLayer(options: Omit<AnnotationLayerOptions, 'token'>): TileLayer<XYZ>;
124
159
  /**
125
- * 获取当前底图类型
126
- * @returns 当前底图类型
160
+ * 添加GeoServer图层
127
161
  */
128
- getCurrentBaseLayerType(): string | null;
162
+ addGeoServerLayer(url: string, layerName: string, options?: GeoServerLayerOptions): TileLayer<TileWMS>;
163
+ /**
164
+ * 移除指定类型的图层
165
+ */
166
+ removeLayersByType(type: string): this;
167
+ /**
168
+ * 清除所有图层
169
+ */
170
+ clearAllLayers(): this;
171
+ /**
172
+ * 获取图层数量统计
173
+ */
174
+ getLayerStats(): {
175
+ totalTypes: number;
176
+ totalLayers: number;
177
+ layersByType: Record<string, number>;
178
+ };
129
179
  /**
130
180
  * 获取可用的图层类型列表
131
- * @returns 图层类型数组
132
181
  */
133
182
  getAvailableLayerTypes(): string[];
134
183
  /**
135
184
  * 检查指定图层类型是否存在
136
- * @param type 图层类型
137
- * @returns 是否存在
138
185
  */
139
186
  hasLayerType(type: string): boolean;
140
187
  /**
141
- * 添加注记图层(实例方法)
142
- * @param options 注记图层选项(不包含token)
143
- * @returns 创建的图层
144
- */
145
- addAnnotationLayer(options: Omit<AnnotationLayerOptions, 'token'>): TileLayer<XYZ>;
146
- /**
147
- * 添加注记图层(静态方法)
148
- * @param map 地图实例
149
- * @param options 注记图层选项
150
- * @returns 创建的图层
188
+ * 销毁实例,清理资源
151
189
  */
152
- static addAnnotationLayer(map: Map, options: AnnotationLayerOptions): TileLayer<XYZ>;
190
+ destroy(): this;
153
191
  /**
154
- * 将所有图层添加到地图
192
+ * 将所有初始化好的图层添加到地图
155
193
  * @private
156
194
  */
157
195
  private addMapLayer;
158
196
  /**
159
197
  * 处理图层(应用裁剪等)
160
- * @param layer 原始图层
161
- * @returns 处理后的图层
162
198
  * @private
163
199
  */
164
200
  private processLayer;
165
- /**
166
- * 添加GeoServer图层
167
- * @param url GeoServer服务URL
168
- * @param layerName 图层名称
169
- * @param options 图层选项
170
- * @returns 创建的WMS图层
171
- */
172
- addGeoServerLayer(url: string, layerName: string, options?: GeoServerLayerOptions): TileLayer<TileWMS>;
173
201
  /**
174
202
  * 创建天地图图层(实例方法)
175
- * @param options 天地图图层选项
176
- * @returns 创建的图层
177
203
  * @private
178
204
  */
179
205
  private createTiandituLayer;
180
206
  /**
181
207
  * 创建注记图层(实例方法)
182
- * @param options 注记图层选项
183
- * @returns 创建的图层
184
208
  * @private
185
209
  */
186
210
  private createAnnotationLayer;
187
211
  /**
188
- * 创建天地图底图图层(静态方法)
189
- * @param options 天地图图层选项
190
- * @returns 创建的图层
212
+ * 创建天地图底图图层
191
213
  */
192
214
  static getTiandiTuLayer(options: TiandituLayerOptions): TileLayer<XYZ>;
193
215
  /**
194
- * 创建天地图注记图层(静态方法)
195
- * @param options 注记图层选项
196
- * @returns 创建的图层
216
+ * 创建天地图注记图层
197
217
  */
198
218
  static createAnnotationLayer(options: AnnotationLayerOptions): TileLayer<XYZ>;
219
+ /**
220
+ * 添加注记图层到地图(静态方法)
221
+ */
222
+ static addAnnotationLayer(map: Map, options: AnnotationLayerOptions): TileLayer<XYZ>;
199
223
  /**
200
224
  * 获取天地图注记图层(向后兼容的静态方法)
201
- * @param options 注记图层选项
202
- * @returns 创建的图层
203
225
  * @deprecated 使用 createAnnotationLayer 替代
204
226
  */
205
227
  static getAnnotationLayer(options: AnnotationLayerOptions): TileLayer<XYZ>;
206
228
  /**
207
229
  * 创建WMTS瓦片网格
208
- * @param length 层级数量
209
- * @returns WMTS瓦片网格
210
230
  */
211
231
  static getTileGrid(length: number): WMTSTileGrid;
212
- /**
213
- * 移除指定类型的图层
214
- * @param type 图层类型
215
- */
216
- removeLayersByType(type: string): void;
217
- /**
218
- * 清除所有图层
219
- */
220
- clearAllLayers(): void;
221
- /**
222
- * 获取图层数量统计
223
- * @returns 图层统计信息
224
- */
225
- getLayerStats(): {
226
- totalTypes: number;
227
- totalLayers: number;
228
- layersByType: Record<string, number>;
229
- };
230
- /**
231
- * 销毁实例,清理资源
232
- */
233
- destroy(): void;
234
232
  }
235
233
  export {};
@@ -19,6 +19,7 @@ const CUSTOM_LAYER_KEY = '__custom__';
19
19
  * 地图底图图层管理类
20
20
  */
21
21
  export default class MapBaseLayers {
22
+ //************* Constructor & Initialization *************
22
23
  /**
23
24
  * 构造函数
24
25
  * @param map OpenLayers地图实例
@@ -31,21 +32,16 @@ export default class MapBaseLayers {
31
32
  this.currentAnnotationType = null;
32
33
  this.errorHandler = ErrorHandler.getInstance();
33
34
  try {
34
- // 参数验证
35
+ // 1. 参数验证
35
36
  this.validateConstructorParams(map, options);
36
37
  this.map = map;
37
38
  this.options = this.mergeDefaultOptions(options);
38
- // 初始化图层
39
+ // 2. 初始化图层列表(准备数据)
39
40
  this.initializeLayers();
40
- if (this.layers && Object.keys(this.layers).length > 0) {
41
- this.addMapLayer();
42
- if (!Array.isArray(this.options.layers)) {
43
- const defaultType = this.getDefaultBaseLayerType();
44
- if (defaultType) {
45
- this.switchBaseLayer(defaultType);
46
- }
47
- }
48
- }
41
+ // 3. 将图层添加到地图(执行操作)
42
+ this.addMapLayer();
43
+ // 4. 设置初始状态
44
+ this.setupInitialState();
49
45
  }
50
46
  catch (error) {
51
47
  this.errorHandler.createAndHandleError(`Failed to initialize MapBaseLayers: ${error}`, ErrorType.MAP_ERROR, { map, options, error });
@@ -54,8 +50,6 @@ export default class MapBaseLayers {
54
50
  }
55
51
  /**
56
52
  * 验证构造函数参数
57
- * @param map 地图实例
58
- * @param options 配置选项
59
53
  * @private
60
54
  */
61
55
  validateConstructorParams(map, options) {
@@ -64,39 +58,36 @@ export default class MapBaseLayers {
64
58
  }
65
59
  /**
66
60
  * 合并默认配置选项
67
- * @param options 用户配置选项
68
- * @returns 合并后的配置选项
69
61
  * @private
70
62
  */
71
63
  mergeDefaultOptions(options) {
72
64
  return { ...ConfigManager.DEFAULT_MAP_LAYERS_OPTIONS, ...options };
73
65
  }
74
66
  /**
75
- * 初始化图层
67
+ * 初始化图层数据结构
76
68
  * @private
77
69
  */
78
70
  initializeLayers() {
79
- const { layers, token } = this.options;
71
+ const { layers, token, annotation } = this.options;
72
+ // 初始化底图配置
80
73
  if (Array.isArray(layers)) {
81
74
  this.layers = { [CUSTOM_LAYER_KEY]: layers };
82
75
  }
83
76
  else if (layers && Object.keys(layers).length > 0) {
84
77
  this.layers = layers;
85
78
  }
79
+ else if (token) {
80
+ // 如果没有提供layers但提供了token,则初始化标准天地图
81
+ this.initTiandituLayers();
82
+ }
86
83
  else {
87
84
  this.layers = {};
88
- if (token) {
89
- this.initTiandituLayers();
90
- }
91
85
  }
92
- // 添加注记图层
93
- if (this.options.annotation) {
94
- if (!this.options.token) {
95
- throw new Error('请配置token后才能使用天地图注记');
96
- }
97
- const { token, zIndex = ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX } = this.options;
98
- this.loadDefaultAnnotationLayer(token, zIndex);
86
+ // 初始化注记配置
87
+ if (annotation) {
88
+ this.initAnnotationLayer();
99
89
  }
90
+ return this;
100
91
  }
101
92
  /**
102
93
  * 初始化天地图图层
@@ -108,7 +99,6 @@ export default class MapBaseLayers {
108
99
  }
109
100
  const { token, zIndex = ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX } = this.options;
110
101
  try {
111
- // 创建基础图层
112
102
  this.layers.vec_c = [this.createTiandituLayer({ type: 'vec_c', token, zIndex, visible: false })];
113
103
  this.layers.img_c = [this.createTiandituLayer({ type: 'img_c', token, zIndex, visible: false })];
114
104
  this.layers.ter_c = [this.createTiandituLayer({ type: 'ter_c', token, zIndex, visible: false })];
@@ -117,26 +107,113 @@ export default class MapBaseLayers {
117
107
  this.errorHandler.createAndHandleError(`Failed to initialize Tianditu layers: ${error}`, ErrorType.LAYER_ERROR, { token, zIndex, error });
118
108
  throw error;
119
109
  }
110
+ return this;
111
+ }
112
+ /**
113
+ * 初始化注记图层
114
+ * @private
115
+ */
116
+ initAnnotationLayer() {
117
+ if (!this.options.token) {
118
+ throw new Error('请配置token后才能使用天地图注记');
119
+ }
120
+ const { token, zIndex = ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX } = this.options;
121
+ this.loadDefaultAnnotationLayer(token, zIndex);
122
+ }
123
+ /**
124
+ * 设置初始图层状态(默认显示的底图)
125
+ * @private
126
+ */
127
+ setupInitialState() {
128
+ if (this.layers && Object.keys(this.layers).length > 0) {
129
+ // 如果是自定义数组图层,默认已经添加并显示了(取决于配置)
130
+ // 如果是键值对配置的图层(包括天地图),需要选择一个默认显示
131
+ if (!Array.isArray(this.options.layers)) {
132
+ const defaultType = this.getDefaultBaseLayerType();
133
+ if (defaultType) {
134
+ this.switchBaseLayer(defaultType);
135
+ }
136
+ }
137
+ }
138
+ }
139
+ //************* Base Layer Management *************
140
+ /**
141
+ * 切换底图图层
142
+ * @param type 图层类型
143
+ */
144
+ switchBaseLayer(type) {
145
+ try {
146
+ if (!this.validateSwitchBaseLayer(type)) {
147
+ return this;
148
+ }
149
+ // 1. 隐藏所有底图
150
+ this.setAllBaseLayersVisible(false);
151
+ // 2. 显示目标底图
152
+ this.setLayerTypeVisible(type, true);
153
+ // 3. 更新当前状态
154
+ this.currentBaseLayerType = type;
155
+ // 4. 调整注记图层层级(保持在底图之上)
156
+ this.updateAnnotationLayerZIndex();
157
+ }
158
+ catch (error) {
159
+ this.errorHandler.createAndHandleError(`Failed to switch base layer to '${type}': ${error}`, ErrorType.LAYER_ERROR, { type, error });
160
+ }
161
+ return this;
162
+ }
163
+ /**
164
+ * 验证是否可以切换到底图
165
+ * @private
166
+ */
167
+ validateSwitchBaseLayer(type) {
168
+ if (Array.isArray(this.options.layers)) {
169
+ this.errorHandler.createAndHandleError('需要按照键值对的方式配置底图才可使用切换底图功能', ErrorType.LAYER_ERROR, { layersType: 'array', requestedType: type });
170
+ return false;
171
+ }
172
+ if (TIANDITU_TYPES.includes(type) && !this.options.token) {
173
+ this.errorHandler.createAndHandleError('请配置token后才能使用天地图底图', ErrorType.LAYER_ERROR, { requestedType: type });
174
+ return false;
175
+ }
176
+ if (!this.layers[type]) {
177
+ this.errorHandler.createAndHandleError(`图层类型 '${type}' 不存在`, ErrorType.LAYER_ERROR, { availableTypes: Object.keys(this.layers), requestedType: type });
178
+ return false;
179
+ }
180
+ return true;
181
+ }
182
+ /**
183
+ * 获取当前底图类型
184
+ */
185
+ getCurrentBaseLayerType() {
186
+ return this.currentBaseLayerType;
120
187
  }
188
+ /**
189
+ * 获取默认底图类型
190
+ * @private
191
+ */
121
192
  getDefaultBaseLayerType() {
122
193
  const types = Object.keys(this.layers);
123
- if (types.length === 0) {
194
+ if (types.length === 0)
124
195
  return null;
196
+ return this.layers.vec_c ? 'vec_c' : types[0];
197
+ }
198
+ /**
199
+ * 设置所有底图的可见性
200
+ * @private
201
+ */
202
+ setAllBaseLayersVisible(visible) {
203
+ for (const key in this.layers) {
204
+ this.setLayerTypeVisible(key, visible);
125
205
  }
126
- if (this.layers.vec_c) {
127
- return 'vec_c';
128
- }
129
- return types[0];
130
206
  }
131
207
  /**
132
- * 加载默认注记图层(cia_c)
133
- * @param token 天地图token
134
- * @param baseZIndex 基础层级
208
+ * 设置指定类型图层的可见性
135
209
  * @private
136
210
  */
137
- loadDefaultAnnotationLayer(token, baseZIndex) {
138
- this.setAnnotationLayer('cia_c', token, baseZIndex);
211
+ setLayerTypeVisible(type, visible) {
212
+ this.layers[type]?.forEach((layer) => {
213
+ layer.setVisible(visible);
214
+ });
139
215
  }
216
+ //************* Annotation Layer Management *************
140
217
  /**
141
218
  * 切换注记类别
142
219
  * @param annotationType 注记类型 ('cva_c' | 'cia_c' | 'cta_c')
@@ -155,181 +232,234 @@ export default class MapBaseLayers {
155
232
  catch (error) {
156
233
  this.errorHandler.createAndHandleError(`Failed to switch annotation layer to '${annotationType}': ${error}`, ErrorType.LAYER_ERROR, { annotationType, error });
157
234
  }
235
+ return this;
158
236
  }
159
237
  /**
160
- * 设置注记图层(私有方法,用于消除代码重复)
161
- * @param annotationType 注记类型
162
- * @param token 天地图token
163
- * @param baseZIndex 基础层级
238
+ * 设置注记图层(核心实现)
164
239
  * @private
165
240
  */
166
241
  setAnnotationLayer(annotationType, token, baseZIndex) {
167
- // 移除当前注记图层
168
- if (this.currentAnnotationLayer) {
169
- this.map.removeLayer(this.currentAnnotationLayer);
170
- }
171
- // 创建新的注记图层,确保层级在基本图层之上
242
+ // 1. 移除旧图层
243
+ this.removeCurrentAnnotationLayer();
244
+ // 2. 计算新层级
172
245
  const annotationZIndex = baseZIndex + ConfigManager.TIANDITU_CONFIG.ANNOTATION_ZINDEX_OFFSET;
246
+ // 3. 创建新图层
173
247
  let annotationLayer = this.createAnnotationLayer({
174
248
  type: annotationType,
175
249
  token,
176
250
  zIndex: annotationZIndex,
177
251
  visible: true
178
252
  });
179
- // 应用剪切处理
253
+ // 4. 应用剪切
180
254
  annotationLayer = this.processLayer(annotationLayer);
255
+ // 5. 添加到地图并更新状态
181
256
  this.currentAnnotationLayer = annotationLayer;
182
257
  this.currentAnnotationType = annotationType;
183
258
  this.map.addLayer(this.currentAnnotationLayer);
259
+ return this;
260
+ }
261
+ /**
262
+ * 移除当前注记图层
263
+ * @private
264
+ */
265
+ removeCurrentAnnotationLayer() {
266
+ if (this.currentAnnotationLayer) {
267
+ this.map.removeLayer(this.currentAnnotationLayer);
268
+ this.currentAnnotationLayer = null;
269
+ // 注意:这里不清除 currentAnnotationType,因为可能只是临时移除
270
+ }
271
+ }
272
+ /**
273
+ * 更新注记图层层级
274
+ * @private
275
+ */
276
+ updateAnnotationLayerZIndex() {
277
+ if (this.currentAnnotationLayer && this.currentAnnotationType) {
278
+ const baseZIndex = this.options.zIndex ?? ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX;
279
+ const annotationZIndex = baseZIndex + ConfigManager.TIANDITU_CONFIG.ANNOTATION_ZINDEX_OFFSET;
280
+ this.currentAnnotationLayer.setZIndex(annotationZIndex);
281
+ }
282
+ }
283
+ /**
284
+ * 加载默认注记图层(cia_c)
285
+ * @private
286
+ */
287
+ loadDefaultAnnotationLayer(token, baseZIndex) {
288
+ this.setAnnotationLayer('cia_c', token, baseZIndex);
289
+ return this;
184
290
  }
185
291
  /**
186
292
  * 获取当前注记类型
187
- * @returns 当前注记类型
188
293
  */
189
294
  getCurrentAnnotationType() {
190
295
  return this.currentAnnotationType;
191
296
  }
192
297
  /**
193
298
  * 显示/隐藏注记图层
194
- * @param visible 是否可见
195
299
  */
196
300
  setAnnotationVisible(visible) {
197
301
  if (this.currentAnnotationLayer) {
198
302
  this.currentAnnotationLayer.setVisible(visible);
199
303
  }
304
+ return this;
200
305
  }
201
306
  /**
202
307
  * 检查注记图层是否可见
203
- * @returns 是否可见
204
308
  */
205
309
  isAnnotationVisible() {
206
310
  return this.currentAnnotationLayer ? this.currentAnnotationLayer.getVisible() : false;
207
311
  }
208
312
  /**
209
- * 切换底图图层
210
- * @param type 图层类型
313
+ * 添加注记图层(实例方法)
211
314
  */
212
- switchBaseLayer(type) {
315
+ addAnnotationLayer(options) {
213
316
  try {
214
- if (Array.isArray(this.options.layers)) {
215
- this.errorHandler.createAndHandleError('需要按照键值对的方式配置底图才可使用切换底图功能', ErrorType.LAYER_ERROR, { layersType: 'array', requestedType: type });
216
- return;
217
- }
218
- if (TIANDITU_TYPES.includes(type) && !this.options.token) {
219
- this.errorHandler.createAndHandleError('请配置token后才能使用天地图底图', ErrorType.LAYER_ERROR, { requestedType: type });
220
- return;
317
+ if (!this.options.token) {
318
+ throw new Error('Token is required for annotation layer');
221
319
  }
320
+ return MapBaseLayers.addAnnotationLayer(this.map, {
321
+ ...options,
322
+ token: this.options.token
323
+ });
324
+ }
325
+ catch (error) {
326
+ this.errorHandler.createAndHandleError(`Failed to add annotation layer: ${error}`, ErrorType.LAYER_ERROR, { options, error });
327
+ throw error;
328
+ }
329
+ }
330
+ //************* Layer Operations *************
331
+ /**
332
+ * 添加GeoServer图层
333
+ */
334
+ addGeoServerLayer(url, layerName, options = {}) {
335
+ try {
336
+ ValidationUtils.validateNonEmptyString(url, 'Valid URL is required for GeoServer layer');
337
+ ValidationUtils.validateNonEmptyString(layerName, 'Valid layer name is required for GeoServer layer');
338
+ const wmsLayer = new TileLayer({
339
+ source: new TileWMS({
340
+ url: url,
341
+ params: {
342
+ 'LAYERS': layerName,
343
+ 'TILED': true,
344
+ 'VERSION': options.version || '1.1.1',
345
+ ...options.params
346
+ },
347
+ serverType: 'geoserver',
348
+ crossOrigin: options.crossOrigin || 'anonymous',
349
+ }),
350
+ zIndex: options.zIndex ?? ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX,
351
+ visible: options.visible ?? true,
352
+ });
353
+ this.map.addLayer(wmsLayer);
354
+ return wmsLayer;
355
+ }
356
+ catch (error) {
357
+ this.errorHandler.createAndHandleError(`Failed to add GeoServer layer: ${error}`, ErrorType.LAYER_ERROR, { url, layerName, options, error });
358
+ throw error;
359
+ }
360
+ }
361
+ /**
362
+ * 移除指定类型的图层
363
+ */
364
+ removeLayersByType(type) {
365
+ try {
222
366
  if (!this.layers[type]) {
223
- this.errorHandler.createAndHandleError(`图层类型 '${type}' 不存在`, ErrorType.LAYER_ERROR, { availableTypes: Object.keys(this.layers), requestedType: type });
224
- return;
367
+ return this;
225
368
  }
226
- // 隐藏所有图层
369
+ this.layers[type].forEach((layer) => {
370
+ this.map.removeLayer(layer);
371
+ });
372
+ delete this.layers[type];
373
+ if (this.currentBaseLayerType === type) {
374
+ this.currentBaseLayerType = null;
375
+ }
376
+ }
377
+ catch (error) {
378
+ this.errorHandler.createAndHandleError(`Failed to remove layers of type '${type}': ${error}`, ErrorType.LAYER_ERROR, { type, error });
379
+ }
380
+ return this;
381
+ }
382
+ /**
383
+ * 清除所有图层
384
+ */
385
+ clearAllLayers() {
386
+ try {
387
+ // 1. 清除底图
227
388
  for (const key in this.layers) {
228
389
  this.layers[key]?.forEach((layer) => {
229
- layer.setVisible(false);
390
+ this.map.removeLayer(layer);
230
391
  });
231
392
  }
232
- // 显示指定类型的图层
233
- this.layers[type]?.forEach((layer) => {
234
- layer.setVisible(true);
235
- });
236
- this.currentBaseLayerType = type;
237
- // 如果存在注记图层,更新其层级确保在新的基本图层之上
238
- if (this.currentAnnotationLayer && this.currentAnnotationType) {
239
- const baseZIndex = this.options.zIndex ?? ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX;
240
- const annotationZIndex = baseZIndex + ConfigManager.TIANDITU_CONFIG.ANNOTATION_ZINDEX_OFFSET;
241
- this.currentAnnotationLayer.setZIndex(annotationZIndex);
242
- }
393
+ this.layers = {};
394
+ this.currentBaseLayerType = null;
395
+ // 2. 清除注记
396
+ this.removeCurrentAnnotationLayer();
397
+ this.currentAnnotationType = null;
243
398
  }
244
399
  catch (error) {
245
- this.errorHandler.createAndHandleError(`Failed to switch base layer to '${type}': ${error}`, ErrorType.LAYER_ERROR, { type, error });
400
+ this.errorHandler.createAndHandleError(`Failed to clear all layers: ${error}`, ErrorType.LAYER_ERROR, { error });
246
401
  }
402
+ return this;
247
403
  }
248
404
  /**
249
- * 获取当前底图类型
250
- * @returns 当前底图类型
405
+ * 获取图层数量统计
251
406
  */
252
- getCurrentBaseLayerType() {
253
- return this.currentBaseLayerType;
407
+ getLayerStats() {
408
+ const layersByType = {};
409
+ let totalLayers = 0;
410
+ for (const key in this.layers) {
411
+ const count = this.layers[key]?.length || 0;
412
+ layersByType[key] = count;
413
+ totalLayers += count;
414
+ }
415
+ return {
416
+ totalTypes: Object.keys(this.layers).length,
417
+ totalLayers,
418
+ layersByType
419
+ };
254
420
  }
255
421
  /**
256
422
  * 获取可用的图层类型列表
257
- * @returns 图层类型数组
258
423
  */
259
424
  getAvailableLayerTypes() {
260
425
  return Object.keys(this.layers);
261
426
  }
262
427
  /**
263
428
  * 检查指定图层类型是否存在
264
- * @param type 图层类型
265
- * @returns 是否存在
266
429
  */
267
430
  hasLayerType(type) {
268
431
  return type in this.layers && this.layers[type] !== undefined;
269
432
  }
270
433
  /**
271
- * 添加注记图层(实例方法)
272
- * @param options 注记图层选项(不包含token)
273
- * @returns 创建的图层
274
- */
275
- addAnnotationLayer(options) {
276
- try {
277
- if (!this.options.token) {
278
- throw new Error('Token is required for annotation layer');
279
- }
280
- return MapBaseLayers.addAnnotationLayer(this.map, {
281
- ...options,
282
- token: this.options.token
283
- });
284
- }
285
- catch (error) {
286
- this.errorHandler.createAndHandleError(`Failed to add annotation layer: ${error}`, ErrorType.LAYER_ERROR, { options, error });
287
- throw error;
288
- }
289
- }
290
- /**
291
- * 添加注记图层(静态方法)
292
- * @param map 地图实例
293
- * @param options 注记图层选项
294
- * @returns 创建的图层
434
+ * 销毁实例,清理资源
295
435
  */
296
- static addAnnotationLayer(map, options) {
436
+ destroy() {
297
437
  try {
298
- ErrorHandler.validateMap(map);
299
- if (!options.token) {
300
- throw new Error('Token is required for annotation layer');
301
- }
302
- const layer = MapBaseLayers.createAnnotationLayer({
303
- type: options.type,
304
- token: options.token,
305
- zIndex: options.zIndex ?? ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX,
306
- visible: options.visible ?? true
307
- });
308
- map.addLayer(layer);
309
- return layer;
438
+ this.clearAllLayers();
310
439
  }
311
440
  catch (error) {
312
- const errorHandler = ErrorHandler.getInstance();
313
- errorHandler.createAndHandleError(`Failed to add annotation layer: ${error}`, ErrorType.LAYER_ERROR, { options, error });
314
- throw error;
441
+ this.errorHandler.createAndHandleError(`Failed to destroy MapBaseLayers: ${error}`, ErrorType.MAP_ERROR, { error });
315
442
  }
443
+ return this;
316
444
  }
445
+ //************* Helper Methods *************
317
446
  /**
318
- * 将所有图层添加到地图
447
+ * 将所有初始化好的图层添加到地图
319
448
  * @private
320
449
  */
321
450
  addMapLayer() {
322
451
  try {
323
452
  if (!this.layers || Object.keys(this.layers).length === 0) {
324
- return;
453
+ return this;
325
454
  }
326
455
  for (const key in this.layers) {
327
456
  const layerList = this.layers[key];
328
- if (!layerList || layerList.length === 0) {
457
+ if (!layerList || layerList.length === 0)
329
458
  continue;
330
- }
459
+ // 处理并更新图层列表
331
460
  const processedLayerList = layerList.map(layer => this.processLayer(layer));
332
461
  this.layers[key] = processedLayerList;
462
+ // 添加到地图
333
463
  processedLayerList.forEach((layer) => {
334
464
  this.map.addLayer(layer);
335
465
  });
@@ -339,11 +469,10 @@ export default class MapBaseLayers {
339
469
  this.errorHandler.createAndHandleError(`Failed to add map layers: ${error}`, ErrorType.LAYER_ERROR, { layersCount: Object.keys(this.layers).length, error });
340
470
  throw error;
341
471
  }
472
+ return this;
342
473
  }
343
474
  /**
344
475
  * 处理图层(应用裁剪等)
345
- * @param layer 原始图层
346
- * @returns 处理后的图层
347
476
  * @private
348
477
  */
349
478
  processLayer(layer) {
@@ -359,44 +488,8 @@ export default class MapBaseLayers {
359
488
  throw error;
360
489
  }
361
490
  }
362
- /**
363
- * 添加GeoServer图层
364
- * @param url GeoServer服务URL
365
- * @param layerName 图层名称
366
- * @param options 图层选项
367
- * @returns 创建的WMS图层
368
- */
369
- addGeoServerLayer(url, layerName, options = {}) {
370
- try {
371
- ValidationUtils.validateNonEmptyString(url, 'Valid URL is required for GeoServer layer');
372
- ValidationUtils.validateNonEmptyString(layerName, 'Valid layer name is required for GeoServer layer');
373
- const wmsLayer = new TileLayer({
374
- source: new TileWMS({
375
- url: url,
376
- params: {
377
- 'LAYERS': layerName,
378
- 'TILED': true,
379
- 'VERSION': options.version || '1.1.1',
380
- ...options.params
381
- },
382
- serverType: 'geoserver',
383
- crossOrigin: options.crossOrigin || 'anonymous',
384
- }),
385
- zIndex: options.zIndex ?? ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX,
386
- visible: options.visible ?? true,
387
- });
388
- this.map.addLayer(wmsLayer);
389
- return wmsLayer;
390
- }
391
- catch (error) {
392
- this.errorHandler.createAndHandleError(`Failed to add GeoServer layer: ${error}`, ErrorType.LAYER_ERROR, { url, layerName, options, error });
393
- throw error;
394
- }
395
- }
396
491
  /**
397
492
  * 创建天地图图层(实例方法)
398
- * @param options 天地图图层选项
399
- * @returns 创建的图层
400
493
  * @private
401
494
  */
402
495
  createTiandituLayer(options) {
@@ -404,17 +497,14 @@ export default class MapBaseLayers {
404
497
  }
405
498
  /**
406
499
  * 创建注记图层(实例方法)
407
- * @param options 注记图层选项
408
- * @returns 创建的图层
409
500
  * @private
410
501
  */
411
502
  createAnnotationLayer(options) {
412
503
  return MapBaseLayers.createAnnotationLayer(options);
413
504
  }
505
+ //************* Static Methods *************
414
506
  /**
415
- * 创建天地图底图图层(静态方法)
416
- * @param options 天地图图层选项
417
- * @returns 创建的图层
507
+ * 创建天地图底图图层
418
508
  */
419
509
  static getTiandiTuLayer(options) {
420
510
  try {
@@ -440,9 +530,7 @@ export default class MapBaseLayers {
440
530
  }
441
531
  }
442
532
  /**
443
- * 创建天地图注记图层(静态方法)
444
- * @param options 注记图层选项
445
- * @returns 创建的图层
533
+ * 创建天地图注记图层
446
534
  */
447
535
  static createAnnotationLayer(options) {
448
536
  try {
@@ -467,10 +555,32 @@ export default class MapBaseLayers {
467
555
  throw error;
468
556
  }
469
557
  }
558
+ /**
559
+ * 添加注记图层到地图(静态方法)
560
+ */
561
+ static addAnnotationLayer(map, options) {
562
+ try {
563
+ ErrorHandler.validateMap(map);
564
+ if (!options.token) {
565
+ throw new Error('Token is required for annotation layer');
566
+ }
567
+ const layer = MapBaseLayers.createAnnotationLayer({
568
+ type: options.type,
569
+ token: options.token,
570
+ zIndex: options.zIndex ?? ConfigManager.TIANDITU_CONFIG.DEFAULT_ZINDEX,
571
+ visible: options.visible ?? true
572
+ });
573
+ map.addLayer(layer);
574
+ return layer;
575
+ }
576
+ catch (error) {
577
+ const errorHandler = ErrorHandler.getInstance();
578
+ errorHandler.createAndHandleError(`Failed to add annotation layer: ${error}`, ErrorType.LAYER_ERROR, { options, error });
579
+ throw error;
580
+ }
581
+ }
470
582
  /**
471
583
  * 获取天地图注记图层(向后兼容的静态方法)
472
- * @param options 注记图层选项
473
- * @returns 创建的图层
474
584
  * @deprecated 使用 createAnnotationLayer 替代
475
585
  */
476
586
  static getAnnotationLayer(options) {
@@ -478,8 +588,6 @@ export default class MapBaseLayers {
478
588
  }
479
589
  /**
480
590
  * 创建WMTS瓦片网格
481
- * @param length 层级数量
482
- * @returns WMTS瓦片网格
483
591
  */
484
592
  static getTileGrid(length) {
485
593
  try {
@@ -509,77 +617,4 @@ export default class MapBaseLayers {
509
617
  throw error;
510
618
  }
511
619
  }
512
- /**
513
- * 移除指定类型的图层
514
- * @param type 图层类型
515
- */
516
- removeLayersByType(type) {
517
- try {
518
- if (!this.layers[type]) {
519
- return;
520
- }
521
- this.layers[type].forEach((layer) => {
522
- this.map.removeLayer(layer);
523
- });
524
- delete this.layers[type];
525
- if (this.currentBaseLayerType === type) {
526
- this.currentBaseLayerType = null;
527
- }
528
- }
529
- catch (error) {
530
- this.errorHandler.createAndHandleError(`Failed to remove layers of type '${type}': ${error}`, ErrorType.LAYER_ERROR, { type, error });
531
- }
532
- }
533
- /**
534
- * 清除所有图层
535
- */
536
- clearAllLayers() {
537
- try {
538
- for (const key in this.layers) {
539
- this.layers[key]?.forEach((layer) => {
540
- this.map.removeLayer(layer);
541
- });
542
- }
543
- // 清除注记图层
544
- if (this.currentAnnotationLayer) {
545
- this.map.removeLayer(this.currentAnnotationLayer);
546
- this.currentAnnotationLayer = null;
547
- this.currentAnnotationType = null;
548
- }
549
- this.layers = {};
550
- this.currentBaseLayerType = null;
551
- }
552
- catch (error) {
553
- this.errorHandler.createAndHandleError(`Failed to clear all layers: ${error}`, ErrorType.LAYER_ERROR, { error });
554
- }
555
- }
556
- /**
557
- * 获取图层数量统计
558
- * @returns 图层统计信息
559
- */
560
- getLayerStats() {
561
- const layersByType = {};
562
- let totalLayers = 0;
563
- for (const key in this.layers) {
564
- const count = this.layers[key]?.length || 0;
565
- layersByType[key] = count;
566
- totalLayers += count;
567
- }
568
- return {
569
- totalTypes: Object.keys(this.layers).length,
570
- totalLayers,
571
- layersByType
572
- };
573
- }
574
- /**
575
- * 销毁实例,清理资源
576
- */
577
- destroy() {
578
- try {
579
- this.clearAllLayers();
580
- }
581
- catch (error) {
582
- this.errorHandler.createAndHandleError(`Failed to destroy MapBaseLayers: ${error}`, ErrorType.MAP_ERROR, { error });
583
- }
584
- }
585
620
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "my-openlayer",
3
3
  "private": false,
4
- "version": "2.3.1",
4
+ "version": "2.3.2",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",