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 +1 -1
- package/MyOl.js +6 -3
- package/core/ConfigManager.d.ts +0 -3
- package/core/ConfigManager.js +0 -3
- package/core/Polygon.d.ts +4 -4
- package/core/Polygon.js +100 -53
- package/package.json +1 -1
- package/types.d.ts +4 -0
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
|
|
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
|
/**
|
package/core/ConfigManager.d.ts
CHANGED
|
@@ -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;
|
package/core/ConfigManager.js
CHANGED
|
@@ -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
|
|
55
|
-
* @
|
|
53
|
+
* 创建样式或样式函数
|
|
54
|
+
* @param options 配置选项
|
|
55
|
+
* @returns 样式或样式函数
|
|
56
56
|
*/
|
|
57
|
-
private
|
|
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 =
|
|
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
|
|
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
|
|
153
|
-
* @
|
|
166
|
+
* 创建样式或样式函数
|
|
167
|
+
* @param options 配置选项
|
|
168
|
+
* @returns 样式或样式函数
|
|
154
169
|
*/
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
|
|
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
|
-
|
|
184
|
-
text
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
268
|
-
|
|
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
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
|
* 文本选项接口 - 文本标注相关配置
|