my-openlayer 2.3.2 → 2.4.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
@@ -33,7 +33,7 @@ export default class MyOl {
33
33
  * @param id 地图容器 DOM 元素 ID
34
34
  * @param options 地图初始化配置
35
35
  */
36
- constructor(id: string, options?: Partial<MapInitType>);
36
+ constructor(id: string | HTMLElement, options?: Partial<MapInitType>);
37
37
  /**
38
38
  * 验证构造函数参数
39
39
  * @private
package/MyOl.js CHANGED
@@ -69,16 +69,19 @@ class MyOl {
69
69
  * @private
70
70
  */
71
71
  validateConstructorParams(id, options) {
72
- if (!id || typeof id !== 'string') {
72
+ if (!id) {
73
+ throw new Error('地图容器 ID 或 HTMLElement 不能为空');
74
+ }
75
+ if (typeof id === 'string' && id.trim() === '') {
73
76
  throw new Error('地图容器 ID 必须是非空字符串');
74
77
  }
75
78
  if (!options || typeof options !== 'object') {
76
79
  throw new Error('地图配置选项不能为空');
77
80
  }
78
81
  // 检查 DOM 元素是否存在
79
- const element = document.getElementById(id);
82
+ const element = typeof id === 'string' ? document.getElementById(id) : id;
80
83
  if (!element) {
81
- throw new Error(`找不到 ID 为 '${id}' 的 DOM 元素`);
84
+ throw new Error(typeof id === 'string' ? `找不到 ID 为 '${id}' 的 DOM 元素` : '提供的 DOM 元素无效');
82
85
  }
83
86
  }
84
87
  /**
@@ -44,9 +44,6 @@ export declare class ConfigManager {
44
44
  static readonly DEFAULT_POLYGON_OPTIONS: {
45
45
  zIndex: number;
46
46
  visible: boolean;
47
- strokeColor: string;
48
- strokeWidth: number;
49
- fillColor: string;
50
47
  textFont: string;
51
48
  textFillColor: string;
52
49
  textStrokeColor: string;
@@ -88,9 +88,6 @@ ConfigManager.DEFAULT_LINE_OPTIONS = {
88
88
  ConfigManager.DEFAULT_POLYGON_OPTIONS = {
89
89
  zIndex: 11,
90
90
  visible: true,
91
- strokeColor: '#EBEEF5',
92
- strokeWidth: 2,
93
- fillColor: 'rgba(255, 255, 255, 0)',
94
91
  textFont: '14px Calibri,sans-serif',
95
92
  textFillColor: '#FFF',
96
93
  textStrokeColor: '#409EFF',
package/core/Polygon.d.ts CHANGED
@@ -50,11 +50,11 @@ export default class Polygon {
50
50
  */
51
51
  addPolygonByUrl(url: string, options?: PolygonOptions): VectorLayer<VectorSource>;
52
52
  /**
53
- * 设置要素样式
54
- * @param features 要素数组
55
- * @param options 样式配置选项
53
+ * 创建样式或样式函数
54
+ * @param options 配置选项
55
+ * @returns 样式或样式函数
56
56
  */
57
- private setFeatureStyles;
57
+ private createStyle;
58
58
  /**
59
59
  * 获取要素文本
60
60
  * @param feature 要素对象
package/core/Polygon.js CHANGED
@@ -79,9 +79,19 @@ export default class Polygon {
79
79
  if (mergedOptions.layerName) {
80
80
  new MapTools(this.map).removeLayer(mergedOptions.layerName);
81
81
  }
82
+ const format = new GeoJSON();
83
+ // 优化:在解析 Feature 时直接注入 layerName,利用解析过程的遍历,避免解析后的二次循环
84
+ if (mergedOptions.layerName) {
85
+ const originalReadFeatureFromObject = format.readFeatureFromObject;
86
+ format.readFeatureFromObject = function (object, options) {
87
+ const feature = originalReadFeatureFromObject.call(this, object, options);
88
+ feature.set('layerName', mergedOptions.layerName, true); // true 表示静默设置,不触发事件
89
+ return feature;
90
+ };
91
+ }
82
92
  let features;
83
93
  try {
84
- features = new GeoJSON().readFeatures(dataJSON, mergedOptions.projectionOptOptions ?? {});
94
+ features = format.readFeatures(dataJSON, mergedOptions.projectionOptOptions ?? {});
85
95
  }
86
96
  catch (error) {
87
97
  throw new Error(`Failed to parse GeoJSON data: ${error}`);
@@ -92,10 +102,9 @@ export default class Polygon {
92
102
  layerName: mergedOptions.layerName
93
103
  },
94
104
  source: new VectorSource({ features }),
105
+ style: this.createStyle(mergedOptions),
95
106
  zIndex: mergedOptions.zIndex
96
107
  });
97
- // 设置要素样式
98
- this.setFeatureStyles(features, mergedOptions);
99
108
  layer.setVisible(mergedOptions.visible);
100
109
  this.map.addLayer(layer);
101
110
  // 如果需要适应视图
@@ -120,9 +129,19 @@ export default class Polygon {
120
129
  if (mergedOptions.layerName) {
121
130
  new MapTools(this.map).removeLayer(mergedOptions.layerName);
122
131
  }
132
+ const format = new GeoJSON(mergedOptions.projectionOptOptions ?? {});
133
+ // 优化:在解析 Feature 时直接注入 layerName,利用解析过程的遍历,避免解析后的二次循环
134
+ if (mergedOptions.layerName) {
135
+ const originalReadFeatureFromObject = format.readFeatureFromObject;
136
+ format.readFeatureFromObject = function (object, options) {
137
+ const feature = originalReadFeatureFromObject.call(this, object, options);
138
+ feature.set('layerName', mergedOptions.layerName, true); // true 表示静默设置,不触发事件
139
+ return feature;
140
+ };
141
+ }
123
142
  const source = new VectorSource({
124
143
  url,
125
- format: new GeoJSON(mergedOptions.projectionOptOptions ?? {})
144
+ format
126
145
  });
127
146
  const layer = new VectorLayer({
128
147
  properties: {
@@ -130,13 +149,9 @@ export default class Polygon {
130
149
  layerName: mergedOptions.layerName
131
150
  },
132
151
  source,
152
+ style: this.createStyle(mergedOptions),
133
153
  zIndex: mergedOptions.zIndex
134
154
  });
135
- // 在数据加载后设置样式
136
- source.once('featuresloadend', () => {
137
- const loadedFeatures = source.getFeatures();
138
- this.setFeatureStyles(loadedFeatures, mergedOptions);
139
- });
140
155
  layer.setVisible(mergedOptions.visible);
141
156
  this.map.addLayer(layer);
142
157
  // 如果需要适应视图
@@ -148,51 +163,78 @@ export default class Polygon {
148
163
  return layer;
149
164
  }
150
165
  /**
151
- * 设置要素样式
152
- * @param features 要素数组
153
- * @param options 样式配置选项
166
+ * 创建样式或样式函数
167
+ * @param options 配置选项
168
+ * @returns 样式或样式函数
154
169
  */
155
- setFeatureStyles(features, options) {
156
- features.forEach(feature => {
157
- feature.set('type', options.layerName);
158
- feature.set('layerName', options.layerName);
159
- // 如果传入了自定义样式,直接使用
160
- if (options.style) {
161
- if (typeof options.style === 'function') {
162
- feature.setStyle(options.style(feature));
163
- }
164
- else {
165
- feature.setStyle(options.style);
170
+ //************* 创建样式功能块 *************//
171
+ createStyle(options) {
172
+ // 如果传入了自定义样式,直接使用
173
+ if (options.style) {
174
+ return options.style;
175
+ }
176
+ const withDefaultStroke = options.withDefaultStroke ?? true;
177
+ const withDefaultFill = options.withDefaultFill ?? true;
178
+ const strokeColor = options.strokeColor ?? (withDefaultStroke ? '#EBEEF5' : undefined);
179
+ const strokeWidth = options.strokeWidth ?? 2;
180
+ const staticFillColor = options.fillColor ?? (withDefaultFill ? 'rgba(255, 255, 255, 0)' : undefined);
181
+ const stroke = strokeColor ? new Stroke({
182
+ color: strokeColor,
183
+ width: strokeWidth,
184
+ lineDash: options.lineDash,
185
+ lineDashOffset: options.lineDashOffset
186
+ }) : undefined;
187
+ // 预先创建基础样式(如果不需要基于feature动态计算fillColor)
188
+ let baseStyle;
189
+ if (!options.fillColorCallBack) {
190
+ const fill = staticFillColor ? new Fill({ color: staticFillColor }) : undefined;
191
+ if (stroke || fill) {
192
+ baseStyle = new Style({
193
+ stroke,
194
+ fill
195
+ });
196
+ }
197
+ }
198
+ // 如果没有动态部分(没有回调且不显示文本),直接返回基础样式
199
+ if (baseStyle && !options.textVisible) {
200
+ return baseStyle;
201
+ }
202
+ // 返回样式函数
203
+ return (feature, resolution) => {
204
+ const styles = [];
205
+ // 1. 处理几何样式
206
+ if (baseStyle) {
207
+ styles.push(baseStyle);
208
+ }
209
+ else {
210
+ const fillColor = options.fillColorCallBack ? options.fillColorCallBack(feature) : staticFillColor;
211
+ const fill = fillColor ? new Fill({ color: fillColor }) : undefined;
212
+ if (stroke || fill) {
213
+ styles.push(new Style({
214
+ stroke,
215
+ fill
216
+ }));
166
217
  }
167
- return;
168
218
  }
169
- const fillColor = options.fillColorCallBack ? options.fillColorCallBack(feature) : options.fillColor;
170
- const featureStyle = new Style({
171
- stroke: new Stroke({
172
- color: options.strokeColor,
173
- width: options.strokeWidth,
174
- lineDash: options.lineDash,
175
- lineDashOffset: options.lineDashOffset
176
- }),
177
- fill: new Fill({ color: fillColor })
178
- });
179
- // 添加文本样式
219
+ // 2. 处理文本样式
180
220
  if (options.textVisible) {
181
221
  const text = this.getFeatureText(feature, options);
182
222
  if (text) {
183
- featureStyle.setText(new Text({
184
- text,
185
- font: options.textFont,
186
- fill: new Fill({ color: options.textFillColor }),
187
- stroke: new Stroke({
188
- color: options.textStrokeColor,
189
- width: options.textStrokeWidth
223
+ styles.push(new Style({
224
+ text: new Text({
225
+ text,
226
+ font: options.textFont,
227
+ fill: new Fill({ color: options.textFillColor }),
228
+ stroke: new Stroke({
229
+ color: options.textStrokeColor,
230
+ width: options.textStrokeWidth
231
+ })
190
232
  })
191
233
  }));
192
234
  }
193
235
  }
194
- feature.setStyle(featureStyle);
195
- });
236
+ return styles;
237
+ };
196
238
  }
197
239
  /**
198
240
  * 获取要素文本
@@ -237,9 +279,6 @@ export default class Polygon {
237
279
  throw new Error(`Layer '${layerName}' is not a vector layer`);
238
280
  }
239
281
  const mergedOptions = {
240
- strokeColor: '#EBEEF5',
241
- strokeWidth: 2,
242
- fillColor: 'rgba(255, 255, 255, 0.3)',
243
282
  textFont: '14px Calibri,sans-serif',
244
283
  textFillColor: '#FFF',
245
284
  textStrokeWidth: 2,
@@ -262,13 +301,21 @@ export default class Polygon {
262
301
  */
263
302
  updateSingleFeatureColor(feature, colorObj, options) {
264
303
  const name = options?.textKey ? feature.get(options.textKey) : '';
265
- const newColor = colorObj?.[name] || options?.fillColor;
304
+ const withDefaultStroke = options?.withDefaultStroke ?? true;
305
+ const withDefaultFill = options?.withDefaultFill ?? true;
306
+ const strokeColor = options?.strokeColor ?? (withDefaultStroke ? '#EBEEF5' : undefined);
307
+ const strokeWidth = options?.strokeWidth ?? 2;
308
+ const defaultFillColor = 'rgba(255, 255, 255, 0.3)';
309
+ const resolvedFillColor = options?.fillColor ?? (withDefaultFill ? defaultFillColor : undefined);
310
+ const newColor = colorObj?.[name] || resolvedFillColor;
311
+ const stroke = strokeColor ? new Stroke({
312
+ color: strokeColor,
313
+ width: strokeWidth
314
+ }) : undefined;
315
+ const fill = newColor ? new Fill({ color: newColor }) : undefined;
266
316
  const featureStyle = new Style({
267
- stroke: new Stroke({
268
- color: options?.strokeColor,
269
- width: options?.strokeWidth
270
- }),
271
- fill: new Fill({ color: newColor })
317
+ stroke,
318
+ fill
272
319
  });
273
320
  // 添加文本样式
274
321
  if (options?.textVisible) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "my-openlayer",
3
3
  "private": false,
4
- "version": "2.3.2",
4
+ "version": "2.4.1",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
package/types.d.ts CHANGED
@@ -114,6 +114,10 @@ export interface StyleOptions {
114
114
  fillColor?: string;
115
115
  /** 填充颜色回调函数 */
116
116
  fillColorCallBack?: (feature: Feature) => string;
117
+ /** 是否使用默认描边 */
118
+ withDefaultStroke?: boolean;
119
+ /** 是否使用默认填充 */
120
+ withDefaultFill?: boolean;
117
121
  }
118
122
  /**
119
123
  * 文本选项接口 - 文本标注相关配置