ly-utils-lib 1.0.12 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1002 -685
- package/dist/array.cjs +237 -0
- package/dist/array.cjs.map +1 -0
- package/dist/array.d.cts +2 -0
- package/dist/array.d.ts +2 -0
- package/dist/array.js +150 -0
- package/dist/array.js.map +1 -0
- package/dist/crypto.cjs +193 -0
- package/dist/crypto.cjs.map +1 -0
- package/dist/crypto.d.cts +3 -0
- package/dist/crypto.d.ts +3 -0
- package/dist/crypto.js +144 -0
- package/dist/crypto.js.map +1 -0
- package/dist/date.cjs +563 -0
- package/dist/date.cjs.map +1 -0
- package/dist/date.d.cts +2 -0
- package/dist/date.d.ts +2 -0
- package/dist/date.js +451 -0
- package/dist/date.js.map +1 -0
- package/dist/excel.cjs +227 -0
- package/dist/excel.cjs.map +1 -0
- package/dist/excel.d.cts +2 -0
- package/dist/excel.d.ts +2 -0
- package/dist/excel.js +196 -0
- package/dist/excel.js.map +1 -0
- package/dist/index-B80SEVzM.d.cts +382 -0
- package/dist/index-B80SEVzM.d.ts +382 -0
- package/dist/index-Ba1rjTzj.d.cts +299 -0
- package/dist/index-Ba1rjTzj.d.ts +299 -0
- package/dist/index-Bg1ise7y.d.cts +253 -0
- package/dist/index-Bg1ise7y.d.ts +253 -0
- package/dist/index-BoqNpwNa.d.cts +203 -0
- package/dist/index-BoqNpwNa.d.ts +203 -0
- package/dist/index-C0qUnb9Y.d.cts +533 -0
- package/dist/index-C0qUnb9Y.d.ts +533 -0
- package/dist/index-Cq1GhjpY.d.cts +229 -0
- package/dist/index-Cq1GhjpY.d.ts +229 -0
- package/dist/index-Cy-mb5v_.d.cts +262 -0
- package/dist/index-Cy-mb5v_.d.ts +262 -0
- package/dist/index-D1f9Sym2.d.cts +148 -0
- package/dist/index-D1f9Sym2.d.ts +148 -0
- package/dist/index-Dan5oF-5.d.cts +213 -0
- package/dist/index-Dan5oF-5.d.ts +213 -0
- package/dist/index-XABfrs7z.d.cts +596 -0
- package/dist/index-XABfrs7z.d.ts +596 -0
- package/dist/index-YXWfKCK7.d.cts +109 -0
- package/dist/index-YXWfKCK7.d.ts +109 -0
- package/dist/index.cjs +3691 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +3629 -0
- package/dist/index.js.map +1 -0
- package/dist/map.cjs +839 -0
- package/dist/map.cjs.map +1 -0
- package/dist/map.d.cts +6 -0
- package/dist/map.d.ts +6 -0
- package/dist/map.js +811 -0
- package/dist/map.js.map +1 -0
- package/dist/object.cjs +316 -0
- package/dist/object.cjs.map +1 -0
- package/dist/object.d.cts +2 -0
- package/dist/object.d.ts +2 -0
- package/dist/object.js +247 -0
- package/dist/object.js.map +1 -0
- package/dist/pdf.cjs +197 -0
- package/dist/pdf.cjs.map +1 -0
- package/dist/pdf.d.cts +3 -0
- package/dist/pdf.d.ts +3 -0
- package/dist/pdf.js +173 -0
- package/dist/pdf.js.map +1 -0
- package/dist/storage.cjs +255 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +1 -0
- package/dist/storage.d.ts +1 -0
- package/dist/storage.js +226 -0
- package/dist/storage.js.map +1 -0
- package/dist/string.cjs +232 -0
- package/dist/string.cjs.map +1 -0
- package/dist/string.d.cts +2 -0
- package/dist/string.d.ts +2 -0
- package/dist/string.js +170 -0
- package/dist/string.js.map +1 -0
- package/dist/utils.cjs +429 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +2 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +371 -0
- package/dist/utils.js.map +1 -0
- package/dist/websocket.cjs +338 -0
- package/dist/websocket.cjs.map +1 -0
- package/dist/websocket.d.cts +1 -0
- package/dist/websocket.d.ts +1 -0
- package/dist/websocket.js +330 -0
- package/dist/websocket.js.map +1 -0
- package/package.json +159 -33
- package/dist/ly-utils-lib.cjs.js +0 -115
- package/dist/ly-utils-lib.cjs.js.map +0 -1
- package/dist/ly-utils-lib.es.js +0 -58589
- package/dist/ly-utils-lib.es.js.map +0 -1
- package/dist/ly-utils-lib.umd.js +0 -115
- package/dist/ly-utils-lib.umd.js.map +0 -1
- package/dist/types/index.d.ts +0 -15
- package/dist/types/utils/esToolkit.d.ts +0 -2
- package/dist/types/utils/ol.d.ts +0 -175
- package/dist/types/utils/router.d.ts +0 -10
- package/dist/types/utils/storage.d.ts +0 -42
- package/dist/types/utils/time.d.ts +0 -66
- package/dist/types/utils/tool.d.ts +0 -80
- package/dist/vite.svg +0 -1
package/dist/map.js
ADDED
|
@@ -0,0 +1,811 @@
|
|
|
1
|
+
import { Map as Map$1, View, Feature } from 'ol';
|
|
2
|
+
import { defaults, ScaleLine, FullScreen } from 'ol/control';
|
|
3
|
+
import { Point, LineString, Polygon } from 'ol/geom';
|
|
4
|
+
import { Draw, Snap, Modify, Select } from 'ol/interaction';
|
|
5
|
+
import Overlay from 'ol/Overlay';
|
|
6
|
+
import TileLayer from 'ol/layer/Tile';
|
|
7
|
+
import VectorLayer from 'ol/layer/Vector';
|
|
8
|
+
import { fromLonLat, transform, toLonLat } from 'ol/proj';
|
|
9
|
+
import OSM from 'ol/source/OSM';
|
|
10
|
+
import VectorSource from 'ol/source/Vector';
|
|
11
|
+
import XYZ from 'ol/source/XYZ';
|
|
12
|
+
import GeoJSON from 'ol/format/GeoJSON';
|
|
13
|
+
import { Style, Icon, Circle, Stroke, Fill } from 'ol/style';
|
|
14
|
+
import { boundingExtent } from 'ol/extent';
|
|
15
|
+
|
|
16
|
+
// src/modules/map/index.ts
|
|
17
|
+
var MapInstance = class {
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.vectorSources = /* @__PURE__ */ new Map();
|
|
20
|
+
this.vectorLayers = /* @__PURE__ */ new Map();
|
|
21
|
+
this.overlays = /* @__PURE__ */ new Map();
|
|
22
|
+
this.themeLayers = /* @__PURE__ */ new Map();
|
|
23
|
+
this.drawInteraction = null;
|
|
24
|
+
this.modifyInteraction = null;
|
|
25
|
+
this.snapInteraction = null;
|
|
26
|
+
this.selectInteraction = null;
|
|
27
|
+
this.currentTheme = "light";
|
|
28
|
+
this.icons = /* @__PURE__ */ new Map();
|
|
29
|
+
this.enableDynamicScale = false;
|
|
30
|
+
this.projection = "EPSG:4326";
|
|
31
|
+
this.enableDynamicScale = options.enableDynamicScale || false;
|
|
32
|
+
this.projection = options.projection || "EPSG:4326";
|
|
33
|
+
this.currentTheme = options.theme || "light";
|
|
34
|
+
if (options.icons) {
|
|
35
|
+
Object.entries(options.icons).forEach(([name, config]) => {
|
|
36
|
+
this.icons.set(name, config);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const controls = defaults({
|
|
40
|
+
zoom: false,
|
|
41
|
+
rotate: false,
|
|
42
|
+
attribution: false
|
|
43
|
+
});
|
|
44
|
+
if (options.showScaleLine !== false) {
|
|
45
|
+
controls.push(new ScaleLine());
|
|
46
|
+
}
|
|
47
|
+
if (options.showFullScreen !== false) {
|
|
48
|
+
controls.push(new FullScreen());
|
|
49
|
+
}
|
|
50
|
+
this.map = new Map$1({
|
|
51
|
+
target: options.container,
|
|
52
|
+
layers: [],
|
|
53
|
+
view: new View({
|
|
54
|
+
center: fromLonLat(options.center || [116.3974, 39.9093]),
|
|
55
|
+
// 默认北京
|
|
56
|
+
zoom: options.zoom || 10,
|
|
57
|
+
minZoom: options.minZoom || 1,
|
|
58
|
+
maxZoom: options.maxZoom || 20,
|
|
59
|
+
projection: this.projection,
|
|
60
|
+
constrainResolution: true,
|
|
61
|
+
smoothResolutionConstraint: false
|
|
62
|
+
}),
|
|
63
|
+
controls
|
|
64
|
+
});
|
|
65
|
+
if (options.themeConfig) {
|
|
66
|
+
this.setupThemeLayers(options.themeConfig);
|
|
67
|
+
}
|
|
68
|
+
if (options.layers) {
|
|
69
|
+
options.layers.forEach((layer) => this.map.addLayer(layer.layer));
|
|
70
|
+
}
|
|
71
|
+
if (this.enableDynamicScale) {
|
|
72
|
+
this.map.on("moveend", () => this.handleZoomChange());
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// ==================== 主题管理 ====================
|
|
76
|
+
/**
|
|
77
|
+
* 设置主题图层
|
|
78
|
+
*/
|
|
79
|
+
setupThemeLayers(config) {
|
|
80
|
+
const lightUrl = config.lightUrl || "https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}";
|
|
81
|
+
const darkUrl = config.darkUrl || "https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=9&x={x}&y={y}&z={z}";
|
|
82
|
+
const lightLayer = new TileLayer({
|
|
83
|
+
preload: Infinity,
|
|
84
|
+
source: new XYZ({ url: lightUrl })
|
|
85
|
+
});
|
|
86
|
+
const darkLayer = new TileLayer({
|
|
87
|
+
preload: Infinity,
|
|
88
|
+
source: new XYZ({ url: darkUrl })
|
|
89
|
+
});
|
|
90
|
+
this.themeLayers.set("light", lightLayer);
|
|
91
|
+
this.themeLayers.set("dark", darkLayer);
|
|
92
|
+
this.map.addLayer(lightLayer);
|
|
93
|
+
this.map.addLayer(darkLayer);
|
|
94
|
+
this.setTheme(this.currentTheme);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 切换主题
|
|
98
|
+
*/
|
|
99
|
+
setTheme(theme) {
|
|
100
|
+
this.currentTheme = theme;
|
|
101
|
+
this.themeLayers.forEach((layer, key) => {
|
|
102
|
+
layer.setVisible(key === theme);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 获取当前主题
|
|
107
|
+
*/
|
|
108
|
+
getTheme() {
|
|
109
|
+
return this.currentTheme;
|
|
110
|
+
}
|
|
111
|
+
// ==================== 图层管理 ====================
|
|
112
|
+
/**
|
|
113
|
+
* 创建矢量图层
|
|
114
|
+
*/
|
|
115
|
+
createVectorLayer(config) {
|
|
116
|
+
if (this.vectorLayers.has(config.name)) {
|
|
117
|
+
console.warn(`\u56FE\u5C42 "${config.name}" \u5DF2\u5B58\u5728`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const source = new VectorSource({
|
|
121
|
+
format: new GeoJSON()
|
|
122
|
+
});
|
|
123
|
+
const layer = new VectorLayer({
|
|
124
|
+
source,
|
|
125
|
+
style: config.style,
|
|
126
|
+
minZoom: config.minZoom,
|
|
127
|
+
maxZoom: config.maxZoom,
|
|
128
|
+
zIndex: config.zIndex,
|
|
129
|
+
visible: config.visible !== false
|
|
130
|
+
});
|
|
131
|
+
this.vectorSources.set(config.name, source);
|
|
132
|
+
this.vectorLayers.set(config.name, layer);
|
|
133
|
+
this.map.addLayer(layer);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 获取矢量图层
|
|
137
|
+
*/
|
|
138
|
+
getVectorLayer(name) {
|
|
139
|
+
return this.vectorLayers.get(name);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 获取矢量数据源
|
|
143
|
+
*/
|
|
144
|
+
getVectorSource(name) {
|
|
145
|
+
return this.vectorSources.get(name);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 显示/隐藏矢量图层
|
|
149
|
+
*/
|
|
150
|
+
setLayerVisible(name, visible) {
|
|
151
|
+
const layer = this.vectorLayers.get(name);
|
|
152
|
+
if (layer) {
|
|
153
|
+
layer.setVisible(visible);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 设置矢量图层样式
|
|
158
|
+
*/
|
|
159
|
+
setLayerStyle(name, style) {
|
|
160
|
+
const layer = this.vectorLayers.get(name);
|
|
161
|
+
if (layer) {
|
|
162
|
+
layer.setStyle(style);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 清除矢量图层
|
|
167
|
+
*/
|
|
168
|
+
clearLayer(name) {
|
|
169
|
+
const source = this.vectorSources.get(name);
|
|
170
|
+
if (source) {
|
|
171
|
+
source.clear();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* 删除矢量图层
|
|
176
|
+
*/
|
|
177
|
+
removeLayer(name) {
|
|
178
|
+
const layer = this.vectorLayers.get(name);
|
|
179
|
+
if (layer) {
|
|
180
|
+
this.map.removeLayer(layer);
|
|
181
|
+
this.vectorLayers.delete(name);
|
|
182
|
+
this.vectorSources.delete(name);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// ==================== 要素管理 ====================
|
|
186
|
+
/**
|
|
187
|
+
* 添加标记
|
|
188
|
+
*/
|
|
189
|
+
addMarker(options, layerName = "default") {
|
|
190
|
+
if (!this.vectorLayers.has(layerName)) {
|
|
191
|
+
this.createVectorLayer({ name: layerName });
|
|
192
|
+
}
|
|
193
|
+
const source = this.vectorSources.get(layerName);
|
|
194
|
+
const feature = new Feature({
|
|
195
|
+
geometry: new Point(fromLonLat(options.coordinate))
|
|
196
|
+
});
|
|
197
|
+
const style = options.style || this.createMarkerStyle(options);
|
|
198
|
+
feature.setStyle(style);
|
|
199
|
+
source.addFeature(feature);
|
|
200
|
+
return feature;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* 创建标记样式
|
|
204
|
+
*/
|
|
205
|
+
createMarkerStyle(options) {
|
|
206
|
+
if (options.icon && this.icons.has(options.icon)) {
|
|
207
|
+
const iconConfig = this.icons.get(options.icon);
|
|
208
|
+
return new Style({
|
|
209
|
+
image: new Icon({
|
|
210
|
+
anchor: iconConfig.anchor || [0.5, 0.5],
|
|
211
|
+
src: iconConfig.src,
|
|
212
|
+
scale: iconConfig.scale || 1
|
|
213
|
+
})
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (options.iconConfig) {
|
|
217
|
+
return new Style({
|
|
218
|
+
image: new Icon({
|
|
219
|
+
anchor: options.iconConfig.anchor || [0.5, 0.5],
|
|
220
|
+
src: options.iconConfig.src,
|
|
221
|
+
scale: options.iconConfig.scale || 1
|
|
222
|
+
})
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return new Style({
|
|
226
|
+
image: new Circle({
|
|
227
|
+
radius: options.radius || 7,
|
|
228
|
+
fill: new Fill({ color: options.color || "#ff3333" }),
|
|
229
|
+
stroke: new Stroke({
|
|
230
|
+
color: options.strokeColor || "#ffffff",
|
|
231
|
+
width: options.strokeWidth || 2
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* 移除标记
|
|
238
|
+
*/
|
|
239
|
+
removeMarker(feature, layerName = "default") {
|
|
240
|
+
const source = this.vectorSources.get(layerName);
|
|
241
|
+
if (source) {
|
|
242
|
+
source.removeFeature(feature);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* 从 GeoJSON 添加要素
|
|
247
|
+
*/
|
|
248
|
+
addFeaturesFromGeoJSON(geoJson, layerName = "default") {
|
|
249
|
+
if (!this.vectorLayers.has(layerName)) {
|
|
250
|
+
this.createVectorLayer({ name: layerName });
|
|
251
|
+
}
|
|
252
|
+
const source = this.vectorSources.get(layerName);
|
|
253
|
+
const format = new GeoJSON();
|
|
254
|
+
const features = format.readFeatures(typeof geoJson === "string" ? geoJson : JSON.stringify(geoJson));
|
|
255
|
+
source.addFeatures(features);
|
|
256
|
+
return features;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* 添加要素
|
|
260
|
+
*/
|
|
261
|
+
addFeature(feature, layerName = "default") {
|
|
262
|
+
if (!this.vectorLayers.has(layerName)) {
|
|
263
|
+
this.createVectorLayer({ name: layerName });
|
|
264
|
+
}
|
|
265
|
+
const source = this.vectorSources.get(layerName);
|
|
266
|
+
source.addFeature(feature);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 批量添加要素
|
|
270
|
+
*/
|
|
271
|
+
addFeatures(features, layerName = "default") {
|
|
272
|
+
if (!this.vectorLayers.has(layerName)) {
|
|
273
|
+
this.createVectorLayer({ name: layerName });
|
|
274
|
+
}
|
|
275
|
+
const source = this.vectorSources.get(layerName);
|
|
276
|
+
source.addFeatures(features);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* 移除要素
|
|
280
|
+
*/
|
|
281
|
+
removeFeature(feature, layerName = "default") {
|
|
282
|
+
const source = this.vectorSources.get(layerName);
|
|
283
|
+
if (source) {
|
|
284
|
+
source.removeFeature(feature);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* 清除所有矢量要素
|
|
289
|
+
*/
|
|
290
|
+
clearFeatures(layerName = "default") {
|
|
291
|
+
const source = this.vectorSources.get(layerName);
|
|
292
|
+
if (source) {
|
|
293
|
+
source.clear();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* 获取图层中的所有要素
|
|
298
|
+
*/
|
|
299
|
+
getFeatures(layerName = "default") {
|
|
300
|
+
const source = this.vectorSources.get(layerName);
|
|
301
|
+
return source ? source.getFeatures() : [];
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* 创建 GeoJSON
|
|
305
|
+
*/
|
|
306
|
+
createGeoJSON(type, data) {
|
|
307
|
+
const coordinates = this.getCoordinates(type, data);
|
|
308
|
+
const id = this.generateUUID();
|
|
309
|
+
return {
|
|
310
|
+
type: "FeatureCollection",
|
|
311
|
+
features: [{
|
|
312
|
+
type: "Feature",
|
|
313
|
+
geometry: {
|
|
314
|
+
type,
|
|
315
|
+
coordinates
|
|
316
|
+
},
|
|
317
|
+
properties: {
|
|
318
|
+
id,
|
|
319
|
+
value: data
|
|
320
|
+
}
|
|
321
|
+
}]
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* 获取坐标
|
|
326
|
+
*/
|
|
327
|
+
getCoordinates(type, data) {
|
|
328
|
+
if (type === "Point") {
|
|
329
|
+
return fromLonLat(transform(data.points, "EPSG:3857", "EPSG:4326"));
|
|
330
|
+
} else if (type === "LineString") {
|
|
331
|
+
return this.setPointArray(data.points);
|
|
332
|
+
} else if (type === "Polygon") {
|
|
333
|
+
return [this.setPointArray(data.points)];
|
|
334
|
+
}
|
|
335
|
+
return [];
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* 设置点数组
|
|
339
|
+
*/
|
|
340
|
+
setPointArray(points) {
|
|
341
|
+
return points.map((item) => fromLonLat(transform(item, "EPSG:3857", "EPSG:4326")));
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* 生成 UUID
|
|
345
|
+
*/
|
|
346
|
+
generateUUID() {
|
|
347
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
348
|
+
const r = Math.random() * 16 | 0;
|
|
349
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
350
|
+
return v.toString(16);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* 设置要素样式
|
|
355
|
+
*/
|
|
356
|
+
setFeatureStyle(feature, options) {
|
|
357
|
+
const style = this.createFeatureStyle(options);
|
|
358
|
+
feature.setStyle(style);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* 创建要素样式
|
|
362
|
+
*/
|
|
363
|
+
createFeatureStyle(options) {
|
|
364
|
+
if (options.style) {
|
|
365
|
+
return options.style;
|
|
366
|
+
}
|
|
367
|
+
if (options.icon && this.icons.has(options.icon)) {
|
|
368
|
+
const iconConfig = this.icons.get(options.icon);
|
|
369
|
+
return new Style({
|
|
370
|
+
image: new Icon({
|
|
371
|
+
anchor: iconConfig.anchor || [0.5, 0.5],
|
|
372
|
+
src: iconConfig.src,
|
|
373
|
+
scale: iconConfig.scale || 1
|
|
374
|
+
})
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
if (options.iconConfig) {
|
|
378
|
+
return new Style({
|
|
379
|
+
image: new Icon({
|
|
380
|
+
anchor: options.iconConfig.anchor || [0.5, 0.5],
|
|
381
|
+
src: options.iconConfig.src,
|
|
382
|
+
scale: options.iconConfig.scale || 1
|
|
383
|
+
})
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
return new Style({
|
|
387
|
+
stroke: new Stroke({
|
|
388
|
+
color: options.strokeColor || "#3388ff",
|
|
389
|
+
width: options.strokeWidth || 2
|
|
390
|
+
}),
|
|
391
|
+
fill: new Fill({
|
|
392
|
+
color: options.fillColor || "rgba(51, 136, 255, 0.2)"
|
|
393
|
+
}),
|
|
394
|
+
image: new Circle({
|
|
395
|
+
radius: 7,
|
|
396
|
+
fill: new Fill({ color: options.strokeColor || "#3388ff" }),
|
|
397
|
+
stroke: new Stroke({
|
|
398
|
+
color: "#ffffff",
|
|
399
|
+
width: 2
|
|
400
|
+
})
|
|
401
|
+
})
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
// ==================== 动态缩放 ====================
|
|
405
|
+
/**
|
|
406
|
+
* 处理缩放变化
|
|
407
|
+
*/
|
|
408
|
+
handleZoomChange() {
|
|
409
|
+
const zoom = this.getZoom();
|
|
410
|
+
if (zoom !== void 0) {
|
|
411
|
+
this.updateIconScale(zoom);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* 更新图标缩放比例
|
|
416
|
+
*/
|
|
417
|
+
updateIconScale(zoom) {
|
|
418
|
+
let scale = 1;
|
|
419
|
+
if (zoom >= 14) {
|
|
420
|
+
scale = 0.5;
|
|
421
|
+
} else if (zoom < 14 && zoom >= 12) {
|
|
422
|
+
scale = 0.4;
|
|
423
|
+
} else if (zoom < 12) {
|
|
424
|
+
scale = 0.3;
|
|
425
|
+
}
|
|
426
|
+
this.vectorLayers.forEach((layer) => {
|
|
427
|
+
const features = layer.getSource()?.getFeatures();
|
|
428
|
+
if (features) {
|
|
429
|
+
features.forEach((feature) => {
|
|
430
|
+
const style = feature.getStyle();
|
|
431
|
+
if (style) {
|
|
432
|
+
const image = style.getImage();
|
|
433
|
+
if (image instanceof Icon) {
|
|
434
|
+
image.setScale(scale);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
// ==================== Overlay 管理 ====================
|
|
442
|
+
/**
|
|
443
|
+
* 创建 Overlay
|
|
444
|
+
*/
|
|
445
|
+
createOverlay(options) {
|
|
446
|
+
const overlay = new Overlay({
|
|
447
|
+
element: options.element,
|
|
448
|
+
autoPan: options.autoPan !== false,
|
|
449
|
+
offset: options.offset,
|
|
450
|
+
positioning: options.positioning || "bottom-center"
|
|
451
|
+
});
|
|
452
|
+
this.overlays.set(options.name, overlay);
|
|
453
|
+
this.map.addOverlay(overlay);
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* 显示 Overlay
|
|
457
|
+
*/
|
|
458
|
+
showOverlay(name, coordinate) {
|
|
459
|
+
const overlay = this.overlays.get(name);
|
|
460
|
+
if (overlay) {
|
|
461
|
+
overlay.setPosition(fromLonLat(coordinate));
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* 隐藏 Overlay
|
|
466
|
+
*/
|
|
467
|
+
hideOverlay(name) {
|
|
468
|
+
const overlay = this.overlays.get(name);
|
|
469
|
+
if (overlay) {
|
|
470
|
+
overlay.setPosition(void 0);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* 移除 Overlay
|
|
475
|
+
*/
|
|
476
|
+
removeOverlay(name) {
|
|
477
|
+
const overlay = this.overlays.get(name);
|
|
478
|
+
if (overlay) {
|
|
479
|
+
this.map.removeOverlay(overlay);
|
|
480
|
+
this.overlays.delete(name);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
// ==================== 交互管理 ====================
|
|
484
|
+
/**
|
|
485
|
+
* 开始绘制
|
|
486
|
+
*/
|
|
487
|
+
startDraw(options) {
|
|
488
|
+
this.stopDraw();
|
|
489
|
+
const source = options.layerName && this.vectorSources.has(options.layerName) ? this.vectorSources.get(options.layerName) : new VectorSource();
|
|
490
|
+
this.drawInteraction = new Draw({
|
|
491
|
+
source,
|
|
492
|
+
type: options.type,
|
|
493
|
+
style: options.style
|
|
494
|
+
});
|
|
495
|
+
this.map.addInteraction(this.drawInteraction);
|
|
496
|
+
if (options.onDrawEnd) {
|
|
497
|
+
this.drawInteraction.on("drawend", (evt) => {
|
|
498
|
+
options.onDrawEnd?.(evt.feature);
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
this.snapInteraction = new Snap({ source });
|
|
502
|
+
this.map.addInteraction(this.snapInteraction);
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* 停止绘制
|
|
506
|
+
*/
|
|
507
|
+
stopDraw() {
|
|
508
|
+
if (this.drawInteraction) {
|
|
509
|
+
this.map.removeInteraction(this.drawInteraction);
|
|
510
|
+
this.drawInteraction = null;
|
|
511
|
+
}
|
|
512
|
+
if (this.snapInteraction) {
|
|
513
|
+
this.map.removeInteraction(this.snapInteraction);
|
|
514
|
+
this.snapInteraction = null;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* 开始编辑
|
|
519
|
+
*/
|
|
520
|
+
startModify(layerName = "default") {
|
|
521
|
+
this.stopModify();
|
|
522
|
+
const source = this.vectorSources.get(layerName);
|
|
523
|
+
if (!source) {
|
|
524
|
+
console.warn(`\u56FE\u5C42 "${layerName}" \u4E0D\u5B58\u5728`);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
this.modifyInteraction = new Modify({
|
|
528
|
+
source
|
|
529
|
+
});
|
|
530
|
+
this.map.addInteraction(this.modifyInteraction);
|
|
531
|
+
this.snapInteraction = new Snap({ source });
|
|
532
|
+
this.map.addInteraction(this.snapInteraction);
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* 停止编辑
|
|
536
|
+
*/
|
|
537
|
+
stopModify() {
|
|
538
|
+
if (this.modifyInteraction) {
|
|
539
|
+
this.map.removeInteraction(this.modifyInteraction);
|
|
540
|
+
this.modifyInteraction = null;
|
|
541
|
+
}
|
|
542
|
+
if (this.snapInteraction) {
|
|
543
|
+
this.map.removeInteraction(this.snapInteraction);
|
|
544
|
+
this.snapInteraction = null;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* 开始选择
|
|
549
|
+
*/
|
|
550
|
+
startSelect(layerName = "default", onSelect) {
|
|
551
|
+
this.stopSelect();
|
|
552
|
+
this.selectInteraction = new Select({
|
|
553
|
+
layers: this.vectorLayers.get(layerName) ? [this.vectorLayers.get(layerName)] : void 0
|
|
554
|
+
});
|
|
555
|
+
this.map.addInteraction(this.selectInteraction);
|
|
556
|
+
if (onSelect) {
|
|
557
|
+
this.selectInteraction.on("select", (evt) => {
|
|
558
|
+
onSelect(evt.selected);
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* 停止选择
|
|
564
|
+
*/
|
|
565
|
+
stopSelect() {
|
|
566
|
+
if (this.selectInteraction) {
|
|
567
|
+
this.map.removeInteraction(this.selectInteraction);
|
|
568
|
+
this.selectInteraction = null;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* 获取选中的要素
|
|
573
|
+
*/
|
|
574
|
+
getSelectedFeatures() {
|
|
575
|
+
return this.selectInteraction?.getFeatures().getArray() || [];
|
|
576
|
+
}
|
|
577
|
+
// ==================== 地图控制 ====================
|
|
578
|
+
/**
|
|
579
|
+
* 获取原始地图实例
|
|
580
|
+
*/
|
|
581
|
+
getOlMap() {
|
|
582
|
+
return this.map;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* 获取视图
|
|
586
|
+
*/
|
|
587
|
+
getView() {
|
|
588
|
+
return this.map.getView();
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* 设置中心点
|
|
592
|
+
*/
|
|
593
|
+
setCenter(coord) {
|
|
594
|
+
const view = this.getView();
|
|
595
|
+
if (view) {
|
|
596
|
+
view.setCenter(fromLonLat(coord));
|
|
597
|
+
this.map.render();
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* 获取中心点
|
|
602
|
+
*/
|
|
603
|
+
getCenter() {
|
|
604
|
+
const view = this.getView();
|
|
605
|
+
if (view) {
|
|
606
|
+
const center = view.getCenter();
|
|
607
|
+
return center ? toLonLat(center) : void 0;
|
|
608
|
+
}
|
|
609
|
+
return void 0;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* 设置缩放级别
|
|
613
|
+
*/
|
|
614
|
+
setZoom(zoom) {
|
|
615
|
+
const view = this.getView();
|
|
616
|
+
if (view) {
|
|
617
|
+
view.setZoom(zoom);
|
|
618
|
+
this.map.render();
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* 获取缩放级别
|
|
623
|
+
*/
|
|
624
|
+
getZoom() {
|
|
625
|
+
return this.getView()?.getZoom();
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* 缩放到指定范围
|
|
629
|
+
*/
|
|
630
|
+
fit(extent, options) {
|
|
631
|
+
if (!extent) return;
|
|
632
|
+
const view = this.getView();
|
|
633
|
+
if (view) {
|
|
634
|
+
view.fit(extent, options);
|
|
635
|
+
this.map.render();
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* 缩放到图层
|
|
640
|
+
*/
|
|
641
|
+
fitLayer(layerName, options) {
|
|
642
|
+
const source = this.vectorSources.get(layerName);
|
|
643
|
+
if (source) {
|
|
644
|
+
const extent = source.getExtent();
|
|
645
|
+
if (extent && extent[0] !== Infinity) {
|
|
646
|
+
this.fit(extent, options);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* 缩放到坐标数组
|
|
652
|
+
*/
|
|
653
|
+
fitCoordinates(coordinates, options) {
|
|
654
|
+
const extent = boundingExtent(coordinates);
|
|
655
|
+
this.fit(extent, options);
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* 添加图层
|
|
659
|
+
*/
|
|
660
|
+
addLayer(layer) {
|
|
661
|
+
this.map.addLayer(layer.layer);
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* 移除图层
|
|
665
|
+
*/
|
|
666
|
+
removeMapLayer(layer) {
|
|
667
|
+
this.map.removeLayer(layer.layer);
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* 更新地图大小
|
|
671
|
+
*/
|
|
672
|
+
updateSize() {
|
|
673
|
+
this.map.updateSize();
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* 地图事件监听
|
|
677
|
+
*/
|
|
678
|
+
on(event, callback) {
|
|
679
|
+
this.map.on(event, callback);
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* 移除事件监听
|
|
683
|
+
*/
|
|
684
|
+
off(event, callback) {
|
|
685
|
+
this.map.un(event, callback);
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* 销毁地图
|
|
689
|
+
*/
|
|
690
|
+
destroy() {
|
|
691
|
+
this.stopDraw();
|
|
692
|
+
this.stopModify();
|
|
693
|
+
this.stopSelect();
|
|
694
|
+
this.overlays.forEach((overlay) => this.map.removeOverlay(overlay));
|
|
695
|
+
this.overlays.clear();
|
|
696
|
+
this.vectorLayers.forEach((layer) => this.map.removeLayer(layer));
|
|
697
|
+
this.vectorLayers.clear();
|
|
698
|
+
this.vectorSources.clear();
|
|
699
|
+
this.map.setTarget(void 0);
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
function createOSMLayer(name = "OSM") {
|
|
703
|
+
return {
|
|
704
|
+
name,
|
|
705
|
+
layer: new TileLayer({
|
|
706
|
+
source: new OSM()
|
|
707
|
+
})
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
function createXYZLayer(url, name = "XYZ") {
|
|
711
|
+
return {
|
|
712
|
+
name,
|
|
713
|
+
layer: new TileLayer({
|
|
714
|
+
source: new XYZ({
|
|
715
|
+
url
|
|
716
|
+
})
|
|
717
|
+
})
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
function createGaodeLayer(name = "\u9AD8\u5FB7\u5730\u56FE") {
|
|
721
|
+
return createXYZLayer(
|
|
722
|
+
"https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
|
|
723
|
+
name
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
function createTiandituLayer(token, type = "vec", name = "\u5929\u5730\u56FE") {
|
|
727
|
+
const url = `https://t{s}.tianditu.gov.cn/DataServer?T=${type}_w&x={x}&y={y}&l={z}&tk=${token}`;
|
|
728
|
+
return createXYZLayer(url, name);
|
|
729
|
+
}
|
|
730
|
+
function lonLatToXY(lon, lat) {
|
|
731
|
+
return fromLonLat([lon, lat]);
|
|
732
|
+
}
|
|
733
|
+
function xyToLonLat(x, y) {
|
|
734
|
+
return toLonLat([x, y]);
|
|
735
|
+
}
|
|
736
|
+
function createPointFeature(coordinate) {
|
|
737
|
+
return new Feature({
|
|
738
|
+
geometry: new Point(fromLonLat(coordinate))
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
function createLineFeature(coordinates) {
|
|
742
|
+
return new Feature({
|
|
743
|
+
geometry: new LineString(coordinates.map((coord) => fromLonLat(coord)))
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
function createPolygonFeature(coordinates) {
|
|
747
|
+
return new Feature({
|
|
748
|
+
geometry: new Polygon(coordinates.map((ring) => ring.map((coord) => fromLonLat(coord))))
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
function createStyledPointFeature(coordinate, style) {
|
|
752
|
+
const feature = createPointFeature(coordinate);
|
|
753
|
+
feature.setStyle(style);
|
|
754
|
+
return feature;
|
|
755
|
+
}
|
|
756
|
+
function createStyledLineFeature(coordinates, style) {
|
|
757
|
+
const feature = createLineFeature(coordinates);
|
|
758
|
+
feature.setStyle(style);
|
|
759
|
+
return feature;
|
|
760
|
+
}
|
|
761
|
+
function createStyledPolygonFeature(coordinates, style) {
|
|
762
|
+
const feature = createPolygonFeature(coordinates);
|
|
763
|
+
feature.setStyle(style);
|
|
764
|
+
return feature;
|
|
765
|
+
}
|
|
766
|
+
function createIconStyle(iconUrl, options) {
|
|
767
|
+
return new Style({
|
|
768
|
+
image: new Icon({
|
|
769
|
+
anchor: options?.anchor || [0.5, 0.5],
|
|
770
|
+
src: iconUrl,
|
|
771
|
+
scale: options?.scale || 1,
|
|
772
|
+
color: options?.color
|
|
773
|
+
})
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
function createCircleStyle(options) {
|
|
777
|
+
return new Style({
|
|
778
|
+
image: new Circle({
|
|
779
|
+
radius: options?.radius || 7,
|
|
780
|
+
fill: new Fill({ color: options?.fillColor || "#3388ff" }),
|
|
781
|
+
stroke: new Stroke({
|
|
782
|
+
color: options?.strokeColor || "#ffffff",
|
|
783
|
+
width: options?.strokeWidth || 2
|
|
784
|
+
})
|
|
785
|
+
})
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
function createStrokeStyle(options) {
|
|
789
|
+
return new Style({
|
|
790
|
+
stroke: new Stroke({
|
|
791
|
+
color: options?.color || "#3388ff",
|
|
792
|
+
width: options?.width || 2,
|
|
793
|
+
lineDash: options?.lineDash
|
|
794
|
+
})
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
function createFillStyle(options) {
|
|
798
|
+
return new Style({
|
|
799
|
+
stroke: new Stroke({
|
|
800
|
+
color: options?.strokeColor || "#3388ff",
|
|
801
|
+
width: options?.strokeWidth || 2
|
|
802
|
+
}),
|
|
803
|
+
fill: new Fill({
|
|
804
|
+
color: options?.fillColor || "rgba(51, 136, 255, 0.2)"
|
|
805
|
+
})
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
export { MapInstance, createCircleStyle, createFillStyle, createGaodeLayer, createIconStyle, createLineFeature, createOSMLayer, createPointFeature, createPolygonFeature, createStrokeStyle, createStyledLineFeature, createStyledPointFeature, createStyledPolygonFeature, createTiandituLayer, createXYZLayer, lonLatToXY, xyToLonLat };
|
|
810
|
+
//# sourceMappingURL=map.js.map
|
|
811
|
+
//# sourceMappingURL=map.js.map
|