my-openlayer 2.4.12 → 2.5.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 (171) hide show
  1. package/CHANGELOG.md +251 -251
  2. package/LICENSE +21 -21
  3. package/MyOl.d.ts +9 -9
  4. package/MyOl.js +17 -14
  5. package/README.md +174 -148
  6. package/core/line/Line.d.ts +40 -0
  7. package/core/line/Line.js +144 -0
  8. package/core/line/LineFeatureFactory.d.ts +17 -0
  9. package/core/line/LineFeatureFactory.js +75 -0
  10. package/core/line/LineFlowAnimator.d.ts +53 -0
  11. package/core/line/LineFlowAnimator.js +297 -0
  12. package/core/line/LineStyleFactory.d.ts +43 -0
  13. package/core/line/LineStyleFactory.js +135 -0
  14. package/core/{RiverLayerManager.d.ts → line/RiverLayerManager.d.ts} +2 -2
  15. package/core/{RiverLayerManager.js → line/RiverLayerManager.js} +3 -5
  16. package/core/line/index.d.ts +6 -0
  17. package/core/line/index.js +5 -0
  18. package/core/{ConfigManager.d.ts → map/ConfigManager.d.ts} +25 -1
  19. package/core/{ConfigManager.js → map/ConfigManager.js} +22 -1
  20. package/core/{EventManager.d.ts → map/EventManager.d.ts} +1 -1
  21. package/core/{EventManager.js → map/EventManager.js} +2 -2
  22. package/core/{MapBaseLayers.d.ts → map/MapBaseLayers.d.ts} +1 -1
  23. package/core/{MapBaseLayers.js → map/MapBaseLayers.js} +3 -3
  24. package/core/{MapTools.d.ts → map/MapTools.d.ts} +5 -2
  25. package/core/{MapTools.js → map/MapTools.js} +11 -5
  26. package/core/{MeasureHandler.d.ts → map/MeasureHandler.d.ts} +1 -1
  27. package/core/{MeasureHandler.js → map/MeasureHandler.js} +41 -41
  28. package/core/map/index.d.ts +5 -0
  29. package/core/map/index.js +5 -0
  30. package/core/{Point.d.ts → point/Point.d.ts} +6 -14
  31. package/core/point/Point.js +272 -0
  32. package/core/point/PointClusterLayer.d.ts +10 -0
  33. package/core/point/PointClusterLayer.js +52 -0
  34. package/core/point/PointOverlay.d.ts +13 -0
  35. package/core/point/PointOverlay.js +57 -0
  36. package/core/point/PointPulseLayer.d.ts +13 -0
  37. package/core/point/PointPulseLayer.js +207 -0
  38. package/core/point/index.d.ts +4 -0
  39. package/core/point/index.js +4 -0
  40. package/core/{Polygon.d.ts → polygon/Polygon.d.ts} +4 -50
  41. package/core/polygon/Polygon.js +248 -0
  42. package/core/polygon/PolygonHeatmapLayer.d.ts +11 -0
  43. package/core/polygon/PolygonHeatmapLayer.js +40 -0
  44. package/core/polygon/PolygonImageLayer.d.ts +9 -0
  45. package/core/polygon/PolygonImageLayer.js +61 -0
  46. package/core/polygon/PolygonMaskLayer.d.ts +20 -0
  47. package/core/polygon/PolygonMaskLayer.js +107 -0
  48. package/core/polygon/PolygonStyleFactory.d.ts +12 -0
  49. package/core/polygon/PolygonStyleFactory.js +100 -0
  50. package/core/polygon/index.d.ts +5 -0
  51. package/core/polygon/index.js +5 -0
  52. package/core/{SelectHandler.d.ts → select/SelectHandler.d.ts} +2 -3
  53. package/core/{SelectHandler.js → select/SelectHandler.js} +4 -4
  54. package/core/select/index.d.ts +1 -0
  55. package/core/select/index.js +1 -0
  56. package/core/{VueTemplatePoint.d.ts → vue-template-point/VueTemplatePoint.d.ts} +1 -1
  57. package/core/{VueTemplatePoint.js → vue-template-point/VueTemplatePoint.js} +4 -4
  58. package/core/vue-template-point/index.d.ts +1 -0
  59. package/core/vue-template-point/index.js +1 -0
  60. package/docs/.vitepress/config.mts +57 -57
  61. package/docs/ConfigManager.md +71 -71
  62. package/docs/ErrorHandler.md +106 -106
  63. package/docs/EventManager.md +142 -142
  64. package/docs/Line.md +215 -187
  65. package/docs/MapBaseLayers.md +198 -198
  66. package/docs/MapTools.md +172 -172
  67. package/docs/MeasureHandler.md +87 -87
  68. package/docs/MyOl.md +247 -247
  69. package/docs/Point.md +136 -136
  70. package/docs/Polygon.md +241 -241
  71. package/docs/RiverLayerManager.md +187 -187
  72. package/docs/SelectHandler.md +147 -147
  73. package/docs/ValidationUtils.md +83 -83
  74. package/docs/VueTemplatePoint.md +214 -214
  75. package/docs/index.md +73 -73
  76. package/index.d.ts +10 -15
  77. package/index.js +7 -13
  78. package/package.json +11 -1
  79. package/types/base.d.ts +47 -0
  80. package/types/base.js +1 -0
  81. package/types/common.d.ts +59 -0
  82. package/types/common.js +1 -0
  83. package/types/index.d.ts +9 -0
  84. package/types/index.js +1 -0
  85. package/types/line.d.ts +41 -0
  86. package/types/line.js +1 -0
  87. package/types/map.d.ts +77 -0
  88. package/types/map.js +1 -0
  89. package/types/point.d.ts +54 -0
  90. package/types/point.js +1 -0
  91. package/types/polygon.d.ts +8 -0
  92. package/types/polygon.js +1 -0
  93. package/types/select.d.ts +25 -0
  94. package/types/select.js +1 -0
  95. package/types/vue-template-point.d.ts +54 -0
  96. package/{types.js → types/vue-template-point.js} +0 -3
  97. package/utils/ProjectionUtils.d.ts +28 -0
  98. package/utils/ProjectionUtils.js +34 -0
  99. package/utils/ValidationUtils.d.ts +33 -86
  100. package/utils/ValidationUtils.js +60 -165
  101. package/core/Line.d.ts +0 -49
  102. package/core/Line.js +0 -114
  103. package/core/Point.js +0 -560
  104. package/core/Polygon.js +0 -646
  105. package/docs/.vitepress/dist/404.html +0 -22
  106. package/docs/.vitepress/dist/ConfigManager.html +0 -46
  107. package/docs/.vitepress/dist/ErrorHandler.html +0 -52
  108. package/docs/.vitepress/dist/EventManager.html +0 -58
  109. package/docs/.vitepress/dist/Line.html +0 -92
  110. package/docs/.vitepress/dist/MapBaseLayers.html +0 -52
  111. package/docs/.vitepress/dist/MapTools.html +0 -81
  112. package/docs/.vitepress/dist/MeasureHandler.html +0 -32
  113. package/docs/.vitepress/dist/MyOl.html +0 -62
  114. package/docs/.vitepress/dist/Point.html +0 -81
  115. package/docs/.vitepress/dist/Polygon.html +0 -102
  116. package/docs/.vitepress/dist/RiverLayerManager.html +0 -66
  117. package/docs/.vitepress/dist/SelectHandler.html +0 -46
  118. package/docs/.vitepress/dist/ValidationUtils.html +0 -47
  119. package/docs/.vitepress/dist/VueTemplatePoint.html +0 -112
  120. package/docs/.vitepress/dist/assets/ConfigManager.md.BOMdGTaa.js +0 -22
  121. package/docs/.vitepress/dist/assets/ConfigManager.md.BOMdGTaa.lean.js +0 -1
  122. package/docs/.vitepress/dist/assets/ErrorHandler.md.yUiuJ9w9.js +0 -28
  123. package/docs/.vitepress/dist/assets/ErrorHandler.md.yUiuJ9w9.lean.js +0 -1
  124. package/docs/.vitepress/dist/assets/EventManager.md.BhCUVy1f.js +0 -34
  125. package/docs/.vitepress/dist/assets/EventManager.md.BhCUVy1f.lean.js +0 -1
  126. package/docs/.vitepress/dist/assets/Line.md.BAQOzmSt.js +0 -68
  127. package/docs/.vitepress/dist/assets/Line.md.BAQOzmSt.lean.js +0 -1
  128. package/docs/.vitepress/dist/assets/MapBaseLayers.md.Bw0L_m0b.js +0 -28
  129. package/docs/.vitepress/dist/assets/MapBaseLayers.md.Bw0L_m0b.lean.js +0 -1
  130. package/docs/.vitepress/dist/assets/MapTools.md.DaYgiDPe.js +0 -57
  131. package/docs/.vitepress/dist/assets/MapTools.md.DaYgiDPe.lean.js +0 -1
  132. package/docs/.vitepress/dist/assets/MeasureHandler.md.7Sf4ymRv.js +0 -8
  133. package/docs/.vitepress/dist/assets/MeasureHandler.md.7Sf4ymRv.lean.js +0 -1
  134. package/docs/.vitepress/dist/assets/MyOl.md.D-14Gzjy.js +0 -38
  135. package/docs/.vitepress/dist/assets/MyOl.md.D-14Gzjy.lean.js +0 -1
  136. package/docs/.vitepress/dist/assets/Point.md.Bi9juuuv.js +0 -57
  137. package/docs/.vitepress/dist/assets/Point.md.Bi9juuuv.lean.js +0 -1
  138. package/docs/.vitepress/dist/assets/Polygon.md.-JIqEvzD.js +0 -78
  139. package/docs/.vitepress/dist/assets/Polygon.md.-JIqEvzD.lean.js +0 -1
  140. package/docs/.vitepress/dist/assets/RiverLayerManager.md.CfUu2RxH.js +0 -42
  141. package/docs/.vitepress/dist/assets/RiverLayerManager.md.CfUu2RxH.lean.js +0 -1
  142. package/docs/.vitepress/dist/assets/SelectHandler.md.COR4ez_p.js +0 -22
  143. package/docs/.vitepress/dist/assets/SelectHandler.md.COR4ez_p.lean.js +0 -1
  144. package/docs/.vitepress/dist/assets/ValidationUtils.md.ReTVWa73.js +0 -23
  145. package/docs/.vitepress/dist/assets/ValidationUtils.md.ReTVWa73.lean.js +0 -1
  146. package/docs/.vitepress/dist/assets/VueTemplatePoint.md.CtxSb5Pm.js +0 -88
  147. package/docs/.vitepress/dist/assets/VueTemplatePoint.md.CtxSb5Pm.lean.js +0 -1
  148. package/docs/.vitepress/dist/assets/app.YvjVuxaB.js +0 -1
  149. package/docs/.vitepress/dist/assets/chunks/framework.C_W0ODpn.js +0 -18
  150. package/docs/.vitepress/dist/assets/chunks/theme.Bf87fILP.js +0 -1
  151. package/docs/.vitepress/dist/assets/index.md.BJz6tHSr.js +0 -26
  152. package/docs/.vitepress/dist/assets/index.md.BJz6tHSr.lean.js +0 -1
  153. package/docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
  154. package/docs/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
  155. package/docs/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
  156. package/docs/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
  157. package/docs/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
  158. package/docs/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
  159. package/docs/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
  160. package/docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
  161. package/docs/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
  162. package/docs/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
  163. package/docs/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
  164. package/docs/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
  165. package/docs/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
  166. package/docs/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
  167. package/docs/.vitepress/dist/assets/style.C2pAQzDq.css +0 -1
  168. package/docs/.vitepress/dist/hashmap.json +0 -1
  169. package/docs/.vitepress/dist/index.html +0 -50
  170. package/docs/.vitepress/dist/vp-icons.css +0 -1
  171. package/types.d.ts +0 -431
package/core/Line.js DELETED
@@ -1,114 +0,0 @@
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 { ConfigManager } from "./ConfigManager";
9
- /**
10
- * 线要素管理类
11
- * 用于在地图上添加和管理线要素
12
- *
13
- * @example
14
- * ```typescript
15
- * const lineManager = new Line(map);
16
- * const layer = lineManager.addLine(geoJsonData, {
17
- * type: 'road',
18
- * strokeColor: '#ff0000',
19
- * strokeWidth: 3
20
- * });
21
- * ```
22
- */
23
- export default class Line {
24
- mergeDefaultOptions(options) {
25
- const layerName = options?.layerName || ConfigManager.DEFAULT_LINE_OPTIONS.layerName;
26
- const defaultOptions = {
27
- ...ConfigManager.DEFAULT_LINE_OPTIONS,
28
- layerName
29
- };
30
- const mergedOptions = { ...defaultOptions, ...options };
31
- return { ...mergedOptions, layerName };
32
- }
33
- createStyleFunction(mergedOptions) {
34
- return (feature) => {
35
- if (feature instanceof Feature) {
36
- feature.set('type', mergedOptions.type);
37
- feature.set('layerName', mergedOptions.layerName);
38
- }
39
- if (mergedOptions.style) {
40
- if (typeof mergedOptions.style === 'function') {
41
- return mergedOptions.style(feature);
42
- }
43
- else {
44
- return mergedOptions.style;
45
- }
46
- }
47
- return new Style({
48
- stroke: new Stroke({
49
- color: mergedOptions.strokeColor,
50
- width: mergedOptions.strokeWidth,
51
- lineDash: mergedOptions.lineDash,
52
- lineDashOffset: mergedOptions.lineDashOffset
53
- })
54
- });
55
- };
56
- }
57
- createLayer(source, mergedOptions) {
58
- const layer = new VectorLayer({
59
- properties: {
60
- name: mergedOptions.layerName,
61
- layerName: mergedOptions.layerName
62
- },
63
- source,
64
- style: this.createStyleFunction(mergedOptions),
65
- zIndex: mergedOptions.zIndex
66
- });
67
- layer.setVisible(mergedOptions.visible);
68
- this.map.addLayer(layer);
69
- return layer;
70
- }
71
- /**
72
- * 构造函数
73
- * @param map OpenLayers地图实例
74
- */
75
- constructor(map) {
76
- ValidationUtils.validateMapInstance(map);
77
- this.map = map;
78
- }
79
- /**
80
- * 添加线要素
81
- * @param data GeoJSON格式的线数据
82
- * @param options 配置项
83
- * @returns 创建的矢量图层
84
- */
85
- addLine(data, options) {
86
- ValidationUtils.validateGeoJSONData(data);
87
- const mergedOptions = this.mergeDefaultOptions(options);
88
- const features = new GeoJSON().readFeatures(data, options?.projectionOptOptions);
89
- const source = new VectorSource({ features });
90
- return this.createLayer(source, mergedOptions);
91
- }
92
- /**
93
- * 从URL添加线要素
94
- * @param url 数据URL
95
- * @param options 配置项
96
- * @returns 创建的矢量图层
97
- */
98
- addLineByUrl(url, options = {}) {
99
- const mergedOptions = this.mergeDefaultOptions(options);
100
- const source = new VectorSource({
101
- url,
102
- format: new GeoJSON(options.projectionOptOptions)
103
- });
104
- return this.createLayer(source, mergedOptions);
105
- }
106
- /**
107
- * 移除线图层
108
- * @param layerName 图层名称
109
- */
110
- removeLineLayer(layerName) {
111
- ValidationUtils.validateLayerName(layerName);
112
- MapTools.removeLayer(this.map, layerName);
113
- }
114
- }
package/core/Point.js DELETED
@@ -1,560 +0,0 @@
1
- "use strict";
2
- import Overlay from 'ol/Overlay';
3
- import Feature from "ol/Feature";
4
- import { Point as olPoint } from "ol/geom";
5
- import { Text, Style, Fill, Stroke, Icon, Circle as CircleStyle } from "ol/style";
6
- import VectorLayer from "ol/layer/Vector";
7
- import VectorSource from "ol/source/Vector";
8
- import { Cluster } from 'ol/source';
9
- import VueTemplatePoint from './VueTemplatePoint';
10
- import { ValidationUtils } from '../utils/ValidationUtils';
11
- import MapTools from './MapTools';
12
- import { ConfigManager } from "./ConfigManager";
13
- export default class Point {
14
- constructor(map) {
15
- this.map = map;
16
- }
17
- /**
18
- * 创建文本样式
19
- * @private
20
- * @param options 选项
21
- * @param text 文本内容
22
- * @returns 文本样式
23
- */
24
- createTextStyle(options, text) {
25
- const defaultTextOptions = ConfigManager.DEFAULT_POINT_TEXT_OPTIONS;
26
- return new Text({
27
- text: text,
28
- font: options.textFont || defaultTextOptions.textFont,
29
- fill: new Fill({
30
- color: options.textFillColor || defaultTextOptions.textFillColor
31
- }),
32
- stroke: new Stroke({
33
- color: options.textStrokeColor || defaultTextOptions.textStrokeColor,
34
- width: options.textStrokeWidth || defaultTextOptions.textStrokeWidth
35
- }),
36
- offsetY: options.textOffsetY || defaultTextOptions.textOffsetY,
37
- });
38
- }
39
- /**
40
- * 创建图标样式
41
- * @private
42
- * @param options 选项
43
- * @returns 图标样式
44
- */
45
- createIconStyle(options) {
46
- const iconOptions = {
47
- src: options.img,
48
- scale: options.scale ?? ConfigManager.DEFAULT_POINT_ICON_SCALE,
49
- };
50
- if (options.iconColor) {
51
- iconOptions.color = options.iconColor;
52
- }
53
- return new Icon(iconOptions);
54
- }
55
- /**
56
- * 创建点样式
57
- * @private
58
- * @param options 选项
59
- * @param item 数据项
60
- * @returns 样式对象
61
- */
62
- createPointStyle(options, item) {
63
- const style = {};
64
- if (options.textKey && item) {
65
- style.text = this.createTextStyle(options, item[options.textKey]);
66
- }
67
- if (options.img) {
68
- style.image = this.createIconStyle(options);
69
- }
70
- return new Style(style);
71
- }
72
- /**
73
- * 创建集群样式
74
- * @private
75
- * @param options 选项
76
- * @param name 名称
77
- * @returns 样式对象
78
- */
79
- createClusterStyle(options, name) {
80
- const style = {};
81
- if (options.textKey) {
82
- style.text = this.createTextStyle(options, name);
83
- }
84
- if (options.img) {
85
- style.image = this.createIconStyle(options);
86
- }
87
- return new Style(style);
88
- }
89
- /**
90
- * 将颜色透明度按动画进度衰减。
91
- * @private
92
- */
93
- withOpacity(color, opacity) {
94
- const safeOpacity = Math.max(0, Math.min(1, opacity));
95
- const rgbaMatch = color.match(/^rgba?\(([^)]+)\)$/i);
96
- if (rgbaMatch) {
97
- const parts = rgbaMatch[1].split(',').map(part => part.trim());
98
- if (parts.length >= 3) {
99
- const alpha = parts.length >= 4 ? Number(parts[3]) : 1;
100
- const nextAlpha = Number.isFinite(alpha) ? alpha * safeOpacity : safeOpacity;
101
- return `rgba(${parts[0]}, ${parts[1]}, ${parts[2]}, ${nextAlpha})`;
102
- }
103
- }
104
- if (/^#[0-9a-f]{6}$/i.test(color)) {
105
- const red = parseInt(color.slice(1, 3), 16);
106
- const green = parseInt(color.slice(3, 5), 16);
107
- const blue = parseInt(color.slice(5, 7), 16);
108
- return `rgba(${red}, ${green}, ${blue}, ${safeOpacity})`;
109
- }
110
- return color;
111
- }
112
- /**
113
- * 创建高性能闪烁点要素。
114
- * @private
115
- */
116
- createPulsePointFeatures(pointData, options) {
117
- const pointFeatureList = [];
118
- pointData.forEach(item => {
119
- if (!ValidationUtils.validateCoordinates(item)) {
120
- return;
121
- }
122
- pointFeatureList.push(new Feature({
123
- rawData: item,
124
- type: options.layerName,
125
- layerName: options.layerName,
126
- geometry: new olPoint([item.lgtd, item.lttd])
127
- }));
128
- });
129
- return pointFeatureList;
130
- }
131
- /**
132
- * 配置图层属性
133
- * @private
134
- * @param layer 图层
135
- * @param options 选项
136
- */
137
- configureLayer(layer, options) {
138
- layer.setVisible(options.visible === undefined ? true : options.visible);
139
- this.map.addLayer(layer);
140
- }
141
- /**
142
- *
143
- * @param pointData
144
- * @param type
145
- * @param options {
146
- * textKey: String 数据中的文本的key
147
- * img: String 图标
148
- * }
149
- */
150
- addPoint(pointData, options) {
151
- if (!ValidationUtils.validatePointData(pointData)) {
152
- return null;
153
- }
154
- const pointFeatureList = [];
155
- pointData.forEach((item) => {
156
- if (!ValidationUtils.validateCoordinates(item)) {
157
- return;
158
- }
159
- const pointFeature = new Feature({
160
- rawData: item,
161
- type: options.layerName,
162
- layerName: options.layerName,
163
- geometry: new olPoint([item.lgtd, item.lttd])
164
- });
165
- if (options.style) {
166
- if (typeof options.style === 'function') {
167
- pointFeature.setStyle(options.style(pointFeature));
168
- }
169
- else {
170
- pointFeature.setStyle(options.style);
171
- }
172
- }
173
- else {
174
- pointFeature.setStyle(this.createPointStyle(options, item));
175
- }
176
- pointFeatureList.push(pointFeature);
177
- });
178
- const PointVectorLayer = new VectorLayer({
179
- layerName: options.layerName,
180
- source: new VectorSource({
181
- features: pointFeatureList
182
- }),
183
- zIndex: options.zIndex || ConfigManager.DEFAULT_POINT_OPTIONS.zIndex,
184
- });
185
- this.configureLayer(PointVectorLayer, options);
186
- return PointVectorLayer;
187
- }
188
- addClusterPoint(pointData, options) {
189
- if (!ValidationUtils.validatePointData(pointData)) {
190
- return null;
191
- }
192
- const pointFeatureList = [];
193
- pointData.forEach(item => {
194
- if (!ValidationUtils.validateCoordinates(item)) {
195
- return;
196
- }
197
- const pointFeature = new Feature({
198
- type: options.layerName,
199
- layerName: options.layerName,
200
- geometry: new olPoint([item.lgtd, item.lttd]),
201
- name: options.textKey ? item[options.textKey] : '',
202
- rawData: item,
203
- });
204
- pointFeatureList.push(pointFeature);
205
- });
206
- const source = new VectorSource({
207
- features: pointFeatureList,
208
- });
209
- const clusterSource = new Cluster({
210
- distance: options.distance || ConfigManager.DEFAULT_CLUSTER_OPTIONS.distance, // The distance for clustering in pixels
211
- minDistance: options.minDistance || ConfigManager.DEFAULT_CLUSTER_OPTIONS.minDistance,
212
- source: source,
213
- });
214
- const clusterLayer = new VectorLayer({
215
- layerName: options.layerName,
216
- source: clusterSource,
217
- style: (feature) => {
218
- if (options.style) {
219
- if (typeof options.style === 'function') {
220
- return options.style(feature);
221
- }
222
- else {
223
- return options.style;
224
- }
225
- }
226
- const name = feature.get('features')[0].get('name');
227
- return this.createClusterStyle(options, name);
228
- },
229
- zIndex: options.zIndex || ConfigManager.DEFAULT_CLUSTER_OPTIONS.zIndex,
230
- });
231
- this.configureLayer(clusterLayer, options);
232
- return clusterLayer;
233
- }
234
- /**
235
- * 添加高性能闪烁点图层。
236
- *
237
- * 与 addDomPoint 不同,该方法使用 VectorLayer 批量渲染点位,并通过单个
238
- * requestAnimationFrame 驱动闪烁圈,适合村庄预警等大量点位场景。
239
- */
240
- addPulsePointLayer(pointData, options) {
241
- if (!ValidationUtils.validatePointData(pointData)) {
242
- return null;
243
- }
244
- const pulseOptions = {
245
- enabled: options.pulse?.enabled ?? true,
246
- duration: options.pulse?.duration ?? 2400,
247
- radius: options.pulse?.radius ?? [8, 26],
248
- colorMap: options.pulse?.colorMap ?? {
249
- 0: 'rgba(255, 48, 54, 0.45)',
250
- 1: 'rgba(255, 136, 0, 0.45)',
251
- 2: 'rgba(253, 216, 46, 0.38)',
252
- 3: 'rgba(6, 183, 253, 0.3)'
253
- },
254
- strokeColorMap: options.pulse?.strokeColorMap,
255
- strokeWidth: options.pulse?.strokeWidth ?? 0,
256
- frameCount: Math.max(1, options.pulse?.frameCount ?? 24)
257
- };
258
- const levelKey = options.levelKey ?? 'lev';
259
- const pulseStyleCache = new globalThis.Map();
260
- const staticStyleCache = new globalThis.Map();
261
- let frameIndex = 0;
262
- let renderedFrameIndex = -1;
263
- let rafId = null;
264
- let running = false;
265
- const source = new VectorSource({
266
- features: this.createPulsePointFeatures(pointData, options)
267
- });
268
- const createStyles = (feature) => {
269
- const rawData = feature.get('rawData');
270
- const level = rawData?.[levelKey] ?? 'default';
271
- const progress = frameIndex / Math.max(1, pulseOptions.frameCount - 1);
272
- const [minRadius, maxRadius] = pulseOptions.radius;
273
- const radius = minRadius + (maxRadius - minRadius) * progress;
274
- const opacity = 1 - progress;
275
- const fillColor = pulseOptions.colorMap[level] ?? pulseOptions.colorMap.default ?? 'rgba(6, 183, 253, 0.32)';
276
- const strokeColor = pulseOptions.strokeColorMap?.[level] ?? pulseOptions.strokeColorMap?.default;
277
- const styles = [];
278
- if (pulseOptions.enabled) {
279
- const pulseCacheKey = `${level}_${frameIndex}`;
280
- let pulseStyle = pulseStyleCache.get(pulseCacheKey);
281
- if (!pulseStyle) {
282
- pulseStyle = new Style({
283
- zIndex: 0,
284
- image: new CircleStyle({
285
- radius,
286
- fill: new Fill({ color: this.withOpacity(fillColor, opacity) }),
287
- stroke: strokeColor && pulseOptions.strokeWidth > 0
288
- ? new Stroke({ color: this.withOpacity(strokeColor, opacity), width: pulseOptions.strokeWidth })
289
- : undefined
290
- })
291
- });
292
- pulseStyleCache.set(pulseCacheKey, pulseStyle);
293
- }
294
- styles.push(pulseStyle);
295
- }
296
- const text = options.textVisible && options.textKey && rawData ? rawData[options.textKey] ?? '' : '';
297
- const staticCacheKey = [
298
- options.img ?? options.icon?.src ?? '',
299
- options.scale ?? options.icon?.scale ?? ConfigManager.DEFAULT_POINT_ICON_SCALE,
300
- options.iconColor ?? options.icon?.color ?? '',
301
- text
302
- ].join('|');
303
- let pointStyle = staticStyleCache.get(staticCacheKey);
304
- if (pointStyle) {
305
- styles.push(pointStyle);
306
- return styles;
307
- }
308
- const pointStyleOptions = {};
309
- const iconSrc = options.img ?? options.icon?.src;
310
- if (iconSrc) {
311
- pointStyleOptions.image = new Icon({
312
- src: iconSrc,
313
- scale: options.scale ?? options.icon?.scale ?? ConfigManager.DEFAULT_POINT_ICON_SCALE,
314
- color: options.iconColor ?? options.icon?.color
315
- });
316
- }
317
- else if (options.icon) {
318
- pointStyleOptions.image = new CircleStyle({
319
- radius: options.icon.radius ?? 5,
320
- fill: new Fill({ color: options.icon.fillColor ?? '#06b7fd' }),
321
- stroke: new Stroke({
322
- color: options.icon.strokeColor ?? '#ffffff',
323
- width: options.icon.strokeWidth ?? 2
324
- })
325
- });
326
- }
327
- if (text) {
328
- pointStyleOptions.text = this.createTextStyle(options, text);
329
- }
330
- if (pointStyleOptions.image || pointStyleOptions.text) {
331
- pointStyle = new Style(pointStyleOptions);
332
- pointStyle.setZIndex(1);
333
- staticStyleCache.set(staticCacheKey, pointStyle);
334
- styles.push(pointStyle);
335
- }
336
- return styles;
337
- };
338
- const layer = new VectorLayer({
339
- layerName: options.layerName,
340
- source,
341
- style: createStyles,
342
- zIndex: options.zIndex || ConfigManager.DEFAULT_POINT_OPTIONS.zIndex,
343
- });
344
- layer.setVisible(options.visible === undefined ? true : options.visible);
345
- this.map.addLayer(layer);
346
- const tick = () => {
347
- if (!running)
348
- return;
349
- const duration = Math.max(1, pulseOptions.duration);
350
- const now = typeof performance !== 'undefined' ? performance.now() : Date.now();
351
- const nextFrameIndex = Math.floor(((now % duration) / duration) * pulseOptions.frameCount);
352
- if (nextFrameIndex !== renderedFrameIndex) {
353
- frameIndex = nextFrameIndex;
354
- renderedFrameIndex = nextFrameIndex;
355
- layer.changed();
356
- }
357
- rafId = requestAnimationFrame(tick);
358
- };
359
- const stop = () => {
360
- running = false;
361
- if (rafId !== null) {
362
- cancelAnimationFrame(rafId);
363
- rafId = null;
364
- }
365
- };
366
- const start = () => {
367
- if (running || !pulseOptions.enabled)
368
- return;
369
- running = true;
370
- tick();
371
- };
372
- start();
373
- return {
374
- layer,
375
- source,
376
- start,
377
- stop,
378
- setVisible: (visible) => {
379
- layer.setVisible(visible);
380
- },
381
- updateData: (nextData) => {
382
- source.clear();
383
- source.addFeatures(this.createPulsePointFeatures(nextData, options));
384
- },
385
- remove: () => {
386
- stop();
387
- source.clear();
388
- this.map.removeLayer(layer);
389
- }
390
- };
391
- }
392
- // // 在流域中心添加闪烁点位
393
- // addTwinkleLayerFromPolygon(twinkleList: any[], className: string, key: string, json: MapJSONData, options?: PolygonOptions) {
394
- // new MapTools(this.map).removeLayer('twinklePoint')
395
- // // 计算多边形的中心点坐标
396
- // const calculatePolygonCenter = (polygonCoordinates: any) => {
397
- // const polygon = turf.polygon(polygonCoordinates[0]);
398
- // const centroid = turf.centroid(polygon);
399
- // return centroid.geometry.coordinates;
400
- // };
401
- // const features: any[] = json.features
402
- // const vectorSource = new VectorSource({
403
- // format: new GeoJSON(),
404
- // });
405
- // twinkleList.forEach(item => {
406
- // const feature = features.find((ele: any) => {
407
- // return ele.properties.BASIN === item.idx
408
- // })
409
- // if (!feature) return
410
- // feature.properties.level = item.lev
411
- // const geojson = new GeoJSON();
412
- // const olFeature = geojson.readFeature(feature);
413
- // if (Array.isArray(olFeature)) {
414
- // vectorSource.addFeatures(olFeature);
415
- // } else {
416
- // vectorSource.addFeature(olFeature);
417
- // }
418
- // if (feature) {
419
- // const polygonCenter = calculatePolygonCenter(feature.geometry.coordinates)
420
- // item.lgtd = polygonCenter[0]
421
- // item.lttd = polygonCenter[1]
422
- // }
423
- // })
424
- // const basinLayer = new VectorLayer({
425
- // name: 'twinklePoint',
426
- // layerName: 'twinklePoint',
427
- // source: vectorSource,
428
- // style: function (feature: any) {
429
- // if (options?.style) {
430
- // if (typeof options.style === 'function') {
431
- // return options.style(feature);
432
- // } else {
433
- // return options.style;
434
- // }
435
- // }
436
- // return new Style({
437
- // stroke: new Stroke({
438
- // color: 'rgb(139,188,245)',
439
- // width: 3
440
- // }),
441
- // fill: new Fill({ color: 'rgba(255, 255, 255, 0)' }),
442
- // text: new Text({
443
- // text: feature.values_['BASIN'] || "",
444
- // font: '14px Calibri,sans-serif',
445
- // fill: new Fill({ color: '#FFF' }),
446
- // stroke: new Stroke({
447
- // color: '#409EFF', width: 2
448
- // }),
449
- // })
450
- // })
451
- // },
452
- // zIndex: 21
453
- // } as any)
454
- // this.map.addLayer(basinLayer)
455
- // this.addTwinkleLayer(twinkleList.map(item => ({...item, className: item[key]})), className, key)
456
- // }
457
- /**
458
- * 添加闪烁点
459
- * @param twinkleList 闪烁点数据
460
- * @param callback
461
- */
462
- addDomPoint(twinkleList, callback) {
463
- let anchors = [];
464
- twinkleList.forEach(twinkleItem => {
465
- let element;
466
- // 创建或获取DOM元素
467
- if (twinkleItem.element) {
468
- if (typeof twinkleItem.element === 'function') {
469
- element = twinkleItem.element(twinkleItem);
470
- }
471
- else {
472
- element = twinkleItem.element;
473
- }
474
- // 如果有className,追加到自定义元素
475
- if (twinkleItem.className) {
476
- const classes = twinkleItem.className.split(/\s+/).filter(Boolean);
477
- if (classes.length > 0) {
478
- element.classList.add(...classes);
479
- }
480
- }
481
- }
482
- else {
483
- element = document.createElement('div');
484
- element.className = twinkleItem.className || '';
485
- }
486
- // 添加点击事件
487
- if (callback) {
488
- element.addEventListener('click', () => {
489
- callback(twinkleItem);
490
- });
491
- }
492
- // 创建一个覆盖物
493
- const anchor = new Overlay({
494
- element: element,
495
- positioning: ConfigManager.DEFAULT_DOM_POINT_OVERLAY_OPTIONS.positioning,
496
- stopEvent: ConfigManager.DEFAULT_DOM_POINT_OVERLAY_OPTIONS.stopEvent // 允许事件穿透,但我们在上面阻止了冒泡
497
- });
498
- // 关键的一点,需要设置附加到地图上的位置
499
- anchor.setPosition([twinkleItem.lgtd, twinkleItem.lttd]);
500
- // 然后添加到map上
501
- this.map.addOverlay(anchor);
502
- anchors.push(anchor);
503
- });
504
- return {
505
- anchors,
506
- remove: () => {
507
- anchors.forEach(anchor => {
508
- const element = anchor.getElement();
509
- if (element) {
510
- element.remove();
511
- }
512
- this.map.removeOverlay(anchor);
513
- });
514
- anchors = [];
515
- },
516
- setVisible: (visible) => {
517
- anchors.forEach(anchor => {
518
- const element = anchor.getElement();
519
- if (element) {
520
- element.style.display = visible ? '' : 'none';
521
- }
522
- });
523
- }
524
- };
525
- }
526
- /**
527
- * 添加vue组件为点位
528
- * @param pointDataList 点位信息列表
529
- * @param template vue组件模板
530
- * @param Vue Vue实例
531
- * @returns 返回控制对象,包含显示、隐藏、移除方法
532
- * @throws 当参数无效时抛出错误
533
- */
534
- addVueTemplatePoint(pointDataList, template, options) {
535
- if (!pointDataList || !Array.isArray(pointDataList) || pointDataList.length === 0) {
536
- throw new Error('Valid point info list is required');
537
- }
538
- if (!template) {
539
- throw new Error('Vue template is required');
540
- }
541
- try {
542
- const vueTemplatePoint = new VueTemplatePoint(this.map);
543
- return vueTemplatePoint.addVueTemplatePoint(pointDataList, template, options);
544
- }
545
- catch (error) {
546
- throw new Error(`Failed to create Vue template points: ${error}`);
547
- }
548
- }
549
- /**
550
- * 地图定位
551
- * @deprecated 请使用 MapTools.locationAction 方法代替
552
- * @param lgtd 经度
553
- * @param lttd 纬度
554
- * @param zoom 缩放级别
555
- * @param duration 动画时长
556
- */
557
- locationAction(lgtd, lttd, zoom = 20, duration = 3000) {
558
- return new MapTools(this.map).locationAction(lgtd, lttd, zoom, duration);
559
- }
560
- }