my-openlayer 2.1.0 → 2.1.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.
@@ -1,6 +1,7 @@
1
1
  import Map from "ol/Map";
2
2
  import { FeatureLike } from "ol/Feature";
3
- import { SelectOptions, SelectMode } from "../types";
3
+ import { Style } from "ol/style";
4
+ import { SelectOptions, SelectMode, ProgrammaticSelectOptions } from "../types";
4
5
  /**
5
6
  * 要素选择处理器类
6
7
  * 用于在地图上选择和高亮显示要素,支持单选、多选等多种选择模式
@@ -56,7 +57,7 @@ export default class SelectHandler {
56
57
  constructor(map: Map);
57
58
  /**
58
59
  * 启用要素选择
59
- * @param mode 选择模式:'click'(点击)、'hover'(悬停)、'box'(框选)、'ctrl'(Ctrl+点击)
60
+ * @param mode 选择模式:'click'(点击)、'hover'(悬停)、'ctrl'(Ctrl+点击)
60
61
  * @param options 选择配置选项
61
62
  * @returns SelectHandler 实例(支持链式调用)
62
63
  */
@@ -79,18 +80,18 @@ export default class SelectHandler {
79
80
  /**
80
81
  * 通过要素ID选择要素
81
82
  * @param featureIds 要素ID数组
82
- * @param layerName 图层名称(可选)
83
+ * @param options 编程式选择配置选项
83
84
  * @returns SelectHandler 实例(支持链式调用)
84
85
  */
85
- selectByIds(featureIds: string[], layerName?: string): this;
86
+ selectByIds(featureIds: string[], options?: ProgrammaticSelectOptions): this;
86
87
  /**
87
88
  * 通过属性选择要素
88
89
  * @param propertyName 属性名称
89
90
  * @param propertyValue 属性值
90
- * @param layerName 图层名称(可选)
91
+ * @param options 编程式选择配置选项
91
92
  * @returns SelectHandler 实例(支持链式调用)
92
93
  */
93
- selectByProperty(propertyName: string, propertyValue: any, layerName?: string): this;
94
+ selectByProperty(propertyName: string, propertyValue: any, options?: ProgrammaticSelectOptions): this;
94
95
  /**
95
96
  * 判断选择是否已启用
96
97
  * @returns 是否已启用
@@ -101,6 +102,14 @@ export default class SelectHandler {
101
102
  * @returns 当前选择模式
102
103
  */
103
104
  getCurrentMode(): SelectMode | undefined;
105
+ /**
106
+ * 定位至要素
107
+ * @private
108
+ * @param features 要素数组
109
+ * @param duration 动画持续时间(毫秒),默认500
110
+ * @param padding 边距(像素),默认100
111
+ */
112
+ private fitToFeatures;
104
113
  /**
105
114
  * 销毁选择处理器,清理所有资源
106
115
  */
@@ -130,6 +139,12 @@ export default class SelectHandler {
130
139
  * @private
131
140
  */
132
141
  private createSelectStyle;
142
+ /**
143
+ * 更新选择样式
144
+ * @param selectStyle 新的选择样式
145
+ * @returns SelectHandler 实例(支持链式调用)
146
+ */
147
+ updateSelectStyle(selectStyle: Style | Style[] | ((feature: FeatureLike) => Style | Style[])): this;
133
148
  /**
134
149
  * 附加事件监听器
135
150
  * @private
@@ -69,10 +69,12 @@ export default class SelectHandler {
69
69
  this.map = map;
70
70
  this.eventManager = new EventManager(map);
71
71
  this.errorHandler = ErrorHandler.getInstance();
72
+ // 默认启用点击选择模式,支持多选
73
+ this.enableSelect('click', { multi: true });
72
74
  }
73
75
  /**
74
76
  * 启用要素选择
75
- * @param mode 选择模式:'click'(点击)、'hover'(悬停)、'box'(框选)、'ctrl'(Ctrl+点击)
77
+ * @param mode 选择模式:'click'(点击)、'hover'(悬停)、'ctrl'(Ctrl+点击)
76
78
  * @param options 选择配置选项
77
79
  * @returns SelectHandler 实例(支持链式调用)
78
80
  */
@@ -144,10 +146,10 @@ export default class SelectHandler {
144
146
  /**
145
147
  * 通过要素ID选择要素
146
148
  * @param featureIds 要素ID数组
147
- * @param layerName 图层名称(可选)
149
+ * @param options 编程式选择配置选项
148
150
  * @returns SelectHandler 实例(支持链式调用)
149
151
  */
150
- selectByIds(featureIds, layerName) {
152
+ selectByIds(featureIds, options) {
151
153
  try {
152
154
  if (!this.selectInteraction) {
153
155
  console.warn('选择交互未启用,无法选择要素');
@@ -159,11 +161,13 @@ export default class SelectHandler {
159
161
  }
160
162
  // 清除当前选择
161
163
  this.clearSelection();
164
+ // 临时存储选中的要素
165
+ const selectedFeatures = [];
162
166
  // 获取所有图层
163
167
  const layers = this.map.getLayers().getArray();
164
168
  for (const layer of layers) {
165
169
  // 过滤图层
166
- if (layerName && layer.get('layerName') !== layerName) {
170
+ if (options?.layerName && layer.get('layerName') !== options.layerName) {
167
171
  continue;
168
172
  }
169
173
  if (layer instanceof VectorLayer) {
@@ -174,15 +178,31 @@ export default class SelectHandler {
174
178
  for (const featureId of featureIds) {
175
179
  const feature = source.getFeatureById(featureId);
176
180
  if (feature) {
181
+ selectedFeatures.push(feature);
177
182
  this.selectInteraction.getFeatures().push(feature);
178
183
  }
179
184
  }
180
185
  }
181
186
  }
187
+ // 如果传入了自定义样式,为选中的要素设置样式
188
+ if (options?.selectStyle && selectedFeatures.length > 0) {
189
+ for (const feature of selectedFeatures) {
190
+ if (typeof options.selectStyle === 'function') {
191
+ feature.setStyle(options.selectStyle(feature));
192
+ }
193
+ else {
194
+ feature.setStyle(options.selectStyle);
195
+ }
196
+ }
197
+ }
198
+ // 定位至选中要素
199
+ if (options?.fitView && selectedFeatures.length > 0) {
200
+ this.fitToFeatures(selectedFeatures, options.fitDuration ?? 500, options.fitPadding ?? 100);
201
+ }
182
202
  return this;
183
203
  }
184
204
  catch (error) {
185
- this.errorHandler.handleError(new MyOpenLayersError(`通过ID选择要素失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { featureIds, layerName }));
205
+ this.errorHandler.handleError(new MyOpenLayersError(`通过ID选择要素失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { featureIds, options }));
186
206
  throw error;
187
207
  }
188
208
  }
@@ -190,10 +210,10 @@ export default class SelectHandler {
190
210
  * 通过属性选择要素
191
211
  * @param propertyName 属性名称
192
212
  * @param propertyValue 属性值
193
- * @param layerName 图层名称(可选)
213
+ * @param options 编程式选择配置选项
194
214
  * @returns SelectHandler 实例(支持链式调用)
195
215
  */
196
- selectByProperty(propertyName, propertyValue, layerName) {
216
+ selectByProperty(propertyName, propertyValue, options) {
197
217
  try {
198
218
  if (!this.selectInteraction) {
199
219
  console.warn('选择交互未启用,无法选择要素');
@@ -204,11 +224,13 @@ export default class SelectHandler {
204
224
  }
205
225
  // 清除当前选择
206
226
  this.clearSelection();
227
+ // 临时存储选中的要素
228
+ const selectedFeatures = [];
207
229
  // 获取所有图层
208
230
  const layers = this.map.getLayers().getArray();
209
231
  for (const layer of layers) {
210
232
  // 过滤图层
211
- if (layerName && layer.get('layerName') !== layerName) {
233
+ if (options?.layerName && layer.get('layerName') !== options.layerName) {
212
234
  continue;
213
235
  }
214
236
  if (layer instanceof VectorLayer) {
@@ -219,15 +241,31 @@ export default class SelectHandler {
219
241
  const features = source.getFeatures();
220
242
  for (const feature of features) {
221
243
  if (feature.get(propertyName) === propertyValue) {
244
+ selectedFeatures.push(feature);
222
245
  this.selectInteraction.getFeatures().push(feature);
223
246
  }
224
247
  }
225
248
  }
226
249
  }
250
+ // 如果传入了自定义样式,为选中的要素设置样式
251
+ if (options?.selectStyle && selectedFeatures.length > 0) {
252
+ for (const feature of selectedFeatures) {
253
+ if (typeof options.selectStyle === 'function') {
254
+ feature.setStyle(options.selectStyle(feature));
255
+ }
256
+ else {
257
+ feature.setStyle(options.selectStyle);
258
+ }
259
+ }
260
+ }
261
+ // 定位至选中要素
262
+ if (options?.fitView && selectedFeatures.length > 0) {
263
+ this.fitToFeatures(selectedFeatures, options.fitDuration ?? 500, options.fitPadding ?? 100);
264
+ }
227
265
  return this;
228
266
  }
229
267
  catch (error) {
230
- this.errorHandler.handleError(new MyOpenLayersError(`通过属性选择要素失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { propertyName, propertyValue, layerName }));
268
+ this.errorHandler.handleError(new MyOpenLayersError(`通过属性选择要素失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { propertyName, propertyValue, options }));
231
269
  throw error;
232
270
  }
233
271
  }
@@ -245,6 +283,49 @@ export default class SelectHandler {
245
283
  getCurrentMode() {
246
284
  return this.currentMode;
247
285
  }
286
+ /**
287
+ * 定位至要素
288
+ * @private
289
+ * @param features 要素数组
290
+ * @param duration 动画持续时间(毫秒),默认500
291
+ * @param padding 边距(像素),默认100
292
+ */
293
+ fitToFeatures(features, duration = 500, padding = 100) {
294
+ try {
295
+ if (!features || features.length === 0) {
296
+ return;
297
+ }
298
+ // 创建一个包含所有要素的范围
299
+ let extent;
300
+ for (const feature of features) {
301
+ const geometry = feature.getGeometry();
302
+ if (geometry) {
303
+ const featureExtent = geometry.getExtent();
304
+ if (!extent) {
305
+ extent = featureExtent;
306
+ }
307
+ else {
308
+ // 扩展范围以包含当前要素
309
+ extent = [
310
+ Math.min(extent[0], featureExtent[0]),
311
+ Math.min(extent[1], featureExtent[1]),
312
+ Math.max(extent[2], featureExtent[2]),
313
+ Math.max(extent[3], featureExtent[3])
314
+ ];
315
+ }
316
+ }
317
+ }
318
+ if (extent) {
319
+ this.map.getView().fit(extent, {
320
+ duration,
321
+ padding: [padding, padding, padding, padding]
322
+ });
323
+ }
324
+ }
325
+ catch (error) {
326
+ console.error('定位至要素失败:', error);
327
+ }
328
+ }
248
329
  /**
249
330
  * 销毁选择处理器,清理所有资源
250
331
  */
@@ -307,9 +388,6 @@ export default class SelectHandler {
307
388
  return pointerMove;
308
389
  case 'ctrl':
309
390
  return platformModifierKeyOnly;
310
- case 'box':
311
- // 框选需要额外的 DragBox 交互,这里暂不实现
312
- return click;
313
391
  default:
314
392
  return click;
315
393
  }
@@ -357,6 +435,34 @@ export default class SelectHandler {
357
435
  }
358
436
  };
359
437
  }
438
+ /**
439
+ * 更新选择样式
440
+ * @param selectStyle 新的选择样式
441
+ * @returns SelectHandler 实例(支持链式调用)
442
+ */
443
+ updateSelectStyle(selectStyle) {
444
+ if (!this.selectInteraction) {
445
+ console.warn('选择交互未启用,无法更新样式');
446
+ return this;
447
+ }
448
+ try {
449
+ // 更新选择交互的样式
450
+ this.selectInteraction.getStyle = () => {
451
+ if (typeof selectStyle === 'function') {
452
+ return selectStyle;
453
+ }
454
+ return selectStyle;
455
+ };
456
+ // 触发样式更新
457
+ const features = this.selectInteraction.getFeatures();
458
+ features.changed();
459
+ return this;
460
+ }
461
+ catch (error) {
462
+ this.errorHandler.handleError(new MyOpenLayersError(`更新选择样式失败: ${error instanceof Error ? error.message : '未知错误'}`, ErrorType.COMPONENT_ERROR, { selectStyle }));
463
+ throw error;
464
+ }
465
+ }
360
466
  /**
361
467
  * 附加事件监听器
362
468
  * @private
package/index.d.ts CHANGED
@@ -16,4 +16,4 @@ export { ValidationUtils } from './utils/ValidationUtils';
16
16
  export type { BaseOptions, StyleOptions, TextOptions } from './types';
17
17
  export type { PointOptions, LineOptions, PolygonOptions } from './types';
18
18
  export type { OptionsType } 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';
19
+ export type { MapInitType, MapLayersOptions, HeatMapOptions, ImageLayerData, MaskLayerOptions, ColorMap, FeatureColorUpdateOptions, PointData, LineData, ClusterOptions, MeasureHandlerType, VueTemplatePointOptions, MapJSONData, FeatureData, AnnotationType, TiandituType, MapLayers, AnnotationLayerOptions, SelectOptions, SelectMode, SelectCallbackEvent, ProgrammaticSelectOptions } from './types';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "my-openlayer",
3
3
  "private": false,
4
- "version": "2.1.0",
4
+ "version": "2.1.2",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
package/types.d.ts CHANGED
@@ -306,7 +306,7 @@ export interface VueTemplatePointInstance {
306
306
  /**
307
307
  * 选择模式类型
308
308
  */
309
- export type SelectMode = 'click' | 'hover' | 'box' | 'ctrl';
309
+ export type SelectMode = 'click' | 'hover' | 'ctrl';
310
310
  /**
311
311
  * 选择回调事件接口
312
312
  */
@@ -337,4 +337,19 @@ export interface SelectOptions {
337
337
  /** 取消选中要素时的回调函数 */
338
338
  onDeselect?: (event: SelectCallbackEvent) => void;
339
339
  }
340
+ /**
341
+ * 编程式选择选项接口
342
+ */
343
+ export interface ProgrammaticSelectOptions {
344
+ /** 图层名称,指定在哪个图层中选择要素 */
345
+ layerName?: string;
346
+ /** 自定义选中样式(仅作用于此次选择) */
347
+ selectStyle?: Style | Style[] | ((feature: FeatureLike) => Style | Style[]);
348
+ /** 是否定位至选中要素,默认 false */
349
+ fitView?: boolean;
350
+ /** 定位动画持续时间(毫秒),默认 500 */
351
+ fitDuration?: number;
352
+ /** 定位时的边距(像素),默认 100 */
353
+ fitPadding?: number;
354
+ }
340
355
  export {};