my-openlayer 2.5.4 → 3.0.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/MyOl.d.ts +3 -22
  3. package/MyOl.js +52 -112
  4. package/README.md +116 -29
  5. package/core/line/Line.d.ts +24 -5
  6. package/core/line/Line.js +38 -10
  7. package/core/map/ConfigManager.d.ts +169 -89
  8. package/core/map/ConfigManager.js +157 -175
  9. package/core/map/MapBaseLayers.d.ts +6 -0
  10. package/core/map/MapBaseLayers.js +9 -0
  11. package/core/map/MapTools.d.ts +17 -1
  12. package/core/map/MapTools.js +39 -5
  13. package/core/point/Point.d.ts +54 -14
  14. package/core/point/Point.js +132 -76
  15. package/core/point/PointOverlay.d.ts +2 -4
  16. package/core/point/PointOverlay.js +2 -1
  17. package/core/point/PointPulseLayer.js +6 -4
  18. package/core/polygon/Polygon.d.ts +32 -17
  19. package/core/polygon/Polygon.js +87 -64
  20. package/core/polygon/PolygonHeatmapLayer.js +15 -2
  21. package/core/polygon/PolygonMaskLayer.d.ts +2 -2
  22. package/core/polygon/PolygonMaskLayer.js +3 -1
  23. package/core/polygon/PolygonStyleFactory.d.ts +4 -3
  24. package/core/projection/ProjectionManager.d.ts +66 -0
  25. package/core/projection/ProjectionManager.js +144 -0
  26. package/core/projection/index.d.ts +2 -0
  27. package/core/projection/index.js +1 -0
  28. package/core/select/SelectHandler.d.ts +1 -1
  29. package/core/vue-template-point/VueTemplatePoint.d.ts +2 -4
  30. package/core/vue-template-point/VueTemplatePoint.js +16 -2
  31. package/docs/.vitepress/config.mts +1 -0
  32. package/docs/Line.md +4 -4
  33. package/docs/MIGRATION-3.0.md +221 -0
  34. package/docs/Point.md +24 -6
  35. package/docs/Polygon.md +14 -5
  36. package/index.d.ts +6 -3
  37. package/index.js +4 -1
  38. package/package.json +6 -3
  39. package/types/base.d.ts +4 -4
  40. package/types/common.d.ts +8 -6
  41. package/types/handle.d.ts +34 -0
  42. package/types/handle.js +1 -0
  43. package/types/index.d.ts +1 -0
  44. package/types/line.d.ts +3 -2
  45. package/types/map.d.ts +1 -1
  46. package/types/point.d.ts +11 -3
  47. package/utils/ErrorHandler.d.ts +12 -0
  48. package/utils/ErrorHandler.js +21 -0
@@ -0,0 +1,221 @@
1
+ # my-openlayer 3.0 迁移指南
2
+
3
+ 3.0 完成了一次系统性的 API 改造。图层类 `add*` 返回值会从原始 OpenLayers layer 改成统一 Handle;迁移后可以用同一套 `remove()` / `setVisible()` 管理生命周期。本指南分三段:
4
+
5
+ 1. **必须改的**(编译错误)
6
+ 2. **推荐改的**(用新 API 写新代码)
7
+ 3. **保留旧 API 的期限**
8
+
9
+ ---
10
+
11
+ ## 1. 必须改的(编译错误)
12
+
13
+ ### 1.1 `layerName` 在公开 `add*` 签名上变成必填
14
+
15
+ 所有 `Point.addPoint / addClusterPoint / addPulsePointLayer`、`Line.addLine / addLineByUrl / addFlowLine / addFlowLineByUrl`、`Polygon.addPolygon / addPolygonByUrl` 现在要求 `options.layerName` 是 `string`(不再可选)。
16
+
17
+ ```ts
18
+ // ❌ 2.x:layerName 可选,遗忘时取 ConfigManager 默认值 'lineLayer'
19
+ line.addLine(data)
20
+ line.addLine(data, { strokeColor: 'red' })
21
+
22
+ // ✅ 3.0:必须传 layerName
23
+ line.addLine(data, { layerName: 'my-line' })
24
+ line.addLine(data, { layerName: 'my-line', strokeColor: 'red' })
25
+ ```
26
+
27
+ > **为什么**:依赖默认 `layerName` 的两次调用会互相覆盖,是 2.x 最常见的"图层莫名消失"陷阱。
28
+
29
+ `PointOptions / LineOptions / PolygonOptions` interface **本身**没改(`layerName?: string` 仍然可选),所以已有的工厂函数、配置对象不受影响 —— 只是公开方法签名收紧了。
30
+
31
+ ### 1.2 `add*` 返回值改为 Handle
32
+
33
+ 真实图层类 `add*` 不再直接返回 OpenLayers layer,而是返回统一 `LayerHandle`。
34
+
35
+ ```ts
36
+ // ❌ 2.x
37
+ const layer = line.addLine(data, { layerName: 'l1' })
38
+ layer.getSource()
39
+ layer.setVisible(false)
40
+
41
+ // ✅ 3.0
42
+ const handle = line.addLine(data, { layerName: 'l1' })
43
+ handle.layer.getSource()
44
+ handle.setVisible(false)
45
+ handle.remove()
46
+ ```
47
+
48
+ `addDomPoint` / `addVueTemplatePoint` 不是 OL 图层,3.0 返回 `ControlHandle`:
49
+
50
+ ```ts
51
+ const domHandle = point.addDomPoint(points)
52
+ domHandle.target // Overlay[]
53
+ domHandle.anchors // 兼容原字段
54
+
55
+ const vueHandle = point.addVueTemplatePoint(points, Component)
56
+ vueHandle.target // VueTemplatePointInstance[]
57
+ vueHandle.getPoints() // 兼容原方法
58
+ ```
59
+
60
+ ---
61
+
62
+ ## 2. 推荐改的(用新 API 写新代码)
63
+
64
+ ### 2.1 用 `add*` 拿统一句柄
65
+
66
+ 新代码统一用 `add*` 系列:
67
+
68
+ ```ts
69
+ import type { LayerHandle } from 'my-openlayer'
70
+
71
+ // 跨 Point / Line / Polygon 一致的形态
72
+ const pointHandle: LayerHandle | null = myOl.getPoint().addPoint(data, { layerName: 'p1' })
73
+ const lineHandle: LayerHandle = myOl.getLine().addLine(data, { layerName: 'l1' })
74
+ const polyHandle: LayerHandle = myOl.getPolygon().addPolygon(data, { layerName: 'r1' })
75
+
76
+ // 统一生命周期
77
+ pointHandle?.setVisible(false)
78
+ pointHandle?.remove()
79
+ ```
80
+
81
+ 动画句柄(`PulsePointLayerHandle` / `FlowLineLayerHandle`)现在显式继承 `AnimatedLayerHandle`:
82
+
83
+ ```ts
84
+ import type { AnimatedLayerHandle } from 'my-openlayer'
85
+
86
+ const flowHandle: AnimatedLayerHandle | null = myOl.getLine().addFlowLine(data, { layerName: 'flow' })
87
+ flowHandle?.start()
88
+ flowHandle?.pause?.()
89
+ flowHandle?.remove()
90
+ ```
91
+
92
+ ### 2.2 `*ByUrl` 统一异步返回 Handle
93
+
94
+ 旧的 `Line.addLineByUrl` / `Polygon.addPolygonByUrl` 同步返回 layer,但 features 仍在异步加载,导致 `fitView` 经常失败、`getFeatures().length === 0`。3.0 改为先 `fetch` JSON,再调用对应 add 方法:
95
+
96
+ ```ts
97
+ // ❌ 2.x:返回 layer 时 features 还在路上
98
+ const layer = polygon.addPolygonByUrl('/boundary.geojson', { layerName: 'b' })
99
+ // layer.getSource().getFeatures().length === 0 ← 经常踩坑
100
+
101
+ // ✅ 3.0:await 后拿到完整 LayerHandle
102
+ const handle = await polygon.addPolygonByUrl('/boundary.geojson', { layerName: 'b' })
103
+ console.log(handle.layer.getSource()?.getFeatures().length) // 准确
104
+ ```
105
+
106
+ ### 2.3 Point 新增 `*ByUrl` Promise API
107
+
108
+ 之前 `Point` 没有任何 `*ByUrl` 方法,必须自己 `fetch + addPoint`。3.0 补齐:
109
+
110
+ ```ts
111
+ // 从 URL 加载点位(自动识别 PointData[] 数组或 GeoJSON FeatureCollection)
112
+ const handle = await myOl.getPoint().addPointByUrl('/points.json', { layerName: 'p1' })
113
+
114
+ const handle = await myOl.getPoint().addPulsePointLayerByUrl('/villages.json', {
115
+ layerName: 'villages',
116
+ pulse: { enabled: true, frameCount: 24 }
117
+ })
118
+ ```
119
+
120
+ ### 2.4 投影注册抽到 `ProjectionManager`
121
+
122
+ 2.x 用 `options.projection` 注册自定义投影。3.0 仍然支持,**外加**一个独立入口:
123
+
124
+ ```ts
125
+ import { ProjectionManager } from 'my-openlayer'
126
+
127
+ // 应用启动时一次性注册自定义 EPSG
128
+ ProjectionManager.register({
129
+ code: 'EPSG:2380',
130
+ def: '+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=WGS84 +units=m +no_defs'
131
+ // units 省略时由 proj4 自动推导
132
+ })
133
+
134
+ // 之后任何 new MyOl({ projection: { code: 'EPSG:2380' } }) 都能直接用
135
+ ```
136
+
137
+ ### 2.5 `ConfigManager.setDefaults` 全局覆盖默认值
138
+
139
+ ```ts
140
+ import { ConfigManager } from 'my-openlayer'
141
+
142
+ // 应用启动时把所有线的默认宽度改成 3px
143
+ ConfigManager.setDefaults('LINE_OPTIONS', { strokeWidth: 3 })
144
+
145
+ // 嵌套对象深合并
146
+ ConfigManager.setDefaults('FLOW_LINE_OPTIONS', {
147
+ flowSymbol: { scale: 1.2 } // 其它 flowSymbol 字段保持原默认
148
+ })
149
+
150
+ // 测试结束后重置
151
+ ConfigManager.resetDefaults() // 全部
152
+ ConfigManager.resetDefaults('LINE_OPTIONS') // 单组
153
+ ```
154
+
155
+ 所有现有 `add*` 方法都通过 `ConfigManager.DEFAULT_X` getter 读默认值,因此 `setDefaults` **立即对所有后续调用生效**,不需要改任何业务代码。
156
+
157
+ ### 2.6 `PulsePointIconOptions.src` → `img`
158
+
159
+ 为了和 `PointOptions.img` 命名统一:
160
+
161
+ ```ts
162
+ // ❌ 2.x(仍可用,但 @deprecated)
163
+ point.addPulsePointLayer(data, {
164
+ layerName: 'p',
165
+ icon: { src: '/icon.svg', scale: 0.8 }
166
+ })
167
+
168
+ // ✅ 3.0
169
+ point.addPulsePointLayer(data, {
170
+ layerName: 'p',
171
+ icon: { img: '/icon.svg', scale: 0.8 }
172
+ })
173
+ ```
174
+
175
+ PointPulseLayer 同时识别 `img` 和 `src`,平滑过渡。
176
+
177
+ ### 2.7 用具体错误类型做精细化处理
178
+
179
+ ```ts
180
+ import { LayerNotFoundError, InvalidGeoJSONError, ProjectionError } from 'my-openlayer'
181
+
182
+ try {
183
+ polygon.updateFeatureColor('nonexistent', { /* ... */ })
184
+ } catch (e) {
185
+ if (e instanceof LayerNotFoundError) {
186
+ // 友好提示
187
+ showToast(`图层 "${e.context.layerName}" 不存在,请先调用 addPolygon`)
188
+ } else if (e instanceof InvalidGeoJSONError) {
189
+ showToast('GeoJSON 数据格式有误')
190
+ } else {
191
+ throw e
192
+ }
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ ## 3. 保留旧 API 的期限
199
+
200
+ 下列旧 API 在 3.0 标了 `@deprecated`,**3.x 整个生命周期都仍然可用**,但 3.x 末尾(4.0)会移除。建议趁早迁移:
201
+
202
+ | 旧 API | 替代品 |
203
+ |---|---|
204
+ | `add*` 不传 `layerName`(仅使用 `ConfigManager.DEFAULT_*.layerName`) | `add*` 显式传 `layerName` |
205
+ | `addPolygonByUrl`(同步返回 layer) | `await addPolygonByUrl`(Promise<LayerHandle>) |
206
+ | `addLineByUrl`(同步返回 layer) | `await addLineByUrl`(Promise<LayerHandle>) |
207
+ | `MyOl.getView` | `MyOl.createView` |
208
+ | `PulsePointIconOptions.src` | `PulsePointIconOptions.img` |
209
+ | `(MyOl as any).initializeProjections` | `ProjectionManager.initialize` |
210
+
211
+ ---
212
+
213
+ ## 4. 升级前后检查清单
214
+
215
+ - [ ] 所有 `add*` 调用都显式传 `layerName`(TS 编译会提示)
216
+ - [ ] `addPolygonByUrl` / `addLineByUrl` 调用处加 `await`,并通过 `handle.layer` 访问底层图层
217
+ - [ ] `MyOl.destroy()` 调用后是否真的需要重建地图(destroy 已强化级联清理,老代码可能不再需要手动 stop 各 handle)
218
+ - [ ] 自定义投影注册:尝试迁移到 `ProjectionManager.register` 集中管理
219
+ - [ ] 全局样式默认值:用 `ConfigManager.setDefaults` 替代多处复制 options
220
+
221
+ 升级过程中遇到任何"老代码 TS 编译过不去"的情况,请优先翻看本指南第 1 节。
package/docs/Point.md CHANGED
@@ -94,24 +94,32 @@ constructor(map: Map)
94
94
  添加普通点图层。
95
95
 
96
96
  ```typescript
97
- addPoint(pointData: PointData[], options: PointOptions): VectorLayer<VectorSource> | null
97
+ addPoint(pointData: PointData[], options: PointOptions & { layerName: string }): LayerHandle<VectorLayer<VectorSource>> | null
98
98
  ```
99
99
 
100
100
  - **pointData**: 点位数据数组。
101
101
  - **options**: 配置选项。
102
- - **返回值**: 创建的向量图层,如果数据无效返回 `null`。
102
+ - **返回值**: `{ layer, remove(), setVisible() }` 形态的统一句柄;如果数据无效返回 `null`。
103
103
 
104
104
  ### addClusterPoint
105
105
 
106
106
  添加聚合点图层。
107
107
 
108
108
  ```typescript
109
- addClusterPoint(pointData: PointData[], options: ClusterOptions): VectorLayer<VectorSource> | null
109
+ addClusterPoint(pointData: PointData[], options: ClusterOptions & { layerName: string }): LayerHandle<VectorLayer<VectorSource>> | null
110
110
  ```
111
111
 
112
112
  - **pointData**: 点位数据数组。
113
113
  - **options**: 聚合配置选项。
114
- - **返回值**: 创建的聚合图层。
114
+ - **返回值**: `{ layer, remove(), setVisible() }` 形态的统一句柄。
115
+
116
+ ### addPointByUrl
117
+
118
+ 从 URL 加载点位数据,支持 `PointData[]` 数组或 GeoJSON FeatureCollection。
119
+
120
+ ```typescript
121
+ addPointByUrl(url: string, options: PointOptions & { layerName: string }): Promise<LayerHandle<VectorLayer<VectorSource>> | null>
122
+ ```
115
123
 
116
124
  ### addDomPoint
117
125
 
@@ -119,6 +127,7 @@ addClusterPoint(pointData: PointData[], options: ClusterOptions): VectorLayer<Ve
119
127
 
120
128
  ```typescript
121
129
  addDomPoint(twinkleList: TwinkleItem[], callback?: Function): {
130
+ target: Overlay[],
122
131
  anchors: Overlay[],
123
132
  remove: () => void,
124
133
  setVisible: (visible: boolean) => void
@@ -127,7 +136,7 @@ addDomPoint(twinkleList: TwinkleItem[], callback?: Function): {
127
136
 
128
137
  - **twinkleList**: 包含经纬度和类名的数据列表。
129
138
  - **callback**: 点击回调函数。
130
- - **返回值**: 控制对象,包含 `remove` 和 `setVisible` 方法。
139
+ - **返回值**: 控制对象,包含 `target`、`anchors`、`remove` 和 `setVisible`。
131
140
 
132
141
  ### addPulsePointLayer
133
142
 
@@ -141,12 +150,21 @@ addPulsePointLayer(pointData: PointData[], options: PulsePointOptions): PulsePoi
141
150
  - **options**: 闪烁点配置选项,复用 `addPoint` 的图标、文本和图层参数习惯。
142
151
  - **返回值**: 控制对象,包含动画启停、显隐、数据更新和移除方法;如果数据无效返回 `null`。
143
152
 
153
+ ### addPulsePointLayerByUrl
154
+
155
+ 从 URL 加载点位数据并添加高性能闪烁点图层。
156
+
157
+ ```typescript
158
+ addPulsePointLayerByUrl(url: string, options: PulsePointOptions & { layerName: string }): Promise<PulsePointLayerHandle | null>
159
+ ```
160
+
144
161
  ### addVueTemplatePoint
145
162
 
146
163
  添加 Vue 组件作为点位。
147
164
 
148
165
  ```typescript
149
166
  addVueTemplatePoint(pointDataList: PointData[], template: any, options?: VueTemplatePointOptions): {
167
+ target: VueTemplatePointInstance[],
150
168
  setVisible: (visible: boolean) => void,
151
169
  setOneVisibleByProp: (propName: string, propValue: any, visible: boolean) => void,
152
170
  remove: () => void,
@@ -157,7 +175,7 @@ addVueTemplatePoint(pointDataList: PointData[], template: any, options?: VueTemp
157
175
  - **pointDataList**: 点位数据列表。
158
176
  - **template**: Vue 组件。
159
177
  - **options**: 配置选项。
160
- - **返回值**: 控制对象,包含显示/隐藏和移除方法。
178
+ - **返回值**: 控制对象,包含 `target`、显示/隐藏、按属性显示/隐藏和移除方法。
161
179
 
162
180
  ## 使用示例
163
181
 
package/docs/Polygon.md CHANGED
@@ -69,7 +69,7 @@ const polygon = new Polygon(map: Map);
69
69
  添加多边形图层。
70
70
 
71
71
  ```typescript
72
- addPolygon(data: MapJSONData, options?: PolygonOptions): VectorLayer<VectorSource>
72
+ addPolygon(data: MapJSONData, options: PolygonOptions & { layerName: string }): LayerHandle<VectorLayer<VectorSource>>
73
73
  ```
74
74
 
75
75
  | 参数 | 类型 | 说明 |
@@ -82,7 +82,7 @@ addPolygon(data: MapJSONData, options?: PolygonOptions): VectorLayer<VectorSourc
82
82
  从 URL 加载多边形图层。
83
83
 
84
84
  ```typescript
85
- addPolygonByUrl(url: string, options?: PolygonOptions): VectorLayer<VectorSource>
85
+ addPolygonByUrl(url: string, options: PolygonOptions & { layerName: string }): Promise<LayerHandle<VectorLayer<VectorSource>>>
86
86
  ```
87
87
 
88
88
  ### addBorderPolygon
@@ -90,7 +90,8 @@ addPolygonByUrl(url: string, options?: PolygonOptions): VectorLayer<VectorSource
90
90
  添加边界图层(通常用于行政区划边界,支持镂空效果)。
91
91
 
92
92
  ```typescript
93
- addBorderPolygon(data: MapJSONData, options?: PolygonOptions): VectorLayer<VectorSource>
93
+ addBorderPolygon(data: MapJSONData, options?: PolygonOptions): LayerHandle<VectorLayer<VectorSource>>
94
+ addBorderPolygonByUrl(url: string, options?: PolygonOptions): Promise<LayerHandle<VectorLayer<VectorSource>>>
94
95
  ```
95
96
 
96
97
  ### updateFeatureColor
@@ -116,7 +117,7 @@ updateFeatureColor(
116
117
  添加静态图片图层(如叠加平面图、卫星图)。
117
118
 
118
119
  ```typescript
119
- addImageLayer(imageData: ImageLayerData, options?: PolygonOptions): ImageLayer<any>
120
+ addImageLayer(imageData: ImageLayerData, options?: PolygonOptions): LayerHandle<ImageLayer<any>>
120
121
  ```
121
122
 
122
123
  ### addHeatmap
@@ -124,7 +125,15 @@ addImageLayer(imageData: ImageLayerData, options?: PolygonOptions): ImageLayer<a
124
125
  添加热力图。
125
126
 
126
127
  ```typescript
127
- addHeatmap(pointData: PointData[], options?: HeatMapOptions): Heatmap
128
+ addHeatmap(pointData: PointData[], options?: HeatMapOptions): LayerHandle<BaseLayer>
129
+ ```
130
+
131
+ ### addMaskLayer
132
+
133
+ 添加遮罩图层。
134
+
135
+ ```typescript
136
+ addMaskLayer(data: MapJSONData, options?: MaskLayerOptions): LayerHandle<VectorLayer<VectorSource>>
128
137
  ```
129
138
 
130
139
  ### setOutLayer
package/index.d.ts CHANGED
@@ -7,10 +7,13 @@ export { Polygon } from './core/polygon';
7
7
  export { MapBaseLayers, MapTools, MeasureHandler, ConfigManager, EventManager } from './core/map';
8
8
  export { VueTemplatePoint } from './core/vue-template-point';
9
9
  export { SelectHandler } from './core/select';
10
+ export { ProjectionManager, PROJECTIONS } from './core/projection';
11
+ export type { CustomProjectionRegistration } from './core/projection';
10
12
  export type { MapEventType, EventCallback, MapEventData } from './core/map/EventManager';
11
- export { ErrorHandler, MyOpenLayersError, ErrorType } from './utils/ErrorHandler';
13
+ export { ErrorHandler, MyOpenLayersError, ErrorType, LayerNotFoundError, InvalidGeoJSONError, ProjectionError } from './utils/ErrorHandler';
12
14
  export { default as ValidationUtils } from './utils/ValidationUtils';
13
- export type { BaseOptions, StyleOptions, TextOptions } from './types';
15
+ export type { BaseOptions, StyleOptions, TextOptions, LayerHandle, AnimatedLayerHandle } from './types';
14
16
  export type { PointOptions, LineOptions, FlowLineOptions, FlowLineLayerHandle, PolygonOptions, PulsePointOptions, PulsePointLayerHandle } from './types';
15
17
  export type { OptionsType } from './types';
16
- export type { MapInitType, MapLayersOptions, HeatMapOptions, ImageLayerData, MaskLayerOptions, FeatureColorUpdateOptions, PointData, PulsePointIconOptions, LineData, ClusterOptions, MeasureHandlerType, VueTemplatePointOptions, MapJSONData, FeatureData, AnnotationType, TiandituType, MapLayers, AnnotationLayerOptions, SelectOptions, SelectMode, SelectCallbackEvent, ProgrammaticSelectOptions } from './types';
18
+ export type { MapInitType, MapLayersOptions, HeatMapOptions, ImageLayerData, MaskLayerOptions, FeatureColorUpdateOptions, PointData, PulsePointIconOptions, LineData, ClusterOptions, MeasureHandlerType, VueTemplatePointOptions, VueTemplatePointInstance, TwinkleItem, MapJSONData, FeatureData, AnnotationType, TiandituType, MapLayers, AnnotationLayerOptions, SelectOptions, SelectMode, SelectCallbackEvent, ProgrammaticSelectOptions } from './types';
19
+ export { VueTemplatePointState } from './types';
package/index.js CHANGED
@@ -7,7 +7,10 @@ export { Polygon } from './core/polygon';
7
7
  export { MapBaseLayers, MapTools, MeasureHandler, ConfigManager, EventManager } from './core/map';
8
8
  export { VueTemplatePoint } from './core/vue-template-point';
9
9
  export { SelectHandler } from './core/select';
10
+ export { ProjectionManager, PROJECTIONS } from './core/projection';
10
11
  // 错误处理
11
- export { ErrorHandler, MyOpenLayersError, ErrorType } from './utils/ErrorHandler';
12
+ export { ErrorHandler, MyOpenLayersError, ErrorType, LayerNotFoundError, InvalidGeoJSONError, ProjectionError } from './utils/ErrorHandler';
12
13
  // 验证工具
13
14
  export { default as ValidationUtils } from './utils/ValidationUtils';
15
+ // Vue 模板点位状态枚举(运行时值,需要单独导出)
16
+ export { VueTemplatePointState } from './types';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "my-openlayer",
3
3
  "private": false,
4
- "version": "2.5.4",
4
+ "version": "3.0.1",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "main": "index.js",
@@ -47,7 +47,8 @@
47
47
  "publish-flat-dry": "npm run build && npm run prepare-publish && cd temp-publish && npm publish --dry-run",
48
48
  "docs:dev": "vitepress dev docs",
49
49
  "docs:build": "vitepress build docs",
50
- "docs:preview": "vitepress preview docs"
50
+ "docs:preview": "vitepress preview docs",
51
+ "demo:build": "vite build --base /my-openlayer/demo/ --outDir demo-dist"
51
52
  },
52
53
  "dependencies": {
53
54
  "@turf/turf": "^7.2.0",
@@ -57,12 +58,14 @@
57
58
  "devDependencies": {
58
59
  "@types/proj4": "^2.5.2",
59
60
  "@vitejs/plugin-vue": "^5.0.4",
61
+ "happy-dom": "^20.9.0",
60
62
  "typescript": "~5.6.2",
61
63
  "vite": "^5.4.10",
62
- "vitest": "^2.1.9",
63
64
  "vite-plugin-css-modules": "^0.0.1",
64
65
  "vite-plugin-libcss": "^1.1.1",
65
66
  "vitepress": "^1.6.4",
67
+ "vitest": "^2.1.9",
68
+ "vue-router": "^4.6.4",
66
69
  "vue-tsc": "^2.0.6"
67
70
  },
68
71
  "peerDependencies": {
package/types/base.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import Feature, { FeatureLike } from "ol/Feature";
1
+ import { FeatureLike } from "ol/Feature";
2
2
  import { Style } from "ol/style";
3
3
  import type { MapJSONData } from "./common";
4
4
  /**
@@ -17,7 +17,7 @@ export interface BaseOptions {
17
17
  /**
18
18
  * @deprecated 新项目请使用 dataProjection / featureProjection。
19
19
  */
20
- projectionOptOptions?: any;
20
+ projectionOptOptions?: Record<string, unknown>;
21
21
  style?: Style | Style[] | ((feature: FeatureLike) => Style | Style[]);
22
22
  }
23
23
  /**
@@ -29,7 +29,7 @@ export interface StyleOptions {
29
29
  lineDash?: number[];
30
30
  lineDashOffset?: number;
31
31
  fillColor?: string;
32
- fillColorCallBack?: (feature: Feature) => string;
32
+ fillColorCallBack?: (feature: FeatureLike) => string;
33
33
  withDefaultStroke?: boolean;
34
34
  withDefaultFill?: boolean;
35
35
  }
@@ -38,7 +38,7 @@ export interface StyleOptions {
38
38
  */
39
39
  export interface TextOptions {
40
40
  textVisible?: boolean;
41
- textCallBack?: (feature: Feature) => string;
41
+ textCallBack?: (feature: FeatureLike) => string;
42
42
  textFont?: string;
43
43
  textFillColor?: string;
44
44
  textStrokeColor?: string;
package/types/common.d.ts CHANGED
@@ -3,10 +3,10 @@
3
3
  */
4
4
  export interface FeatureData {
5
5
  type: string;
6
- properties: any;
6
+ properties: Record<string, unknown>;
7
7
  geometry: {
8
8
  type: "Polygon" | "MultiPolygon" | "Point" | "LineString" | "MultiLineString" | "MultiPoint" | "GeometryCollection";
9
- coordinates: any[];
9
+ coordinates: number[] | number[][] | number[][][] | number[][][][];
10
10
  };
11
11
  }
12
12
  /**
@@ -33,18 +33,18 @@ export type OptionsType = {
33
33
  mapClipData?: MapJSONData;
34
34
  dataProjection?: string;
35
35
  featureProjection?: string;
36
- projectionOptOptions?: any;
37
- style?: any;
36
+ projectionOptOptions?: Record<string, unknown>;
37
+ style?: Style | Style[] | ((feature: FeatureLike) => Style | Style[]);
38
38
  strokeColor?: string | number[];
39
39
  strokeWidth?: number;
40
40
  lineDash?: number[];
41
41
  lineDashOffset?: number;
42
42
  fillColor?: string;
43
- fillColorCallBack?: (feature: any) => string;
43
+ fillColorCallBack?: (feature: FeatureLike) => string;
44
44
  withDefaultStroke?: boolean;
45
45
  withDefaultFill?: boolean;
46
46
  textVisible?: boolean;
47
- textCallBack?: (feature: any) => string;
47
+ textCallBack?: (feature: FeatureLike) => string;
48
48
  textFont?: string;
49
49
  textFillColor?: string;
50
50
  textStrokeColor?: string;
@@ -57,3 +57,5 @@ export type OptionsType = {
57
57
  type?: string;
58
58
  mask?: boolean;
59
59
  };
60
+ import type { FeatureLike } from "ol/Feature";
61
+ import type { Style } from "ol/style";
@@ -0,0 +1,34 @@
1
+ /**
2
+ * P1-1:统一图层句柄接口。
3
+ *
4
+ * 真实图层类 add* 方法在 3.0 之后都返回符合 LayerHandle 的对象,
5
+ * 用户记一次 `{ layer, remove, setVisible }` 就能跨 Point / Line / Polygon 通用。
6
+ *
7
+ * 动画句柄(流动线、闪烁点)扩展为 AnimatedLayerHandle,额外暴露 start/stop。
8
+ * Overlay / Vue 组件点这类非图层控制对象使用 ControlHandle,通过 target 暴露控制目标。
9
+ */
10
+ import type BaseLayer from "ol/layer/Base";
11
+ export interface LayerHandle<L extends BaseLayer = BaseLayer> {
12
+ /** 实际的 OL 图层实例。 */
13
+ readonly layer: L;
14
+ /** 从地图移除此图层,停止所有动画与监听。可安全多次调用。 */
15
+ remove(): void;
16
+ /** 切换图层可见性。 */
17
+ setVisible(visible: boolean): void;
18
+ }
19
+ export interface AnimatedLayerHandle<L extends BaseLayer = BaseLayer> extends LayerHandle<L> {
20
+ start(): void;
21
+ stop(): void;
22
+ pause?(): void;
23
+ resume?(): void;
24
+ /** 更新底层数据(数据形态因实现而异)。 */
25
+ updateData?(data: unknown): void;
26
+ }
27
+ export interface ControlHandle<T = unknown> {
28
+ /** 非 OL 图层控制目标,例如 Overlay[] 或 VueTemplatePointInstance[]。 */
29
+ readonly target: T;
30
+ /** 移除控制目标。可安全多次调用。 */
31
+ remove(): void;
32
+ /** 切换控制目标可见性。 */
33
+ setVisible(visible: boolean): void;
34
+ }
@@ -0,0 +1 @@
1
+ export {};
package/types/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export type { BaseOptions, StyleOptions, TextOptions } from './base';
2
+ export type { LayerHandle, AnimatedLayerHandle, ControlHandle } from './handle';
2
3
  export type { FeatureData, MapJSONData, OptionsType, MeasureHandlerType, EventType } from './common';
3
4
  export type { MapInitType, MapLayersOptions, MapLayers, AnnotationType, TiandituType, AnnotationLayerOptions, HeatMapOptions, ImageLayerData, MaskLayerOptions } from './map';
4
5
  export type { PointOptions, PointData, ClusterOptions, PulsePointIconOptions, PulsePointOptions, PulsePointLayerHandle, TwinkleItem } from './point';
package/types/line.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import VectorLayer from "ol/layer/Vector";
2
2
  import VectorSource from "ol/source/Vector";
3
3
  import type { BaseOptions, StyleOptions, TextOptions } from "./base";
4
+ import type { AnimatedLayerHandle } from "./handle";
4
5
  import type { MapJSONData } from "./common";
5
6
  export interface LineOptions extends BaseOptions, StyleOptions, TextOptions {
6
7
  type?: string;
@@ -8,7 +9,7 @@ export interface LineOptions extends BaseOptions, StyleOptions, TextOptions {
8
9
  export interface LineData {
9
10
  type: string;
10
11
  coordinates: number[][];
11
- [key: string]: any;
12
+ [key: string]: unknown;
12
13
  }
13
14
  export interface FlowLineOptions extends LineOptions {
14
15
  loop?: boolean;
@@ -28,7 +29,7 @@ export interface FlowLineOptions extends LineOptions {
28
29
  trailEnabled?: boolean;
29
30
  trailLength?: number;
30
31
  }
31
- export interface FlowLineLayerHandle {
32
+ export interface FlowLineLayerHandle extends AnimatedLayerHandle<VectorLayer<VectorSource>> {
32
33
  layer: VectorLayer<VectorSource>;
33
34
  animationLayer: VectorLayer<VectorSource>;
34
35
  start: () => void;
package/types/map.d.ts CHANGED
@@ -65,7 +65,7 @@ export interface ImageLayerData {
65
65
  extent?: number[];
66
66
  }
67
67
  export interface MaskLayerOptions {
68
- extent?: any;
68
+ extent?: number[];
69
69
  fillColor?: string;
70
70
  strokeWidth?: number;
71
71
  strokeColor?: string;
package/types/point.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import VectorLayer from "ol/layer/Vector";
2
2
  import VectorSource from "ol/source/Vector";
3
3
  import type { BaseOptions, StyleOptions, TextOptions } from "./base";
4
+ import type { AnimatedLayerHandle } from "./handle";
4
5
  export interface PointOptions extends BaseOptions, StyleOptions, TextOptions {
5
6
  textKey?: string;
6
7
  img?: string;
@@ -10,13 +11,20 @@ export interface PointOptions extends BaseOptions, StyleOptions, TextOptions {
10
11
  export interface PointData {
11
12
  lgtd: number;
12
13
  lttd: number;
13
- [key: string]: any;
14
+ [key: string]: unknown;
14
15
  }
15
16
  export interface ClusterOptions extends PointOptions {
16
17
  distance?: number;
17
18
  minDistance?: number;
18
19
  }
19
20
  export interface PulsePointIconOptions {
21
+ /**
22
+ * 图标资源 URL。
23
+ */
24
+ img?: string;
25
+ /**
26
+ * @deprecated 请使用 `img` 字段,3.x 末尾会移除。
27
+ */
20
28
  src?: string;
21
29
  scale?: number;
22
30
  color?: string;
@@ -38,7 +46,7 @@ export interface PulsePointOptions extends PointOptions {
38
46
  frameCount?: number;
39
47
  };
40
48
  }
41
- export interface PulsePointLayerHandle {
49
+ export interface PulsePointLayerHandle extends AnimatedLayerHandle<VectorLayer<VectorSource>> {
42
50
  layer: VectorLayer<VectorSource>;
43
51
  source: VectorSource;
44
52
  start: () => void;
@@ -50,5 +58,5 @@ export interface PulsePointLayerHandle {
50
58
  export interface TwinkleItem extends PointData {
51
59
  className?: string;
52
60
  element?: HTMLElement | ((item: TwinkleItem) => HTMLElement);
53
- [key: string]: any;
61
+ [key: string]: unknown;
54
62
  }
@@ -18,6 +18,18 @@ export declare class MyOpenLayersError extends Error {
18
18
  readonly context?: any;
19
19
  constructor(message: string, type: ErrorType, context?: any);
20
20
  }
21
+ /**
22
+ * P2-2:具体错误子类,方便调用方用 instanceof 判分支。
23
+ */
24
+ export declare class LayerNotFoundError extends MyOpenLayersError {
25
+ constructor(layerName: string, context?: any);
26
+ }
27
+ export declare class InvalidGeoJSONError extends MyOpenLayersError {
28
+ constructor(reason: string, context?: any);
29
+ }
30
+ export declare class ProjectionError extends MyOpenLayersError {
31
+ constructor(reason: string, context?: any);
32
+ }
21
33
  /**
22
34
  * 错误处理工具类
23
35
  */
@@ -30,6 +30,27 @@ export class MyOpenLayersError extends Error {
30
30
  }
31
31
  }
32
32
  }
33
+ /**
34
+ * P2-2:具体错误子类,方便调用方用 instanceof 判分支。
35
+ */
36
+ export class LayerNotFoundError extends MyOpenLayersError {
37
+ constructor(layerName, context) {
38
+ super(`Layer '${layerName}' not found. 请检查 layerName 拼写、图层是否已被 remove,或在 fitView / removeLayer 调用前先 await *ByUrl。`, ErrorType.LAYER_ERROR, { layerName, ...context });
39
+ this.name = 'LayerNotFoundError';
40
+ }
41
+ }
42
+ export class InvalidGeoJSONError extends MyOpenLayersError {
43
+ constructor(reason, context) {
44
+ super(`Invalid GeoJSON data: ${reason}. 请检查数据是否为标准 GeoJSON FeatureCollection / Feature / Geometry。`, ErrorType.DATA_ERROR, context);
45
+ this.name = 'InvalidGeoJSONError';
46
+ }
47
+ }
48
+ export class ProjectionError extends MyOpenLayersError {
49
+ constructor(reason, context) {
50
+ super(`Projection error: ${reason}. 请确认 EPSG code 已通过 ProjectionManager.register 或 options.projection 注册。`, ErrorType.MAP_ERROR, context);
51
+ this.name = 'ProjectionError';
52
+ }
53
+ }
33
54
  /**
34
55
  * 错误处理工具类
35
56
  */