my-openlayer 2.0.1 → 2.1.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/MyOl.d.ts CHANGED
@@ -5,6 +5,7 @@ import Point from "./core/Point";
5
5
  import Line from "./core/Line";
6
6
  import MapBaseLayers from "./core/MapBaseLayers";
7
7
  import MapTools from "./core/MapTools";
8
+ import SelectHandler from "./core/SelectHandler";
8
9
  import { ErrorHandler } from './utils/ErrorHandler';
9
10
  import { EventManager } from './core/EventManager';
10
11
  import { ConfigManager } from './core/ConfigManager';
@@ -20,6 +21,7 @@ export default class MyOl {
20
21
  private _mapTools?;
21
22
  private _point?;
22
23
  private _line?;
24
+ private _selectHandler?;
23
25
  private readonly errorHandler;
24
26
  private _eventManager?;
25
27
  private readonly configManager;
@@ -83,6 +85,11 @@ export default class MyOl {
83
85
  * @returns Line 线要素操作实例
84
86
  */
85
87
  getLine(): Line;
88
+ /**
89
+ * 获取要素选择处理器模块
90
+ * @returns SelectHandler 要素选择处理器实例
91
+ */
92
+ getSelectHandler(): SelectHandler;
86
93
  /**
87
94
  * 获取地图工具模块
88
95
  * @returns MapTools 地图工具实例
package/MyOl.js CHANGED
@@ -12,6 +12,7 @@ import Point from "./core/Point";
12
12
  import Line from "./core/Line";
13
13
  import MapBaseLayers from "./core/MapBaseLayers";
14
14
  import MapTools from "./core/MapTools";
15
+ import SelectHandler from "./core/SelectHandler";
15
16
  import { ErrorHandler, MyOpenLayersError, ErrorType } from './utils/ErrorHandler';
16
17
  import { EventManager } from './core/EventManager';
17
18
  import { ConfigManager } from './core/ConfigManager';
@@ -240,6 +241,23 @@ class MyOl {
240
241
  throw error;
241
242
  }
242
243
  }
244
+ /**
245
+ * 获取要素选择处理器模块
246
+ * @returns SelectHandler 要素选择处理器实例
247
+ */
248
+ getSelectHandler() {
249
+ try {
250
+ if (!this._selectHandler) {
251
+ this._selectHandler = new SelectHandler(this.map);
252
+ console.debug('要素选择模块已加载');
253
+ }
254
+ return this._selectHandler;
255
+ }
256
+ catch (error) {
257
+ this.errorHandler.handleError(new MyOpenLayersError('要素选择模块初始化失败', ErrorType.COMPONENT_ERROR, { error }));
258
+ throw error;
259
+ }
260
+ }
243
261
  /**
244
262
  * 获取地图工具模块
245
263
  * @returns MapTools 地图工具实例
@@ -358,6 +376,7 @@ class MyOl {
358
376
  this._polygon = undefined;
359
377
  this._mapTools = undefined;
360
378
  this._baseLayers = undefined;
379
+ this._selectHandler = undefined;
361
380
  // 销毁地图
362
381
  this.map.setTarget(undefined);
363
382
  console.debug('地图实例已销毁', { map: this.map });
package/core/Line.d.ts CHANGED
@@ -52,33 +52,33 @@ export default class Line {
52
52
  */
53
53
  constructor(map: Map);
54
54
  /**
55
- * 添加线要素(使用GeoJSON数据)
55
+ * 添加线要素
56
56
  * @param data GeoJSON格式的线数据
57
57
  * @param options 配置项
58
58
  * @returns 创建的矢量图层
59
59
  */
60
60
  addLine(data: MapJSONData, options?: LineOptions): VectorLayer<VectorSource>;
61
61
  /**
62
- * 添加线要素(从URL加载)
62
+ * URL添加线要素
63
63
  * @param url 数据URL
64
64
  * @param options 配置项
65
65
  * @returns 创建的矢量图层
66
66
  */
67
- addLine(url: string, options?: LineOptions): VectorLayer<VectorSource>;
67
+ addLineByUrl(url: string, options?: LineOptions): VectorLayer<VectorSource>;
68
68
  /**
69
- * 添加分级河流图层(使用GeoJSON数据)
69
+ * 添加分级河流图层,根据缩放级别显示不同级别的河流
70
70
  * @param fyRiverJson 河流 GeoJSON 数据
71
71
  * @param options 河流图层配置选项
72
72
  * @throws {Error} 当数据格式无效时抛出错误
73
73
  */
74
74
  addRiverLayersByZoom(fyRiverJson: MapJSONData, options?: RiverLayerOptions): void;
75
75
  /**
76
- * 添加分级河流图层(从URL加载)
76
+ * URL添加分级河流图层,根据缩放级别显示不同级别的河流
77
77
  * @param url 河流数据URL
78
78
  * @param options 河流图层配置选项
79
79
  * @throws {Error} 当数据格式无效时抛出错误
80
80
  */
81
- addRiverLayersByZoom(url: string, options?: RiverLayerOptions): void;
81
+ addRiverLayersByZoomByUrl(url: string, options?: RiverLayerOptions): void;
82
82
  /**
83
83
  * 显示或隐藏河流图层
84
84
  * @param show 是否显示河流图层
@@ -90,19 +90,19 @@ export default class Line {
90
90
  */
91
91
  showRiverLayerByZoom(): void;
92
92
  /**
93
- * 添加按级别显示不同宽度的河流图层(使用GeoJSON数据)
93
+ * 添加按级别显示不同宽度的河流图层
94
94
  * @param data 河流 GeoJSON 数据
95
95
  * @param options 河流图层配置选项
96
96
  * @returns 创建的河流图层
97
97
  */
98
98
  addRiverWidthByLevel(data: MapJSONData, options?: RiverLayerOptions): VectorLayer<VectorSource>;
99
99
  /**
100
- * 添加按级别显示不同宽度的河流图层(从URL加载)
100
+ * URL添加按级别显示不同宽度的河流图层
101
101
  * @param url 河流数据URL
102
102
  * @param options 河流图层配置选项
103
103
  * @returns 创建的河流图层
104
104
  */
105
- addRiverWidthByLevel(url: string, options?: RiverLayerOptions): VectorLayer<VectorSource>;
105
+ addRiverWidthByLevelByUrl(url: string, options?: RiverLayerOptions): VectorLayer<VectorSource>;
106
106
  /**
107
107
  * 移除线图层
108
108
  * @param layerName 图层名称
package/core/Line.js CHANGED
@@ -43,10 +43,7 @@ export default class Line {
43
43
  this.eventManager = new EventManager(map);
44
44
  }
45
45
  addLine(data, options = {}) {
46
- const isUrl = typeof data === 'string';
47
- if (!isUrl) {
48
- ValidationUtils.validateGeoJSONData(data);
49
- }
46
+ ValidationUtils.validateGeoJSONData(data);
50
47
  const defaultOptions = {
51
48
  type: 'line',
52
49
  strokeColor: 'rgba(3, 122, 255, 1)',
@@ -56,15 +53,62 @@ export default class Line {
56
53
  layerName: options.layerName || 'lineLayer'
57
54
  };
58
55
  const mergedOptions = { ...defaultOptions, ...options };
59
- // 根据数据类型创建 VectorSource
60
- const source = isUrl
61
- ? new VectorSource({
62
- url: data,
63
- format: new GeoJSON(options.projectionOptOptions)
64
- })
65
- : new VectorSource({
66
- features: new GeoJSON().readFeatures(data, options.projectionOptOptions)
67
- });
56
+ const features = new GeoJSON().readFeatures(data, options.projectionOptOptions);
57
+ const layer = new VectorLayer({
58
+ properties: {
59
+ name: mergedOptions.layerName,
60
+ layerName: mergedOptions.layerName
61
+ },
62
+ source: new VectorSource({ features }),
63
+ style: (feature) => {
64
+ if (feature instanceof Feature) {
65
+ feature.set('type', mergedOptions.type);
66
+ feature.set('layerName', mergedOptions.type);
67
+ }
68
+ // 如果传入了自定义样式,直接使用
69
+ if (mergedOptions.style) {
70
+ if (typeof mergedOptions.style === 'function') {
71
+ return mergedOptions.style(feature);
72
+ }
73
+ else {
74
+ return mergedOptions.style;
75
+ }
76
+ }
77
+ return new Style({
78
+ stroke: new Stroke({
79
+ color: mergedOptions.strokeColor,
80
+ width: mergedOptions.strokeWidth,
81
+ lineDash: mergedOptions.lineDash,
82
+ lineDashOffset: mergedOptions.lineDashOffset
83
+ })
84
+ });
85
+ },
86
+ zIndex: mergedOptions.zIndex
87
+ });
88
+ layer.setVisible(mergedOptions.visible);
89
+ this.map.addLayer(layer);
90
+ return layer;
91
+ }
92
+ /**
93
+ * 从URL添加线要素
94
+ * @param url 数据URL
95
+ * @param options 配置项
96
+ * @returns 创建的矢量图层
97
+ */
98
+ addLineByUrl(url, options = {}) {
99
+ const defaultOptions = {
100
+ type: 'line',
101
+ strokeColor: 'rgba(3, 122, 255, 1)',
102
+ strokeWidth: 2,
103
+ visible: true,
104
+ zIndex: 15,
105
+ layerName: options.layerName || 'lineLayer'
106
+ };
107
+ const mergedOptions = { ...defaultOptions, ...options };
108
+ const source = new VectorSource({
109
+ url,
110
+ format: new GeoJSON(options.projectionOptOptions)
111
+ });
68
112
  const layer = new VectorLayer({
69
113
  properties: {
70
114
  name: mergedOptions.layerName,
@@ -101,10 +145,7 @@ export default class Line {
101
145
  return layer;
102
146
  }
103
147
  addRiverLayersByZoom(fyRiverJson, options = {}) {
104
- const isUrl = typeof fyRiverJson === 'string';
105
- if (!isUrl) {
106
- ValidationUtils.validateGeoJSONData(fyRiverJson);
107
- }
148
+ ValidationUtils.validateGeoJSONData(fyRiverJson);
108
149
  const defaultOptions = {
109
150
  type: 'river',
110
151
  levelCount: 5,
@@ -126,44 +167,106 @@ export default class Line {
126
167
  this.riverLayerList = [];
127
168
  // 创建分级河流图层
128
169
  for (let level = 1; level <= mergedOptions.levelCount; level++) {
129
- const vectorSource = isUrl
130
- ? new VectorSource({
131
- url: fyRiverJson,
132
- format: new GeoJSON(),
133
- loader: function (extent, resolution, projection, success, failure) {
134
- fetch(fyRiverJson)
135
- .then(response => response.json())
136
- .then(data => {
137
- const geojson = new GeoJSON();
138
- data.features.forEach((feature) => {
139
- if (feature.properties && feature.properties.level === level) {
140
- try {
141
- const olFeature = geojson.readFeature(feature);
142
- if (Array.isArray(olFeature)) {
143
- vectorSource.addFeatures(olFeature);
144
- }
145
- else {
146
- vectorSource.addFeature(olFeature);
147
- }
148
- }
149
- catch (error) {
150
- console.warn(`Failed to load river feature at level ${level}:`, error);
151
- }
170
+ const vectorSource = new VectorSource({
171
+ format: new GeoJSON(),
172
+ loader: () => {
173
+ const geojson = new GeoJSON();
174
+ fyRiverJson.features.forEach((feature) => {
175
+ if (feature.properties && feature.properties.level === level) {
176
+ try {
177
+ const olFeature = geojson.readFeature(feature);
178
+ if (Array.isArray(olFeature)) {
179
+ vectorSource.addFeatures(olFeature);
152
180
  }
153
- });
154
- success?.(vectorSource.getFeatures());
155
- })
156
- .catch(error => {
157
- console.error('Error loading river data:', error);
158
- failure?.();
159
- });
181
+ else {
182
+ vectorSource.addFeature(olFeature);
183
+ }
184
+ }
185
+ catch (error) {
186
+ console.warn(`Failed to load river feature at level ${level}:`, error);
187
+ }
188
+ }
189
+ });
190
+ }
191
+ });
192
+ const riverLayer = new VectorLayer({
193
+ properties: {
194
+ name: mergedOptions.layerName,
195
+ layerName: mergedOptions.layerName,
196
+ riverLevel: level
197
+ },
198
+ source: vectorSource,
199
+ style: (feature) => {
200
+ if (feature instanceof Feature) {
201
+ feature.set('type', mergedOptions.layerName);
202
+ feature.set('layerName', mergedOptions.layerName);
203
+ }
204
+ // 如果传入了自定义样式,直接使用
205
+ if (mergedOptions.style) {
206
+ if (typeof mergedOptions.style === 'function') {
207
+ return mergedOptions.style(feature);
208
+ }
209
+ else {
210
+ return mergedOptions.style;
211
+ }
160
212
  }
161
- })
162
- : new VectorSource({
163
- format: new GeoJSON(),
164
- loader: () => {
213
+ return new Style({
214
+ stroke: new Stroke({
215
+ color: mergedOptions.strokeColor,
216
+ width: mergedOptions.strokeWidth
217
+ })
218
+ });
219
+ },
220
+ zIndex: mergedOptions.zIndex
221
+ });
222
+ riverLayer.setVisible(false);
223
+ this.riverLayerList.push(riverLayer);
224
+ this.map.addLayer(riverLayer);
225
+ }
226
+ // 设置缩放事件监听
227
+ this.eventManager.on('moveend', () => {
228
+ this.showRiverLayerByZoom();
229
+ });
230
+ // 初始显示
231
+ this.showRiverLayerByZoom();
232
+ }
233
+ /**
234
+ * 从URL添加分级河流图层,根据缩放级别显示不同级别的河流
235
+ * @param url 河流数据URL
236
+ * @param options 河流图层配置选项
237
+ * @throws {Error} 当数据格式无效时抛出错误
238
+ */
239
+ addRiverLayersByZoomByUrl(url, options = {}) {
240
+ const defaultOptions = {
241
+ type: 'river',
242
+ levelCount: 5,
243
+ zoomOffset: 8,
244
+ strokeColor: 'rgb(0,113,255)',
245
+ strokeWidth: 3,
246
+ visible: true,
247
+ zIndex: 15,
248
+ layerName: 'riverLayer',
249
+ removeExisting: options.removeExisting ?? false,
250
+ levelWidthMap: this.defaultLevelWidthMap
251
+ };
252
+ const mergedOptions = { ...defaultOptions, ...options };
253
+ // 清除现有河流图层
254
+ if (mergedOptions.removeExisting) {
255
+ this.clearRiverLayers();
256
+ }
257
+ this.riverLayerShow = mergedOptions.visible;
258
+ this.riverLayerList = [];
259
+ // 创建分级河流图层
260
+ for (let level = 1; level <= mergedOptions.levelCount; level++) {
261
+ const vectorSource = new VectorSource({
262
+ url,
263
+ format: new GeoJSON(),
264
+ loader: function (extent, resolution, projection, success, failure) {
265
+ fetch(url)
266
+ .then(response => response.json())
267
+ .then(data => {
165
268
  const geojson = new GeoJSON();
166
- fyRiverJson.features.forEach((feature) => {
269
+ data.features.forEach((feature) => {
167
270
  if (feature.properties && feature.properties.level === level) {
168
271
  try {
169
272
  const olFeature = geojson.readFeature(feature);
@@ -179,8 +282,14 @@ export default class Line {
179
282
  }
180
283
  }
181
284
  });
182
- }
183
- });
285
+ success?.(vectorSource.getFeatures());
286
+ })
287
+ .catch(error => {
288
+ console.error('Error loading river data:', error);
289
+ failure?.();
290
+ });
291
+ }
292
+ });
184
293
  const riverLayer = new VectorLayer({
185
294
  properties: {
186
295
  name: mergedOptions.layerName,
@@ -251,10 +360,64 @@ export default class Line {
251
360
  });
252
361
  }
253
362
  addRiverWidthByLevel(data, options = {}) {
254
- const isUrl = typeof data === 'string';
255
- if (!isUrl) {
256
- ValidationUtils.validateGeoJSONData(data);
363
+ ValidationUtils.validateGeoJSONData(data);
364
+ // 合并默认配置
365
+ const mergedOptions = {
366
+ type: 'river',
367
+ layerName: 'river',
368
+ strokeColor: 'rgba(3, 122, 255, 1)',
369
+ strokeWidth: 2,
370
+ visible: true,
371
+ zIndex: 15,
372
+ levelWidthMap: this.defaultLevelWidthMap,
373
+ removeExisting: options.removeExisting ?? false,
374
+ ...options
375
+ };
376
+ // 移除同名图层(如果存在)
377
+ if (mergedOptions.removeExisting && mergedOptions.layerName) {
378
+ MapTools.removeLayer(this.map, mergedOptions.layerName);
257
379
  }
380
+ // 解析 GeoJSON 数据
381
+ const features = new GeoJSON().readFeatures(data, options.projectionOptOptions);
382
+ // 创建河流图层
383
+ const riverLayer = new VectorLayer({
384
+ properties: {
385
+ name: mergedOptions.layerName,
386
+ layerName: mergedOptions.layerName
387
+ },
388
+ source: new VectorSource({ features }),
389
+ style: (feature) => {
390
+ // 如果传入了自定义样式,直接使用
391
+ if (mergedOptions.style) {
392
+ if (typeof mergedOptions.style === 'function') {
393
+ return mergedOptions.style(feature);
394
+ }
395
+ else {
396
+ return mergedOptions.style;
397
+ }
398
+ }
399
+ const level = feature.get('level');
400
+ const levelWidth = mergedOptions.levelWidthMap[Number(level)] || 1;
401
+ return new Style({
402
+ stroke: new Stroke({
403
+ color: mergedOptions.strokeColor,
404
+ width: levelWidth
405
+ })
406
+ });
407
+ },
408
+ zIndex: mergedOptions.zIndex
409
+ });
410
+ riverLayer.setVisible(mergedOptions.visible);
411
+ this.map.addLayer(riverLayer);
412
+ return riverLayer;
413
+ }
414
+ /**
415
+ * 从URL添加按级别显示不同宽度的河流图层
416
+ * @param url 河流数据URL
417
+ * @param options 河流图层配置选项
418
+ * @returns 创建的河流图层
419
+ */
420
+ addRiverWidthByLevelByUrl(url, options = {}) {
258
421
  // 合并默认配置
259
422
  const mergedOptions = {
260
423
  type: 'river',
@@ -271,15 +434,10 @@ export default class Line {
271
434
  if (mergedOptions.removeExisting && mergedOptions.layerName) {
272
435
  MapTools.removeLayer(this.map, mergedOptions.layerName);
273
436
  }
274
- // 根据数据类型创建 VectorSource
275
- const source = isUrl
276
- ? new VectorSource({
277
- url: data,
278
- format: new GeoJSON(options.projectionOptOptions)
279
- })
280
- : new VectorSource({
281
- features: new GeoJSON().readFeatures(data, options.projectionOptOptions)
282
- });
437
+ const source = new VectorSource({
438
+ url,
439
+ format: new GeoJSON(options.projectionOptOptions)
440
+ });
283
441
  // 创建河流图层
284
442
  const riverLayer = new VectorLayer({
285
443
  properties: {
package/core/Polygon.d.ts CHANGED
@@ -25,7 +25,7 @@ export default class Polygon {
25
25
  */
26
26
  getLevColor(lev: string | number): string;
27
27
  /**
28
- * 添加地图边框图层(使用GeoJSON数据)
28
+ * 添加地图边框图层
29
29
  * @param data 图层数据,必须是有效的 GeoJSON 格式
30
30
  * @param options 图层配置选项
31
31
  * @returns 创建的图层实例
@@ -33,15 +33,15 @@ export default class Polygon {
33
33
  */
34
34
  addBorderPolygon(data: MapJSONData, options?: PolygonOptions): VectorLayer<VectorSource>;
35
35
  /**
36
- * 添加地图边框图层(从URL加载)
36
+ * URL添加地图边框图层
37
37
  * @param url 数据URL
38
38
  * @param options 图层配置选项
39
39
  * @returns 创建的图层实例
40
40
  * @throws 当数据格式无效时抛出错误
41
41
  */
42
- addBorderPolygon(url: string, options?: PolygonOptions): VectorLayer<VectorSource>;
42
+ addBorderPolygonByUrl(url: string, options?: PolygonOptions): VectorLayer<VectorSource>;
43
43
  /**
44
- * 添加多边形图层(使用GeoJSON数据)
44
+ * 添加多边形图层
45
45
  * @param dataJSON GeoJSON 数据
46
46
  * @param options 图层配置选项
47
47
  * @returns 创建的矢量图层
@@ -49,13 +49,13 @@ export default class Polygon {
49
49
  */
50
50
  addPolygon(dataJSON: MapJSONData, options?: PolygonOptions): VectorLayer<VectorSource>;
51
51
  /**
52
- * 添加多边形图层(从URL加载)
52
+ * URL添加多边形图层
53
53
  * @param url 数据URL
54
54
  * @param options 图层配置选项
55
55
  * @returns 创建的矢量图层
56
56
  * @throws 当数据格式无效时抛出错误
57
57
  */
58
- addPolygon(url: string, options?: PolygonOptions): VectorLayer<VectorSource>;
58
+ addPolygonByUrl(url: string, options?: PolygonOptions): VectorLayer<VectorSource>;
59
59
  /**
60
60
  * 设置要素样式
61
61
  * @param features 要素数组
package/core/Polygon.js CHANGED
@@ -40,30 +40,50 @@ export default class Polygon {
40
40
  const key = lev.toString();
41
41
  return this.colorMap[key] || 'rgba(128, 128, 128, 0.6)';
42
42
  }
43
+ /**
44
+ * 添加地图边框图层
45
+ * @param data 图层数据,必须是有效的 GeoJSON 格式
46
+ * @param options 图层配置选项
47
+ * @returns 创建的图层实例
48
+ * @throws 当数据格式无效时抛出错误
49
+ */
43
50
  addBorderPolygon(data, options) {
44
- const isUrl = typeof data === 'string';
45
- if (!isUrl) {
46
- ValidationUtils.validateGeoJSONData(data);
47
- }
51
+ ValidationUtils.validateGeoJSONData(data);
48
52
  const mergedOptions = {
49
- layerName: 'border',
50
53
  fillColor: 'rgba(255, 255, 255, 0)',
51
54
  ...options
52
55
  };
53
- // 使用类型断言来调用重载方法
54
- const layer = isUrl
55
- ? this.addPolygon(data, mergedOptions)
56
- : this.addPolygon(data, mergedOptions);
57
- if (mergedOptions.mask && !isUrl) {
56
+ const layer = this.addPolygon(data, mergedOptions);
57
+ if (mergedOptions.mask) {
58
58
  this.setOutLayer(data);
59
59
  }
60
60
  return layer;
61
61
  }
62
+ /**
63
+ * 从URL添加地图边框图层
64
+ * @param url 数据URL
65
+ * @param options 图层配置选项
66
+ * @returns 创建的图层实例
67
+ * @throws 当数据格式无效时抛出错误
68
+ */
69
+ addBorderPolygonByUrl(url, options) {
70
+ const mergedOptions = {
71
+ layerName: 'border',
72
+ fillColor: 'rgba(255, 255, 255, 0)',
73
+ ...options
74
+ };
75
+ const layer = this.addPolygonByUrl(url, mergedOptions);
76
+ return layer;
77
+ }
78
+ /**
79
+ * 添加多边形图层
80
+ * @param dataJSON GeoJSON 数据
81
+ * @param options 图层配置选项
82
+ * @returns 创建的矢量图层
83
+ * @throws 当数据格式无效时抛出错误
84
+ */
62
85
  addPolygon(dataJSON, options) {
63
- const isUrl = typeof dataJSON === 'string';
64
- if (!isUrl) {
65
- ValidationUtils.validateGeoJSONData(dataJSON);
66
- }
86
+ ValidationUtils.validateGeoJSONData(dataJSON);
67
87
  const mergedOptions = {
68
88
  zIndex: 11,
69
89
  visible: true,
@@ -81,48 +101,75 @@ export default class Polygon {
81
101
  new MapTools(this.map).removeLayer(mergedOptions.layerName);
82
102
  }
83
103
  let features;
84
- // 根据数据类型创建 VectorSource
85
- const source = isUrl
86
- ? new VectorSource({
87
- url: dataJSON,
88
- format: new GeoJSON(mergedOptions.projectionOptOptions ?? {})
89
- })
90
- : (() => {
91
- try {
92
- features = new GeoJSON().readFeatures(dataJSON, mergedOptions.projectionOptOptions ?? {});
93
- }
94
- catch (error) {
95
- throw new Error(`Failed to parse GeoJSON data: ${error}`);
96
- }
97
- return new VectorSource({ features });
98
- })();
104
+ try {
105
+ features = new GeoJSON().readFeatures(dataJSON, mergedOptions.projectionOptOptions ?? {});
106
+ }
107
+ catch (error) {
108
+ throw new Error(`Failed to parse GeoJSON data: ${error}`);
109
+ }
99
110
  const layer = new VectorLayer({
100
111
  properties: {
101
112
  name: mergedOptions.layerName,
102
113
  layerName: mergedOptions.layerName
103
114
  },
104
- source,
115
+ source: new VectorSource({ features }),
105
116
  zIndex: mergedOptions.zIndex
106
117
  });
107
- // 如果不是URL,设置要素样式
108
- if (!isUrl) {
109
- this.setFeatureStyles(features, mergedOptions);
110
- }
111
- else {
112
- // 如果是URL,需要在数据加载后设置样式
113
- source.once('featuresloadend', () => {
114
- const loadedFeatures = source.getFeatures();
115
- this.setFeatureStyles(loadedFeatures, mergedOptions);
116
- });
117
- }
118
+ // 设置要素样式
119
+ this.setFeatureStyles(features, mergedOptions);
118
120
  layer.setVisible(mergedOptions.visible);
119
121
  this.map.addLayer(layer);
120
122
  // 如果需要适应视图
121
- if (mergedOptions.fitView && !isUrl) {
123
+ if (mergedOptions.fitView) {
122
124
  this.fitViewToLayer(layer);
123
125
  }
124
- else if (mergedOptions.fitView && isUrl) {
125
- // 如果是URL,需要在数据加载后适应视图
126
+ return layer;
127
+ }
128
+ /**
129
+ * 从URL添加多边形图层
130
+ * @param url 数据URL
131
+ * @param options 图层配置选项
132
+ * @returns 创建的矢量图层
133
+ * @throws 当数据格式无效时抛出错误
134
+ */
135
+ addPolygonByUrl(url, options) {
136
+ const mergedOptions = {
137
+ zIndex: 11,
138
+ visible: true,
139
+ strokeColor: '#EBEEF5',
140
+ strokeWidth: 2,
141
+ fillColor: 'rgba(255, 255, 255, 0)',
142
+ textFont: '14px Calibri,sans-serif',
143
+ textFillColor: '#FFF',
144
+ textStrokeColor: '#409EFF',
145
+ textStrokeWidth: 2,
146
+ ...options
147
+ };
148
+ // 如果指定了图层名称,先移除同名图层
149
+ if (mergedOptions.layerName) {
150
+ new MapTools(this.map).removeLayer(mergedOptions.layerName);
151
+ }
152
+ const source = new VectorSource({
153
+ url,
154
+ format: new GeoJSON(mergedOptions.projectionOptOptions ?? {})
155
+ });
156
+ const layer = new VectorLayer({
157
+ properties: {
158
+ name: mergedOptions.layerName,
159
+ layerName: mergedOptions.layerName
160
+ },
161
+ source,
162
+ zIndex: mergedOptions.zIndex
163
+ });
164
+ // 在数据加载后设置样式
165
+ source.once('featuresloadend', () => {
166
+ const loadedFeatures = source.getFeatures();
167
+ this.setFeatureStyles(loadedFeatures, mergedOptions);
168
+ });
169
+ layer.setVisible(mergedOptions.visible);
170
+ this.map.addLayer(layer);
171
+ // 如果需要适应视图
172
+ if (mergedOptions.fitView) {
126
173
  source.once('featuresloadend', () => {
127
174
  this.fitViewToLayer(layer);
128
175
  });
@@ -0,0 +1,147 @@
1
+ import Map from "ol/Map";
2
+ import { FeatureLike } from "ol/Feature";
3
+ import { Style } from "ol/style";
4
+ import { SelectOptions, SelectMode } from "../types";
5
+ /**
6
+ * 要素选择处理器类
7
+ * 用于在地图上选择和高亮显示要素,支持单选、多选等多种选择模式
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const selectHandler = new SelectHandler(map);
12
+ *
13
+ * // 启用点击选择
14
+ * selectHandler.enableSelect('click', {
15
+ * layerFilter: ['pointLayer', 'polygonLayer'],
16
+ * multi: false,
17
+ * onSelect: (event) => {
18
+ * console.log('选中要素:', event.selected);
19
+ * }
20
+ * });
21
+ *
22
+ * // 获取当前选中的要素
23
+ * const selected = selectHandler.getSelectedFeatures();
24
+ *
25
+ * // 清除选择
26
+ * selectHandler.clearSelection();
27
+ *
28
+ * // 禁用选择
29
+ * selectHandler.disableSelect();
30
+ * ```
31
+ */
32
+ export default class SelectHandler {
33
+ /** OpenLayers 地图实例 */
34
+ private readonly map;
35
+ /** 事件管理器实例 */
36
+ private readonly eventManager;
37
+ /** 错误处理器实例 */
38
+ private readonly errorHandler;
39
+ /** Select 交互实例 */
40
+ private selectInteraction?;
41
+ /** 当前选择模式 */
42
+ private currentMode?;
43
+ /** 当前配置选项 */
44
+ private currentOptions?;
45
+ /** 是否已启用选择 */
46
+ private isEnabled;
47
+ /** 默认选中样式 - 点要素 */
48
+ private readonly defaultPointStyle;
49
+ /** 默认选中样式 - 线要素 */
50
+ private readonly defaultLineStyle;
51
+ /** 默认选中样式 - 面要素 */
52
+ private readonly defaultPolygonStyle;
53
+ /**
54
+ * 构造函数
55
+ * @param map OpenLayers地图实例
56
+ */
57
+ constructor(map: Map);
58
+ /**
59
+ * 启用要素选择
60
+ * @param mode 选择模式:'click'(点击)、'hover'(悬停)、'box'(框选)、'ctrl'(Ctrl+点击)
61
+ * @param options 选择配置选项
62
+ * @returns SelectHandler 实例(支持链式调用)
63
+ */
64
+ enableSelect(mode?: SelectMode, options?: SelectOptions): this;
65
+ /**
66
+ * 禁用要素选择
67
+ * @returns SelectHandler 实例(支持链式调用)
68
+ */
69
+ disableSelect(): this;
70
+ /**
71
+ * 获取当前选中的要素
72
+ * @returns 选中的要素数组
73
+ */
74
+ getSelectedFeatures(): FeatureLike[];
75
+ /**
76
+ * 清除所有选择
77
+ * @returns SelectHandler 实例(支持链式调用)
78
+ */
79
+ clearSelection(): this;
80
+ /**
81
+ * 通过要素ID选择要素
82
+ * @param featureIds 要素ID数组
83
+ * @param layerName 图层名称(可选)
84
+ * @param selectStyle 选中样式(可选,仅作用于此次选择)
85
+ * @returns SelectHandler 实例(支持链式调用)
86
+ */
87
+ selectByIds(featureIds: string[], layerName?: string, selectStyle?: Style | Style[] | ((feature: FeatureLike) => Style | Style[])): this;
88
+ /**
89
+ * 通过属性选择要素
90
+ * @param propertyName 属性名称
91
+ * @param propertyValue 属性值
92
+ * @param layerName 图层名称(可选)
93
+ * @param selectStyle 选中样式(可选,仅作用于此次选择)
94
+ * @returns SelectHandler 实例(支持链式调用)
95
+ */
96
+ selectByProperty(propertyName: string, propertyValue: any, layerName?: string, selectStyle?: Style | Style[] | ((feature: FeatureLike) => Style | Style[])): this;
97
+ /**
98
+ * 判断选择是否已启用
99
+ * @returns 是否已启用
100
+ */
101
+ isSelectEnabled(): boolean;
102
+ /**
103
+ * 获取当前选择模式
104
+ * @returns 当前选择模式
105
+ */
106
+ getCurrentMode(): SelectMode | undefined;
107
+ /**
108
+ * 销毁选择处理器,清理所有资源
109
+ */
110
+ destroy(): void;
111
+ /**
112
+ * 合并选项配置
113
+ * @private
114
+ */
115
+ private mergeOptions;
116
+ /**
117
+ * 创建 Select 交互
118
+ * @private
119
+ */
120
+ private createSelectInteraction;
121
+ /**
122
+ * 获取选择条件
123
+ * @private
124
+ */
125
+ private getSelectCondition;
126
+ /**
127
+ * 创建图层过滤器
128
+ * @private
129
+ */
130
+ private createLayerFilter;
131
+ /**
132
+ * 创建选择样式
133
+ * @private
134
+ */
135
+ private createSelectStyle;
136
+ /**
137
+ * 更新选择样式
138
+ * @param selectStyle 新的选择样式
139
+ * @returns SelectHandler 实例(支持链式调用)
140
+ */
141
+ updateSelectStyle(selectStyle: Style | Style[] | ((feature: FeatureLike) => Style | Style[])): this;
142
+ /**
143
+ * 附加事件监听器
144
+ * @private
145
+ */
146
+ private attachEventListeners;
147
+ }
@@ -0,0 +1,445 @@
1
+ import { Select } from "ol/interaction";
2
+ import { click, pointerMove, platformModifierKeyOnly } from "ol/events/condition";
3
+ import VectorLayer from "ol/layer/Vector";
4
+ import { Style, Fill, Stroke, Circle as CircleStyle } from "ol/style";
5
+ import { EventManager } from "./EventManager";
6
+ import { ValidationUtils } from "../utils/ValidationUtils";
7
+ import { ErrorHandler, MyOpenLayersError, ErrorType } from "../utils/ErrorHandler";
8
+ /**
9
+ * 要素选择处理器类
10
+ * 用于在地图上选择和高亮显示要素,支持单选、多选等多种选择模式
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const selectHandler = new SelectHandler(map);
15
+ *
16
+ * // 启用点击选择
17
+ * selectHandler.enableSelect('click', {
18
+ * layerFilter: ['pointLayer', 'polygonLayer'],
19
+ * multi: false,
20
+ * onSelect: (event) => {
21
+ * console.log('选中要素:', event.selected);
22
+ * }
23
+ * });
24
+ *
25
+ * // 获取当前选中的要素
26
+ * const selected = selectHandler.getSelectedFeatures();
27
+ *
28
+ * // 清除选择
29
+ * selectHandler.clearSelection();
30
+ *
31
+ * // 禁用选择
32
+ * selectHandler.disableSelect();
33
+ * ```
34
+ */
35
+ export default class SelectHandler {
36
+ /**
37
+ * 构造函数
38
+ * @param map OpenLayers地图实例
39
+ */
40
+ constructor(map) {
41
+ /** 是否已启用选择 */
42
+ this.isEnabled = false;
43
+ /** 默认选中样式 - 点要素 */
44
+ this.defaultPointStyle = new Style({
45
+ image: new CircleStyle({
46
+ radius: 7,
47
+ fill: new Fill({ color: 'rgba(255, 0, 0, 0.6)' }),
48
+ stroke: new Stroke({ color: '#ff0000', width: 2 })
49
+ })
50
+ });
51
+ /** 默认选中样式 - 线要素 */
52
+ this.defaultLineStyle = new Style({
53
+ stroke: new Stroke({
54
+ color: '#ff0000',
55
+ width: 3
56
+ })
57
+ });
58
+ /** 默认选中样式 - 面要素 */
59
+ this.defaultPolygonStyle = new Style({
60
+ stroke: new Stroke({
61
+ color: '#ff0000',
62
+ width: 2
63
+ }),
64
+ fill: new Fill({
65
+ color: 'rgba(255, 0, 0, 0.2)'
66
+ })
67
+ });
68
+ ValidationUtils.validateMapInstance(map);
69
+ this.map = map;
70
+ this.eventManager = new EventManager(map);
71
+ this.errorHandler = ErrorHandler.getInstance();
72
+ // 默认启用点击选择模式,支持多选
73
+ this.enableSelect('click', { multi: true });
74
+ }
75
+ /**
76
+ * 启用要素选择
77
+ * @param mode 选择模式:'click'(点击)、'hover'(悬停)、'box'(框选)、'ctrl'(Ctrl+点击)
78
+ * @param options 选择配置选项
79
+ * @returns SelectHandler 实例(支持链式调用)
80
+ */
81
+ enableSelect(mode = 'click', options) {
82
+ try {
83
+ // 如果已启用,先禁用
84
+ if (this.isEnabled) {
85
+ this.disableSelect();
86
+ }
87
+ const mergedOptions = this.mergeOptions(options);
88
+ this.currentMode = mode;
89
+ this.currentOptions = mergedOptions;
90
+ // 创建 Select 交互
91
+ this.selectInteraction = this.createSelectInteraction(mode, mergedOptions);
92
+ // 添加事件监听器
93
+ this.attachEventListeners(mergedOptions);
94
+ // 添加到地图
95
+ this.map.addInteraction(this.selectInteraction);
96
+ this.isEnabled = true;
97
+ console.debug('要素选择已启用', { mode, options: mergedOptions });
98
+ return this;
99
+ }
100
+ catch (error) {
101
+ this.errorHandler.handleError(new MyOpenLayersError(`启用要素选择失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { mode, options }));
102
+ throw error;
103
+ }
104
+ }
105
+ /**
106
+ * 禁用要素选择
107
+ * @returns SelectHandler 实例(支持链式调用)
108
+ */
109
+ disableSelect() {
110
+ try {
111
+ if (this.selectInteraction) {
112
+ this.map.removeInteraction(this.selectInteraction);
113
+ this.selectInteraction = undefined;
114
+ }
115
+ this.isEnabled = false;
116
+ this.currentMode = undefined;
117
+ console.debug('要素选择已禁用');
118
+ return this;
119
+ }
120
+ catch (error) {
121
+ this.errorHandler.handleError(new MyOpenLayersError(`禁用要素选择失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR));
122
+ throw error;
123
+ }
124
+ }
125
+ /**
126
+ * 获取当前选中的要素
127
+ * @returns 选中的要素数组
128
+ */
129
+ getSelectedFeatures() {
130
+ if (!this.selectInteraction) {
131
+ return [];
132
+ }
133
+ const features = this.selectInteraction.getFeatures();
134
+ return features.getArray();
135
+ }
136
+ /**
137
+ * 清除所有选择
138
+ * @returns SelectHandler 实例(支持链式调用)
139
+ */
140
+ clearSelection() {
141
+ if (this.selectInteraction) {
142
+ this.selectInteraction.getFeatures().clear();
143
+ }
144
+ return this;
145
+ }
146
+ /**
147
+ * 通过要素ID选择要素
148
+ * @param featureIds 要素ID数组
149
+ * @param layerName 图层名称(可选)
150
+ * @param selectStyle 选中样式(可选,仅作用于此次选择)
151
+ * @returns SelectHandler 实例(支持链式调用)
152
+ */
153
+ selectByIds(featureIds, layerName, selectStyle) {
154
+ try {
155
+ if (!this.selectInteraction) {
156
+ console.warn('选择交互未启用,无法选择要素');
157
+ return this;
158
+ }
159
+ if (!featureIds || featureIds.length === 0) {
160
+ console.warn('要素ID列表为空');
161
+ return this;
162
+ }
163
+ // 清除当前选择
164
+ this.clearSelection();
165
+ // 获取所有图层
166
+ const layers = this.map.getLayers().getArray();
167
+ for (const layer of layers) {
168
+ // 过滤图层
169
+ if (layerName && layer.get('layerName') !== layerName) {
170
+ continue;
171
+ }
172
+ if (layer instanceof VectorLayer) {
173
+ const source = layer.getSource();
174
+ if (!source)
175
+ continue;
176
+ // 查找并选择要素
177
+ for (const featureId of featureIds) {
178
+ const feature = source.getFeatureById(featureId);
179
+ if (feature) {
180
+ // 如果传入了自定义样式,仅为该要素设置样式
181
+ if (selectStyle) {
182
+ if (typeof selectStyle === 'function') {
183
+ feature.setStyle(selectStyle(feature));
184
+ }
185
+ else {
186
+ feature.setStyle(selectStyle);
187
+ }
188
+ }
189
+ this.selectInteraction.getFeatures().push(feature);
190
+ }
191
+ }
192
+ }
193
+ }
194
+ return this;
195
+ }
196
+ catch (error) {
197
+ this.errorHandler.handleError(new MyOpenLayersError(`通过ID选择要素失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { featureIds, layerName }));
198
+ throw error;
199
+ }
200
+ }
201
+ /**
202
+ * 通过属性选择要素
203
+ * @param propertyName 属性名称
204
+ * @param propertyValue 属性值
205
+ * @param layerName 图层名称(可选)
206
+ * @param selectStyle 选中样式(可选,仅作用于此次选择)
207
+ * @returns SelectHandler 实例(支持链式调用)
208
+ */
209
+ selectByProperty(propertyName, propertyValue, layerName, selectStyle) {
210
+ try {
211
+ if (!this.selectInteraction) {
212
+ console.warn('选择交互未启用,无法选择要素');
213
+ return this;
214
+ }
215
+ if (!propertyName) {
216
+ throw new Error('属性名称不能为空');
217
+ }
218
+ // 清除当前选择
219
+ this.clearSelection();
220
+ // 获取所有图层
221
+ const layers = this.map.getLayers().getArray();
222
+ for (const layer of layers) {
223
+ // 过滤图层
224
+ if (layerName && layer.get('layerName') !== layerName) {
225
+ continue;
226
+ }
227
+ if (layer instanceof VectorLayer) {
228
+ const source = layer.getSource();
229
+ if (!source)
230
+ continue;
231
+ // 查找并选择要素
232
+ const features = source.getFeatures();
233
+ for (const feature of features) {
234
+ if (feature.get(propertyName) === propertyValue) {
235
+ // 如果传入了自定义样式,仅为该要素设置样式
236
+ if (selectStyle) {
237
+ if (typeof selectStyle === 'function') {
238
+ feature.setStyle(selectStyle(feature));
239
+ }
240
+ else {
241
+ feature.setStyle(selectStyle);
242
+ }
243
+ }
244
+ this.selectInteraction.getFeatures().push(feature);
245
+ }
246
+ }
247
+ }
248
+ }
249
+ return this;
250
+ }
251
+ catch (error) {
252
+ this.errorHandler.handleError(new MyOpenLayersError(`通过属性选择要素失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { propertyName, propertyValue, layerName }));
253
+ throw error;
254
+ }
255
+ }
256
+ /**
257
+ * 判断选择是否已启用
258
+ * @returns 是否已启用
259
+ */
260
+ isSelectEnabled() {
261
+ return this.isEnabled;
262
+ }
263
+ /**
264
+ * 获取当前选择模式
265
+ * @returns 当前选择模式
266
+ */
267
+ getCurrentMode() {
268
+ return this.currentMode;
269
+ }
270
+ /**
271
+ * 销毁选择处理器,清理所有资源
272
+ */
273
+ destroy() {
274
+ try {
275
+ this.disableSelect();
276
+ console.debug('选择处理器已销毁');
277
+ }
278
+ catch (error) {
279
+ this.errorHandler.handleError(new MyOpenLayersError(`销毁选择处理器失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR));
280
+ }
281
+ }
282
+ /**
283
+ * 合并选项配置
284
+ * @private
285
+ */
286
+ mergeOptions(options) {
287
+ return {
288
+ multi: false,
289
+ layerFilter: undefined,
290
+ featureFilter: undefined,
291
+ hitTolerance: 0,
292
+ selectStyle: undefined,
293
+ onSelect: undefined,
294
+ onDeselect: undefined,
295
+ ...options
296
+ };
297
+ }
298
+ /**
299
+ * 创建 Select 交互
300
+ * @private
301
+ */
302
+ createSelectInteraction(mode, options) {
303
+ // 确定选择条件
304
+ const condition = this.getSelectCondition(mode);
305
+ // 创建图层过滤器
306
+ const layerFilter = this.createLayerFilter(options.layerFilter);
307
+ // 创建要素过滤器
308
+ const filter = options.featureFilter;
309
+ // 创建选择样式
310
+ const style = this.createSelectStyle(options.selectStyle);
311
+ return new Select({
312
+ condition,
313
+ layers: layerFilter,
314
+ filter,
315
+ style,
316
+ multi: options.multi,
317
+ hitTolerance: options.hitTolerance
318
+ });
319
+ }
320
+ /**
321
+ * 获取选择条件
322
+ * @private
323
+ */
324
+ getSelectCondition(mode) {
325
+ switch (mode) {
326
+ case 'click':
327
+ return click;
328
+ case 'hover':
329
+ return pointerMove;
330
+ case 'ctrl':
331
+ return platformModifierKeyOnly;
332
+ case 'box':
333
+ // 框选需要额外的 DragBox 交互,这里暂不实现
334
+ return click;
335
+ default:
336
+ return click;
337
+ }
338
+ }
339
+ /**
340
+ * 创建图层过滤器
341
+ * @private
342
+ */
343
+ createLayerFilter(layerNames) {
344
+ if (!layerNames || layerNames.length === 0) {
345
+ return undefined;
346
+ }
347
+ return (layer) => {
348
+ const layerName = layer.get('layerName') || layer.get('name');
349
+ return layerNames.includes(layerName);
350
+ };
351
+ }
352
+ /**
353
+ * 创建选择样式
354
+ * @private
355
+ */
356
+ createSelectStyle(customStyle) {
357
+ if (customStyle) {
358
+ return customStyle;
359
+ }
360
+ // 返回根据几何类型的默认样式
361
+ return (feature) => {
362
+ const geometry = feature.getGeometry();
363
+ if (!geometry) {
364
+ return this.defaultPointStyle;
365
+ }
366
+ const geometryType = geometry.getType();
367
+ switch (geometryType) {
368
+ case 'Point':
369
+ case 'MultiPoint':
370
+ return this.defaultPointStyle;
371
+ case 'LineString':
372
+ case 'MultiLineString':
373
+ return this.defaultLineStyle;
374
+ case 'Polygon':
375
+ case 'MultiPolygon':
376
+ return this.defaultPolygonStyle;
377
+ default:
378
+ return this.defaultPointStyle;
379
+ }
380
+ };
381
+ }
382
+ /**
383
+ * 更新选择样式
384
+ * @param selectStyle 新的选择样式
385
+ * @returns SelectHandler 实例(支持链式调用)
386
+ */
387
+ updateSelectStyle(selectStyle) {
388
+ if (!this.selectInteraction) {
389
+ console.warn('选择交互未启用,无法更新样式');
390
+ return this;
391
+ }
392
+ try {
393
+ // 更新选择交互的样式
394
+ this.selectInteraction.getStyle = () => {
395
+ if (typeof selectStyle === 'function') {
396
+ return selectStyle;
397
+ }
398
+ return selectStyle;
399
+ };
400
+ // 触发样式更新
401
+ const features = this.selectInteraction.getFeatures();
402
+ features.changed();
403
+ return this;
404
+ }
405
+ catch (error) {
406
+ this.errorHandler.handleError(new MyOpenLayersError(`更新选择样式失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { selectStyle }));
407
+ throw error;
408
+ }
409
+ }
410
+ /**
411
+ * 附加事件监听器
412
+ * @private
413
+ */
414
+ attachEventListeners(options) {
415
+ if (!this.selectInteraction) {
416
+ return;
417
+ }
418
+ // 监听选择事件
419
+ this.selectInteraction.on('select', (event) => {
420
+ const callbackEvent = {
421
+ selected: event.selected,
422
+ deselected: event.deselected,
423
+ mapBrowserEvent: event.mapBrowserEvent
424
+ };
425
+ // 触发选择回调
426
+ if (options.onSelect && event.selected.length > 0) {
427
+ try {
428
+ options.onSelect(callbackEvent);
429
+ }
430
+ catch (error) {
431
+ console.error('选择回调执行失败:', error);
432
+ }
433
+ }
434
+ // 触发取消选择回调
435
+ if (options.onDeselect && event.deselected.length > 0) {
436
+ try {
437
+ options.onDeselect(callbackEvent);
438
+ }
439
+ catch (error) {
440
+ console.error('取消选择回调执行失败:', error);
441
+ }
442
+ }
443
+ });
444
+ }
445
+ }
package/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export { default as MapBaseLayers } from './core/MapBaseLayers';
7
7
  export { default as MapTools } from './core/MapTools';
8
8
  export { default as MeasureHandler } from './core/MeasureHandler';
9
9
  export { default as VueTemplatePoint } from './core/VueTemplatePoint';
10
+ export { default as SelectHandler } from './core/SelectHandler';
10
11
  export { ConfigManager } from './core/ConfigManager';
11
12
  export { EventManager } from './core/EventManager';
12
13
  export type { MapEventType, EventCallback, MapEventData } from './core/EventManager';
@@ -15,4 +16,4 @@ export { ValidationUtils } from './utils/ValidationUtils';
15
16
  export type { BaseOptions, StyleOptions, TextOptions } from './types';
16
17
  export type { PointOptions, LineOptions, PolygonOptions } from './types';
17
18
  export type { OptionsType } from './types';
18
- export type { MapInitType, MapLayersOptions, HeatMapOptions, ImageLayerData, MaskLayerOptions, ColorMap, FeatureColorUpdateOptions, PointData, LineData, ClusterOptions, MeasureHandlerType, VueTemplatePointOptions, MapJSONData, FeatureData, AnnotationType, TiandituType, MapLayers, AnnotationLayerOptions } from './types';
19
+ export type { MapInitType, MapLayersOptions, HeatMapOptions, ImageLayerData, MaskLayerOptions, ColorMap, FeatureColorUpdateOptions, PointData, LineData, ClusterOptions, MeasureHandlerType, VueTemplatePointOptions, MapJSONData, FeatureData, AnnotationType, TiandituType, MapLayers, AnnotationLayerOptions, SelectOptions, SelectMode, SelectCallbackEvent } from './types';
package/index.js CHANGED
@@ -8,6 +8,7 @@ export { default as MapBaseLayers } from './core/MapBaseLayers';
8
8
  export { default as MapTools } from './core/MapTools';
9
9
  export { default as MeasureHandler } from './core/MeasureHandler';
10
10
  export { default as VueTemplatePoint } from './core/VueTemplatePoint';
11
+ export { default as SelectHandler } from './core/SelectHandler';
11
12
  // 新增工具类
12
13
  export { ConfigManager } from './core/ConfigManager';
13
14
  export { EventManager } from './core/EventManager';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "my-openlayer",
3
3
  "private": false,
4
- "version": "2.0.1",
4
+ "version": "2.1.1",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
package/types.d.ts CHANGED
@@ -4,6 +4,7 @@ import { WMTS } from "ol/source";
4
4
  import View from "ol/View";
5
5
  import Feature, { FeatureLike } from "ol/Feature";
6
6
  import { Style } from "ol/style";
7
+ import MapBrowserEvent from "ol/MapBrowserEvent";
7
8
  export interface FeatureData {
8
9
  type: string;
9
10
  properties: any;
@@ -302,4 +303,38 @@ export interface VueTemplatePointInstance {
302
303
  getOptions(): Readonly<VueTemplatePointOptions>;
303
304
  isDestroyed(): boolean;
304
305
  }
306
+ /**
307
+ * 选择模式类型
308
+ */
309
+ export type SelectMode = 'click' | 'hover' | 'box' | 'ctrl';
310
+ /**
311
+ * 选择回调事件接口
312
+ */
313
+ export interface SelectCallbackEvent {
314
+ /** 新选中的要素数组 */
315
+ selected: FeatureLike[];
316
+ /** 取消选中的要素数组 */
317
+ deselected: FeatureLike[];
318
+ /** 地图浏览器事件 */
319
+ mapBrowserEvent: MapBrowserEvent<any>;
320
+ }
321
+ /**
322
+ * 要素选择配置选项
323
+ */
324
+ export interface SelectOptions {
325
+ /** 是否支持多选,默认 false */
326
+ multi?: boolean;
327
+ /** 图层过滤器,指定可选择的图层名称列表 */
328
+ layerFilter?: string[];
329
+ /** 要素过滤器函数 */
330
+ featureFilter?: (feature: FeatureLike) => boolean;
331
+ /** 点击容差(像素),默认为 0 */
332
+ hitTolerance?: number;
333
+ /** 选中要素的样式 */
334
+ selectStyle?: Style | Style[] | ((feature: FeatureLike) => Style | Style[]);
335
+ /** 选中要素时的回调函数 */
336
+ onSelect?: (event: SelectCallbackEvent) => void;
337
+ /** 取消选中要素时的回调函数 */
338
+ onDeselect?: (event: SelectCallbackEvent) => void;
339
+ }
305
340
  export {};