my-openlayer 2.2.0 → 2.3.0

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.
@@ -0,0 +1,342 @@
1
+ import VectorSource from "ol/source/Vector";
2
+ import GeoJSON from "ol/format/GeoJSON";
3
+ import VectorLayer from "ol/layer/Vector";
4
+ import { Stroke, Style } from "ol/style";
5
+ import { Feature } from "ol";
6
+ import MapTools from "./MapTools";
7
+ import { ValidationUtils } from "../utils/ValidationUtils";
8
+ import { EventManager } from "./EventManager";
9
+ import { ErrorHandler } from "../utils/ErrorHandler";
10
+ import { ConfigManager } from "./ConfigManager";
11
+ export default class RiverLayerManager {
12
+ /**
13
+ * 构造函数
14
+ * @param map OpenLayers 地图实例
15
+ * @param eventManager 可选事件管理器,未传入则内部创建
16
+ */
17
+ constructor(map, eventManager) {
18
+ //************* 状态:分级河流图层列表与显示控制 *************
19
+ this.riverLayerList = [];
20
+ this.riverLayerShow = false;
21
+ this.riverZoomOffset = 8;
22
+ //************* 默认配置:按 level 映射线宽 *************
23
+ this.defaultLevelWidthMap = ConfigManager.DEFAULT_RIVER_LEVEL_WIDTH_MAP;
24
+ ValidationUtils.validateMapInstance(map);
25
+ this.map = map;
26
+ this.eventManager = eventManager ?? new EventManager(map);
27
+ }
28
+ addRiverLayersByZoom(fyRiverJson, options = {}) {
29
+ ValidationUtils.validateGeoJSONData(fyRiverJson);
30
+ const defaultOptions = {
31
+ ...ConfigManager.DEFAULT_RIVER_LAYERS_BY_ZOOM_OPTIONS,
32
+ removeExisting: options.removeExisting ?? false,
33
+ levelWidthMap: this.defaultLevelWidthMap
34
+ };
35
+ const mergedOptions = { ...defaultOptions, ...options };
36
+ this.riverZoomOffset = mergedOptions.zoomOffset;
37
+ if (mergedOptions.removeExisting) {
38
+ this.clearRiverLayers();
39
+ }
40
+ this.riverLayerShow = mergedOptions.visible;
41
+ this.riverLayerList = [];
42
+ for (let level = 1; level <= mergedOptions.levelCount; level++) {
43
+ const vectorSource = new VectorSource({
44
+ format: new GeoJSON(),
45
+ loader: () => {
46
+ const geojson = new GeoJSON();
47
+ fyRiverJson.features.forEach((feature) => {
48
+ if (feature.properties && feature.properties.level === level) {
49
+ try {
50
+ const olFeature = geojson.readFeature(feature);
51
+ if (Array.isArray(olFeature)) {
52
+ vectorSource.addFeatures(olFeature);
53
+ }
54
+ else {
55
+ vectorSource.addFeature(olFeature);
56
+ }
57
+ }
58
+ catch (error) {
59
+ ErrorHandler.getInstance().warn(`Failed to load river feature at level ${level}:`, error);
60
+ }
61
+ }
62
+ });
63
+ }
64
+ });
65
+ const riverLayer = new VectorLayer({
66
+ properties: {
67
+ name: mergedOptions.layerName,
68
+ layerName: mergedOptions.layerName,
69
+ riverLevel: level
70
+ },
71
+ source: vectorSource,
72
+ style: (feature) => {
73
+ if (feature instanceof Feature) {
74
+ feature.set("type", mergedOptions.layerName);
75
+ feature.set("layerName", mergedOptions.layerName);
76
+ }
77
+ if (mergedOptions.style) {
78
+ if (typeof mergedOptions.style === "function") {
79
+ return mergedOptions.style(feature);
80
+ }
81
+ else {
82
+ return mergedOptions.style;
83
+ }
84
+ }
85
+ return new Style({
86
+ stroke: new Stroke({
87
+ color: mergedOptions.strokeColor,
88
+ width: mergedOptions.strokeWidth
89
+ })
90
+ });
91
+ },
92
+ zIndex: mergedOptions.zIndex
93
+ });
94
+ riverLayer.setVisible(false);
95
+ this.riverLayerList.push(riverLayer);
96
+ this.map.addLayer(riverLayer);
97
+ }
98
+ this.eventManager.on("moveend", () => {
99
+ this.showRiverLayerByZoom();
100
+ });
101
+ this.showRiverLayerByZoom();
102
+ }
103
+ //************* 分级河流:按缩放级别显示(URL 加载) *************
104
+ /**
105
+ * 从 URL 添加分级河流图层:根据缩放级别显示不同 level 的河流
106
+ * @param url 河流数据 URL(GeoJSON)
107
+ * @param options 河流图层配置选项
108
+ */
109
+ addRiverLayersByZoomByUrl(url, options = {}) {
110
+ const defaultOptions = {
111
+ ...ConfigManager.DEFAULT_RIVER_LAYERS_BY_ZOOM_OPTIONS,
112
+ removeExisting: options.removeExisting ?? false,
113
+ levelWidthMap: this.defaultLevelWidthMap
114
+ };
115
+ const mergedOptions = { ...defaultOptions, ...options };
116
+ this.riverZoomOffset = mergedOptions.zoomOffset;
117
+ if (mergedOptions.removeExisting) {
118
+ this.clearRiverLayers();
119
+ }
120
+ this.riverLayerShow = mergedOptions.visible;
121
+ this.riverLayerList = [];
122
+ for (let level = 1; level <= mergedOptions.levelCount; level++) {
123
+ const vectorSource = new VectorSource({
124
+ url,
125
+ format: new GeoJSON(),
126
+ loader: function (extent, resolution, projection, success, failure) {
127
+ fetch(url)
128
+ .then(response => response.json())
129
+ .then(data => {
130
+ const geojson = new GeoJSON();
131
+ data.features.forEach((feature) => {
132
+ if (feature.properties && feature.properties.level === level) {
133
+ try {
134
+ const olFeature = geojson.readFeature(feature);
135
+ if (Array.isArray(olFeature)) {
136
+ vectorSource.addFeatures(olFeature);
137
+ }
138
+ else {
139
+ vectorSource.addFeature(olFeature);
140
+ }
141
+ }
142
+ catch (error) {
143
+ ErrorHandler.getInstance().warn(`Failed to load river feature at level ${level}:`, error);
144
+ }
145
+ }
146
+ });
147
+ success?.(vectorSource.getFeatures());
148
+ })
149
+ .catch(error => {
150
+ ErrorHandler.getInstance().error("Error loading river data:", error);
151
+ failure?.();
152
+ });
153
+ }
154
+ });
155
+ const riverLayer = new VectorLayer({
156
+ properties: {
157
+ name: mergedOptions.layerName,
158
+ layerName: mergedOptions.layerName,
159
+ riverLevel: level
160
+ },
161
+ source: vectorSource,
162
+ style: (feature) => {
163
+ if (feature instanceof Feature) {
164
+ feature.set("type", mergedOptions.layerName);
165
+ feature.set("layerName", mergedOptions.layerName);
166
+ }
167
+ if (mergedOptions.style) {
168
+ if (typeof mergedOptions.style === "function") {
169
+ return mergedOptions.style(feature);
170
+ }
171
+ else {
172
+ return mergedOptions.style;
173
+ }
174
+ }
175
+ return new Style({
176
+ stroke: new Stroke({
177
+ color: mergedOptions.strokeColor,
178
+ width: mergedOptions.strokeWidth
179
+ })
180
+ });
181
+ },
182
+ zIndex: mergedOptions.zIndex
183
+ });
184
+ riverLayer.setVisible(false);
185
+ this.riverLayerList.push(riverLayer);
186
+ this.map.addLayer(riverLayer);
187
+ }
188
+ this.eventManager.on("moveend", () => {
189
+ this.showRiverLayerByZoom();
190
+ });
191
+ this.showRiverLayerByZoom();
192
+ }
193
+ //************* 分级河流:显示控制 *************
194
+ /**
195
+ * 设置分级河流图层是否显示
196
+ * @param show 是否显示
197
+ */
198
+ showRiverLayer(show) {
199
+ this.riverLayerShow = show;
200
+ this.showRiverLayerByZoom();
201
+ }
202
+ /**
203
+ * 根据当前 zoom 显示对应分级河流图层
204
+ * 缩放越大,显示的 riverLevel 越多
205
+ */
206
+ showRiverLayerByZoom() {
207
+ const zoom = this.map.getView().getZoom();
208
+ if (!zoom) {
209
+ return;
210
+ }
211
+ this.riverLayerList.forEach((layer, index) => {
212
+ const displayThreshold = index + 1 + this.riverZoomOffset;
213
+ if (zoom > displayThreshold) {
214
+ layer.setVisible(this.riverLayerShow);
215
+ }
216
+ else {
217
+ layer.setVisible(false);
218
+ }
219
+ });
220
+ }
221
+ addRiverWidthByLevel(data, options = {}) {
222
+ ValidationUtils.validateGeoJSONData(data);
223
+ const mergedOptions = {
224
+ ...ConfigManager.DEFAULT_RIVER_WIDTH_BY_LEVEL_OPTIONS,
225
+ ...options,
226
+ removeExisting: options.removeExisting ?? ConfigManager.DEFAULT_RIVER_WIDTH_BY_LEVEL_OPTIONS.removeExisting,
227
+ levelWidthMap: options.levelWidthMap ?? this.defaultLevelWidthMap,
228
+ };
229
+ if (mergedOptions.removeExisting && mergedOptions.layerName) {
230
+ MapTools.removeLayer(this.map, mergedOptions.layerName);
231
+ }
232
+ const features = new GeoJSON().readFeatures(data, mergedOptions.projectionOptOptions);
233
+ const riverLayer = new VectorLayer({
234
+ properties: {
235
+ name: mergedOptions.layerName,
236
+ layerName: mergedOptions.layerName
237
+ },
238
+ source: new VectorSource({ features }),
239
+ style: (feature) => {
240
+ if (mergedOptions.style) {
241
+ if (typeof mergedOptions.style === "function") {
242
+ return mergedOptions.style(feature);
243
+ }
244
+ else {
245
+ return mergedOptions.style;
246
+ }
247
+ }
248
+ const level = feature.get("level");
249
+ const levelWidth = mergedOptions.levelWidthMap[Number(level)] || 1;
250
+ return new Style({
251
+ stroke: new Stroke({
252
+ color: mergedOptions.strokeColor,
253
+ width: levelWidth
254
+ })
255
+ });
256
+ },
257
+ zIndex: mergedOptions.zIndex
258
+ });
259
+ riverLayer.setVisible(mergedOptions.visible);
260
+ this.map.addLayer(riverLayer);
261
+ return riverLayer;
262
+ }
263
+ //************* 河流线宽:按 level 设置不同宽度(URL 加载) *************
264
+ /**
265
+ * 从 URL 添加按级别显示不同宽度的河流图层
266
+ * @param url 河流数据 URL(GeoJSON)
267
+ * @param options 河流图层配置选项
268
+ */
269
+ addRiverWidthByLevelByUrl(url, options = {}) {
270
+ const mergedOptions = {
271
+ ...ConfigManager.DEFAULT_RIVER_WIDTH_BY_LEVEL_OPTIONS,
272
+ ...options,
273
+ removeExisting: options.removeExisting ?? ConfigManager.DEFAULT_RIVER_WIDTH_BY_LEVEL_OPTIONS.removeExisting,
274
+ levelWidthMap: options.levelWidthMap ?? this.defaultLevelWidthMap,
275
+ };
276
+ if (mergedOptions.removeExisting && mergedOptions.layerName) {
277
+ MapTools.removeLayer(this.map, mergedOptions.layerName);
278
+ }
279
+ const source = new VectorSource({
280
+ url,
281
+ format: new GeoJSON(options.projectionOptOptions)
282
+ });
283
+ const riverLayer = new VectorLayer({
284
+ properties: {
285
+ name: mergedOptions.layerName,
286
+ layerName: mergedOptions.layerName
287
+ },
288
+ source,
289
+ style: (feature) => {
290
+ if (mergedOptions.style) {
291
+ if (typeof mergedOptions.style === "function") {
292
+ return mergedOptions.style(feature);
293
+ }
294
+ else {
295
+ return mergedOptions.style;
296
+ }
297
+ }
298
+ const level = feature.get("level");
299
+ const levelWidth = mergedOptions.levelWidthMap[Number(level)] || 1;
300
+ return new Style({
301
+ stroke: new Stroke({
302
+ color: mergedOptions.strokeColor,
303
+ width: levelWidth
304
+ })
305
+ });
306
+ },
307
+ zIndex: mergedOptions.zIndex
308
+ });
309
+ riverLayer.setVisible(mergedOptions.visible);
310
+ this.map.addLayer(riverLayer);
311
+ return riverLayer;
312
+ }
313
+ //************* 清理与状态查询 *************
314
+ /**
315
+ * 清除本管理器创建的分级河流图层
316
+ */
317
+ clearRiverLayers() {
318
+ this.riverLayerList.forEach(layer => {
319
+ this.map.removeLayer(layer);
320
+ });
321
+ this.riverLayerList = [];
322
+ this.riverLayerShow = false;
323
+ }
324
+ /**
325
+ * 获取分级河流图层显示状态
326
+ */
327
+ getRiverLayerVisibility() {
328
+ return this.riverLayerShow;
329
+ }
330
+ /**
331
+ * 获取分级河流图层列表副本
332
+ */
333
+ getRiverLayers() {
334
+ return [...this.riverLayerList];
335
+ }
336
+ /**
337
+ * 销毁管理器,释放资源
338
+ */
339
+ destroy() {
340
+ this.clearRiverLayers();
341
+ }
342
+ }
@@ -2,6 +2,7 @@ import Overlay from 'ol/Overlay';
2
2
  import { VueTemplatePointState } from '../types';
3
3
  import { ErrorHandler, ErrorType } from '../utils/ErrorHandler';
4
4
  import { ValidationUtils } from '../utils/ValidationUtils';
5
+ import { ConfigManager } from './ConfigManager';
5
6
  // 动态导入Vue
6
7
  let Vue = null;
7
8
  let isVue3 = false;
@@ -224,10 +225,7 @@ class VueTemplatePointInstanceImpl {
224
225
  */
225
226
  mergeDefaultOptions(options) {
226
227
  return {
227
- positioning: 'center-center',
228
- stopEvent: false,
229
- visible: true,
230
- zIndex: 1,
228
+ ...ConfigManager.DEFAULT_VUE_TEMPLATE_POINT_OPTIONS,
231
229
  ...options
232
230
  };
233
231
  }
package/index.d.ts CHANGED
@@ -8,6 +8,8 @@ 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
10
  export { default as SelectHandler } from './core/SelectHandler';
11
+ export { default as RiverLayerManager } from './core/RiverLayerManager';
12
+ export type { RiverLayerOptions, RiverLevelWidthMap } from './core/RiverLayerManager';
11
13
  export { ConfigManager } from './core/ConfigManager';
12
14
  export { EventManager } from './core/EventManager';
13
15
  export type { MapEventType, EventCallback, MapEventData } from './core/EventManager';
@@ -16,4 +18,4 @@ export { ValidationUtils } from './utils/ValidationUtils';
16
18
  export type { BaseOptions, StyleOptions, TextOptions } from './types';
17
19
  export type { PointOptions, LineOptions, PolygonOptions } from './types';
18
20
  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, ProgrammaticSelectOptions } from './types';
21
+ export type { MapInitType, MapLayersOptions, HeatMapOptions, ImageLayerData, MaskLayerOptions, FeatureColorUpdateOptions, PointData, LineData, ClusterOptions, MeasureHandlerType, VueTemplatePointOptions, MapJSONData, FeatureData, AnnotationType, TiandituType, MapLayers, AnnotationLayerOptions, SelectOptions, SelectMode, SelectCallbackEvent, ProgrammaticSelectOptions } from './types';
package/index.js CHANGED
@@ -9,6 +9,7 @@ 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
11
  export { default as SelectHandler } from './core/SelectHandler';
12
+ export { default as RiverLayerManager } from './core/RiverLayerManager';
12
13
  // 新增工具类
13
14
  export { ConfigManager } from './core/ConfigManager';
14
15
  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.2.0",
4
+ "version": "2.3.0",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
package/types.d.ts CHANGED
@@ -195,12 +195,6 @@ export interface MaskLayerOptions {
195
195
  visible?: boolean;
196
196
  layerName?: string;
197
197
  }
198
- /**
199
- * 颜色映射接口
200
- */
201
- export interface ColorMap {
202
- [level: string]: string;
203
- }
204
198
  /**
205
199
  * 要素颜色更新选项接口
206
200
  */