zhihao-ui 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/es/{BaseInfo-DP7wB6Hy.js → BaseInfo-CqPKfZM2.js} +1 -1
  2. package/dist/es/{BaseItem-zKXAWw6X.js → BaseItem-XXH5e7db.js} +3 -3
  3. package/dist/es/{Button-D71UFKe2.js → Button-DLAiqJPu.js} +2 -2
  4. package/dist/es/{DatePicker-ByaPDV8a.js → DatePicker-DNED5PYV.js} +3 -3
  5. package/dist/es/{DetailHeader-BvwqbiHO.js → DetailHeader-BCF-X9k8.js} +3 -3
  6. package/dist/es/{DetailSubTitle-Brh4lgY7.js → DetailSubTitle-Booxy4wf.js} +2 -2
  7. package/dist/es/{Dialog-Dfj9XSbZ.js → Dialog-gDiUEFNF.js} +3 -3
  8. package/dist/es/{DiyDataTable-CyinC7X9.js → DiyDataTable-CPFSQBiW.js} +4 -4
  9. package/dist/es/{EditInfoPair-Bh8ExT4y.js → EditInfoPair-BeQ_RjRC.js} +3 -3
  10. package/dist/es/{FileWrapper-Cr7F-CIS.js → FileWrapper-CyQAOj8M.js} +4 -4
  11. package/dist/es/{Grid-CzmdTj41.js → Grid-DAZ59W8l.js} +2 -2
  12. package/dist/es/{InfoPair-wZg9g-ul.js → InfoPair-D2gWOKNY.js} +3 -3
  13. package/dist/es/{Input-DRtonb3d.js → Input-DCs9DGvN.js} +3 -3
  14. package/dist/es/{Loading-CujO-NlL.js → Loading-tblIiyvu.js} +2 -2
  15. package/dist/es/Map-CWehCrKQ.js +1610 -0
  16. package/dist/es/{MessageBox-CRUoKQsc.js → MessageBox-Bwv1ICSl.js} +2 -2
  17. package/dist/es/{MoneyInput-D1u6lU9a.js → MoneyInput-BUho-aKW.js} +7 -7
  18. package/dist/es/{PageHeadPanel-COhIV995.js → PageHeadPanel-BBzYKasW.js} +2 -2
  19. package/dist/es/{Table-BFbxIF3i.js → Table-m_nv-2IU.js} +41 -41
  20. package/dist/es/{ToolTips-DNojIdT8.js → ToolTips-BrpfWKhV.js} +5 -5
  21. package/dist/es/index.js +22 -22
  22. package/dist/es/{utils-CVU4so-2.js → utils-sJ-t5B4u.js} +1 -1
  23. package/dist/es/{vendor-Cx2Ws2_l.js → vendor-BUg4XLGS.js} +2787 -2789
  24. package/dist/index.css +1 -1
  25. package/dist/types/components/Map/Map.vue.d.ts +112 -0
  26. package/dist/types/components/Map/config/global.d.ts +1 -0
  27. package/dist/types/components/Map/config/index.d.ts +2 -28
  28. package/dist/types/components/Map/config/map.d.ts +25 -0
  29. package/dist/types/components/Map/function/carTrack.d.ts +1 -1
  30. package/dist/types/components/Map/function/drawLine.d.ts +2 -9
  31. package/dist/types/components/Map/function/drawPolygon.d.ts +0 -7
  32. package/dist/types/components/Map/function/map.d.ts +4 -0
  33. package/dist/types/components/Map/function/props.d.ts +4 -0
  34. package/dist/types/components/Map/function/ship/style.d.ts +4 -2
  35. package/dist/types/components/Map/function/shipTrack.d.ts +1 -1
  36. package/dist/types/components/Map/index.d.ts +364 -0
  37. package/dist/types/components/Map/interface/index.d.ts +0 -1
  38. package/dist/types/components/Map/interface/mapProps.d.ts +1 -0
  39. package/dist/types/components/Map/utils/overlay.d.ts +4 -0
  40. package/dist/umd/index.css +1 -1
  41. package/dist/umd/index.umd.cjs +60 -66
  42. package/package.json +1 -1
  43. package/dist/es/Map-mRzxeRp6.js +0 -1877
@@ -1,1877 +0,0 @@
1
- import { defineComponent, inject, openBlock, createElementBlock, ref, createElementVNode, provide, onMounted, Fragment, createVNode } from "vue";
2
- import { S as ScaleLine$1, t as toLonLat, p as fromLonLat, T as Text, F as Fill, q as Style, r as getLength, s as TileLayer, X as XYZ, R as RBush$1, V as VectorSource, u as VectorLayer, v as debounce, w as Feature, P as Point, I as Icon, x as useDebounceFn, O as Overlay, h as hooks, L as LineString, y as Stroke, z as Polygon, C as CircleStyle, A as Polyline, B as buffer, D as transform, G as getVectorContext, H as DoubleClickZoom, J as merge, K as Draw, M as unByKey, N as getUid, Q as MultiPoint, U as getArea, W as Map$2, Y as View } from "./vendor-Cx2Ws2_l.js";
3
- import { _ as _export_sfc } from "./Button-D71UFKe2.js";
4
- import { w as withInstall } from "./utils-CVU4so-2.js";
5
- const _hoisted_1$1 = { id: "scale-line-container" }, _sfc_main$2 = /* @__PURE__ */ defineComponent({
6
- __name: "scaleLine",
7
- setup(e, { expose: t }) {
8
- const o = inject("mapInstance");
9
- return t({
10
- setScaleLine: (r) => {
11
- var s;
12
- r || (r = "metric");
13
- const a = new ScaleLine$1({
14
- units: r
15
- }), i = document.getElementById("scale-line-container");
16
- i && (a.setTarget(i), (s = o == null ? void 0 : o.value) == null || s.addControl(a));
17
- }
18
- }), (r, a) => (openBlock(), createElementBlock("div", _hoisted_1$1));
19
- }
20
- }), ScaleLine = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-3cec9b07"]]), mapInstance$1 = ref(), getInstall = () => mapInstance$1.value, setInstall = (e) => {
21
- mapInstance$1.value = e;
22
- }, getView = () => getInstall().getView(), getZoom = () => {
23
- var e;
24
- return (e = getView()) == null ? void 0 : e.getZoom();
25
- }, setZoom = (e) => {
26
- var t;
27
- console.log(e), console.log("getView()", getView()), (t = getView()) == null || t.setZoom(e);
28
- }, setCenter = (e, t) => {
29
- var o;
30
- (o = getView()) == null || o.setCenter(fromLonLat([e, t]));
31
- }, getCenter = () => {
32
- var t;
33
- const e = (t = getView()) == null ? void 0 : t.getCenter();
34
- return toLonLat(e);
35
- }, _hoisted_1 = { class: "zoom" }, _sfc_main$1 = /* @__PURE__ */ defineComponent({
36
- __name: "zoomControl",
37
- setup(e) {
38
- const t = inject("mapInstance"), o = () => {
39
- if (t != null && t.value) {
40
- const r = getZoom();
41
- if (!r) return;
42
- setZoom(r + 1);
43
- }
44
- }, n = () => {
45
- if (t != null && t.value) {
46
- const r = getZoom();
47
- if (!r) return;
48
- setZoom(r - 1);
49
- }
50
- };
51
- return (r, a) => (openBlock(), createElementBlock("div", _hoisted_1, [
52
- createElementVNode("div", {
53
- class: "button big-button",
54
- onClick: o
55
- }, " + "),
56
- createElementVNode("div", {
57
- class: "button small-button",
58
- onClick: n
59
- }, " - ")
60
- ]));
61
- }
62
- }), ZoomControl = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-7771507f"]]), CDN_URL = "https://static.zhihaoscm.cn/", TIAN_DI_TU_KEY = "a6e8f78974f2581f2ca00485b40c948f", MAP_ZOOM = {
63
- // 地图默认层级
64
- default: 13,
65
- // 地图缩放最小层级
66
- min: 3,
67
- // 地图缩放最大层级
68
- max: 18,
69
- // 船形图标最小渲染层级
70
- shipTriggleMin: 16,
71
- // 船形图标最大渲染层级
72
- shipModelMax: 18,
73
- //根据原系统canvas图片转换svg长宽比例计算缩放值
74
- scaleNum: 0.555
75
- }, MAP_DEFAULT_CENTER = [114.84, 30.52], projection = {
76
- // 经纬度 源数据 地理坐标 WGS84
77
- data: "EPSG:4326",
78
- // 墨卡托投影坐标 渲染坐标
79
- mercator: "EPSG:3857"
80
- }, formatLength = function(e, t) {
81
- const n = getLength(e);
82
- let r = "";
83
- switch (t) {
84
- case LENGTH_UNIT.M:
85
- r = Math.round(n * 100) / 100 + " m";
86
- break;
87
- case LENGTH_UNIT.KM:
88
- r = Math.round(n / 1e3 * 100) / 100 + " km";
89
- break;
90
- case LENGTH_UNIT.NM:
91
- r = (Math.round(n / 1e3 * 100) / 100 / 1.852).toFixed(2) + " nm";
92
- break;
93
- }
94
- return r;
95
- }, equatorialCircumference = 2003750834e-2;
96
- function lonLatToMercator(e) {
97
- const t = e[0] * equatorialCircumference / 180;
98
- let o = Math.log(Math.tan((90 + e[1]) * Math.PI / 360)) / (Math.PI / 180);
99
- return o = o * equatorialCircumference / 180, [t, o];
100
- }
101
- function getIconFont$1(unicode = "") {
102
- return unicode.indexOf("&") !== -1 && (unicode = unicode.replace("&", "&")), unicode.indexOf("&amp") !== -1 && (unicode = unicode.replace("&amp", "&")), eval('("' + unicode.replace("&#x", "\\u").replace(";", "") + '")');
103
- }
104
- const getIconStyle = (e) => {
105
- const t = new Text({
106
- font: "Normal 14px map-iconfont",
107
- text: getIconFont$1(e),
108
- fill: new Fill({ color: "#fff" }),
109
- offsetY: -14
110
- });
111
- return new Style({
112
- text: t,
113
- zIndex: 100
114
- });
115
- }, adjustBounds = (e, t) => t.length === 2 ? [e[0] - t[0], e[1] - t[1], e[2] + t[0], e[3] + t[1]] : [e[0] + t[0], e[1] + t[1], e[2] + t[2], e[3] + t[3]], isOverlapping = (e, t) => e[0] <= t[2] && e[2] >= t[0] && e[1] <= t[3] && e[3] >= t[1], mercatorToLonLat = (e, t = "lonlat") => {
116
- const o = { lon: 0, lat: 0 }, n = e[0] / equatorialCircumference * 180;
117
- let r = e[1] / equatorialCircumference * 180;
118
- return r = 180 / Math.PI * (2 * Math.atan(Math.exp(r * Math.PI / 180)) - Math.PI / 2), o.lon = n, o.lat = r, t === "lonlat" ? o : [n, r];
119
- };
120
- var BASE_MAP_LINK = ((e) => (e.vectorTile = `https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TIAN_DI_TU_KEY}`, e.vectorTileMark = `https://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TIAN_DI_TU_KEY}`, e.satelliteImgTile = `https://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TIAN_DI_TU_KEY}`, e.satelliteImgTileMark = `https://t0.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TIAN_DI_TU_KEY}`, e.greenTile = `${CDN_URL}/map/tile/{z}/{x}/{y}.png`, e))(BASE_MAP_LINK || {}), LENGTH_UNIT = /* @__PURE__ */ ((e) => (e[e.M = 1] = "M", e[e.KM = 2] = "KM", e[e.NM = 3] = "NM", e))(LENGTH_UNIT || {});
121
- const getLayers = () => {
122
- var e;
123
- return (e = getInstall()) == null ? void 0 : e.getLayers();
124
- }, layerType = ref("vector"), getShowLayerType = () => layerType.value, setShowLayerType = (e) => {
125
- layerType.value = e;
126
- const t = getLayers();
127
- t && t.getArray().forEach((o) => {
128
- o.setVisible(o.className_ === e);
129
- });
130
- }, showGreenTile = ref(), getGreenTileVisible = () => showGreenTile.value, setGreenTileVisible = (e) => {
131
- if (e !== showGreenTile.value) {
132
- if (e) {
133
- const t = getLayers();
134
- if (!t.getArray().find((n) => n.className_ === "greenTile")) {
135
- const n = new TileLayer({
136
- source: new XYZ({ url: BASE_MAP_LINK.greenTile }),
137
- visible: e,
138
- zIndex: 2,
139
- className: "greenTile"
140
- });
141
- t.push(n);
142
- }
143
- } else {
144
- const t = getLayers(), o = t.getArray().find((n) => n.className_ === "greenTile");
145
- o && t.remove(o);
146
- }
147
- showGreenTile.value = e;
148
- }
149
- }, pixelRatio$1 = window.devicePixelRatio || 1, labelFont$1 = `${12 * pixelRatio$1}px Arial`, collisionTree$1 = new RBush$1(), features = /* @__PURE__ */ new Map(), animationFrameIds$1 = /* @__PURE__ */ new Map(), labels$1 = /* @__PURE__ */ new Map();
150
- let currentLabelId = null, metrics = { width: 0, height: 0, textWidth: 0 };
151
- const options$1 = {
152
- padding: 4,
153
- iconSize: 12,
154
- lineColor: "#fff",
155
- blinkInterval: 500,
156
- collisionPadding: 10
157
- };
158
- function getIconFont(unicode = "") {
159
- return unicode.indexOf("&amp;") !== -1 && (unicode = unicode.replace("&amp;", "&")), unicode.indexOf("&amp") !== -1 && (unicode = unicode.replace("&amp", "&")), eval('("' + unicode.replace("&#x", "\\u").replace(";", "") + '")');
160
- }
161
- const getFeatureById = (e) => features.get(e), checkCollision$1 = (e) => {
162
- const t = options$1.collisionPadding, o = {
163
- minX: e[0] - t,
164
- minY: e[1] - t,
165
- maxX: e[2] + t,
166
- maxY: e[3] + t
167
- }, n = collisionTree$1.search(o);
168
- return currentLabelId && n.length > 0 ? n.some((r) => r.id !== currentLabelId) : n.length > 0;
169
- }, calculateTextMetrics$1 = (e, t, o) => {
170
- var i;
171
- e.font = "500 " + labelFont$1;
172
- const n = e.measureText(t.name).width, r = o ? 12 * devicePixelRatio + 10 : 0, a = (((i = t.rightIcons) == null ? void 0 : i.length) || 0) * (options$1.iconSize * devicePixelRatio + 6);
173
- return {
174
- width: r + options$1.padding * 2 + n + a,
175
- textWidth: n,
176
- height: parseInt(labelFont$1) * 1.2
177
- };
178
- }, calculateBestPosition$1 = (e, t) => {
179
- const o = [
180
- { position: "right", alignment: "center" },
181
- // 右侧居中
182
- { position: "left", alignment: "center" },
183
- // 左侧居中
184
- { position: "top", alignment: "center" },
185
- // 上方居中
186
- { position: "bottom", alignment: "center" },
187
- // 下方居中
188
- { position: "right", alignment: "start" },
189
- // 右侧顶部对齐
190
- { position: "right", alignment: "end" },
191
- // 右侧底部对齐
192
- { position: "left", alignment: "start" },
193
- // 左侧顶部对齐
194
- { position: "left", alignment: "end" },
195
- // 左侧底部对齐
196
- { position: "top", alignment: "start" },
197
- // 上方左侧对齐
198
- { position: "top", alignment: "end" },
199
- // 上方右侧对齐
200
- { position: "bottom", alignment: "start" },
201
- // 下方左侧对齐
202
- { position: "bottom", alignment: "end" }
203
- // 下方右侧对齐
204
- ];
205
- for (const { position: r, alignment: a } of o) {
206
- const i = calculateBounds$1(e, r, a, t);
207
- if (!checkCollision$1(i))
208
- return {
209
- bounds: i,
210
- position: r,
211
- connectionPoints: calculateConnectionPoints$1(e, i, r, a)
212
- };
213
- }
214
- const n = calculateBounds$1(e, "right", "start", t);
215
- return {
216
- bounds: n,
217
- position: "right",
218
- connectionPoints: calculateConnectionPoints$1(e, n, "right", "start")
219
- };
220
- }, calculateConnectionPoints$1 = (e, t, o, n) => {
221
- const [r, a, i, s] = t, d = [r + (i - r) / 2, a + (s - a) / 2];
222
- switch (o) {
223
- case "right":
224
- return n === "center" ? { start: e, end: [r, d[1]] } : n === "start" ? { start: e, end: [r, a + 10] } : { start: e, end: [r, s - 10] };
225
- case "left":
226
- return n === "center" ? { start: e, end: [i, d[1]] } : n === "start" ? { start: e, end: [i, a + 10] } : { start: e, end: [i, s - 10] };
227
- case "top":
228
- return n === "center" ? { start: e, end: [d[0], s] } : n === "start" ? { start: e, end: [r + 10, s] } : { start: e, end: [i - 10, s] };
229
- case "bottom":
230
- return n === "center" ? { start: e, end: [d[0], a] } : n === "start" ? { start: e, end: [r + 10, a] } : { start: e, end: [i - 10, a] };
231
- default:
232
- return { start: e, end: [r, d[1]] };
233
- }
234
- }, calculateBounds$1 = (e, t, o, n, r = 30) => {
235
- const [a, i] = e, { width: s, height: d } = n;
236
- switch (t) {
237
- case "right": {
238
- const u = a + r;
239
- let l;
240
- return o === "center" ? l = i - d / 2 : o === "start" ? l = i : l = i - d, [u, l, u + s, l + d];
241
- }
242
- case "left": {
243
- const u = a - s - r;
244
- let l;
245
- return o === "center" ? l = i - d / 2 : o === "start" ? l = i : l = i - d, [u, l, u + s, l + d];
246
- }
247
- case "top": {
248
- const u = i - d - r;
249
- let l;
250
- return o === "center" ? l = a - s / 2 : o === "start" ? l = a : l = a - s, [l, u, l + s, u + d];
251
- }
252
- case "bottom": {
253
- const u = i + r;
254
- let l;
255
- return o === "center" ? l = a - s / 2 : o === "start" ? l = a : l = a - s, [l, u, l + s, u + d];
256
- }
257
- default:
258
- return [a + r, i - d / 2, a + s + r, i + d / 2];
259
- }
260
- }, updateCollisionTree = (e, t) => {
261
- if (labels$1.has(e)) {
262
- const o = labels$1.get(e);
263
- collisionTree$1.remove({
264
- minX: o.bounds[0] - options$1.collisionPadding,
265
- minY: o.bounds[1] - options$1.collisionPadding,
266
- maxX: o.bounds[2] + options$1.collisionPadding,
267
- maxY: o.bounds[3] + options$1.collisionPadding,
268
- id: e
269
- });
270
- }
271
- collisionTree$1.insert({
272
- minX: t.bounds[0] - options$1.collisionPadding,
273
- minY: t.bounds[1] - options$1.collisionPadding,
274
- maxX: t.bounds[2] + options$1.collisionPadding,
275
- maxY: t.bounds[3] + options$1.collisionPadding,
276
- id: e
277
- }), labels$1.set(e, {
278
- id: e,
279
- bounds: t.bounds,
280
- position: t.position,
281
- connectionPoints: t.connectionPoints
282
- });
283
- }, drawConnectionLine$1 = (e, t, o) => {
284
- e.save(), e.beginPath(), e.moveTo(...t), e.lineTo(...o), e.strokeStyle = options$1.lineColor, e.lineWidth = 1, e.stroke(), e.restore();
285
- }, drawLabelBackground$1 = (e, t, o) => {
286
- const n = createRoundedRectPath$1(t, metrics);
287
- e.save(), e.fillStyle = o.blinking ? o.blinkingColor || "#FFF" : "rgba(255, 255, 255, 1)", e.fill(n), e.strokeStyle = options$1.lineColor, e.stroke(), e.restore();
288
- }, drawLabelContent$1 = (e, t, o, n, r) => {
289
- var u;
290
- const a = options$1.padding, i = r ? 12 * devicePixelRatio + 6 : 0, [s, d] = [
291
- t.bounds[0] + i + a,
292
- // 关键修复点:基于原始bounds计算
293
- t.bounds[1] + parseInt(labelFont$1)
294
- ];
295
- if (e.save(), e.fillStyle = n ? "#ffffff" : "#000000", e.font = `500 ${labelFont$1}`, e.fillText(o.name, s, d), (u = o.rightIcons) != null && u.length) {
296
- const l = e.measureText(o.name).width, c = options$1.iconSize * pixelRatio$1;
297
- e.font = `${c}px map-iconfont`, o.rightIcons.forEach((p, m) => {
298
- const h = s + l + a + m * (c + 4), g = getIconFont(p);
299
- g && e.fillText(g, h, d);
300
- });
301
- }
302
- e.restore();
303
- }, createRoundedRectPath$1 = (e, t) => {
304
- const [o, n] = e, r = 0, a = new Path2D(), i = o + t.width + options$1.padding, s = n + t.height;
305
- return a.moveTo(o + r, n), a.lineTo(i - r, n), a.quadraticCurveTo(i, n, i, n + r), a.lineTo(i, s - r), a.quadraticCurveTo(i, s, i - r, s), a.lineTo(o + r, s), a.quadraticCurveTo(o, s, o, s - r), a.lineTo(o, n + r), a.quadraticCurveTo(o, n, o + r, n), a.closePath(), a;
306
- }, handleBlinkAnimation$1 = (e, t, o, n) => {
307
- const r = n.blinkingColor || "#FF0";
308
- clearAnimation$1(e, t);
309
- const a = createRoundedRectPath$1(o.bounds, metrics);
310
- let i = !1, s = 0;
311
- const d = (u) => {
312
- if (u - s > options$1.blinkInterval) {
313
- s = u, e.save(), e.clip(a), e.clearRect(...o.bounds), e.fillStyle = i ? r : "rgba(255, 255, 255, 1)", e.fill(a);
314
- const l = 12 * devicePixelRatio, c = o.bounds[0] + 4, p = o.bounds[1] + (o.bounds[3] - o.bounds[1] - l) / 2;
315
- e.fillStyle = r, e.fillRect(c, p, l, l), drawLabelContent$1(
316
- e,
317
- o,
318
- n,
319
- i,
320
- !0
321
- ), i = !i, e.restore();
322
- }
323
- animationFrameIds$1.set(t, requestAnimationFrame(d));
324
- };
325
- animationFrameIds$1.set(t, requestAnimationFrame(d));
326
- }, clearAll = () => {
327
- clearAllAnimations(), collisionTree$1.clear(), labels$1.clear(), features.clear();
328
- }, clearAllAnimations = () => {
329
- animationFrameIds$1.forEach((e) => cancelAnimationFrame(e)), animationFrameIds$1.clear();
330
- }, clearAnimation$1 = (e, t) => {
331
- if (animationFrameIds$1.has(t)) {
332
- cancelAnimationFrame(animationFrameIds$1.get(t)), animationFrameIds$1.delete(t);
333
- const o = labels$1.get(t);
334
- if (o) {
335
- e.save();
336
- const n = createRoundedRectPath$1(o.bounds, metrics);
337
- e.fillStyle = "rgba(255, 255, 255, 1)", e.fill(n);
338
- const r = getFeatureById(t);
339
- r && drawLabelContent$1(
340
- e,
341
- { bounds: o.bounds },
342
- // 需要传入对应feature(建议存储feature引用)
343
- r,
344
- !1,
345
- r.blinking
346
- ), e.restore();
347
- }
348
- }
349
- }, createLabelRenderer$1 = (e, t, o) => {
350
- currentLabelId = o.id, features.set(currentLabelId, o);
351
- const n = o.blinking || !1;
352
- metrics = calculateTextMetrics$1(e, o, n);
353
- const r = calculateBestPosition$1(t, metrics);
354
- console.log("labelPos", r), drawConnectionLine$1(e, r.connectionPoints.start, r.connectionPoints.end), drawLabelBackground$1(e, r.bounds, o), drawLabelContent$1(e, r, o, !1, n), n ? handleBlinkAnimation$1(e, currentLabelId, r, o) : clearAnimation$1(e, currentLabelId), updateCollisionTree(currentLabelId, r);
355
- };
356
- new RBush$1();
357
- var SHIP_SAIL_STATUS = /* @__PURE__ */ ((e) => (e[e.发动机使用中 = 0] = "发动机使用中", e[e.锚泊 = 1] = "锚泊", e[e.未操作 = 2] = "未操作", e[e.操纵能力受限 = 3] = "操纵能力受限", e[e.吃水受限 = 4] = "吃水受限", e[e.系泊 = 5] = "系泊", e[e.搁浅 = 6] = "搁浅", e[e.从事捕捞 = 7] = "从事捕捞", e[e.航行中 = 8] = "航行中", e[e.留作将来修正导航状态 = 9] = "留作将来修正导航状态", e[e.高速船留用 = 10] = "高速船留用", e[e.机动船尾推作业 = 11] = "机动船尾推作业", e[e.机动船顶推或侧推作业 = 12] = "机动船顶推或侧推作业", e[e.飞翼船留用 = 13] = "飞翼船留用", e[e.现行的 = 14] = "现行的", e[e.未定义 = 15] = "未定义", e))(SHIP_SAIL_STATUS || {}), SHIP_DIRECT = /* @__PURE__ */ ((e) => (e.left = "left", e.right = "right", e.front = "front", e.up = "up", e.down = "down", e.back = "back", e))(SHIP_DIRECT || {});
358
- const shipsSource$1 = new VectorSource(), shipsLayer$1 = new VectorLayer({
359
- source: shipsSource$1,
360
- className: "zh-map--ship-layer",
361
- updateWhileInteracting: !1,
362
- updateWhileAnimating: !1,
363
- renderBuffer: 300,
364
- zIndex: 101
365
- });
366
- let selectedShipId = "", selectedShip, selectedShipFeature$1 = null, hoveredShipId$1 = "", attentionShips$1 = {}, attentionShipsColor$1 = {}, isZooming = !1, lastZoomTime = 0, lastScale = 1;
367
- const ZOOM_ANIMATION_DURATION = 300, config$2 = {
368
- color: "#04C900"
369
- }, isLayerOnMap = (e, t) => e.getLayers().getArray().includes(t);
370
- debounce((e) => {
371
- const t = getInstall();
372
- if (!t) return;
373
- isLayerOnMap(t, shipsLayer$1) || t.addLayer(shipsLayer$1), selectedShipFeature$1 = null, clearShipList$1(), selectedShipId && selectedShip && e.filter((r) => r.id === selectedShipId).length === 0 && e.push(selectedShip);
374
- const o = [];
375
- e.forEach((n) => {
376
- const r = [];
377
- n.existDevice && r.push("&#xe687;"), n.existMobile && r.push("&#xe688;"), n.existWaterGauge && r.push("&#xe686;");
378
- const a = {
379
- ...n,
380
- name: n.cnname || "未命名船舶",
381
- iconSize: 12,
382
- leftIcons: [],
383
- blinking: attentionShips$1[n.id] || !1,
384
- blinkingColor: attentionShipsColor$1[n.id] || "",
385
- rightIcons: r
386
- }, i = new Feature({
387
- geometry: new Point(fromLonLat([n.lon, n.lat])),
388
- id: n.id,
389
- shipId: n.id,
390
- selected: selectedShipId === n.id || n.isSelected,
391
- color: n.fill,
392
- direct: getShipDirectPath$1(n),
393
- hightlight: !1,
394
- shipData: a
395
- });
396
- i.setId(n.id), i.setStyle(createShipStyle$1(i)), (selectedShipId === n.id || n.isSelected) && (selectedShipFeature$1 = i), o.push(i);
397
- }), shipsSource$1.addFeatures(o);
398
- }, 10);
399
- function easeOutCubic(e) {
400
- return 1 - Math.pow(1 - e, 3);
401
- }
402
- const getImageSizeAndScale = (e, t) => {
403
- const o = getInstall(), n = Math.round(Number(o.getView().getZoom())), r = Date.now();
404
- isZooming = r - lastZoomTime < ZOOM_ANIMATION_DURATION;
405
- const a = n <= MAP_ZOOM.shipModelMax && n >= MAP_ZOOM.shipTriggleMin ? "ship" : "triangle";
406
- let i = 0;
407
- if (a === "ship") {
408
- const s = getShipScale$1(e, t) + 0.1;
409
- if (isZooming) {
410
- const d = Math.min(1, (r - lastZoomTime) / ZOOM_ANIMATION_DURATION), u = easeOutCubic(d);
411
- i = lastScale * (1 - u) + s * u;
412
- } else
413
- i = s;
414
- }
415
- return { type: a, scale: i };
416
- }, createShipStyle$1 = (e) => {
417
- const t = e.getProperties(), { selected: o, shipData: n } = t, { wid: r, len: a } = n, { scale: i, type: s } = getImageSizeAndScale(a, r);
418
- e.set("lastScale", i, !0);
419
- const u = [baseStyle(e)];
420
- if (o) {
421
- const c = generateSelectedSvg(i, s);
422
- u.push(c);
423
- }
424
- const l = createLabelStyle$1();
425
- return l && u.push(l), u;
426
- }, baseStyle = (e) => {
427
- const t = e.getProperties(), { len: o, wid: n, color: r, selected: a, hightlight: i, shipData: s, direct: d } = t, { blinkingColor: u } = s, { scale: l, type: c } = getImageSizeAndScale(o, n), p = (s.cog - 90 + 360) % 360;
428
- return new Style({
429
- image: new Icon({
430
- src: generateSvg(c, a, i, u || r, d),
431
- scale: l || MAP_ZOOM.scaleNum,
432
- anchor: [0.5, 0.5],
433
- rotation: p * Math.PI / 180,
434
- rotateWithView: !1,
435
- opacity: isZooming ? 0.8 : 1
436
- }),
437
- zIndex: 98
438
- });
439
- }, generateSelectedSvg = (e, t) => {
440
- const o = t === "ship" ? 109 : 49, n = `<svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${o}" viewBox="0 0 49 49" fill="none">
441
- <path d="M1.99982 46.9998L1.99982 1.99982L46.9998 1.99982L46.9998 46.9998L1.99982 46.9998Z" fill="#FF2424" fill-opacity="0.2"/>
442
- <path fill-rule="evenodd" clip-rule="evenodd" d="M19.9998 0.5V3.5L3.49976 3.5V20H0.499756V0.500002L19.9998 0.5ZM45.4998 3.5H28.9998V0.5H48.4998V20H45.4998V3.5ZM48.4998 29L48.4998 48.5H28.9998V45.5H45.4998L45.4998 29H48.4998ZM3.49976 45.5L3.49976 29H0.499756L0.499758 48.5L19.9998 48.5V45.5L3.49976 45.5Z" fill="#FF2424"/>
443
- </svg>`;
444
- return new Style({
445
- image: new Icon({
446
- src: `data:image/svg+xml;utf8,${encodeURIComponent(n)}`,
447
- scale: e || MAP_ZOOM.scaleNum
448
- }),
449
- zIndex: 100
450
- });
451
- }, createLabelStyle$1 = () => new Style({
452
- renderer: (e, t) => {
453
- try {
454
- e = e;
455
- const o = t.context, n = t.feature.getProperties().shipData;
456
- if (!n) return;
457
- createLabelRenderer$1(o, e, n);
458
- return;
459
- } catch (o) {
460
- console.error(o);
461
- }
462
- },
463
- zIndex: 99
464
- });
465
- debounce((e, t, o) => {
466
- const n = getInstall();
467
- if (e && e.get("shipId")) {
468
- const r = e.get("shipId"), a = e.get("shipId");
469
- if (t === "click" && a && (handleShipSelected(a), o && o(a, !0)), t === "hover") {
470
- hoveredShipId$1 && hoveredShipId$1 !== r && clearHoverHight$1(), hoveredShipId$1 = r, n.getTargetElement().style.cursor = r ? "pointer" : "";
471
- const i = hoveredShipId$1 ? shipsSource$1.getFeatureById(hoveredShipId$1) : null;
472
- i == null || i.set("hightlight", !0), i == null || i.setStyle(createShipStyle$1(i));
473
- }
474
- } else
475
- n.getTargetElement().style.cursor = "", clearHoverHight$1();
476
- }, 10);
477
- const clearHoverHight$1 = () => {
478
- const e = hoveredShipId$1 ? shipsSource$1.getFeatureById(hoveredShipId$1) : null;
479
- hoveredShipId$1 = null, e == null || e.set("hightlight", !1), e == null || e.setStyle(createShipStyle$1(e));
480
- }, handleShipSelected = useDebounceFn((e) => {
481
- const t = selectedShipId ? shipsSource$1.getFeatureById(selectedShipId) : null;
482
- if (selectedShipId = selectedShipId === e ? null : e, t && (t.set("selected", !1), t == null || t.setStyle(createShipStyle$1(t))), selectedShipId) {
483
- const o = shipsSource$1.getFeatureById(selectedShipId);
484
- o && (o.set("selected", !0), o == null || o.setStyle(createShipStyle$1(o)));
485
- }
486
- }, 50, { maxWait: 100 }), getShipDirectPath$1 = (e) => {
487
- const { spd: t, hdg: o, cog: n } = e;
488
- let r = "";
489
- return t && o && n ? n - +o >= 3 ? r = SHIP_DIRECT.right : n - +o <= -3 ? r = SHIP_DIRECT.left : r = SHIP_DIRECT.front : r = SHIP_DIRECT.front, r;
490
- };
491
- function getShipScale$1(e, t) {
492
- const o = getInstall(), n = 97, r = 20, i = 1 / o.getView().getResolution(), s = e * i / n, d = t * i / r;
493
- return Math.max(s, d);
494
- }
495
- const handleShipChange = () => {
496
- lastZoomTime = Date.now(), isZooming = !0;
497
- const e = shipsSource$1.getFeatures();
498
- e.length > 0 && (lastScale = e[0].get("lastScale") || 1), shipsLayer$1.changed(), console.log("changeRecation---changed");
499
- }, generateSvg = (e, t, o, n, r) => `data:image/svg+xml;utf8,${encodeURIComponent(createSvgIcon(e, o, n, r))}`, createSvgIcon = (e, t, o, n) => {
500
- switch (e) {
501
- case "triangle":
502
- return `<svg width="41" height="24" viewBox="0 0 41 24" fill="none" xmlns="http://www.w3.org/2000/svg">
503
- <path d="M30.8843 12.6777L2.21343 21.7067C1.75559 21.8509 1.28947 21.509 1.28947 21.029L1.28947 2.97103C1.28947 2.49102 1.75558 2.14913 2.21342 2.29331L30.8843 11.3223C31.5471 11.531 31.5471 12.469 30.8843 12.6777Z"
504
- fill="${o || config$2.color}" stroke="${t ? "#FF2424" : "black"}" stroke-width="${t ? "2" : "0.578947"}" />
505
- <!--path船航向左边或者向前-->
506
- ${n === SHIP_DIRECT.left && `<path d="M30 12L40 12L40 8" stroke="${t ? "#FF2424" : "black"}" stroke-width="2"/>`}
507
- <!--path船航向右边-->
508
- ${n === SHIP_DIRECT.right && `<path d="M30 12L40 12L40 16" stroke="${t ? "#FF2424" : "black"}" stroke-width="2"/>`}
509
- <!--path黑线无左右-->
510
- ${n === SHIP_DIRECT.front && `<path d="M30 12L40 12" stroke="${t ? "#FF2424" : "black"}" stroke-width="1.5"/>`}
511
- </svg>
512
- `;
513
- case "ship":
514
- return `<svg width="97" height="20" viewBox="0 0 97 20" fill="none" xmlns="http://www.w3.org/2000/svg">
515
- <path d="M0.289474 17.3433L0.289474 2.65655C0.289474 2.28572 0.574654 1.97725 0.944343 1.9482L22.0544 0.289473L67.5204 0.289473C67.6295 0.289473 67.7372 0.314613 67.835 0.362943L86.0565 9.3629C86.5844 9.6236 86.5844 10.3763 86.0565 10.637L67.835 19.6371C67.7372 19.6854 67.6295 19.7105 67.5203 19.7105L22.0544 19.7105L0.944343 18.0517C0.574653 18.0226 0.289474 17.7142 0.289474 17.3433Z"
516
- fill="${o || config$2.color}" stroke="${t ? "#FF2424" : "black"}" stroke-width="${t ? "2" : "0.578947"}"/>
517
- ${n === SHIP_DIRECT.left && `<path d="M86 10L96 10L96 6" stroke="${t ? "#FF2424" : "black"}" stroke-width="1.5"/>`}
518
- ${n === SHIP_DIRECT.right && `<path d="M86 10L96 10L96 14" stroke="${t ? "#FF2424" : "black"}" stroke-width="1.5"/>`}
519
- ${n === SHIP_DIRECT.front && `<path d="M86 10L96 10" stroke="${t ? "#FF2424" : "black"}" stroke-width="1.5"/>`}
520
- </svg>
521
- `;
522
- default:
523
- return "";
524
- }
525
- }, clearShipList$1 = () => {
526
- getInstall() && shipsSource$1 && (shipsSource$1.getFeatures().forEach((t) => {
527
- var o;
528
- (!selectedShipFeature$1 || t.get("shipData").shipId !== ((o = selectedShipFeature$1.get("shipData")) == null ? void 0 : o.id)) && shipsSource$1.removeFeature(t);
529
- }), shipsSource$1 && shipsSource$1.clear(), clearAll());
530
- }, getRightIcons = (e) => {
531
- const t = [];
532
- return e.existDevice && t.push("&#xe687;"), e.existMobile && t.push("&#xe688;"), e.existWaterGauge && t.push("&#xe686;"), t;
533
- }, createLabelRenderer = (e, t, o) => {
534
- if (console.log("createLabelRenderer"), !e) return;
535
- const n = calculateTextMetrics(e, o), r = calculateBestPosition(t, n);
536
- if (!r) return;
537
- drawConnectionLine(e, t, r.connectionPoints.end), drawLabelBackground(e, r.bounds, o, n), drawLabelContent(e, o, r), o.get("blinking") || !1 ? handleBlinkAnimation(e, o, r, n) : clearAnimation(e, o, n);
538
- }, pixelRatio = window.devicePixelRatio || 1, labelFont = `${12 * pixelRatio}px Arial`, options = {
539
- padding: 4,
540
- iconSize: 12,
541
- lineColor: "#fff",
542
- blinkInterval: 500,
543
- collisionPadding: 10
544
- }, calculateTextMetrics = (e, t) => {
545
- var a;
546
- e.font = `500 ${labelFont}`;
547
- const o = e.measureText(t.get("name")).width, n = t.get("selected") ? 12 * devicePixelRatio + 10 : 0, r = (((a = t.get("rightIcons")) == null ? void 0 : a.length) || 0) * (options.iconSize * devicePixelRatio + 6);
548
- return {
549
- width: n + options.padding * 2 + o + r,
550
- textWidth: o,
551
- height: parseInt(labelFont) * 1.2
552
- };
553
- }, calculateBestPosition = (e, t) => {
554
- const o = [
555
- { position: "right", alignment: "center" },
556
- // 右侧居中
557
- { position: "left", alignment: "center" },
558
- // 左侧居中
559
- { position: "top", alignment: "center" },
560
- // 上方居中
561
- { position: "bottom", alignment: "center" },
562
- // 下方居中
563
- { position: "right", alignment: "start" },
564
- // 右侧顶部对齐
565
- { position: "right", alignment: "end" },
566
- // 右侧底部对齐
567
- { position: "left", alignment: "start" },
568
- // 左侧顶部对齐
569
- { position: "left", alignment: "end" },
570
- // 左侧底部对齐
571
- { position: "top", alignment: "start" },
572
- // 上方左侧对齐
573
- { position: "top", alignment: "end" },
574
- // 上方右侧对齐
575
- { position: "bottom", alignment: "start" },
576
- // 下方左侧对齐
577
- { position: "bottom", alignment: "end" }
578
- // 下方右侧对齐
579
- ];
580
- for (const { position: n, alignment: r } of o) {
581
- const a = calculateBounds(e, n, r, t);
582
- if (!checkCollision(a))
583
- return {
584
- bounds: a,
585
- position: n,
586
- connectionPoints: calculateConnectionPoints(e, a, n, r)
587
- };
588
- }
589
- }, calculateBounds = (e, t, o, n, r = 30) => {
590
- const [a, i] = e, { width: s, height: d } = n;
591
- switch (t) {
592
- case "right": {
593
- const u = a + r;
594
- let l;
595
- return o === "center" ? l = i - d / 2 : o === "start" ? l = i : l = i - d, [u, l, u + s, l + d];
596
- }
597
- case "left": {
598
- const u = a - s - r;
599
- let l;
600
- return o === "center" ? l = i - d / 2 : o === "start" ? l = i : l = i - d, [u, l, u + s, l + d];
601
- }
602
- case "top": {
603
- const u = i - d - r;
604
- let l;
605
- return o === "center" ? l = a - s / 2 : o === "start" ? l = a : l = a - s, [l, u, l + s, u + d];
606
- }
607
- case "bottom": {
608
- const u = i + r;
609
- let l;
610
- return o === "center" ? l = a - s / 2 : o === "start" ? l = a : l = a - s, [l, u, l + s, u + d];
611
- }
612
- default:
613
- return [a + r, i - d / 2, a + s + r, i + d / 2];
614
- }
615
- }, collisionTree = new RBush$1(), checkCollision = (e) => {
616
- const t = options.collisionPadding, o = {
617
- minX: e[0] - t,
618
- minY: e[1] - t,
619
- maxX: e[2] + t,
620
- maxY: e[3] + t
621
- };
622
- return collisionTree.search(o).length > 0;
623
- }, calculateConnectionPoints = (e, t, o, n) => {
624
- const [r, a, i, s] = t, d = [r + (i - r) / 2, a + (s - a) / 2];
625
- switch (o) {
626
- case "right":
627
- return n === "center" ? { start: e, end: [r, d[1]] } : n === "start" ? { start: e, end: [r, a + 10] } : { start: e, end: [r, s - 10] };
628
- case "left":
629
- return n === "center" ? { start: e, end: [i, d[1]] } : n === "start" ? { start: e, end: [i, a + 10] } : { start: e, end: [i, s - 10] };
630
- case "top":
631
- return n === "center" ? { start: e, end: [d[0], s] } : n === "start" ? { start: e, end: [r + 10, s] } : { start: e, end: [i - 10, s] };
632
- case "bottom":
633
- return n === "center" ? { start: e, end: [d[0], a] } : n === "start" ? { start: e, end: [r + 10, a] } : { start: e, end: [i - 10, a] };
634
- default:
635
- return { start: e, end: [r, d[1]] };
636
- }
637
- }, drawConnectionLine = (e, t, o) => {
638
- e.save(), e.beginPath(), e.moveTo(...t), e.lineTo(...o), e.strokeStyle = options.lineColor, e.lineWidth = 1, e.stroke(), e.restore();
639
- }, drawLabelBackground = (e, t, o, n) => {
640
- const r = createRoundedRectPath(t, n);
641
- e.save(), e.fillStyle = o.get("blinking") ? o.get("blinkingColor") || "#FFF" : "rgba(255, 255, 255, 1)", e.fill(r), e.strokeStyle = options.lineColor, e.stroke(), e.restore();
642
- }, createRoundedRectPath = (e, t) => {
643
- const [o, n] = e, r = 0, a = new Path2D(), i = o + t.width + options.padding, s = n + t.height;
644
- return a.moveTo(o + r, n), a.lineTo(i - r, n), a.quadraticCurveTo(i, n, i, n + r), a.lineTo(i, s - r), a.quadraticCurveTo(i, s, i - r, s), a.lineTo(o + r, s), a.quadraticCurveTo(o, s, o, s - r), a.lineTo(o, n + r), a.quadraticCurveTo(o, n, o + r, n), a.closePath(), a;
645
- }, drawLabelContent = (ctx, feature, labelPos) => {
646
- const isSelected = feature.get("selected"), isHighlight = feature.get("isHighlight"), name = feature.get("name"), rightIcons = feature.get("rightIcons") || [], basePadding = options.padding, contentOffset = isSelected ? 12 * devicePixelRatio + 6 : 0, [x, y] = [
647
- labelPos.bounds[0] + contentOffset + basePadding,
648
- // 关键修复点:基于原始bounds计算
649
- labelPos.bounds[1] + parseInt(labelFont)
650
- ];
651
- if (ctx.save(), ctx.fillStyle = isHighlight ? "#ffffff" : "#000000", ctx.font = `500 ${labelFont}`, ctx.fillText(name, x, y), rightIcons != null && rightIcons.length) {
652
- const e = ctx.measureText(name).width, t = options.iconSize * pixelRatio;
653
- ctx.font = `${t}px map-iconfont`, rightIcons.forEach((o, n) => {
654
- const r = x + e + basePadding + n * (t + 4), a = getIconFont(o);
655
- a && ctx.fillText(a, r, y);
656
- });
657
- }
658
- ctx.restore();
659
- function getIconFont(unicode = "") {
660
- return unicode.indexOf("&amp;") !== -1 && (unicode = unicode.replace("&amp;", "&")), unicode.indexOf("&amp") !== -1 && (unicode = unicode.replace("&amp", "&")), eval('("' + unicode.replace("&#x", "\\u").replace(";", "") + '")');
661
- }
662
- }, animationFrameIds = /* @__PURE__ */ new Map(), labels = /* @__PURE__ */ new Map(), handleBlinkAnimation = (e, t, o, n) => {
663
- const r = t.get("blinkingColor") || "#FF0";
664
- clearAnimation(e, t, n);
665
- const a = createRoundedRectPath(o.bounds, n);
666
- let i = !1, s = 0;
667
- const d = (u) => {
668
- if (u - s > options.blinkInterval) {
669
- s = u, e.save(), e.clip(a), e.clearRect(...o.bounds), e.fillStyle = i ? r : "rgba(255, 255, 255, 1)", e.fill(a);
670
- const l = 12 * devicePixelRatio, c = o.bounds[0] + 4, p = o.bounds[1] + (o.bounds[3] - o.bounds[1] - l) / 2;
671
- e.fillStyle = r, e.fillRect(c, p, l, l), drawLabelContent(
672
- e,
673
- t,
674
- o
675
- ), i = !i, e.restore();
676
- }
677
- animationFrameIds.set(t.get("id"), requestAnimationFrame(d));
678
- };
679
- animationFrameIds.set(t.get("id"), requestAnimationFrame(d));
680
- }, clearAnimation = (e, t, o) => {
681
- const n = t.get("id");
682
- if (animationFrameIds.has(n)) {
683
- cancelAnimationFrame(animationFrameIds.get(n)), animationFrameIds.delete(n);
684
- const r = labels.get(n);
685
- if (r) {
686
- e.save();
687
- const a = createRoundedRectPath(r.bounds, o);
688
- e.fillStyle = "rgba(255, 255, 255, 1)", e.fill(a), t && drawLabelContent(
689
- e,
690
- t,
691
- r
692
- ), e.restore();
693
- }
694
- }
695
- }, getShipDirectPath = (e) => {
696
- const { spd: t, hdg: o, cog: n } = e;
697
- return t ? o !== null && +o != 511 && n !== null ? n - +o >= 3 ? SHIP_DIRECT.right : n - +o <= -3 ? SHIP_DIRECT.left : SHIP_DIRECT.front : SHIP_DIRECT.front : "";
698
- }, createShipStyle = (e) => {
699
- const { selected: t } = e.getProperties(), o = getShipType(), n = getShipScale(e, o), r = [initShipStyle(e, n, o)];
700
- return t && r.push(selectedShipStyle(n, o)), r.push(createLabelStyle(e)), r;
701
- }, getShipType = () => {
702
- const e = getZoom();
703
- return e <= MAP_ZOOM.shipModelMax && e >= MAP_ZOOM.shipTriggleMin ? "ship" : "triangle";
704
- }, getShipScale = (e, t) => {
705
- if (t === "ship") {
706
- const { shipData: o } = e.getProperties(), { len: n, wid: r } = o, a = 97, i = 20, d = 1 / getView().getResolution(), u = n * d / a, l = r * d / i;
707
- return Math.max(u, l);
708
- }
709
- return 0;
710
- }, initShipStyle = (e, t, o) => {
711
- const { color: n, direct: r, isHighlight: a, shipData: i } = e.getProperties(), s = (i.cog - 90 + 360) % 360;
712
- return new Style({
713
- image: new Icon({
714
- src: d(),
715
- scale: t || MAP_ZOOM.scaleNum,
716
- anchor: [0.5, 0.5],
717
- rotation: s * Math.PI / 180,
718
- rotateWithView: !1
719
- })
720
- });
721
- function d() {
722
- return `data:image/svg+xml;utf8,${encodeURIComponent(u())}`;
723
- }
724
- function u() {
725
- switch (o) {
726
- case "triangle":
727
- return `<svg width="41" height="24" viewBox="0 0 41 24" fill="none" xmlns="http://www.w3.org/2000/svg">
728
- <path d="M30.8843 12.6777L2.21343 21.7067C1.75559 21.8509 1.28947 21.509 1.28947 21.029L1.28947 2.97103C1.28947 2.49102 1.75558 2.14913 2.21342 2.29331L30.8843 11.3223C31.5471 11.531 31.5471 12.469 30.8843 12.6777Z"
729
- fill="${n}" stroke="${a ? "#FF2424" : "black"}" stroke-width="${a ? "2" : "0.578947"}" />
730
- <!--path船航向左边或者向前-->
731
- ${r === SHIP_DIRECT.left && `<path d="M30 12L40 12L40 8" stroke="${a ? "#FF2424" : "black"}" stroke-width="2"/>`}
732
- <!--path船航向右边-->
733
- ${r === SHIP_DIRECT.right && `<path d="M30 12L40 12L40 16" stroke="${a ? "#FF2424" : "black"}" stroke-width="2"/>`}
734
- <!--path黑线无左右-->
735
- ${r === SHIP_DIRECT.front && `<path d="M30 12L40 12" stroke="${a ? "#FF2424" : "black"}" stroke-width="1.5"/>`}
736
- </svg>
737
- `;
738
- case "ship":
739
- return `<svg width="97" height="20" viewBox="0 0 97 20" fill="none" xmlns="http://www.w3.org/2000/svg">
740
- <path d="M0.289474 17.3433L0.289474 2.65655C0.289474 2.28572 0.574654 1.97725 0.944343 1.9482L22.0544 0.289473L67.5204 0.289473C67.6295 0.289473 67.7372 0.314613 67.835 0.362943L86.0565 9.3629C86.5844 9.6236 86.5844 10.3763 86.0565 10.637L67.835 19.6371C67.7372 19.6854 67.6295 19.7105 67.5203 19.7105L22.0544 19.7105L0.944343 18.0517C0.574653 18.0226 0.289474 17.7142 0.289474 17.3433Z"
741
- fill="${n}" stroke="${a ? "#FF2424" : "black"}" stroke-width="${a ? "4" : "0.578947"}"/>
742
- ${r === SHIP_DIRECT.left && `<path d="M86 10L96 10L96 6" stroke="${a ? "#FF2424" : "black"}" stroke-width="1.5"/>`}
743
- ${r === SHIP_DIRECT.right && `<path d="M86 10L96 10L96 14" stroke="${a ? "#FF2424" : "black"}" stroke-width="1.5"/>`}
744
- ${r === SHIP_DIRECT.front && `<path d="M86 10L96 10" stroke="${a ? "#FF2424" : "black"}" stroke-width="1.5"/>`}
745
- </svg>
746
- `;
747
- default:
748
- return "";
749
- }
750
- }
751
- }, selectedShipStyle = (e, t) => {
752
- const o = t === "ship" ? 109 : 49, n = `<svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${o}" viewBox="0 0 49 49" fill="none">
753
- <path d="M1.99982 46.9998L1.99982 1.99982L46.9998 1.99982L46.9998 46.9998L1.99982 46.9998Z" fill="#FF2424" fill-opacity="0.2"/>
754
- <path fill-rule="evenodd" clip-rule="evenodd" d="M19.9998 0.5V3.5L3.49976 3.5V20H0.499756V0.500002L19.9998 0.5ZM45.4998 3.5H28.9998V0.5H48.4998V20H45.4998V3.5ZM48.4998 29L48.4998 48.5H28.9998V45.5H45.4998L45.4998 29H48.4998ZM3.49976 45.5L3.49976 29H0.499756L0.499758 48.5L19.9998 48.5V45.5L3.49976 45.5Z" fill="#FF2424"/>
755
- </svg>`;
756
- return new Style({
757
- image: new Icon({
758
- src: `data:image/svg+xml;utf8,${encodeURIComponent(n)}`,
759
- scale: e || MAP_ZOOM.scaleNum
760
- }),
761
- zIndex: 100
762
- });
763
- }, createLabelStyle = (e) => new Style({
764
- renderer: (t, o) => {
765
- createLabelRenderer(o.context, t, e);
766
- },
767
- zIndex: 99
768
- }), shipsSource = new VectorSource(), shipsLayer = new VectorLayer({
769
- source: shipsSource,
770
- className: "zh-map--ship-layer",
771
- updateWhileInteracting: !1,
772
- updateWhileAnimating: !1,
773
- renderBuffer: 300,
774
- zIndex: 101
775
- });
776
- let hoveredShipId = "", attentionShips = {}, attentionShipsColor = {};
777
- const renderShipList = (e) => {
778
- const t = getInstall();
779
- if (!t) return;
780
- t.getLayers().getArray().includes(shipsLayer) || t.addLayer(shipsLayer), shipsSource && shipsSource.clear();
781
- const o = [];
782
- e.forEach((n) => {
783
- const r = fromLonLat([n.lon, n.lat]), a = new Feature({
784
- geometry: new Point(r),
785
- // 船舶数据
786
- shipData: n,
787
- id: n.id,
788
- name: n.cnname || "未命名船舶",
789
- selected: n.id === (selectedShipFeature == null ? void 0 : selectedShipFeature.get("id")),
790
- // 图标
791
- rightIcons: getRightIcons(n),
792
- // 是否闪烁
793
- blinking: attentionShips[n.id] || !1,
794
- // 闪烁颜色
795
- blinkingColor: attentionShipsColor[n.id] || "",
796
- // 船舶颜色
797
- color: n.fill || "#04C900",
798
- // 船艏向的方向
799
- direct: getShipDirectPath(n),
800
- // 高亮
801
- isHighlight: !1
802
- });
803
- a.setStyle(createShipStyle(a)), o.push(a);
804
- }), shipsSource.addFeatures(o);
805
- };
806
- let selectedShipFeature = null;
807
- const clearShipList = () => {
808
- getInstall() && shipsSource && shipsSource.getFeatures().forEach((t) => {
809
- (!selectedShipFeature || t.get("shipData").shipId !== selectedShipFeature.get("id")) && shipsSource.removeFeature(t);
810
- });
811
- }, renderShipBlink = (e, t) => {
812
- attentionShips = e, attentionShipsColor = t;
813
- }, filterShipShow = (e) => {
814
- if (!getInstall()) return;
815
- const o = shipsSource.getFeatures(), n = selectedShipFeature ? selectedShipFeature.get("id") : "", r = o.filter((i) => i.getId() !== n), a = /* @__PURE__ */ new Map();
816
- e.forEach((i) => {
817
- a.set(i.id, !0);
818
- }), r.forEach((i) => {
819
- const s = i.get("id");
820
- if (!a.has(s))
821
- i.setStyle([]);
822
- else {
823
- const d = i.getStyle();
824
- (d == null ? void 0 : d.length) == 0 && i.setStyle(createShipStyle(i));
825
- }
826
- });
827
- }, renderShipSelected = (e) => {
828
- if (e) {
829
- console.log("选中");
830
- const t = shipsSource.getFeatures().find((o) => o.get("id") === e.id);
831
- if (t)
832
- if (!selectedShipFeature)
833
- selectedShipFeature = t, selectedShipFeature.set("selected", !0), selectedShipFeature.setStyle(createShipStyle(selectedShipFeature));
834
- else {
835
- const o = selectedShipFeature.get("id"), n = shipsSource.getFeatures().find((r) => r.get("id") === o);
836
- n == null || n.set("selected", !1), n == null || n.setStyle(createShipStyle(n)), selectedShipFeature = null;
837
- }
838
- else {
839
- console.log("选中,不存在");
840
- const o = fromLonLat([e.lon, e.lat]);
841
- selectedShipFeature = new Feature({
842
- geometry: new Point(o),
843
- // 船舶数据
844
- shipData: e,
845
- id: e.id,
846
- name: e.cnname || "未命名船舶",
847
- selected: e.id === (selectedShipFeature == null ? void 0 : selectedShipFeature.get("id")),
848
- // 图标
849
- rightIcons: getRightIcons(e),
850
- // 是否闪烁
851
- blinking: attentionShips[e.id] || !1,
852
- // 闪烁颜色
853
- blinkingColor: attentionShipsColor[e.id] || "",
854
- // 船舶颜色
855
- color: e.fill || "#04C900",
856
- // 船艏向的方向
857
- direct: getShipDirectPath(e),
858
- // 高亮
859
- isHighlight: !1
860
- });
861
- }
862
- } else if (console.log("取消选中"), selectedShipFeature) {
863
- selectedShipFeature.set("selected", !1);
864
- const t = shipsSource.getFeatures().find((o) => o.get("id") === (selectedShipFeature == null ? void 0 : selectedShipFeature.get("id")));
865
- t && (selectedShipFeature = t), selectedShipFeature.set("selected", !1), selectedShipFeature.setStyle(createShipStyle(selectedShipFeature)), selectedShipFeature = null;
866
- }
867
- }, handleShipMapEvent = debounce((e, t, o) => {
868
- const n = getInstall();
869
- if (e) {
870
- const r = e.get("shipData"), a = e.get("id");
871
- if (n.getTargetElement().style.cursor = a ? "pointer" : "", t === "click" && (selectedShipFeature && renderShipSelected(r), o && o(a)), t === "hover") {
872
- hoveredShipId && hoveredShipId == a && clearHoverHight(), hoveredShipId = a;
873
- const i = hoveredShipId ? shipsSource.getFeatureById(hoveredShipId) : null;
874
- i == null || i.set("hightlight", !0), i == null || i.setStyle(createShipStyle(i));
875
- }
876
- } else
877
- n.getTargetElement().style.cursor = "", clearHoverHight();
878
- }, 10), clearHoverHight = () => {
879
- const e = hoveredShipId ? shipsSource.getFeatureById(hoveredShipId) : null;
880
- hoveredShipId = null, e == null || e.set("hightlight", !1), e == null || e.setStyle(createShipStyle(e));
881
- }, convertSixHundredThousandToLatLng = function(e, t) {
882
- const o = Number(t) / 6e5;
883
- return [Number(e) / 6e5, o];
884
- }, stopIcon = "&#xe6e2;", stopColor = "#E31818", slowIcon = "&#xe703;", slowColor = "#1890FF", dropletsIcon = "&#xe6d2", DEFAULT_VALUE = "--";
885
- let moveFeatureHandler = null;
886
- const stopIconStyle = getIconStyle(stopIcon), slowIconStyle = getIconStyle(slowIcon), popupEle = document.createElement("div"), popupOverlay = new Overlay({
887
- element: popupEle,
888
- positioning: "top-left",
889
- stopEvent: !1
890
- });
891
- let polyline, linePath, startMarker, position, geoMarker, trackAnimating = !1, lastTime = Date.now(), vectorLayer$3, distance = 0, thresholdNum = 20;
892
- const labelConfig = {
893
- textOffset: [30, -30],
894
- padding: [2, 5, 2, 5],
895
- bgColor: "rgba(255,255,255,0.8)",
896
- textColor: "#333",
897
- fontSize: 12,
898
- fontFamily: "Arial",
899
- fontWeight: "500"
900
- }, routesSource = new VectorSource(), routeLayer = new VectorLayer({
901
- source: routesSource,
902
- className: "zh-map--track-layer",
903
- zIndex: 102
904
- });
905
- let routeFeatures = [], showTracks = [], allTracks = {}, trackId = "", trackColor = "", trackList = [], mapInstance = null;
906
- const reRenderTrackLine = () => {
907
- mapInstance = getInstall(), handlerRenderLine();
908
- }, renderTrackLine = async (e, t, o, n = LENGTH_UNIT.NM, r = "ship", a = 200) => {
909
- if (mapInstance = getInstall(), !mapInstance) return;
910
- if (routeLayer == null || routeLayer.setVisible(!0), t = t == null ? void 0 : t.reverse(), popupOverlay && r === "ship" && (mapInstance != null && mapInstance.getOverlays().getArray().includes(popupOverlay) || mapInstance.addOverlay(popupOverlay)), clearShipList$1(), (t == null ? void 0 : t.length) < 2) {
911
- (showTracks == null ? void 0 : showTracks.findIndex((c) => c.id === e)) < 0 && showTracks.push({ id: e, length: "" });
912
- return;
913
- }
914
- const i = {};
915
- t.forEach((c) => {
916
- c.state ? c.state = Number(c.state) : delete c.state;
917
- }), trackId = e, i[e] = t, trackList = t;
918
- const s = i[e].map(
919
- (c) => transform([c.lon, c.lat], projection.data, projection.mercator)
920
- ), d = new LineString(s), u = formatLength(d, n) || "--", l = showTracks == null ? void 0 : showTracks.findIndex((c) => c.id === e);
921
- l < 0 ? showTracks.push({ id: e, length: u }) : showTracks[l].length = u, allTracks[e] = t, trackList = [], trackColor = o, thresholdNum = a, await handlerRenderLine(), await setTrackViewCenter(trackId);
922
- }, handlerRenderLine = async () => {
923
- const e = trackColor || "", t = trackId, o = allTracks[trackId] || [], n = thresholdNum || 200, r = Math.max(1, Math.floor(o.length / n));
924
- trackList = o.filter((s, d) => d % r === 0).map((s, d) => {
925
- if (Number(s.lon) > 180 || Number(s.lat) > 180) {
926
- const [u, l] = convertSixHundredThousandToLatLng(s.lon, s.lat);
927
- s.lon = u, s.lat = l;
928
- }
929
- return s.center = [s.lon, s.lat], s.centerPoint = lonLatToMercator(s.center), s.id = t, s.index = d, s.time = hooks(s.createdAt).format("YYYY-MM-DD HH:mm:ss"), s;
930
- });
931
- const i = trackList.map((s) => s.centerPoint);
932
- i.length >= 2 && (mapInstance == null || mapInstance.addLayer(routeLayer), await createTrackLineFeature(t, i, e));
933
- }, createTrackLineFeature = (e, t, o) => {
934
- var i;
935
- const n = new LineString(t), r = new Feature({ geometry: n });
936
- r.setStyle(createTrackLineStyle(o)), r.setId(e), r.set("type", "line"), (i = routeLayer == null ? void 0 : routeLayer.getSource()) == null || i.clear(), routeFeatures = [];
937
- const a = routeFeatures.findIndex((s) => s.getId() === e);
938
- a >= 0 ? routeFeatures[a] = r : routeFeatures.push(r), routesSource.addFeatures([...routeFeatures]), createPointFeature(o);
939
- }, createTrackLineStyle = (e) => new Style({
940
- stroke: new Stroke({
941
- color: e,
942
- width: 2
943
- })
944
- }), handleTrackMapEvent = (e, t, o) => {
945
- const n = e == null ? void 0 : e.get("trackId");
946
- if (e && n && t === "hover") {
947
- mapInstance.getTargetElement().style.cursor = n ? "pointer" : "";
948
- const r = e.get("data"), a = renderTrackPointHtml(r), i = o == null ? void 0 : o.coordinate;
949
- i && (popupEle.querySelector(".popup-content"), popupEle.innerHTML = a, popupOverlay == null || popupOverlay.setPosition(i));
950
- } else
951
- popupOverlay && popupOverlay.setPosition(void 0);
952
- }, formatMinutesToDDHHMM = (e) => {
953
- const t = hooks.duration(e, "minutes"), o = Math.floor(t.asDays()), n = t.hours(), r = t.minutes();
954
- let a = `${String(r).padStart(2, "0")}分`;
955
- return n !== 0 && (a = `${String(n).padStart(2, "0")}时${a}`), o !== 0 && (a = `${String(o).padStart(2, "0")}天${a}`), a;
956
- }, renderTrackPointHtml = (e) => {
957
- if (!(e != null && e.time)) return;
958
- let t = "";
959
- return e != null && e.stayTime && (t = `
960
- <div class="item w-100">
961
- <div class="item-label">停泊时间约</div>
962
- <div class="item-item">${formatMinutesToDDHHMM(Number(e.stayTime))}</div>
963
- </div>
964
- `), `
965
- <div class="track-point-popup">
966
- <div class="item">
967
- <div class="item-label">状态</div>
968
- <div class="item-item">${e != null && e.sailStatus ? SHIP_SAIL_STATUS[e.sailStatus] : DEFAULT_VALUE}</div>
969
- </div>
970
- <div class="item">
971
- <div class="item-label">航速</div>
972
- <div class="item-item">${e.speed || DEFAULT_VALUE}</div>
973
- </div>
974
- <div class="item">
975
- <div class="item-label">艏向</div>
976
- <div class="item-item">${e.hdg || DEFAULT_VALUE}</div>
977
- </div>
978
- <div class="item">
979
- <div class="item-label">航向</div>
980
- <div class="item-item">${e.cog || DEFAULT_VALUE}</div>
981
- </div>
982
- <div class="item">
983
- <div class="item-label">经度</div>
984
- <div class="item-item">${e.lon || DEFAULT_VALUE}</div>
985
- </div>
986
- <div class="item">
987
- <div class="item-label">纬度</div>
988
- <div class="item-item">${e.lat || DEFAULT_VALUE}</div>
989
- </div>
990
- <div class="item w-100">
991
- <div class="item-label">时间</div>
992
- <div class="item-item">${e.time}</div>
993
- </div>
994
- ${t ?? t}
995
- </div>`;
996
- }, createPointFeature = (e) => {
997
- const t = trackList || [];
998
- if (!(t && t.length > 1)) return [];
999
- const o = { 16: 24, 17: 15, default: 4 }, n = [], r = t.length;
1000
- for (let a = 0; a < r; a++) {
1001
- t[a].index = a;
1002
- const i = mapInstance == null ? void 0 : mapInstance.getPixelFromCoordinate(t[a].centerPoint);
1003
- if (i) {
1004
- let s = i.concat(i);
1005
- s = adjustBounds(s, [20, 20]);
1006
- const d = mapInstance == null ? void 0 : mapInstance.getView().getZoom();
1007
- if (!d) return;
1008
- if (d > 15) {
1009
- const l = o[d] || o.default;
1010
- s = adjustBounds(s, [l, l]);
1011
- }
1012
- let u = !0;
1013
- if (t[a].state !== "0") {
1014
- for (let l = 0; l < n.length; l++)
1015
- if (isOverlapping(s, n[l].bounds)) {
1016
- u = !1;
1017
- break;
1018
- }
1019
- }
1020
- u && (t[a].bounds = s, n.push(t[a]));
1021
- }
1022
- }
1023
- n.forEach((a) => {
1024
- const i = new Feature({
1025
- geometry: new Point(a.centerPoint),
1026
- time: a.time
1027
- });
1028
- i.set("type", "track_point"), i.set("trackId", a.id), i.set("data", a), i.setStyle(createPointStyle(e, i, a)), routesSource.addFeature(i), typeof a == "object" && Object.prototype.hasOwnProperty.call(a, "state") && createIconFeature(a);
1029
- }), createArrowFetaure(n, e), createIconPointFeature();
1030
- }, createPointStyle = (e, t, o) => {
1031
- var g;
1032
- const n = (g = t == null ? void 0 : t.getGeometry()) == null ? void 0 : g.getCoordinates(), a = document.createElement("canvas").getContext("2d", { willReadFrequently: !0 });
1033
- a.font = `${labelConfig.fontWeight} ${labelConfig.fontSize}px ${labelConfig.fontFamily}`;
1034
- const i = a == null ? void 0 : a.measureText(o.time), s = (i == null ? void 0 : i.width) + labelConfig.padding[1] + labelConfig.padding[3], d = labelConfig.fontSize + labelConfig.padding[0] + labelConfig.padding[2], [u, l] = labelConfig.textOffset, c = [
1035
- n[0] + u,
1036
- n[1] + l - d
1037
- ], p = new LineString([n, c]);
1038
- console.log("lineGeom", p), new Polygon([[
1039
- c,
1040
- [c[0] + s, c[1]],
1041
- [c[0] + s, c[1] + d],
1042
- [c[0], c[1] + d],
1043
- c
1044
- ]]);
1045
- const m = c[0] + labelConfig.padding[3], h = c[1] + labelConfig.padding[0] + labelConfig.fontSize / 2;
1046
- return console.log("textY", m, h, s, d), [
1047
- new Style({
1048
- // 扩大交互热区
1049
- image: new CircleStyle({
1050
- stroke: new Stroke({ color: "rgba(0, 0, 0, 0.01)", width: 20 }),
1051
- radius: 3
1052
- })
1053
- }),
1054
- // 轨迹点样式
1055
- new Style({
1056
- image: new CircleStyle({
1057
- fill: new Fill({ color: e }),
1058
- stroke: new Stroke({ color: "#fff", width: 2 }),
1059
- radius: 3
1060
- })
1061
- }),
1062
- // // 信息框背景
1063
- // new Style({
1064
- // geometry: boxGeom,
1065
- // fill: new Fill({ color: labelConfig.bgColor }),
1066
- // stroke: new Stroke({
1067
- // color: trackColor,
1068
- // width: 1
1069
- // })
1070
- // }),
1071
- // 连接线
1072
- new Style({
1073
- geometry: p,
1074
- stroke: new Stroke({
1075
- color: e,
1076
- width: 1
1077
- })
1078
- }),
1079
- new Style({
1080
- text: new Text({
1081
- text: o.time,
1082
- font: `500 ${labelConfig.fontSize}px ${labelConfig.fontFamily}`,
1083
- textAlign: "left",
1084
- textBaseline: "middle",
1085
- fill: new Fill({ color: labelConfig.textColor }),
1086
- backgroundFill: new Fill({
1087
- color: labelConfig.bgColor
1088
- }),
1089
- backgroundStroke: new Stroke({
1090
- color: e,
1091
- width: 0.5
1092
- }),
1093
- padding: labelConfig.padding,
1094
- offsetX: m - c[0],
1095
- // 转换为相对偏移
1096
- offsetY: h - c[1]
1097
- }),
1098
- zIndex: 99
1099
- })
1100
- ];
1101
- }, createIconFeature = (e) => {
1102
- const t = new Feature({
1103
- //point.centerPoint
1104
- geometry: new Point([e.lon, e.lat]),
1105
- time: e.time
1106
- });
1107
- t.set("type", "track_icon");
1108
- const o = new Style({
1109
- text: new Text({
1110
- font: "Normal 22px map-iconfont",
1111
- text: getIconFont$1(dropletsIcon),
1112
- offsetY: -10,
1113
- fill: new Fill({
1114
- color: Number(e.state) === 0 ? stopColor : Number(e.state) === 1 ? slowColor : ""
1115
- })
1116
- }),
1117
- zIndex: 99
1118
- }), n = [];
1119
- Number(e.state) === 0 ? n.push(stopIconStyle) : Number(e.state) === 1 && n.push(slowIconStyle), n.push(o), t.setStyle(n), routesSource.addFeature(t);
1120
- }, createArrowFetaure = (e, t) => {
1121
- const o = e || [], n = e.length;
1122
- n || (o.push(trackList[0]), o.push(trackList[trackList.length - 1]));
1123
- for (let r = 0; r < n - 1; r++) {
1124
- let a;
1125
- const i = e[r], s = (e[r + 1].index + i.index) / 2;
1126
- if (s % 2 === 0)
1127
- a = trackList[s].centerPoint;
1128
- else {
1129
- const d = trackList[Math.floor(s)], u = trackList[Math.ceil(s)];
1130
- if (d && u) {
1131
- const [l, c] = d.centerPoint, [p, m] = u.centerPoint;
1132
- a = [(l + p) / 2, (c + m) / 2];
1133
- }
1134
- }
1135
- if (a) {
1136
- const d = new Feature({
1137
- geometry: new Point(a)
1138
- });
1139
- d.set("type", "track_arrow"), d.setStyle(
1140
- new Style({
1141
- text: new Text({
1142
- font: "700 14px map-iconfont",
1143
- text: getIconFont$1("&#xe6bc;"),
1144
- fill: new Fill({ color: t }),
1145
- // 设置箭头旋转 角度转为弧度
1146
- rotation: getRotation(
1147
- e[r].center,
1148
- e[r + 1].center
1149
- ) * (Math.PI / 180)
1150
- })
1151
- })
1152
- ), routesSource == null || routesSource.addFeature(d);
1153
- }
1154
- }
1155
- }, setTrackViewCenter = (e) => {
1156
- var r;
1157
- const t = mapInstance.getView(), o = e ? routeFeatures.find((a) => a.getId() === e) : routeFeatures[0];
1158
- if (!o) return;
1159
- const n = (r = o == null ? void 0 : o.getGeometry()) == null ? void 0 : r.getExtent();
1160
- if (n != null && n.length)
1161
- try {
1162
- const a = buffer(n, Math.max(n[2] - n[0], n[3] - n[1]) * 0.02);
1163
- t.fit(a);
1164
- } catch (a) {
1165
- console.log(a);
1166
- }
1167
- }, createIconPointFeature = () => {
1168
- const e = "&#xe69b;", t = "#fcdc3f", o = "#ff0000";
1169
- (trackList.length < 2 ? [trackList[0]] : [trackList[0], trackList[trackList.length - 1]]).forEach((r) => {
1170
- const a = new Feature({
1171
- geometry: new Point(r.centerPoint)
1172
- });
1173
- a.set("type", "track_begin"), a.set("data", r);
1174
- const i = r.index === 0 && trackList.length >= 2 ? t : o;
1175
- a.setStyle(
1176
- new Style({
1177
- text: new Text({
1178
- font: "Normal 14px map-iconfont",
1179
- text: getIconFont$1(e),
1180
- fill: new Fill({ color: i })
1181
- }),
1182
- zIndex: 101
1183
- })
1184
- ), routesSource.addFeature(a);
1185
- });
1186
- }, geoMarkerStyle = new Style({
1187
- text: new Text({
1188
- font: "700 20px map-iconfont",
1189
- text: getIconFont$1("&#xe657;"),
1190
- fill: new Fill({ color: "#ff0000" }),
1191
- rotation: 0
1192
- // 初始旋转角度
1193
- })
1194
- }), playShipTrack = (e, t) => {
1195
- handlePlay(String(e), t);
1196
- }, removeAllTrackLayer = () => {
1197
- showTracks = [], allTracks = {}, routesSource == null || routesSource.clear();
1198
- }, closeTrack = (e = !1) => {
1199
- routeLayer == null || routeLayer.setVisible(!1), e && removeAllTrackLayer(), stopAnimation();
1200
- }, handlePlay = (e, t) => {
1201
- const o = allTracks[String(e)];
1202
- playAnimation(o == null ? void 0 : o.map((n) => [n.lon, n.lat]), t);
1203
- }, moveFeature = (e, t) => {
1204
- var c, p;
1205
- const o = Number(50 * t), n = ((c = e.frameState) == null ? void 0 : c.time) ?? Date.now(), r = n - lastTime;
1206
- if (distance = (distance + o * r / 1e6) % 2, lastTime = n, distance >= 1) {
1207
- stopAnimation();
1208
- return;
1209
- }
1210
- const a = linePath.getCoordinateAt(
1211
- distance > 1 ? 2 - distance : distance
1212
- ), i = linePath.getCoordinateAt(
1213
- distance > 1 ? distance - 0.01 : distance
1214
- ), s = linePath.getCoordinateAt(
1215
- distance > 1 ? 2 - distance : distance + 0.01
1216
- ), u = getRotation(
1217
- mercatorToLonLat(i, "array"),
1218
- mercatorToLonLat(s, "array")
1219
- ) * Math.PI / 180;
1220
- (p = geoMarkerStyle.getText()) == null || p.setRotation(u), position.setCoordinates(a);
1221
- const l = getVectorContext(e);
1222
- l.setStyle(geoMarkerStyle), l.drawGeometry(position), mapInstance == null || mapInstance.render();
1223
- }, startAnimation = () => {
1224
- var e;
1225
- trackAnimating = !0, lastTime = Date.now(), distance = 0, position = ((e = startMarker.getGeometry()) == null ? void 0 : e.clone()) || new Point([0, 0]), moveFeatureHandler && (vectorLayer$3 == null || vectorLayer$3.on("postrender", moveFeatureHandler)), geoMarker == null || geoMarker.setGeometry(void 0);
1226
- }, stopAnimation = () => {
1227
- trackAnimating && (trackAnimating = !1, geoMarker == null || geoMarker.setGeometry(void 0), moveFeatureHandler && vectorLayer$3 && vectorLayer$3.un("postrender", moveFeatureHandler), vectorLayer$3 && (mapInstance == null || mapInstance.removeLayer(vectorLayer$3)), vectorLayer$3 = null, geoMarker = null);
1228
- }, playAnimation = (e, t) => {
1229
- trackAnimating && stopAnimation(), polyline = new Polyline({
1230
- factor: 1e6
1231
- }).writeGeometry(new LineString(e)), linePath = new Polyline({
1232
- factor: 1e6
1233
- }).readGeometry(polyline, {
1234
- dataProjection: projection.data,
1235
- featureProjection: projection.mercator
1236
- }), startMarker = new Feature({
1237
- type: "icon",
1238
- geometry: new Point(linePath.getFirstCoordinate())
1239
- });
1240
- const o = startMarker.getGeometry();
1241
- position = o ? o.clone() : new Point([0, 0]), geoMarker = new Feature({
1242
- type: "geoMarker",
1243
- style: geoMarkerStyle,
1244
- geometry: position
1245
- }), vectorLayer$3 = new VectorLayer({
1246
- source: new VectorSource({
1247
- features: [geoMarker]
1248
- })
1249
- }), mapInstance == null || mapInstance.addLayer(vectorLayer$3), moveFeatureHandler = (n) => moveFeature(n, t), startAnimation();
1250
- }, getRotation = (e, t, o) => {
1251
- function n(c) {
1252
- return 180 * (c % (2 * Math.PI)) / Math.PI;
1253
- }
1254
- function r(c) {
1255
- return c % 360 * Math.PI / 180;
1256
- }
1257
- function a(c) {
1258
- var p;
1259
- if (!c) throw new Error("Coordinate is required");
1260
- if (!Array.isArray(c)) {
1261
- if ((c == null ? void 0 : c.type) === "Feature" && (c == null ? void 0 : c.geometry) !== null && ((p = c == null ? void 0 : c.geometry) == null ? void 0 : p.type) === "Point")
1262
- return c == null ? void 0 : c.geometry.coordinates;
1263
- if (c.type === "Point") return (c == null ? void 0 : c.coordinates) || [];
1264
- }
1265
- if (Array.isArray(c) && c.length >= 2 && !Array.isArray(c[0]) && !Array.isArray(c[1]))
1266
- return c;
1267
- throw new Error(
1268
- "Coordinate must be GeoJSON Point or an Array of numbers"
1269
- );
1270
- }
1271
- function i(c, p, m = {}) {
1272
- if (m.final)
1273
- return function(L, I) {
1274
- return (i(I, L) + 180) % 360;
1275
- }(c, p);
1276
- const h = a(c), g = a(p), f = r(h[0]), w = r(g[0]), v = r(h[1]), S = r(g[1]), T = Math.sin(w - f) * Math.cos(S), $ = Math.cos(v) * Math.sin(S) - Math.sin(v) * Math.cos(S) * Math.cos(w - f);
1277
- return n(Math.atan2(T, $));
1278
- }
1279
- function s(c) {
1280
- return !isNaN(c) && c !== null && !Array.isArray(c);
1281
- }
1282
- function d(c, p = {}, m = {}) {
1283
- return c || console.log("Coordinates are required"), Array.isArray(c) || console.log("Coordinates must be an Array"), c.length < 2 && console.log("Coordinates must be at least 2 numbers long"), (!s(c[0]) || !s(c[1])) && console.log("Coordinates must contain numbers"), u({ type: "Point", coordinates: c }, p, m);
1284
- }
1285
- function u(c, p = {}, m = {}) {
1286
- const h = {
1287
- type: "Feature",
1288
- id: "",
1289
- properties: {},
1290
- bbox: {},
1291
- geometry: {}
1292
- };
1293
- return m.id !== void 0 && (h.id = m.id), m.bbox && (h.bbox = m.bbox), h.properties = p, h.geometry = c, h;
1294
- }
1295
- const l = i(d(e), d(t), o);
1296
- return l < 0 ? 360 + l : l;
1297
- }, disableDoubleClickZoom = () => {
1298
- getInstall().getInteractions().forEach((t) => {
1299
- t instanceof DoubleClickZoom && t.setActive(!1);
1300
- });
1301
- }, enableDoubleClickZoom = () => {
1302
- getInstall().getInteractions().forEach((t) => {
1303
- t instanceof DoubleClickZoom && t.setActive(!0);
1304
- });
1305
- }, measureHistory = ref([]), config$1 = {
1306
- // 绘制线条的回调
1307
- lineDrawEndFn: (e) => {
1308
- console.log("lineDrawEndFn", e);
1309
- },
1310
- //
1311
- unit: "km"
1312
- }, setConfig$1 = (e) => {
1313
- console.log("setConfig", e), merge(config$1, e), console.log("setConfig", config$1);
1314
- };
1315
- let helpTooltipElement$1;
1316
- const state = ref(!1), open$1 = () => {
1317
- initMapLayer(), disableDoubleClickZoom(), changeCursor("pointer");
1318
- const e = getInstall();
1319
- e.on("pointermove", pointerMoveHandler$1), console.log("openMeasure", e.getViewport()), e.getViewport().addEventListener("mouseout", () => {
1320
- helpTooltipElement$1 && helpTooltipElement$1.classList.add("hidden");
1321
- }), addInteraction(), state.value = !0;
1322
- };
1323
- let vectorSource$3, vectorLayer$2;
1324
- const initMapLayer = () => {
1325
- vectorSource$3 = new VectorSource(), vectorLayer$2 = new VectorLayer({
1326
- source: vectorSource$3,
1327
- zIndex: 1e3,
1328
- style: {
1329
- "fill-color": "rgba(255, 255, 255, 0.2)",
1330
- "stroke-color": "#ffcc33",
1331
- "stroke-width": 2,
1332
- "circle-radius": 7,
1333
- "circle-fill-color": "#ffcc33"
1334
- }
1335
- }), getInstall().addLayer(vectorLayer$2);
1336
- };
1337
- let sketch$1, helpTooltip;
1338
- const pointerMoveHandler$1 = (e) => {
1339
- if (e.dragging)
1340
- return;
1341
- let t = "点击选择起点";
1342
- sketch$1 && (t = "单击继续,双击结束"), helpTooltipElement$1 && (helpTooltipElement$1.innerHTML = t, helpTooltip.setPosition(e.coordinate), helpTooltipElement$1.classList.remove("hidden"));
1343
- }, changeCursor = (e) => {
1344
- getInstall().getTargetElement().style.cursor = e;
1345
- };
1346
- let draw$1;
1347
- const addInteraction = () => {
1348
- draw$1 = new Draw({
1349
- source: vectorSource$3,
1350
- type: "LineString",
1351
- style: new Style({
1352
- fill: new Fill({
1353
- color: "rgba(255, 255, 255, 0.2)"
1354
- }),
1355
- stroke: new Stroke({
1356
- color: "rgba(255,204,51)",
1357
- lineDash: [10, 10],
1358
- width: 2
1359
- }),
1360
- image: new CircleStyle({
1361
- radius: 5,
1362
- stroke: new Stroke({
1363
- color: "rgba(0, 0, 0, 0.7)"
1364
- }),
1365
- fill: new Fill({
1366
- color: "rgba(255, 255, 255, 0.2)"
1367
- })
1368
- })
1369
- }),
1370
- // 添加条件函数,判断是否应该出发点绘制
1371
- condition: (t) => t.originalEvent.target.tagName !== "DIV"
1372
- }), getInstall().addInteraction(draw$1), createMeasureTooltip$1(), createHelpTooltip$1();
1373
- let e;
1374
- draw$1.on("drawstart", function(t) {
1375
- var n;
1376
- sketch$1 = t.feature, sketch$1.set("randomId", generateRandomId());
1377
- let o;
1378
- e = (n = sketch$1.getGeometry()) == null ? void 0 : n.on("change", function(r) {
1379
- const a = r.target, i = computedDistance(a, config$1.unit);
1380
- o = a.getLastCoordinate(), measureTooltipElement$1 && i && (measureTooltipElement$1.innerHTML = i), measureTooltip$1.setPosition(o);
1381
- });
1382
- }), draw$1.on("drawend", function() {
1383
- var t;
1384
- if (measureTooltipElement$1 && (measureTooltipElement$1.className = "ol-tooltip ol-tooltip-static ol-tooltip-measure"), measureTooltipElement$1 != null && measureTooltipElement$1.innerHTML) {
1385
- const o = (sketch$1 == null ? void 0 : sketch$1.get("randomId")) || generateRandomId();
1386
- measureHistory.value.push({ id: o, value: measureTooltipElement$1 == null ? void 0 : measureTooltipElement$1.innerHTML }), measureTooltipElement$1.innerHTML = `${measureTooltipElement$1.innerHTML}<div class="ol-tooltip-delete-button" data-id="${o}"><i class="map-iconfont icon-delete"></i></div>`;
1387
- }
1388
- (t = document.querySelector(".ol-selectable:has(.ol-tooltip-delete-button):last-child .ol-tooltip-delete-button")) == null || t.addEventListener("click", (o) => {
1389
- var r;
1390
- o.preventDefault(), o.stopPropagation();
1391
- const n = (r = o.target) == null ? void 0 : r.getAttribute("data-id");
1392
- n && deleteLine(n);
1393
- }), measureTooltip$1.setOffset([0, -7]), sketch$1 = null, measureTooltipElement$1 = null, createMeasureTooltip$1(), e && unByKey(e), config$1.lineDrawEndFn(measureHistory.value);
1394
- });
1395
- }, generateRandomId = () => Math.random().toString(36).substring(2, 9);
1396
- let measureTooltipElement$1, measureTooltip$1;
1397
- const createMeasureTooltip$1 = () => {
1398
- measureTooltipElement$1 != null && measureTooltipElement$1.parentNode && measureTooltipElement$1.parentNode.removeChild(measureTooltipElement$1), measureTooltipElement$1 = document.createElement("div"), measureTooltipElement$1.className = "ol-tooltip ol-tooltip-measure", measureTooltip$1 = new Overlay({
1399
- element: measureTooltipElement$1,
1400
- offset: [0, -15],
1401
- positioning: "bottom-center",
1402
- stopEvent: !1,
1403
- insertFirst: !1
1404
- }), getInstall().addOverlay(measureTooltip$1);
1405
- }, createHelpTooltip$1 = () => {
1406
- helpTooltipElement$1 != null && helpTooltipElement$1.parentNode && helpTooltipElement$1.parentNode.removeChild(helpTooltipElement$1), helpTooltipElement$1 = document.createElement("div"), helpTooltipElement$1.className = "ol-tooltip hidden", helpTooltip = new Overlay({
1407
- element: helpTooltipElement$1,
1408
- offset: [15, 0],
1409
- positioning: "center-left"
1410
- }), getInstall().addOverlay(helpTooltip);
1411
- }, close$1 = () => {
1412
- measureHistory.value.forEach((e, t) => {
1413
- var r, a;
1414
- const o = document.querySelectorAll(".ol-tooltip.ol-tooltip-static.ol-tooltip-measure");
1415
- o[t] && ((a = (r = o[t]) == null ? void 0 : r.parentNode) == null || a.removeChild(o[t]));
1416
- const n = vectorSource$3.getFeatures();
1417
- n[t] && vectorSource$3.removeFeature(n[t]);
1418
- }), removeInteraction(), enableDoubleClickZoom(), state.value = !1;
1419
- }, deleteLine = (e) => {
1420
- var o, n;
1421
- const t = measureHistory.value.findIndex((r) => r.id === e);
1422
- if (t !== -1) {
1423
- measureHistory.value.splice(t, 1);
1424
- const r = document.querySelectorAll(".ol-tooltip.ol-tooltip-static.ol-tooltip-measure");
1425
- r[t] && ((n = (o = r[t]) == null ? void 0 : o.parentNode) == null || n.removeChild(r[t]));
1426
- const a = vectorSource$3.getFeatures();
1427
- a[t] && vectorSource$3.removeFeature(a[t]);
1428
- }
1429
- config$1.lineDrawEndFn(measureHistory.value);
1430
- }, computedDistance = (e, t) => {
1431
- const n = getLength(e);
1432
- let r = "";
1433
- switch (t) {
1434
- case "m":
1435
- r = `${Math.round(n * 100) / 100} m`;
1436
- break;
1437
- case "km":
1438
- r = `${Math.round(n / 1e3 * 100) / 100} km`;
1439
- break;
1440
- case "nm":
1441
- r = `${Math.round(n / 1.852 * 100) / 100} nm`;
1442
- break;
1443
- }
1444
- return r;
1445
- }, removeInteraction = () => {
1446
- measureHistory.value = [], document.querySelectorAll(".ol-tooltip.ol-tooltip-static").forEach((t) => {
1447
- var o;
1448
- (o = t == null ? void 0 : t.parentNode) == null || o.removeChild(t);
1449
- }), vectorSource$3.clear();
1450
- const e = getInstall();
1451
- if (draw$1) {
1452
- const t = e.getInteractions().getArray().find((o) => getUid(o) === getUid(draw$1));
1453
- t && e.removeInteraction(t);
1454
- }
1455
- e.removeLayer(vectorLayer$2), helpTooltipElement$1 != null && helpTooltipElement$1.parentNode && helpTooltipElement$1.parentNode.removeChild(helpTooltipElement$1), measureTooltipElement$1 != null && measureTooltipElement$1.parentNode && measureTooltipElement$1.parentNode.removeChild(measureTooltipElement$1);
1456
- }, getState = () => state.value, drawLine = {
1457
- open: open$1,
1458
- close: close$1,
1459
- deleteLine,
1460
- setConfig: setConfig$1,
1461
- getState
1462
- }, config = {
1463
- // 回调函数
1464
- endCallback: void 0
1465
- }, setConfig = (e) => {
1466
- merge(config, e);
1467
- }, open = () => {
1468
- console.log("绘制多边形"), initLayer(), initDraw(), createMeasureTooltip(), createHelpTooltip();
1469
- };
1470
- let vectorLayer$1 = null, vectorSource$2 = null;
1471
- const initLayer = () => {
1472
- if (vectorLayer$1 || vectorSource$2) return;
1473
- const e = new VectorSource(), t = new VectorLayer({
1474
- source: e,
1475
- style: new Style({
1476
- stroke: new Stroke({
1477
- color: "#fbcc33",
1478
- width: 2
1479
- })
1480
- })
1481
- });
1482
- vectorLayer$1 = t, vectorSource$2 = e;
1483
- const o = getInstall();
1484
- o.on("pointermove", pointerMoveHandler), o.addLayer(t), o.on(["dblclick"], function(n) {
1485
- draw && (n.stopPropagation(), n.preventDefault());
1486
- });
1487
- };
1488
- let sketch;
1489
- const pointerMoveHandler = (e) => {
1490
- if (e.dragging) return;
1491
- const t = sketch ? "单击继续,双击结束" : "点击选择起点";
1492
- helpTooltipElement && (helpTooltipElement.innerHTML = t, tipOverlay.setPosition(e.coordinate));
1493
- };
1494
- let draw;
1495
- const initDraw = () => {
1496
- let e = !1;
1497
- draw = new Draw({
1498
- type: "Polygon",
1499
- source: vectorSource$2,
1500
- trace: !0,
1501
- style: [new Style({
1502
- stroke: new Stroke({
1503
- color: "rgba(255, 255, 255, 1)",
1504
- width: 1.5,
1505
- lineDash: [10, 10]
1506
- }),
1507
- fill: new Fill({
1508
- color: "rgba(255, 255, 255, 0.25)"
1509
- })
1510
- }), new Style({
1511
- image: new CircleStyle({
1512
- radius: 5,
1513
- fill: new Fill({
1514
- color: "rgb(51,112,255, 1)"
1515
- })
1516
- }),
1517
- geometry: function(o) {
1518
- const n = o.getGeometry().getCoordinates();
1519
- return new MultiPoint(n);
1520
- }
1521
- })]
1522
- }), getInstall().addInteraction(draw);
1523
- let t;
1524
- draw.on("drawstart", function(o) {
1525
- var n;
1526
- sketch = o.feature, t = (n = sketch.getGeometry()) == null ? void 0 : n.on("change", (r) => {
1527
- const a = r.target, i = computedArea(a, "nm"), d = a.getCoordinates()[0], u = new LineString([d[d.length - 2], d[d.length - 1]]), l = computedDistance(u, "nm");
1528
- if (e = Number(getLength(u) / 1e3) > 150, !i) return;
1529
- const c = '<span class="error pl-4">超出可以绘画的距离</span>';
1530
- measureTooltipElement && (measureTooltipElement.innerHTML = `
1531
- <div class="text">
1532
- 面积:${i}
1533
- ${e ? c : ""}
1534
- </div>
1535
- `), helpTooltipElement && (helpTooltipElement.innerHTML = `
1536
- <div class="text">
1537
- 面积:${i}
1538
- </div>
1539
- <div class="text ${e ? "error" : ""}">
1540
- 线段 ${d.length - 2}: ${l}
1541
- ${e ? c : ""}
1542
-
1543
- </div>
1544
- <div>
1545
- <span class="text">单击继续,双击结束</span>
1546
- </div>
1547
- `);
1548
- });
1549
- }), draw.on("drawend", function(o) {
1550
- var i;
1551
- if (!o.feature.getGeometry()) return;
1552
- measureTooltipElement && (measureTooltipElement.innerHTML += '<span class="delete-icon"><i class="map-iconfont icon-delete" /></div>'), measureTooltip.setOffset([10, 0]);
1553
- const r = o.feature.getGeometry().getCoordinates(), a = r[0][r[0].length - 2];
1554
- measureTooltip.setPosition(a), draw && draw.setActive(!1), helpTooltipElement != null && helpTooltipElement.parentNode && helpTooltipElement.parentNode.removeChild(helpTooltipElement), t && unByKey(t), console.log("coordinates", r), config.endCallback(r), (i = document.querySelector(".delete-icon")) == null || i.addEventListener("click", () => {
1555
- reset();
1556
- });
1557
- });
1558
- }, computedArea = (e, t) => {
1559
- const o = getArea(e);
1560
- switch (t) {
1561
- case "km":
1562
- return o > 1e4 ? Math.round(o / 1e6 * 100) / 100 + " km<sup>2</sup>" : Math.round(o * 100) / 100 + " m<sup>2</sup>";
1563
- case "nm":
1564
- return o > 1e4 ? Math.round(o / 1e6 / Math.pow(1.852, 2) * 100) / 100 + " nm<sup>2</sup>" : Math.round(o * 100) / 100 + " m<sup>2</sup>";
1565
- }
1566
- };
1567
- let measureTooltipElement, measureTooltip;
1568
- const createMeasureTooltip = () => {
1569
- measureTooltipElement != null && measureTooltipElement.parentNode && measureTooltipElement.parentNode.removeChild(measureTooltipElement), measureTooltipElement = document.createElement("div"), measureTooltipElement.style.display = "flex", measureTooltipElement.className = "ol-tooltip ol-tooltip-draw-polygon", measureTooltip = new Overlay({
1570
- element: measureTooltipElement,
1571
- offset: [0, -15],
1572
- positioning: "bottom-center"
1573
- // stopEvent: false,
1574
- // insertFirst: false
1575
- }), getInstall().addOverlay(measureTooltip);
1576
- };
1577
- let helpTooltipElement, tipOverlay;
1578
- const createHelpTooltip = () => {
1579
- helpTooltipElement != null && helpTooltipElement.parentNode && helpTooltipElement.parentNode.removeChild(helpTooltipElement), helpTooltipElement = document.createElement("div"), helpTooltipElement.className = "ol-tooltip ol-help-tooltip hidden", tipOverlay = new Overlay({
1580
- element: helpTooltipElement,
1581
- offset: [15, 0],
1582
- positioning: "center-left"
1583
- }), getInstall().addOverlay(tipOverlay);
1584
- }, reset = () => {
1585
- var e;
1586
- vectorSource$2.clear(), draw == null || draw.setActive(!0), (e = measureTooltipElement == null ? void 0 : measureTooltipElement.parentNode) == null || e.removeChild(measureTooltipElement), measureTooltip.setPosition(void 0), createMeasureTooltip(), createHelpTooltip(), getInstall().removeOverlay(tipOverlay), getInstall().removeOverlay(measureTooltip);
1587
- }, close = () => {
1588
- vectorSource$2 == null || vectorSource$2.clear(), vectorSource$2 = null;
1589
- const e = getInstall();
1590
- vectorLayer$1 && (e.removeLayer(vectorLayer$1), vectorLayer$1 = null), sketch = null, draw && (e.removeInteraction(draw), draw = null);
1591
- }, drawPolygon = {
1592
- open,
1593
- reset,
1594
- close,
1595
- setConfig
1596
- }, vectorSource$1 = new VectorSource();
1597
- new VectorLayer({
1598
- source: vectorSource$1
1599
- });
1600
- let currentTruckOverlay = null;
1601
- const locationTruck = async (e) => {
1602
- const t = getInstall();
1603
- if (!t || (console.log("vehicleInfo", e), !(e != null && e.lon && (e != null && e.lat)))) return;
1604
- const o = Math.abs(Number(e.lon)) > 180 ? convertSixHundredThousandToLatLng(e.lon, e.lat) : [e.lon, e.lat];
1605
- drawTruckIcon(e, fromLonLat(o));
1606
- const n = t.getView(), r = new Point(o);
1607
- n.setCenter(transform(r.getCoordinates(), projection.data, projection.mercator));
1608
- }, drawTruckIcon = (e, t) => {
1609
- const o = getInstall(), n = `${CDN_URL}map/car-icon.gif`;
1610
- currentTruckOverlay || (currentTruckOverlay = new Overlay({
1611
- element: document.createElement("div"),
1612
- positioning: "center-center",
1613
- stopEvent: !1
1614
- // 允许交互事件穿透
1615
- }), o.addOverlay(currentTruckOverlay));
1616
- const r = currentTruckOverlay.getElement();
1617
- r.style.backgroundImage = `url(${n})`, r.style.width = "80px", r.style.height = "80px";
1618
- const a = (e == null ? void 0 : e.drc) || "";
1619
- r.style.transform = `rotate(${a}deg)`, r.style.backgroundSize = "cover", currentTruckOverlay == null || currentTruckOverlay.setPosition(t);
1620
- }, renderTruckTrack = (e, t, o, n = 1e3) => {
1621
- renderTrackLine(e, t, o, LENGTH_UNIT.KM, "truck", n);
1622
- }, closeTruckTrack = () => {
1623
- closeTrack();
1624
- }, removeTruckIcon = () => {
1625
- const e = currentTruckOverlay == null ? void 0 : currentTruckOverlay.getElement();
1626
- e && (e.innerHTML = "");
1627
- }, resetTrackView = (e) => {
1628
- setTrackViewCenter(e);
1629
- }, playTrack = (e, t) => {
1630
- playShipTrack(e, t);
1631
- }, carTrack = {
1632
- locationTruck,
1633
- renderTruckTrack,
1634
- removeTruckIcon,
1635
- closeTruckTrack,
1636
- resetTrackView,
1637
- playTrack
1638
- }, PORT_LAYER_CLASS_NAME = "zh-map-port-layer";
1639
- let vectorLayer, vectorSource;
1640
- const renderPortList = (e) => {
1641
- var o;
1642
- if (!e || e.length === 0) return;
1643
- const t = getZoom();
1644
- vectorSource || (vectorSource = new VectorSource()), e.forEach((n) => {
1645
- if ((selectedPortFeature == null ? void 0 : selectedPortFeature.get("portData").id) === n.id) return;
1646
- const [r, a] = n.latLon.split(","), i = new Feature({
1647
- geometry: new Point(fromLonLat([Number(r), Number(a)]))
1648
- });
1649
- i.setStyle(setPortStyle(n, t, !1)), i.set("portData", n), vectorSource.addFeature(i);
1650
- }), vectorLayer || (vectorLayer = new VectorLayer({
1651
- className: PORT_LAYER_CLASS_NAME,
1652
- source: vectorSource,
1653
- zIndex: 100
1654
- }), (o = getInstall()) == null || o.addLayer(vectorLayer));
1655
- }, setPortStyle = (e, t, o) => {
1656
- const n = (a) => `<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
1657
- <path fill-rule="evenodd" clip-rule="evenodd" d="M22.6563 44.9304C22.5453 44.8844 22.4445 44.817 22.3595 44.7321C22.3595 44.7321 9.36986 31.7424 9.32952 31.6913C7.09059 29.0791 5.64794 25.8802 5.17255 22.4736C4.69716 19.0671 5.20896 15.5957 6.64728 12.471C8.08561 9.34625 10.3902 6.69909 13.2878 4.84325C16.1855 2.98741 19.5548 2.00068 22.9965 2C26.4381 1.99932 29.8078 2.98473 32.7062 4.83943C35.6046 6.69414 37.9102 9.34039 39.3498 12.4646C40.7893 15.5888 41.3025 19.0599 40.8284 22.4666C40.3544 25.8734 38.913 29.0729 36.6751 31.686C36.6401 31.737 23.6531 44.7321 23.6531 44.7321C23.5682 44.817 23.4674 44.8844 23.3564 44.9304C23.2454 44.9763 23.1265 45 23.0063 45C22.8862 45 22.7673 44.9763 22.6563 44.9304Z" fill="${a}"/>
1658
- <g clip-path="url(#clip0_10059_122082)">
1659
- <path d="M34.8624 22.8687L32.5874 25.6313L33.4812 25.7125C33.4812 25.7125 30.5562 28.0687 27.9562 28.2312C25.3562 28.3937 24.1374 24.9 24.1374 24.9V19.1312H27.6312V17.425H24.2999V15.15C25.7624 14.6625 26.7374 13.2812 26.7374 11.6562C26.7374 9.625 25.1124 8 23.0812 8H22.9999C20.9687 8 19.3437 9.625 19.3437 11.6562C19.3437 13.2812 20.3999 14.6625 21.7812 15.15V17.425H18.4499V19.1312H21.9437V24.9C21.9437 24.9 20.6437 28.3125 18.0437 28.2312C15.4437 28.0687 12.5187 25.7125 12.5187 25.7125L13.4124 25.6313L11.0562 22.8687L10.2437 26.2812L11.2187 26.0375C11.2187 26.0375 13.1687 29.5313 16.1749 30.8313C19.1812 32.2125 22.1874 33.9187 22.8374 34C23.4874 33.9187 26.4937 32.2125 29.4187 30.8313C32.3437 29.45 34.3749 26.0375 34.3749 26.0375L35.3499 26.2812L34.8624 22.8687ZM23.0812 13.6875C21.9437 13.6875 21.0499 12.7937 21.0499 11.6562C21.0499 10.6 21.9437 9.70625 22.9999 9.70625H23.0812C24.1374 9.70625 25.0312 10.6 25.0312 11.6562C25.1124 12.7937 24.1374 13.6875 23.0812 13.6875Z" fill="white"/>
1660
- </g>
1661
- <defs>
1662
- <clipPath id="clip0_10059_122082">
1663
- <rect width="26" height="26" fill="white" transform="translate(10 8)"/>
1664
- </clipPath>
1665
- </defs>
1666
- </svg>
1667
- `, r = () => `data:image/svg+xml;utf8,${encodeURIComponent(n(o ? "#FF5733" : "#3370FF"))}`;
1668
- return new Style({
1669
- text: new Text({
1670
- text: e.shortName,
1671
- font: "12px sans-serif",
1672
- fill: new Fill({
1673
- color: o ? "#ffffff" : "#000000"
1674
- }),
1675
- backgroundFill: new Fill({
1676
- color: o ? "#FF5733" : "#FFFFFF"
1677
- }),
1678
- offsetY: 30
1679
- }),
1680
- image: new Icon({
1681
- src: r(),
1682
- scale: 0.5 * t / 10
1683
- })
1684
- });
1685
- }, clearPortList = () => {
1686
- if (selectedPortFeature) {
1687
- console.log("清除非选中的港口");
1688
- const e = selectedPortFeature.get("portData").id;
1689
- vectorSource.getFeatures().forEach((t) => {
1690
- t.get("portData").id !== e && vectorSource.removeFeature(t);
1691
- });
1692
- } else
1693
- console.log("清除所有港口"), vectorSource.clear();
1694
- };
1695
- let selectedPortFeature = null;
1696
- const selectedPort = (e) => {
1697
- clearPrevSelectedPort(), addSelectedPortStyle(e);
1698
- }, clearPrevSelectedPort = () => {
1699
- if (selectedPortFeature) {
1700
- const e = selectedPortFeature.get("portData"), t = getZoom();
1701
- selectedPortFeature.setStyle(setPortStyle(e, t, !1));
1702
- }
1703
- }, addSelectedPortStyle = (e) => {
1704
- const t = e.get("portData"), o = getZoom();
1705
- selectedPortFeature = e, e.setStyle(setPortStyle(t, o, !0));
1706
- }, handlePortHover = (e) => {
1707
- const t = getInstall(), o = t.forEachFeatureAtPixel(e, (n) => n);
1708
- o && o.get("portData") && (t.getTargetElement().style.cursor = "pointer");
1709
- }, _sfc_main = /* @__PURE__ */ defineComponent({
1710
- __name: "Map",
1711
- props: {
1712
- zoom: { default: MAP_ZOOM.default },
1713
- center: { default: MAP_DEFAULT_CENTER },
1714
- layerType: { default: "vector" },
1715
- showGreenLayer: { type: Boolean, default: !1 },
1716
- showScale: { type: Boolean, default: !0 },
1717
- scaleLineUnit: { default: "metric" },
1718
- mapMoveEnd: { type: Function, default: () => {
1719
- } },
1720
- lineDrawEnd: {},
1721
- selectShip: { type: Function, default: () => {
1722
- } },
1723
- selectPort: { type: Function, default: () => {
1724
- } }
1725
- },
1726
- setup(e, { expose: t }) {
1727
- const o = ref(), n = ref(), r = e, a = ref();
1728
- provide("mapInstance", a);
1729
- const i = ref(!1), s = () => {
1730
- var h;
1731
- if (i.value) return;
1732
- const u = {
1733
- vectorTile: new TileLayer({
1734
- source: new XYZ({ url: BASE_MAP_LINK.vectorTile }),
1735
- visible: r.layerType === "vector",
1736
- zIndex: 0,
1737
- preload: 1,
1738
- className: "vector"
1739
- }),
1740
- vectorTileMark: new TileLayer({
1741
- source: new XYZ({ url: BASE_MAP_LINK.vectorTileMark }),
1742
- visible: r.layerType === "vector",
1743
- zIndex: 1,
1744
- preload: 1,
1745
- className: "vector"
1746
- }),
1747
- satelliteImgTile: new TileLayer({
1748
- source: new XYZ({ url: BASE_MAP_LINK.satelliteImgTile }),
1749
- visible: r.layerType === "satellite",
1750
- zIndex: 0,
1751
- preload: 1,
1752
- className: "satellite"
1753
- }),
1754
- satelliteImgTileMark: new TileLayer({
1755
- source: new XYZ({ url: BASE_MAP_LINK.satelliteImgTileMark }),
1756
- visible: r.layerType === "satellite",
1757
- zIndex: 1,
1758
- preload: 1,
1759
- className: "satellite"
1760
- }),
1761
- greenMark: new TileLayer({
1762
- source: new XYZ({ url: BASE_MAP_LINK.greenTile }),
1763
- visible: r.showGreenLayer,
1764
- zIndex: 2,
1765
- className: "greenTile"
1766
- })
1767
- }, l = {
1768
- zoom: r.zoom,
1769
- center: fromLonLat(r.center),
1770
- minZoom: MAP_ZOOM.min,
1771
- maxZoom: MAP_ZOOM.max,
1772
- constrainResolution: !0,
1773
- enableRotation: !1,
1774
- multiWorld: !0
1775
- };
1776
- a.value = new Map$2({
1777
- target: "map",
1778
- layers: [
1779
- u.vectorTile,
1780
- u.vectorTileMark,
1781
- u.satelliteImgTile,
1782
- u.satelliteImgTileMark
1783
- // BASE_MAP.greenMark
1784
- ],
1785
- view: new View(l)
1786
- }), a.value.on("moveend", () => {
1787
- var f;
1788
- const g = getZoom();
1789
- (f = r.mapMoveEnd) == null || f.call(r, g), reRenderTrackLine();
1790
- }), a.value.on("pointermove", (g) => {
1791
- const f = a.value.getEventPixel(g.originalEvent), w = a.value.getFeaturesAtPixel(f), v = w.length > 0 ? w[0] : void 0;
1792
- handleShipMapEvent(v, "hover"), v && (handleTrackMapEvent(v, "hover", g), handlePortHover(f));
1793
- });
1794
- const c = (g) => {
1795
- handleShipMapEvent(g, "click", r == null ? void 0 : r.selectShip);
1796
- }, p = (g) => {
1797
- const f = g.get("portData");
1798
- selectedPort(g), r == null || r.selectPort(String(f == null ? void 0 : f.id));
1799
- }, m = debounce((g) => {
1800
- if (drawLine.getState()) return;
1801
- const f = a.value.getEventPixel(g.originalEvent), w = a.value.forEachFeatureAtPixel(
1802
- f,
1803
- (v) => {
1804
- if (v != null && v.get("shipData") || v != null && v.get("portData"))
1805
- return v;
1806
- }
1807
- );
1808
- w && (g.preventDefault(), g.stopPropagation(), w.get("shipData") ? c(w) : w.get("portData") && p(w));
1809
- }, 150);
1810
- a.value.on("click", m), a.value.getView().on("change:resolution", () => {
1811
- handleShipChange();
1812
- }), i.value = !0, setInstall(a.value), setShowLayerType(r.layerType), console.log("props.showGreenLayer", r.showGreenLayer), setGreenTileVisible(r.showGreenLayer), drawLine.setConfig({ lineDrawEndFn: r.lineDrawEnd }), (h = n.value) == null || h.setScaleLine(r.scaleLineUnit);
1813
- };
1814
- return onMounted(() => {
1815
- s();
1816
- }), t({
1817
- getInstall,
1818
- getZoom,
1819
- setZoom,
1820
- getView,
1821
- setCenter,
1822
- getCenter,
1823
- layer: {
1824
- getGreenTileVisible,
1825
- setGreenTileVisible,
1826
- getShowLayerType,
1827
- setShowLayerType
1828
- },
1829
- ship: {
1830
- render: renderShipList,
1831
- selected: renderShipSelected,
1832
- filter: filterShipShow,
1833
- blinking: renderShipBlink,
1834
- clear: clearShipList
1835
- },
1836
- track: {
1837
- renderTrackLine,
1838
- handleTrackMapEvent,
1839
- removeAllTrackLayer,
1840
- playShipTrack,
1841
- setTrackViewCenter,
1842
- closeTrack
1843
- },
1844
- port: {
1845
- render: renderPortList,
1846
- clear: clearPortList,
1847
- selected: selectedPort
1848
- },
1849
- drawLine,
1850
- // 绘制矩形
1851
- drawPolygon,
1852
- carTrack,
1853
- utils: {
1854
- getCalculateExtent: () => {
1855
- const u = getView().calculateExtent(a.value.getSize()), l = transform([u[0], u[1]], projection.mercator, projection.data), c = transform([u[2], u[3]], projection.mercator, projection.data);
1856
- return [l[0], l[1], c[0], c[1]];
1857
- },
1858
- convertSixHundredThousandToLatLng
1859
- }
1860
- }), (u, l) => (openBlock(), createElementBlock(Fragment, null, [
1861
- createElementVNode("div", {
1862
- id: "map",
1863
- ref_key: "zhMapRef",
1864
- ref: o,
1865
- class: "zh-map"
1866
- }, null, 512),
1867
- createVNode(ScaleLine, {
1868
- ref_key: "scaleLineRef",
1869
- ref: n
1870
- }, null, 512),
1871
- createVNode(ZoomControl, { ref: "zoomControlRef" }, null, 512)
1872
- ], 64));
1873
- }
1874
- }), Map$1 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-6bb98b8e"]]), ZhMap = withInstall(Map$1);
1875
- export {
1876
- ZhMap as Z
1877
- };