gisviewer-vue3-arcgis
Version:
在应用中引入私服的包, 项目根目录下 新建文件 .npmrc 在 .npmrc 中对包源进行配置:
274 lines (273 loc) • 8.92 kB
JavaScript
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
};