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.
- package/CHANGELOG.md +251 -251
- package/LICENSE +21 -21
- package/MyOl.d.ts +9 -9
- package/MyOl.js +17 -14
- package/README.md +174 -148
- package/core/line/Line.d.ts +40 -0
- package/core/line/Line.js +144 -0
- package/core/line/LineFeatureFactory.d.ts +17 -0
- package/core/line/LineFeatureFactory.js +75 -0
- package/core/line/LineFlowAnimator.d.ts +53 -0
- package/core/line/LineFlowAnimator.js +297 -0
- package/core/line/LineStyleFactory.d.ts +43 -0
- package/core/line/LineStyleFactory.js +135 -0
- package/core/{RiverLayerManager.d.ts → line/RiverLayerManager.d.ts} +2 -2
- package/core/{RiverLayerManager.js → line/RiverLayerManager.js} +3 -5
- package/core/line/index.d.ts +6 -0
- package/core/line/index.js +5 -0
- package/core/{ConfigManager.d.ts → map/ConfigManager.d.ts} +25 -1
- package/core/{ConfigManager.js → map/ConfigManager.js} +22 -1
- package/core/{EventManager.d.ts → map/EventManager.d.ts} +1 -1
- package/core/{EventManager.js → map/EventManager.js} +2 -2
- package/core/{MapBaseLayers.d.ts → map/MapBaseLayers.d.ts} +1 -1
- package/core/{MapBaseLayers.js → map/MapBaseLayers.js} +3 -3
- package/core/{MapTools.d.ts → map/MapTools.d.ts} +5 -2
- package/core/{MapTools.js → map/MapTools.js} +11 -5
- package/core/{MeasureHandler.d.ts → map/MeasureHandler.d.ts} +1 -1
- package/core/{MeasureHandler.js → map/MeasureHandler.js} +41 -41
- package/core/map/index.d.ts +5 -0
- package/core/map/index.js +5 -0
- package/core/{Point.d.ts → point/Point.d.ts} +6 -14
- package/core/point/Point.js +272 -0
- package/core/point/PointClusterLayer.d.ts +10 -0
- package/core/point/PointClusterLayer.js +52 -0
- package/core/point/PointOverlay.d.ts +13 -0
- package/core/point/PointOverlay.js +57 -0
- package/core/point/PointPulseLayer.d.ts +13 -0
- package/core/point/PointPulseLayer.js +207 -0
- package/core/point/index.d.ts +4 -0
- package/core/point/index.js +4 -0
- package/core/{Polygon.d.ts → polygon/Polygon.d.ts} +4 -50
- package/core/polygon/Polygon.js +248 -0
- package/core/polygon/PolygonHeatmapLayer.d.ts +11 -0
- package/core/polygon/PolygonHeatmapLayer.js +40 -0
- package/core/polygon/PolygonImageLayer.d.ts +9 -0
- package/core/polygon/PolygonImageLayer.js +61 -0
- package/core/polygon/PolygonMaskLayer.d.ts +20 -0
- package/core/polygon/PolygonMaskLayer.js +107 -0
- package/core/polygon/PolygonStyleFactory.d.ts +12 -0
- package/core/polygon/PolygonStyleFactory.js +100 -0
- package/core/polygon/index.d.ts +5 -0
- package/core/polygon/index.js +5 -0
- package/core/{SelectHandler.d.ts → select/SelectHandler.d.ts} +2 -3
- package/core/{SelectHandler.js → select/SelectHandler.js} +4 -4
- package/core/select/index.d.ts +1 -0
- package/core/select/index.js +1 -0
- package/core/{VueTemplatePoint.d.ts → vue-template-point/VueTemplatePoint.d.ts} +1 -1
- package/core/{VueTemplatePoint.js → vue-template-point/VueTemplatePoint.js} +4 -4
- package/core/vue-template-point/index.d.ts +1 -0
- package/core/vue-template-point/index.js +1 -0
- package/docs/.vitepress/config.mts +57 -57
- package/docs/ConfigManager.md +71 -71
- package/docs/ErrorHandler.md +106 -106
- package/docs/EventManager.md +142 -142
- package/docs/Line.md +215 -187
- package/docs/MapBaseLayers.md +198 -198
- package/docs/MapTools.md +172 -172
- package/docs/MeasureHandler.md +87 -87
- package/docs/MyOl.md +247 -247
- package/docs/Point.md +136 -136
- package/docs/Polygon.md +241 -241
- package/docs/RiverLayerManager.md +187 -187
- package/docs/SelectHandler.md +147 -147
- package/docs/ValidationUtils.md +83 -83
- package/docs/VueTemplatePoint.md +214 -214
- package/docs/index.md +73 -73
- package/index.d.ts +10 -15
- package/index.js +7 -13
- package/package.json +11 -1
- package/types/base.d.ts +47 -0
- package/types/base.js +1 -0
- package/types/common.d.ts +59 -0
- package/types/common.js +1 -0
- package/types/index.d.ts +9 -0
- package/types/index.js +1 -0
- package/types/line.d.ts +41 -0
- package/types/line.js +1 -0
- package/types/map.d.ts +77 -0
- package/types/map.js +1 -0
- package/types/point.d.ts +54 -0
- package/types/point.js +1 -0
- package/types/polygon.d.ts +8 -0
- package/types/polygon.js +1 -0
- package/types/select.d.ts +25 -0
- package/types/select.js +1 -0
- package/types/vue-template-point.d.ts +54 -0
- package/{types.js → types/vue-template-point.js} +0 -3
- package/utils/ProjectionUtils.d.ts +28 -0
- package/utils/ProjectionUtils.js +34 -0
- package/utils/ValidationUtils.d.ts +33 -86
- package/utils/ValidationUtils.js +60 -165
- package/core/Line.d.ts +0 -49
- package/core/Line.js +0 -114
- package/core/Point.js +0 -560
- package/core/Polygon.js +0 -646
- package/docs/.vitepress/dist/404.html +0 -22
- package/docs/.vitepress/dist/ConfigManager.html +0 -46
- package/docs/.vitepress/dist/ErrorHandler.html +0 -52
- package/docs/.vitepress/dist/EventManager.html +0 -58
- package/docs/.vitepress/dist/Line.html +0 -92
- package/docs/.vitepress/dist/MapBaseLayers.html +0 -52
- package/docs/.vitepress/dist/MapTools.html +0 -81
- package/docs/.vitepress/dist/MeasureHandler.html +0 -32
- package/docs/.vitepress/dist/MyOl.html +0 -62
- package/docs/.vitepress/dist/Point.html +0 -81
- package/docs/.vitepress/dist/Polygon.html +0 -102
- package/docs/.vitepress/dist/RiverLayerManager.html +0 -66
- package/docs/.vitepress/dist/SelectHandler.html +0 -46
- package/docs/.vitepress/dist/ValidationUtils.html +0 -47
- package/docs/.vitepress/dist/VueTemplatePoint.html +0 -112
- package/docs/.vitepress/dist/assets/ConfigManager.md.BOMdGTaa.js +0 -22
- package/docs/.vitepress/dist/assets/ConfigManager.md.BOMdGTaa.lean.js +0 -1
- package/docs/.vitepress/dist/assets/ErrorHandler.md.yUiuJ9w9.js +0 -28
- package/docs/.vitepress/dist/assets/ErrorHandler.md.yUiuJ9w9.lean.js +0 -1
- package/docs/.vitepress/dist/assets/EventManager.md.BhCUVy1f.js +0 -34
- package/docs/.vitepress/dist/assets/EventManager.md.BhCUVy1f.lean.js +0 -1
- package/docs/.vitepress/dist/assets/Line.md.BAQOzmSt.js +0 -68
- package/docs/.vitepress/dist/assets/Line.md.BAQOzmSt.lean.js +0 -1
- package/docs/.vitepress/dist/assets/MapBaseLayers.md.Bw0L_m0b.js +0 -28
- package/docs/.vitepress/dist/assets/MapBaseLayers.md.Bw0L_m0b.lean.js +0 -1
- package/docs/.vitepress/dist/assets/MapTools.md.DaYgiDPe.js +0 -57
- package/docs/.vitepress/dist/assets/MapTools.md.DaYgiDPe.lean.js +0 -1
- package/docs/.vitepress/dist/assets/MeasureHandler.md.7Sf4ymRv.js +0 -8
- package/docs/.vitepress/dist/assets/MeasureHandler.md.7Sf4ymRv.lean.js +0 -1
- package/docs/.vitepress/dist/assets/MyOl.md.D-14Gzjy.js +0 -38
- package/docs/.vitepress/dist/assets/MyOl.md.D-14Gzjy.lean.js +0 -1
- package/docs/.vitepress/dist/assets/Point.md.Bi9juuuv.js +0 -57
- package/docs/.vitepress/dist/assets/Point.md.Bi9juuuv.lean.js +0 -1
- package/docs/.vitepress/dist/assets/Polygon.md.-JIqEvzD.js +0 -78
- package/docs/.vitepress/dist/assets/Polygon.md.-JIqEvzD.lean.js +0 -1
- package/docs/.vitepress/dist/assets/RiverLayerManager.md.CfUu2RxH.js +0 -42
- package/docs/.vitepress/dist/assets/RiverLayerManager.md.CfUu2RxH.lean.js +0 -1
- package/docs/.vitepress/dist/assets/SelectHandler.md.COR4ez_p.js +0 -22
- package/docs/.vitepress/dist/assets/SelectHandler.md.COR4ez_p.lean.js +0 -1
- package/docs/.vitepress/dist/assets/ValidationUtils.md.ReTVWa73.js +0 -23
- package/docs/.vitepress/dist/assets/ValidationUtils.md.ReTVWa73.lean.js +0 -1
- package/docs/.vitepress/dist/assets/VueTemplatePoint.md.CtxSb5Pm.js +0 -88
- package/docs/.vitepress/dist/assets/VueTemplatePoint.md.CtxSb5Pm.lean.js +0 -1
- package/docs/.vitepress/dist/assets/app.YvjVuxaB.js +0 -1
- package/docs/.vitepress/dist/assets/chunks/framework.C_W0ODpn.js +0 -18
- package/docs/.vitepress/dist/assets/chunks/theme.Bf87fILP.js +0 -1
- package/docs/.vitepress/dist/assets/index.md.BJz6tHSr.js +0 -26
- package/docs/.vitepress/dist/assets/index.md.BJz6tHSr.lean.js +0 -1
- package/docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/docs/.vitepress/dist/assets/style.C2pAQzDq.css +0 -1
- package/docs/.vitepress/dist/hashmap.json +0 -1
- package/docs/.vitepress/dist/index.html +0 -50
- package/docs/.vitepress/dist/vp-icons.css +0 -1
- 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
|
-
}
|