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
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import Feature from "ol/Feature";
|
|
2
|
+
import { Point as OlPoint } from "ol/geom";
|
|
3
|
+
import VectorLayer from "ol/layer/Vector";
|
|
4
|
+
import VectorSource from "ol/source/Vector";
|
|
5
|
+
import { Circle as CircleStyle, Fill, Icon, Stroke, Style, Text } from "ol/style";
|
|
6
|
+
import ProjectionUtils from "../../utils/ProjectionUtils";
|
|
7
|
+
import ValidationUtils from "../../utils/ValidationUtils";
|
|
8
|
+
import { ConfigManager } from "../map";
|
|
9
|
+
/**
|
|
10
|
+
* 高性能闪烁点图层构建器。
|
|
11
|
+
*/
|
|
12
|
+
export default class PointPulseLayer {
|
|
13
|
+
static createTextStyle(options, text) {
|
|
14
|
+
const defaultTextOptions = ConfigManager.DEFAULT_POINT_TEXT_OPTIONS;
|
|
15
|
+
return new Text({
|
|
16
|
+
text,
|
|
17
|
+
font: options.textFont || defaultTextOptions.textFont,
|
|
18
|
+
fill: new Fill({ color: options.textFillColor || defaultTextOptions.textFillColor }),
|
|
19
|
+
stroke: new Stroke({
|
|
20
|
+
color: options.textStrokeColor || defaultTextOptions.textStrokeColor,
|
|
21
|
+
width: options.textStrokeWidth || defaultTextOptions.textStrokeWidth
|
|
22
|
+
}),
|
|
23
|
+
offsetY: options.textOffsetY || defaultTextOptions.textOffsetY
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
static withOpacity(color, opacity) {
|
|
27
|
+
const safeOpacity = Math.max(0, Math.min(1, opacity));
|
|
28
|
+
const rgbaMatch = color.match(/^rgba?\(([^)]+)\)$/i);
|
|
29
|
+
if (rgbaMatch) {
|
|
30
|
+
const parts = rgbaMatch[1].split(',').map(part => part.trim());
|
|
31
|
+
if (parts.length >= 3) {
|
|
32
|
+
const alpha = parts.length >= 4 ? Number(parts[3]) : 1;
|
|
33
|
+
const nextAlpha = Number.isFinite(alpha) ? alpha * safeOpacity : safeOpacity;
|
|
34
|
+
return `rgba(${parts[0]}, ${parts[1]}, ${parts[2]}, ${nextAlpha})`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (/^#[0-9a-f]{6}$/i.test(color)) {
|
|
38
|
+
const red = parseInt(color.slice(1, 3), 16);
|
|
39
|
+
const green = parseInt(color.slice(3, 5), 16);
|
|
40
|
+
const blue = parseInt(color.slice(5, 7), 16);
|
|
41
|
+
return `rgba(${red}, ${green}, ${blue}, ${safeOpacity})`;
|
|
42
|
+
}
|
|
43
|
+
return color;
|
|
44
|
+
}
|
|
45
|
+
static createFeatures(pointData, options) {
|
|
46
|
+
const pointFeatureList = [];
|
|
47
|
+
pointData.forEach(item => {
|
|
48
|
+
if (!ValidationUtils.validateCoordinates(item)) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
pointFeatureList.push(new Feature({
|
|
52
|
+
rawData: item,
|
|
53
|
+
type: options.layerName,
|
|
54
|
+
layerName: options.layerName,
|
|
55
|
+
geometry: new OlPoint(ProjectionUtils.transformCoordinate([item.lgtd, item.lttd], options))
|
|
56
|
+
}));
|
|
57
|
+
});
|
|
58
|
+
return pointFeatureList;
|
|
59
|
+
}
|
|
60
|
+
static create(map, pointData, options) {
|
|
61
|
+
const pulseOptions = {
|
|
62
|
+
enabled: options.pulse?.enabled ?? true,
|
|
63
|
+
duration: options.pulse?.duration ?? 2400,
|
|
64
|
+
radius: options.pulse?.radius ?? [8, 26],
|
|
65
|
+
colorMap: options.pulse?.colorMap ?? {
|
|
66
|
+
0: 'rgba(255, 48, 54, 0.45)',
|
|
67
|
+
1: 'rgba(255, 136, 0, 0.45)',
|
|
68
|
+
2: 'rgba(253, 216, 46, 0.38)',
|
|
69
|
+
3: 'rgba(6, 183, 253, 0.3)'
|
|
70
|
+
},
|
|
71
|
+
strokeColorMap: options.pulse?.strokeColorMap,
|
|
72
|
+
strokeWidth: options.pulse?.strokeWidth ?? 0,
|
|
73
|
+
frameCount: Math.max(1, options.pulse?.frameCount ?? 24)
|
|
74
|
+
};
|
|
75
|
+
const levelKey = options.levelKey ?? 'lev';
|
|
76
|
+
const pulseStyleCache = new globalThis.Map();
|
|
77
|
+
const staticStyleCache = new globalThis.Map();
|
|
78
|
+
let frameIndex = 0;
|
|
79
|
+
let renderedFrameIndex = -1;
|
|
80
|
+
let rafId = null;
|
|
81
|
+
let running = false;
|
|
82
|
+
const source = new VectorSource({
|
|
83
|
+
features: PointPulseLayer.createFeatures(pointData, options)
|
|
84
|
+
});
|
|
85
|
+
const createStyles = (feature) => {
|
|
86
|
+
const rawData = feature.get('rawData');
|
|
87
|
+
const level = rawData?.[levelKey] ?? 'default';
|
|
88
|
+
const progress = frameIndex / Math.max(1, pulseOptions.frameCount - 1);
|
|
89
|
+
const [minRadius, maxRadius] = pulseOptions.radius;
|
|
90
|
+
const radius = minRadius + (maxRadius - minRadius) * progress;
|
|
91
|
+
const opacity = 1 - progress;
|
|
92
|
+
const fillColor = pulseOptions.colorMap[level] ?? pulseOptions.colorMap.default ?? 'rgba(6, 183, 253, 0.32)';
|
|
93
|
+
const strokeColor = pulseOptions.strokeColorMap?.[level] ?? pulseOptions.strokeColorMap?.default;
|
|
94
|
+
const styles = [];
|
|
95
|
+
if (pulseOptions.enabled) {
|
|
96
|
+
const pulseCacheKey = `${level}_${frameIndex}`;
|
|
97
|
+
let pulseStyle = pulseStyleCache.get(pulseCacheKey);
|
|
98
|
+
if (!pulseStyle) {
|
|
99
|
+
pulseStyle = new Style({
|
|
100
|
+
zIndex: 0,
|
|
101
|
+
image: new CircleStyle({
|
|
102
|
+
radius,
|
|
103
|
+
fill: new Fill({ color: PointPulseLayer.withOpacity(fillColor, opacity) }),
|
|
104
|
+
stroke: strokeColor && pulseOptions.strokeWidth > 0
|
|
105
|
+
? new Stroke({ color: PointPulseLayer.withOpacity(strokeColor, opacity), width: pulseOptions.strokeWidth })
|
|
106
|
+
: undefined
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
pulseStyleCache.set(pulseCacheKey, pulseStyle);
|
|
110
|
+
}
|
|
111
|
+
styles.push(pulseStyle);
|
|
112
|
+
}
|
|
113
|
+
const text = options.textVisible && options.textKey && rawData ? rawData[options.textKey] ?? '' : '';
|
|
114
|
+
const staticCacheKey = [
|
|
115
|
+
options.img ?? options.icon?.src ?? '',
|
|
116
|
+
options.scale ?? options.icon?.scale ?? ConfigManager.DEFAULT_POINT_ICON_SCALE,
|
|
117
|
+
options.iconColor ?? options.icon?.color ?? '',
|
|
118
|
+
text
|
|
119
|
+
].join('|');
|
|
120
|
+
let pointStyle = staticStyleCache.get(staticCacheKey);
|
|
121
|
+
if (pointStyle) {
|
|
122
|
+
styles.push(pointStyle);
|
|
123
|
+
return styles;
|
|
124
|
+
}
|
|
125
|
+
const pointStyleOptions = {};
|
|
126
|
+
const iconSrc = options.img ?? options.icon?.src;
|
|
127
|
+
if (iconSrc) {
|
|
128
|
+
pointStyleOptions.image = new Icon({
|
|
129
|
+
src: iconSrc,
|
|
130
|
+
scale: options.scale ?? options.icon?.scale ?? ConfigManager.DEFAULT_POINT_ICON_SCALE,
|
|
131
|
+
color: options.iconColor ?? options.icon?.color
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else if (options.icon) {
|
|
135
|
+
pointStyleOptions.image = new CircleStyle({
|
|
136
|
+
radius: options.icon.radius ?? 5,
|
|
137
|
+
fill: new Fill({ color: options.icon.fillColor ?? '#06b7fd' }),
|
|
138
|
+
stroke: new Stroke({
|
|
139
|
+
color: options.icon.strokeColor ?? '#ffffff',
|
|
140
|
+
width: options.icon.strokeWidth ?? 2
|
|
141
|
+
})
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (text) {
|
|
145
|
+
pointStyleOptions.text = PointPulseLayer.createTextStyle(options, text);
|
|
146
|
+
}
|
|
147
|
+
if (pointStyleOptions.image || pointStyleOptions.text) {
|
|
148
|
+
pointStyle = new Style(pointStyleOptions);
|
|
149
|
+
pointStyle.setZIndex(1);
|
|
150
|
+
staticStyleCache.set(staticCacheKey, pointStyle);
|
|
151
|
+
styles.push(pointStyle);
|
|
152
|
+
}
|
|
153
|
+
return styles;
|
|
154
|
+
};
|
|
155
|
+
const layer = new VectorLayer({
|
|
156
|
+
layerName: options.layerName,
|
|
157
|
+
source,
|
|
158
|
+
style: createStyles,
|
|
159
|
+
zIndex: options.zIndex || ConfigManager.DEFAULT_POINT_OPTIONS.zIndex,
|
|
160
|
+
});
|
|
161
|
+
layer.setVisible(options.visible === undefined ? true : options.visible);
|
|
162
|
+
map.addLayer(layer);
|
|
163
|
+
const tick = () => {
|
|
164
|
+
if (!running)
|
|
165
|
+
return;
|
|
166
|
+
const duration = Math.max(1, pulseOptions.duration);
|
|
167
|
+
const now = typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
168
|
+
const nextFrameIndex = Math.floor(((now % duration) / duration) * pulseOptions.frameCount);
|
|
169
|
+
if (nextFrameIndex !== renderedFrameIndex) {
|
|
170
|
+
frameIndex = nextFrameIndex;
|
|
171
|
+
renderedFrameIndex = nextFrameIndex;
|
|
172
|
+
layer.changed();
|
|
173
|
+
}
|
|
174
|
+
rafId = requestAnimationFrame(tick);
|
|
175
|
+
};
|
|
176
|
+
const stop = () => {
|
|
177
|
+
running = false;
|
|
178
|
+
if (rafId !== null) {
|
|
179
|
+
cancelAnimationFrame(rafId);
|
|
180
|
+
rafId = null;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const start = () => {
|
|
184
|
+
if (running || !pulseOptions.enabled)
|
|
185
|
+
return;
|
|
186
|
+
running = true;
|
|
187
|
+
tick();
|
|
188
|
+
};
|
|
189
|
+
start();
|
|
190
|
+
return {
|
|
191
|
+
layer,
|
|
192
|
+
source,
|
|
193
|
+
start,
|
|
194
|
+
stop,
|
|
195
|
+
setVisible: (visible) => layer.setVisible(visible),
|
|
196
|
+
updateData: (nextData) => {
|
|
197
|
+
source.clear();
|
|
198
|
+
source.addFeatures(PointPulseLayer.createFeatures(nextData, options));
|
|
199
|
+
},
|
|
200
|
+
remove: () => {
|
|
201
|
+
stop();
|
|
202
|
+
source.clear();
|
|
203
|
+
map.removeLayer(layer);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import Map from "ol/Map";
|
|
2
2
|
import VectorLayer from "ol/layer/Vector";
|
|
3
3
|
import VectorSource from "ol/source/Vector";
|
|
4
|
-
import { Image as ImageLayer
|
|
5
|
-
import { Geometry } from "ol/geom";
|
|
4
|
+
import { Image as ImageLayer } from "ol/layer";
|
|
6
5
|
import Feature from "ol/Feature";
|
|
7
|
-
import { PolygonOptions, MapJSONData, PointData, HeatMapOptions, ImageLayerData, MaskLayerOptions, FeatureColorUpdateOptions } from '
|
|
6
|
+
import { PolygonOptions, MapJSONData, PointData, HeatMapOptions, ImageLayerData, MaskLayerOptions, FeatureColorUpdateOptions } from '../../types';
|
|
8
7
|
/**
|
|
9
8
|
* Polygon 类用于处理地图上的面要素操作
|
|
10
9
|
* 包括添加多边形、边框、图片图层、热力图等功能
|
|
@@ -49,19 +48,6 @@ export default class Polygon {
|
|
|
49
48
|
* @throws 当数据格式无效时抛出错误
|
|
50
49
|
*/
|
|
51
50
|
addPolygonByUrl(url: string, options?: PolygonOptions): VectorLayer<VectorSource>;
|
|
52
|
-
/**
|
|
53
|
-
* 创建样式或样式函数
|
|
54
|
-
* @param options 配置选项
|
|
55
|
-
* @returns 样式或样式函数
|
|
56
|
-
*/
|
|
57
|
-
private createStyle;
|
|
58
|
-
/**
|
|
59
|
-
* 获取要素文本
|
|
60
|
-
* @param feature 要素对象
|
|
61
|
-
* @param options 配置选项
|
|
62
|
-
* @returns 文本内容
|
|
63
|
-
*/
|
|
64
|
-
private getFeatureText;
|
|
65
51
|
/**
|
|
66
52
|
* 适应图层视图
|
|
67
53
|
* @param layer 图层对象
|
|
@@ -77,13 +63,6 @@ export default class Polygon {
|
|
|
77
63
|
updateFeatureColor(layerName: string, colorObj?: {
|
|
78
64
|
[propName: string]: string;
|
|
79
65
|
}, options?: FeatureColorUpdateOptions): void;
|
|
80
|
-
/**
|
|
81
|
-
* 更新单个要素的颜色
|
|
82
|
-
* @param feature 要素对象
|
|
83
|
-
* @param colorObj 颜色映射对象
|
|
84
|
-
* @param options 配置选项
|
|
85
|
-
*/
|
|
86
|
-
private updateSingleFeatureColor;
|
|
87
66
|
/**
|
|
88
67
|
* 设置外围蒙版图层
|
|
89
68
|
*
|
|
@@ -99,7 +78,7 @@ export default class Polygon {
|
|
|
99
78
|
strokeWidth?: number;
|
|
100
79
|
strokeColor?: string;
|
|
101
80
|
zIndex?: number;
|
|
102
|
-
}): VectorLayer<VectorSource<Feature<Geometry>>, Feature<Geometry>>;
|
|
81
|
+
}): VectorLayer<VectorSource<Feature<import("ol/geom").Geometry>>, Feature<import("ol/geom").Geometry>>;
|
|
103
82
|
/**
|
|
104
83
|
* 添加图片图层
|
|
105
84
|
* @param imageData 图片数据,包含url和extent
|
|
@@ -108,37 +87,12 @@ export default class Polygon {
|
|
|
108
87
|
* @throws 当数据格式无效时抛出错误
|
|
109
88
|
*/
|
|
110
89
|
addImageLayer(imageData: ImageLayerData, options?: PolygonOptions): ImageLayer<any>;
|
|
111
|
-
/**
|
|
112
|
-
* 尝试更新现有图层
|
|
113
|
-
* @private
|
|
114
|
-
*/
|
|
115
|
-
private tryUpdateExistingImageLayer;
|
|
116
|
-
/**
|
|
117
|
-
* 创建新的图像图层
|
|
118
|
-
* @private
|
|
119
|
-
*/
|
|
120
|
-
private createNewImageLayer;
|
|
121
|
-
/**
|
|
122
|
-
* 更新图层属性
|
|
123
|
-
* @private
|
|
124
|
-
*/
|
|
125
|
-
private updateImageLayerProperties;
|
|
126
|
-
/**
|
|
127
|
-
* 配置图层基本属性
|
|
128
|
-
* @private
|
|
129
|
-
*/
|
|
130
|
-
private configureImageLayer;
|
|
131
|
-
/**
|
|
132
|
-
* 添加图层到地图并应用裁剪
|
|
133
|
-
* @private
|
|
134
|
-
*/
|
|
135
|
-
private addImageLayerToMap;
|
|
136
90
|
/**
|
|
137
91
|
* 添加热力图图层
|
|
138
92
|
* @param pointData 点数据数组
|
|
139
93
|
* @param options 热力图配置
|
|
140
94
|
*/
|
|
141
|
-
addHeatmap(pointData: PointData[], options?: HeatMapOptions): Heatmap<Feature<Geometry>, VectorSource<Feature<Geometry>>>;
|
|
95
|
+
addHeatmap(pointData: PointData[], options?: HeatMapOptions): import("ol/layer").Heatmap<Feature<import("ol/geom").Geometry>, VectorSource<Feature<import("ol/geom").Geometry>>>;
|
|
142
96
|
/**
|
|
143
97
|
* 添加遮罩图层
|
|
144
98
|
* @param data GeoJSON格式的遮罩数据
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import VectorLayer from "ol/layer/Vector";
|
|
3
|
+
import VectorSource from "ol/source/Vector";
|
|
4
|
+
import GeoJSON from "ol/format/GeoJSON";
|
|
5
|
+
import { ErrorHandler } from '../../utils/ErrorHandler';
|
|
6
|
+
import ProjectionUtils from '../../utils/ProjectionUtils';
|
|
7
|
+
import ValidationUtils from '../../utils/ValidationUtils';
|
|
8
|
+
import { ConfigManager, MapTools } from "../map";
|
|
9
|
+
import PolygonHeatmapLayer from './PolygonHeatmapLayer';
|
|
10
|
+
import PolygonImageLayer from './PolygonImageLayer';
|
|
11
|
+
import PolygonMaskLayer from './PolygonMaskLayer';
|
|
12
|
+
import PolygonStyleFactory from './PolygonStyleFactory';
|
|
13
|
+
/**
|
|
14
|
+
* Polygon 类用于处理地图上的面要素操作
|
|
15
|
+
* 包括添加多边形、边框、图片图层、热力图等功能
|
|
16
|
+
*/
|
|
17
|
+
export default class Polygon {
|
|
18
|
+
/**
|
|
19
|
+
* 构造函数
|
|
20
|
+
* @param map OpenLayers 地图实例
|
|
21
|
+
*/
|
|
22
|
+
constructor(map) {
|
|
23
|
+
if (!map) {
|
|
24
|
+
throw new Error('Map instance is required');
|
|
25
|
+
}
|
|
26
|
+
this.map = map;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 添加地图边框图层
|
|
30
|
+
* @param data 图层数据,必须是有效的 GeoJSON 格式
|
|
31
|
+
* @param options 图层配置选项
|
|
32
|
+
* @returns 创建的图层实例
|
|
33
|
+
* @throws 当数据格式无效时抛出错误
|
|
34
|
+
*/
|
|
35
|
+
addBorderPolygon(data, options) {
|
|
36
|
+
ValidationUtils.validateGeoJSONData(data);
|
|
37
|
+
const mergedOptions = {
|
|
38
|
+
fillColor: 'rgba(255, 255, 255, 0)',
|
|
39
|
+
...options
|
|
40
|
+
};
|
|
41
|
+
const layer = this.addPolygon(data, mergedOptions);
|
|
42
|
+
if (mergedOptions.mask) {
|
|
43
|
+
this.setOutLayer(data);
|
|
44
|
+
}
|
|
45
|
+
return layer;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 从URL添加地图边框图层
|
|
49
|
+
* @param url 数据URL
|
|
50
|
+
* @param options 图层配置选项
|
|
51
|
+
* @returns 创建的图层实例
|
|
52
|
+
* @throws 当数据格式无效时抛出错误
|
|
53
|
+
*/
|
|
54
|
+
addBorderPolygonByUrl(url, options) {
|
|
55
|
+
const mergedOptions = {
|
|
56
|
+
layerName: 'border',
|
|
57
|
+
fillColor: 'rgba(255, 255, 255, 0)',
|
|
58
|
+
...options
|
|
59
|
+
};
|
|
60
|
+
const layer = this.addPolygonByUrl(url, mergedOptions);
|
|
61
|
+
return layer;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 添加多边形图层
|
|
65
|
+
* @param dataJSON GeoJSON 数据
|
|
66
|
+
* @param options 图层配置选项
|
|
67
|
+
* @returns 创建的矢量图层
|
|
68
|
+
* @throws 当数据格式无效时抛出错误
|
|
69
|
+
*/
|
|
70
|
+
addPolygon(dataJSON, options) {
|
|
71
|
+
ValidationUtils.validateGeoJSONData(dataJSON);
|
|
72
|
+
const mergedOptions = {
|
|
73
|
+
...ConfigManager.DEFAULT_POLYGON_OPTIONS,
|
|
74
|
+
...options
|
|
75
|
+
};
|
|
76
|
+
// 如果指定了图层名称,先移除同名图层
|
|
77
|
+
if (mergedOptions.layerName) {
|
|
78
|
+
new MapTools(this.map).removeLayer(mergedOptions.layerName);
|
|
79
|
+
}
|
|
80
|
+
const format = new GeoJSON();
|
|
81
|
+
// 优化:在解析 Feature 时直接注入 layerName,利用解析过程的遍历,避免解析后的二次循环
|
|
82
|
+
if (mergedOptions.layerName) {
|
|
83
|
+
const originalReadFeatureFromObject = format.readFeatureFromObject;
|
|
84
|
+
format.readFeatureFromObject = function (object, options) {
|
|
85
|
+
const feature = originalReadFeatureFromObject.call(this, object, options);
|
|
86
|
+
feature.set('layerName', mergedOptions.layerName, true); // true 表示静默设置,不触发事件
|
|
87
|
+
return feature;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
let features;
|
|
91
|
+
try {
|
|
92
|
+
features = format.readFeatures(dataJSON, ProjectionUtils.getGeoJSONReadOptions(mergedOptions));
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
throw new Error(`Failed to parse GeoJSON data: ${error}`);
|
|
96
|
+
}
|
|
97
|
+
const layer = new VectorLayer({
|
|
98
|
+
properties: {
|
|
99
|
+
name: mergedOptions.layerName,
|
|
100
|
+
layerName: mergedOptions.layerName
|
|
101
|
+
},
|
|
102
|
+
source: new VectorSource({ features }),
|
|
103
|
+
style: PolygonStyleFactory.createStyle(mergedOptions),
|
|
104
|
+
zIndex: mergedOptions.zIndex
|
|
105
|
+
});
|
|
106
|
+
layer.setVisible(mergedOptions.visible);
|
|
107
|
+
this.map.addLayer(layer);
|
|
108
|
+
// 如果需要适应视图
|
|
109
|
+
if (mergedOptions.fitView) {
|
|
110
|
+
this.fitViewToLayer(layer);
|
|
111
|
+
}
|
|
112
|
+
return layer;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 从URL添加多边形图层
|
|
116
|
+
* @param url 数据URL
|
|
117
|
+
* @param options 图层配置选项
|
|
118
|
+
* @returns 创建的矢量图层
|
|
119
|
+
* @throws 当数据格式无效时抛出错误
|
|
120
|
+
*/
|
|
121
|
+
addPolygonByUrl(url, options) {
|
|
122
|
+
const mergedOptions = {
|
|
123
|
+
...ConfigManager.DEFAULT_POLYGON_OPTIONS,
|
|
124
|
+
...options
|
|
125
|
+
};
|
|
126
|
+
// 如果指定了图层名称,先移除同名图层
|
|
127
|
+
if (mergedOptions.layerName) {
|
|
128
|
+
new MapTools(this.map).removeLayer(mergedOptions.layerName);
|
|
129
|
+
}
|
|
130
|
+
const format = new GeoJSON(ProjectionUtils.getGeoJSONReadOptions(mergedOptions));
|
|
131
|
+
// 优化:在解析 Feature 时直接注入 layerName,利用解析过程的遍历,避免解析后的二次循环
|
|
132
|
+
if (mergedOptions.layerName) {
|
|
133
|
+
const originalReadFeatureFromObject = format.readFeatureFromObject;
|
|
134
|
+
format.readFeatureFromObject = function (object, options) {
|
|
135
|
+
const feature = originalReadFeatureFromObject.call(this, object, options);
|
|
136
|
+
feature.set('layerName', mergedOptions.layerName, true); // true 表示静默设置,不触发事件
|
|
137
|
+
return feature;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const source = new VectorSource({
|
|
141
|
+
url,
|
|
142
|
+
format
|
|
143
|
+
});
|
|
144
|
+
const layer = new VectorLayer({
|
|
145
|
+
properties: {
|
|
146
|
+
name: mergedOptions.layerName,
|
|
147
|
+
layerName: mergedOptions.layerName
|
|
148
|
+
},
|
|
149
|
+
source,
|
|
150
|
+
style: PolygonStyleFactory.createStyle(mergedOptions),
|
|
151
|
+
zIndex: mergedOptions.zIndex
|
|
152
|
+
});
|
|
153
|
+
layer.setVisible(mergedOptions.visible);
|
|
154
|
+
this.map.addLayer(layer);
|
|
155
|
+
// 如果需要适应视图
|
|
156
|
+
if (mergedOptions.fitView) {
|
|
157
|
+
source.once('featuresloadend', () => {
|
|
158
|
+
this.fitViewToLayer(layer);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return layer;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* 适应图层视图
|
|
165
|
+
* @param layer 图层对象
|
|
166
|
+
*/
|
|
167
|
+
fitViewToLayer(layer) {
|
|
168
|
+
const extent = layer.getSource()?.getExtent();
|
|
169
|
+
if (extent) {
|
|
170
|
+
this.map.getView().fit(extent, { duration: 500 });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 根据数据数组更新某个面颜色
|
|
175
|
+
* @param layerName 图层名称
|
|
176
|
+
* @param colorObj 颜色映射对象,键为要素属性值,值为颜色字符串
|
|
177
|
+
* @param options 配置项
|
|
178
|
+
* @throws 当图层不存在时抛出错误
|
|
179
|
+
*/
|
|
180
|
+
updateFeatureColor(layerName, colorObj, options) {
|
|
181
|
+
ValidationUtils.validateLayerName(layerName);
|
|
182
|
+
const layers = MapTools.getLayerByLayerName(this.map, layerName);
|
|
183
|
+
if (layers.length === 0) {
|
|
184
|
+
throw new Error(`Layer with name '${layerName}' not found`);
|
|
185
|
+
}
|
|
186
|
+
const layer = layers[0];
|
|
187
|
+
if (!(layer instanceof VectorLayer)) {
|
|
188
|
+
throw new Error(`Layer '${layerName}' is not a vector layer`);
|
|
189
|
+
}
|
|
190
|
+
const mergedOptions = {
|
|
191
|
+
textFont: '14px Calibri,sans-serif',
|
|
192
|
+
textFillColor: '#FFF',
|
|
193
|
+
textStrokeWidth: 2,
|
|
194
|
+
...options
|
|
195
|
+
};
|
|
196
|
+
const features = layer.getSource()?.getFeatures();
|
|
197
|
+
if (!features) {
|
|
198
|
+
ErrorHandler.getInstance().warn(`No features found in layer '${layerName}'`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
features.forEach((feature) => {
|
|
202
|
+
PolygonStyleFactory.updateSingleFeatureColor(feature, colorObj, mergedOptions);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* 设置外围蒙版图层
|
|
207
|
+
*
|
|
208
|
+
* 详细文档参考 https_blog.csdn.net/?url=https%3A%2F%2Fblog.csdn.net%2Fu012413551%2Farticle%2Fdetails%2F122739501
|
|
209
|
+
*
|
|
210
|
+
* @param data
|
|
211
|
+
* @param options
|
|
212
|
+
*/
|
|
213
|
+
setOutLayer(data, options) {
|
|
214
|
+
return PolygonMaskLayer.setOutLayer(this.map, data, options);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* 添加图片图层
|
|
218
|
+
* @param imageData 图片数据,包含url和extent
|
|
219
|
+
* @param options 配置项
|
|
220
|
+
* @returns 创建的图片图层
|
|
221
|
+
* @throws 当数据格式无效时抛出错误
|
|
222
|
+
*/
|
|
223
|
+
addImageLayer(imageData, options) {
|
|
224
|
+
return PolygonImageLayer.addImageLayer(this.map, imageData, options);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* 添加热力图图层
|
|
228
|
+
* @param pointData 点数据数组
|
|
229
|
+
* @param options 热力图配置
|
|
230
|
+
*/
|
|
231
|
+
addHeatmap(pointData, options) {
|
|
232
|
+
return PolygonHeatmapLayer.addHeatmap(this.map, pointData, options);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* 添加遮罩图层
|
|
236
|
+
* @param data GeoJSON格式的遮罩数据
|
|
237
|
+
* @param options 配置项
|
|
238
|
+
* @returns 创建的遮罩图层
|
|
239
|
+
* @throws 当数据格式无效时抛出错误
|
|
240
|
+
*/
|
|
241
|
+
addMaskLayer(data, options) {
|
|
242
|
+
return PolygonMaskLayer.addMaskLayer(this.map, data, options);
|
|
243
|
+
}
|
|
244
|
+
removePolygonLayer(layerName) {
|
|
245
|
+
new MapTools(this.map).removeLayer(layerName);
|
|
246
|
+
this[layerName] = null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Feature from "ol/Feature";
|
|
2
|
+
import Map from "ol/Map";
|
|
3
|
+
import { Heatmap } from "ol/layer";
|
|
4
|
+
import VectorSource from "ol/source/Vector";
|
|
5
|
+
import type { HeatMapOptions, PointData } from "../../types";
|
|
6
|
+
/**
|
|
7
|
+
* 面热力图辅助类。
|
|
8
|
+
*/
|
|
9
|
+
export default class PolygonHeatmapLayer {
|
|
10
|
+
static addHeatmap(map: Map, pointData: PointData[], options?: HeatMapOptions): Heatmap<Feature<import("ol/geom").Geometry>, VectorSource<Feature<import("ol/geom").Geometry>>>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import Feature from "ol/Feature";
|
|
2
|
+
import { Point } from "ol/geom";
|
|
3
|
+
import { Heatmap } from "ol/layer";
|
|
4
|
+
import VectorSource from "ol/source/Vector";
|
|
5
|
+
import { ConfigManager, MapTools } from "../map";
|
|
6
|
+
/**
|
|
7
|
+
* 面热力图辅助类。
|
|
8
|
+
*/
|
|
9
|
+
export default class PolygonHeatmapLayer {
|
|
10
|
+
static addHeatmap(map, pointData, options) {
|
|
11
|
+
if (options?.layerName) {
|
|
12
|
+
new MapTools(map).removeLayer(options.layerName);
|
|
13
|
+
}
|
|
14
|
+
const mergedOptions = {
|
|
15
|
+
...ConfigManager.DEFAULT_HEATMAP_OPTIONS,
|
|
16
|
+
...options
|
|
17
|
+
};
|
|
18
|
+
const heatmapLayer = new Heatmap({
|
|
19
|
+
source: new VectorSource(),
|
|
20
|
+
weight: (feature) => feature.get('weight'),
|
|
21
|
+
blur: mergedOptions.blur ?? ConfigManager.DEFAULT_HEATMAP_OPTIONS.blur,
|
|
22
|
+
radius: mergedOptions.radius ?? ConfigManager.DEFAULT_HEATMAP_OPTIONS.radius,
|
|
23
|
+
zIndex: mergedOptions.zIndex ?? ConfigManager.DEFAULT_HEATMAP_OPTIONS.zIndex,
|
|
24
|
+
opacity: mergedOptions.opacity ?? ConfigManager.DEFAULT_HEATMAP_OPTIONS.opacity
|
|
25
|
+
});
|
|
26
|
+
if (mergedOptions.layerName) {
|
|
27
|
+
heatmapLayer.set('layerName', mergedOptions.layerName);
|
|
28
|
+
}
|
|
29
|
+
map.addLayer(heatmapLayer);
|
|
30
|
+
const valueKey = mergedOptions.valueKey || ConfigManager.DEFAULT_HEATMAP_VALUE_KEY;
|
|
31
|
+
const max = Math.max(...pointData.map(item => item[valueKey]));
|
|
32
|
+
pointData.forEach(item => {
|
|
33
|
+
heatmapLayer.getSource().addFeature(new Feature({
|
|
34
|
+
geometry: new Point([item.lgtd, item.lttd]),
|
|
35
|
+
weight: item[valueKey] / max
|
|
36
|
+
}));
|
|
37
|
+
});
|
|
38
|
+
return heatmapLayer;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Map from "ol/Map";
|
|
2
|
+
import { Image as ImageLayer } from "ol/layer";
|
|
3
|
+
import type { ImageLayerData, PolygonOptions } from "../../types";
|
|
4
|
+
/**
|
|
5
|
+
* 面图片图层辅助类。
|
|
6
|
+
*/
|
|
7
|
+
export default class PolygonImageLayer {
|
|
8
|
+
static addImageLayer(map: Map, imageData: ImageLayerData, options?: PolygonOptions): ImageLayer<any>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import ImageStatic from "ol/source/ImageStatic";
|
|
2
|
+
import { Image as ImageLayer } from "ol/layer";
|
|
3
|
+
import ValidationUtils from "../../utils/ValidationUtils";
|
|
4
|
+
import { ConfigManager, MapTools } from "../map";
|
|
5
|
+
/**
|
|
6
|
+
* 面图片图层辅助类。
|
|
7
|
+
*/
|
|
8
|
+
export default class PolygonImageLayer {
|
|
9
|
+
static addImageLayer(map, imageData, options) {
|
|
10
|
+
const allowEmptyImg = !imageData.img && !!options?.layerName;
|
|
11
|
+
ValidationUtils.validateImageData(imageData, allowEmptyImg);
|
|
12
|
+
const mergedOptions = {
|
|
13
|
+
...ConfigManager.DEFAULT_IMAGE_OPTIONS,
|
|
14
|
+
...options
|
|
15
|
+
};
|
|
16
|
+
if (mergedOptions.layerName) {
|
|
17
|
+
const existingLayers = MapTools.getLayerByLayerName(map, mergedOptions.layerName);
|
|
18
|
+
if (existingLayers.length > 0) {
|
|
19
|
+
const existingLayer = existingLayers[0];
|
|
20
|
+
if (!imageData.extent) {
|
|
21
|
+
existingLayer.setSource(undefined);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const url = imageData.img || existingLayer.getSource()?.getUrl() || '';
|
|
25
|
+
existingLayer.setSource(new ImageStatic({
|
|
26
|
+
url,
|
|
27
|
+
imageExtent: imageData.extent
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
if (mergedOptions.opacity !== undefined)
|
|
31
|
+
existingLayer.setOpacity(mergedOptions.opacity);
|
|
32
|
+
if (mergedOptions.visible !== undefined)
|
|
33
|
+
existingLayer.setVisible(mergedOptions.visible);
|
|
34
|
+
if (mergedOptions.zIndex !== undefined)
|
|
35
|
+
existingLayer.setZIndex(mergedOptions.zIndex);
|
|
36
|
+
return existingLayer;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const source = imageData.extent
|
|
40
|
+
? new ImageStatic({
|
|
41
|
+
url: imageData.img || '',
|
|
42
|
+
imageExtent: imageData.extent
|
|
43
|
+
})
|
|
44
|
+
: undefined;
|
|
45
|
+
const imageLayer = new ImageLayer({
|
|
46
|
+
source,
|
|
47
|
+
opacity: mergedOptions.opacity,
|
|
48
|
+
visible: mergedOptions.visible
|
|
49
|
+
});
|
|
50
|
+
imageLayer.set('name', mergedOptions.layerName);
|
|
51
|
+
imageLayer.set('layerName', mergedOptions.layerName);
|
|
52
|
+
imageLayer.setZIndex(mergedOptions.zIndex);
|
|
53
|
+
if (mergedOptions.mapClip && mergedOptions.mapClipData) {
|
|
54
|
+
const clippedLayer = MapTools.setMapClip(imageLayer, mergedOptions.mapClipData);
|
|
55
|
+
map.addLayer(clippedLayer);
|
|
56
|
+
return clippedLayer;
|
|
57
|
+
}
|
|
58
|
+
map.addLayer(imageLayer);
|
|
59
|
+
return imageLayer;
|
|
60
|
+
}
|
|
61
|
+
}
|