UNPKG

gisviewer-vue3-arcgis

Version:

在应用中引入私服的包, 项目根目录下 新建文件 .npmrc 在 .npmrc 中对包源进行配置:

274 lines (273 loc) 8.92 kB
import y from "ol/Feature"; import { Point as d } from "ol/geom"; import f from "ol/layer/Vector"; import S from "ol/source/Vector"; import { Style as l, Fill as w, Stroke as M, Icon as m } from "ol/style"; import b from "ol/style/Circle"; import { toRaw as v } from "vue"; import C from "../../../stores/index.mjs"; class O { constructor(i) { this.isDotStyle = !0, this.hasGpu = !1, this.clearTraceTimer = null, this.minSegmentDuration = 1, this.historyTrimThreshold = 64, this.hiddenStyle = new l({}), this.simpleMarkerStyle = new l({ image: new b({ radius: 2, fill: new w({ color: "#1DFF1D" }), stroke: new M({ color: "#fff", width: 1 }) }) }), this.styleCache = /* @__PURE__ */ new Map(), this.historyPositionMap = /* @__PURE__ */ new Map(), this.vehicleObjectMap = /* @__PURE__ */ new Map(); const t = localStorage.getItem("gpu"); this.hasGpu = t !== "Unknown", this.hasGpu && (this.rafSignal = requestAnimationFrame(() => this.render())), this.mapConfig = v(C.useAppDataStore.mapConfig), this.map = i, this.dotStyleResolution = this.map.getView().getResolutionForZoom(17); const e = this.map.getView().getResolution(); this.isDotStyle = e > this.dotStyleResolution, this.map.getView().on("change:resolution", () => { const s = this.map.getView().getResolution(), a = s > this.dotStyleResolution; a !== this.isDotStyle && (this.isDotStyle = a, this.refreshAllStyles(s)); }), this.vectorSource = new S(), this.carLayer = new f({ source: this.vectorSource }), this.map.addLayer(this.carLayer); } /** * 新增交通对象 * @param objects */ addVehicles(i) { const t = this.map.getView().getResolution(), e = i.map((s) => { const { vehicleId: a, heading: n, localTimestamp: c } = s, r = Number(s.x), o = Number(s.y), h = new y({ geometry: new d([r, o]) }); return this.hasGpu ? (this.historyPositionMap.set(a, [ { pos: [r, o, 0], heading: n, time: c } ]), this.vehicleObjectMap.set(a, { feature: h, data: s, historyIndex: 0, waitForDelete: !1, isMoving: !1 }), h.setStyle(this.getVehicleStyle(s, t))) : h.setStyle(this.simpleMarkerStyle), h; }); this.vectorSource.addFeatures(e); } /** * 更新交通对象位置 * @param objects */ updateVehicles(i) { i.forEach((t) => { const { vehicleId: e, heading: s, localTimestamp: a } = t, n = Number(t.x), c = Number(t.y), r = this.vehicleObjectMap.get(e); r && (this.hasGpu ? (r.data = t, this.historyPositionMap.get( e ).push({ pos: [n, c, 0], heading: s, time: a })) : r.feature.getGeometry().setCoordinates([n, c])); }); } /** * 分辨率跨越dotStyleResolution阈值时,刷新所有feature的样式 */ refreshAllStyles(i) { this.hasGpu && this.vehicleObjectMap.forEach((t) => { t.feature.setStyle(this.getVehicleStyle(t.data, i)); }); } destroy() { this.deleteVehicles([]), this.rafSignal && cancelAnimationFrame(this.rafSignal), this.map.removeLayer(this.carLayer), this.carLayer.dispose(); } deleteVehicles(i) { this.hasGpu ? i.forEach((t) => { const e = this.vehicleObjectMap.get(t); e && (e.waitForDelete = !0); }) : i.forEach((t) => { const e = this.vehicleObjectMap.get(t); e && (this.vectorSource.removeFeature(e.feature), this.vehicleObjectMap.delete(t), this.historyPositionMap.delete(t)); }); } render() { const i = Date.now(); this.vehicleObjectMap.keys().forEach((t) => { this.updatePosition(t, i); }), this.rafSignal = requestAnimationFrame(() => this.render()); } /** * 更新车辆位置 * @param vehicleId */ updatePosition(i, t) { const e = this.historyPositionMap.get(i), s = this.vehicleObjectMap.get(i); if (!e || !s) return; const a = s.historyIndex; if (!s.isMoving && e.length - a <= 2) return; s.isMoving = !0, s.segmentStartTime == null && (s.segmentStartTime = t, s.segmentTotalTime = Math.max( this.minSegmentDuration, e[a + 1].time - e[a].time )); const n = Math.max( this.minSegmentDuration, s.segmentTotalTime ?? this.minSegmentDuration ), c = t - s.segmentStartTime, r = Math.min(1, Math.max(0, c / n)); if (r === 1) { s.historyIndex += 1, s.historyIndex >= this.historyTrimThreshold && (e.splice(0, s.historyIndex), s.historyIndex = 0); const o = s.historyIndex; if (e.length - o === 1) { s.waitForDelete ? (this.vectorSource.removeFeature(s.feature), this.vehicleObjectMap.delete(i), this.historyPositionMap.delete(i)) : (s.segmentStartTime = void 0, s.segmentTotalTime = void 0, s.feature.setStyle(this.hiddenStyle), s.isMoving = !1); return; } else { s.segmentStartTime = t; const h = c - n; s.segmentTotalTime = Math.max( this.minSegmentDuration, e[o + 1].time - e[o].time - h ), Math.abs( e[o + 1].heading - e[o].heading ) > 180 && (e[o + 1].heading > e[o].heading ? e[o].heading += 360 : e[o + 1].heading += 360), s.feature.getGeometry().setCoordinates(e[o].pos), this.applyVehicleHeadingStyle( s, e[o].heading ); } } else { const o = e[a], h = e[a + 1], g = o.pos[0] + (h.pos[0] - o.pos[0]) * r, p = o.pos[1] + (h.pos[1] - o.pos[1]) * r, u = o.heading + (h.heading - o.heading) * r; s.feature.getGeometry().setCoordinates([g, p]), this.applyVehicleHeadingStyle(s, u); } } /** * 根据插值角度更新车辆图标旋转 */ applyVehicleHeadingStyle(i, t) { if (this.isDotStyle) return; const e = (t % 360 + 360) % 360, s = i.feature.getStyle(), a = s == null ? void 0 : s.getImage(); a instanceof m && (a.setRotation((e + 90) * Math.PI / 180), i.feature.changed()); } /** * 获取车辆feature的样式 * @param trackData 轨迹点数据 * @param resolution 当前分辨率 * @returns */ getVehicleStyle(i, t) { if (this.hasGpu) { let e = ""; if (t > this.dotStyleResolution) { const s = i.speed || 100; s <= 4.2 ? e = "point_red.png" : s <= 8.4 ? e = "point_yellow.png" : e = "point_green.png"; const a = `dot-${e}`; if (this.styleCache.has(a)) return this.styleCache.get(a); { const n = new l({ image: new m({ src: `${this.mapConfig.assetsRoot}/Images/${e}`, scale: 0.3 }) }); return this.styleCache.set(a, n), n; } } else { const s = i.vehicleColor; typeof s == "string" && (e = s.toLowerCase()); const a = this.getCarPicSource(i.vehicleColor); return new l({ image: new m({ src: a, scale: 0.1, rotation: ((i.heading || 0) + 90) * Math.PI / 180 }) }); } } else { const e = "no-gpu"; return this.styleCache.has(e) || this.styleCache.set(e, this.simpleMarkerStyle), this.styleCache.get(e); } } /** * 根据车身颜色代码获取车辆图标路径 * @param carColor * @returns */ getCarPicSource(i) { let t = ""; switch (i) { case "a": case 1: t = "white"; break; case "b": case 2: t = "grey"; break; case "c": case 3: t = "yellow"; break; case "d": case 4: t = "pink"; break; case "e": case 5: t = "red"; break; case "f": case 10: t = "purple"; break; case "g": case 6: t = "green"; break; case "h": case 7: t = "blue"; break; case "i": case 8: t = "brown"; break; case "j": case 9: t = "black"; break; default: t = "grey"; break; } return t = "car/" + t + ".png", `${this.mapConfig.assetsRoot}/Images/${t}`; } /** * 根据号牌颜色属性获取填充色和背景色 * @param plateColor * @returns */ getPlateFontColor(i) { let t = [255, 255, 255, 255], e = [169, 169, 169, 255]; switch (i) { case 0: t = [0, 0, 0, 255], e = [255, 255, 255, 255]; break; case 1: t = [0, 0, 0, 255], e = [244, 164, 96, 255]; break; case 2: t = [255, 255, 255, 255], e = [65, 105, 225, 255]; break; case 3: t = [255, 255, 255, 255], e = [0, 0, 0, 255]; break; case 15: t = [244, 164, 96, 255], e = [0, 250, 154, 255]; break; case 16: t = [0, 0, 0, 255], e = [0, 250, 154, 255]; break; } return { fillColor: t, backgroundColor: e }; } } export { O as default };