my-openlayer 2.3.0 → 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.
- package/core/MapBaseLayers.d.ts +83 -85
- package/core/MapBaseLayers.js +286 -251
- package/core/MapTools.d.ts +27 -0
- package/core/MapTools.js +50 -3
- package/package.json +1 -1
package/core/MapBaseLayers.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
86
|
-
* @param token 天地图token
|
|
87
|
-
* @param baseZIndex 基础层级
|
|
109
|
+
* 设置所有底图的可见性
|
|
88
110
|
* @private
|
|
89
111
|
*/
|
|
90
|
-
private
|
|
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):
|
|
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):
|
|
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
|
-
|
|
158
|
+
addAnnotationLayer(options: Omit<AnnotationLayerOptions, 'token'>): TileLayer<XYZ>;
|
|
124
159
|
/**
|
|
125
|
-
*
|
|
126
|
-
* @returns 当前底图类型
|
|
160
|
+
* 添加GeoServer图层
|
|
127
161
|
*/
|
|
128
|
-
|
|
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
|
-
|
|
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 {};
|
package/core/MapBaseLayers.js
CHANGED
|
@@ -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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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 (
|
|
94
|
-
|
|
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
|
-
*
|
|
133
|
-
* @param token 天地图token
|
|
134
|
-
* @param baseZIndex 基础层级
|
|
208
|
+
* 设置指定类型图层的可见性
|
|
135
209
|
* @private
|
|
136
210
|
*/
|
|
137
|
-
|
|
138
|
-
this.
|
|
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
|
-
|
|
169
|
-
|
|
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
|
-
|
|
315
|
+
addAnnotationLayer(options) {
|
|
213
316
|
try {
|
|
214
|
-
if (
|
|
215
|
-
|
|
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
|
-
|
|
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
|
-
|
|
390
|
+
this.map.removeLayer(layer);
|
|
230
391
|
});
|
|
231
392
|
}
|
|
232
|
-
|
|
233
|
-
this.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this.
|
|
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
|
|
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
|
-
|
|
253
|
-
|
|
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
|
-
|
|
436
|
+
destroy() {
|
|
297
437
|
try {
|
|
298
|
-
|
|
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
|
-
|
|
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/core/MapTools.d.ts
CHANGED
|
@@ -87,6 +87,29 @@ export default class MapTools {
|
|
|
87
87
|
maxZoom?: number;
|
|
88
88
|
duration?: number;
|
|
89
89
|
}): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* 根据GeoJSON数据定位地图视图
|
|
92
|
+
* @param jsonData GeoJSON格式的数据
|
|
93
|
+
* @param fitOptions fit 参数(可选)
|
|
94
|
+
* @returns true 表示已触发定位;false 表示未得到有效范围或数据无效
|
|
95
|
+
*/
|
|
96
|
+
fitByData(jsonData: MapJSONData, fitOptions?: {
|
|
97
|
+
padding?: [number, number, number, number];
|
|
98
|
+
maxZoom?: number;
|
|
99
|
+
duration?: number;
|
|
100
|
+
}): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* 根据GeoJSON数据定位地图视图(静态方法)
|
|
103
|
+
* @param map 地图实例
|
|
104
|
+
* @param jsonData GeoJSON格式的数据
|
|
105
|
+
* @param fitOptions fit 参数(可选)
|
|
106
|
+
* @returns true 表示已触发定位;false 表示未得到有效范围或数据无效
|
|
107
|
+
*/
|
|
108
|
+
static fitByData(map: Map, jsonData: MapJSONData, fitOptions?: {
|
|
109
|
+
padding?: [number, number, number, number];
|
|
110
|
+
maxZoom?: number;
|
|
111
|
+
duration?: number;
|
|
112
|
+
}): boolean;
|
|
90
113
|
/**
|
|
91
114
|
* 视图自适应到指定图层集合的整体范围(overallExtent)
|
|
92
115
|
* 说明:会取每个图层 source 的 extent,合并后执行 view.fit
|
|
@@ -100,4 +123,8 @@ export default class MapTools {
|
|
|
100
123
|
maxZoom?: number;
|
|
101
124
|
duration?: number;
|
|
102
125
|
}): boolean;
|
|
126
|
+
/**
|
|
127
|
+
* 执行地图定位(内部辅助方法)
|
|
128
|
+
*/
|
|
129
|
+
private static executeFit;
|
|
103
130
|
}
|
package/core/MapTools.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
import VectorSource from "ol/source/Vector";
|
|
2
3
|
import GeoJSON from "ol/format/GeoJSON";
|
|
3
4
|
import { ErrorHandler, ErrorType } from "../utils/ErrorHandler";
|
|
4
5
|
import { ValidationUtils } from "../utils/ValidationUtils";
|
|
@@ -212,6 +213,43 @@ class MapTools {
|
|
|
212
213
|
fitToLayers(layerNameOrLayers, fitOptions) {
|
|
213
214
|
return MapTools.fitToLayers(this.map, layerNameOrLayers, fitOptions);
|
|
214
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* 根据GeoJSON数据定位地图视图
|
|
218
|
+
* @param jsonData GeoJSON格式的数据
|
|
219
|
+
* @param fitOptions fit 参数(可选)
|
|
220
|
+
* @returns true 表示已触发定位;false 表示未得到有效范围或数据无效
|
|
221
|
+
*/
|
|
222
|
+
fitByData(jsonData, fitOptions) {
|
|
223
|
+
return MapTools.fitByData(this.map, jsonData, fitOptions);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* 根据GeoJSON数据定位地图视图(静态方法)
|
|
227
|
+
* @param map 地图实例
|
|
228
|
+
* @param jsonData GeoJSON格式的数据
|
|
229
|
+
* @param fitOptions fit 参数(可选)
|
|
230
|
+
* @returns true 表示已触发定位;false 表示未得到有效范围或数据无效
|
|
231
|
+
*/
|
|
232
|
+
static fitByData(map, jsonData, fitOptions) {
|
|
233
|
+
if (!map) {
|
|
234
|
+
throw new Error('Map instance is required');
|
|
235
|
+
}
|
|
236
|
+
if (!jsonData) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
const features = new GeoJSON().readFeatures(jsonData);
|
|
241
|
+
if (!features || features.length === 0) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
const source = new VectorSource({ features });
|
|
245
|
+
const extent = source.getExtent();
|
|
246
|
+
return MapTools.executeFit(map, extent, fitOptions, 'Error fitting view to data');
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
ErrorHandler.getInstance().error('Error fitting view to data:', error);
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
215
253
|
/**
|
|
216
254
|
* 视图自适应到指定图层集合的整体范围(overallExtent)
|
|
217
255
|
* 说明:会取每个图层 source 的 extent,合并后执行 view.fit
|
|
@@ -249,11 +287,20 @@ class MapTools {
|
|
|
249
287
|
ErrorHandler.getInstance().error('Error calculating layer extent:', error);
|
|
250
288
|
}
|
|
251
289
|
});
|
|
252
|
-
if (!hasValidExtent
|
|
290
|
+
if (!hasValidExtent) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
return MapTools.executeFit(map, overallExtent, fitOptions, 'Error fitting view to extent');
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* 执行地图定位(内部辅助方法)
|
|
297
|
+
*/
|
|
298
|
+
static executeFit(map, extent, fitOptions, errorMessage = 'Error fitting view') {
|
|
299
|
+
if (!extent || isEmpty(extent)) {
|
|
253
300
|
return false;
|
|
254
301
|
}
|
|
255
302
|
try {
|
|
256
|
-
map.getView().fit(
|
|
303
|
+
map.getView().fit(extent, {
|
|
257
304
|
padding: fitOptions?.padding ?? [200, 200, 200, 200],
|
|
258
305
|
maxZoom: fitOptions?.maxZoom ?? 14,
|
|
259
306
|
duration: fitOptions?.duration ?? 1500,
|
|
@@ -261,7 +308,7 @@ class MapTools {
|
|
|
261
308
|
return true;
|
|
262
309
|
}
|
|
263
310
|
catch (error) {
|
|
264
|
-
ErrorHandler.getInstance().error(
|
|
311
|
+
ErrorHandler.getInstance().error(errorMessage, error);
|
|
265
312
|
return false;
|
|
266
313
|
}
|
|
267
314
|
}
|