UNPKG

gisviewer-vue3-arcgis

Version:

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

270 lines (269 loc) 9.85 kB
import F from "ol/Feature"; import v from "ol/geom/Point"; import U from "ol/layer/Vector"; import { unByKey as K } from "ol/Observable"; import X from "ol/source/Vector"; import V from "ol/style/Circle"; import y from "ol/style/Fill"; import Z from "ol/style/Icon"; import C from "ol/style/Stroke"; import g from "ol/style/Style"; import z from "ol/style/Text"; import { PixelClusterCalculator as G } from "../cluster/pixel-cluster-calculator.mjs"; class re { // 大于17级时样式是否从圆点变为图标,默认为true constructor(e) { this.showName = "detail", this.showStyle = "scatter", this.viewChangeKey = null, this.mapMoveKey = null, this.resolutionChangeTimeout = null, this.locations = [], this.allLocations = [], this.changeStyle = !0, this.map = e, this.view = e.getView(), this.clusterCalculator = new G(e), this.source = new X(), this.crossLayer = new U({ source: this.source }), this.crossLayer.set("id", "signal-control-cross-layer"), this.map.addLayer(this.crossLayer), this.configureVectorLayerStyle(); } showSignalCross(e) { if (this.changeStyle = e.changeStyle ?? !0, this.crossLayer.setVisible(!0), this.source.clear(), this.showName = e.showName || "detail", this.showStyle = e.style || "scatter", this.viewChangeKey || (this.viewChangeKey = this.view.on("change:resolution", () => { this.showStyle === "cluster" && (this.resolutionChangeTimeout && clearTimeout(this.resolutionChangeTimeout), this.resolutionChangeTimeout = setTimeout(() => { this.calculateCluster(), this.resolutionChangeTimeout = null; }, 150)); })), this.mapMoveKey || (this.mapMoveKey = this.map.on("moveend", () => { this.showStyle === "cluster" && this.calculateCluster(); })), this.showStyle === "scatter") { const t = [], i = []; e.points.forEach((a) => { const r = this.createCrossFeature(a); a.isMalfunction === !0 || a.isOnline === !1 ? i.push(r) : t.push(r); }), this.source.addFeatures(t), this.source.addFeatures(i), this.crossLayer.changed(); } else this.locations = e.points.map((t) => ({ id: t.crossId, x: t.x, y: t.y, visited: !1, clusterId: void 0, properties: t })), this.allLocations = [...this.locations], this.calculateCluster(); return { status: 0, message: "success" }; } calculateCluster() { const e = this.clusterCalculator.calculate(this.locations), t = this.clusterCalculator.calculateSymbolSizes(e); this.showClusterResult(t); } clearSignalCross() { this.source.clear(), this.viewChangeKey && (K(this.viewChangeKey), this.viewChangeKey = null), this.mapMoveKey && (K(this.mapMoveKey), this.mapMoveKey = null), this.resolutionChangeTimeout && (clearTimeout(this.resolutionChangeTimeout), this.resolutionChangeTimeout = null); } changeShowName(e) { this.showName = e, this.showStyle === "scatter" && this.updateScatterSymbol(); } setVisible(e) { this.crossLayer.setVisible(e); } updateScatterSymbol() { this.crossLayer.changed(); } /** * 配置矢量图层样式:复用 Icon,并为不同 feature 渲染不同 Text。 * - 使用 resolution 判断是否显示文字(在指定缩放级别后才显示) * - 使用缓存避免每次渲染都创建新的 Style/Icon/数组对象 */ configureVectorLayerStyle() { const s = this.map.getView(), h = s.getResolutionForZoom(14), u = s.getResolutionForZoom(17), m = s.getResolutionForZoom(17), k = (o, n, l) => o === void 0 && n === void 0 && l === void 0 ? "/GisViewerAssets/Images/cross/gis_xhj_blue.png" : `/GisViewerAssets/Images/cross/ic_${(o ?? "gc").toLowerCase() === "scats" ? "scats" : "gc"}_${n === !1 ? "offline" : "online"}_${l ? "malfunction" : "normal"}.png`, p = /* @__PURE__ */ new Map(), M = /* @__PURE__ */ new Map(), O = /* @__PURE__ */ new WeakMap(), x = { online: "#22c55e", // 绿色 - 在线 offline: "#9ca3af" // 灰色 - 离线 }, I = new C({ color: "#ffffff", width: 1.5 }), L = /* @__PURE__ */ new Map(), A = (o) => { const n = o === !1 ? "offline" : "online", l = L.get(n); if (l) return l; const c = [ new g({ image: new V({ radius: 3, fill: new y({ color: x[n] }), stroke: I }), zIndex: 1 }) ]; return L.set(n, c), c; }, b = /* @__PURE__ */ new Map(), S = (o) => { const n = o === !1 ? "offline" : "online", l = b.get(n); if (l) return l; const c = [ new g({ image: new V({ radius: 5, fill: new y({ color: x[n] }), stroke: I }), zIndex: 1 }) ]; return b.set(n, c), c; }, B = new y({ color: "#1f2937" }), R = new C({ color: "#ffffff", width: 3 }), _ = (o) => { const n = p.get(o); if (n) return n; const l = new g({ image: new Z({ src: o, scale: 0.5, anchor: [0.5, 1], anchorXUnits: "fraction", anchorYUnits: "fraction" }), zIndex: 1 }); return p.set(o, l), l; }, D = (o) => { const n = M.get(o); if (n) return n; const l = [_(o)]; return M.set(o, l), l; }; this.crossLayer.setStyle((o, n) => { if ((o.get("type") ?? "") === "signal-cluster") return this.getClusterStyle(o.getProperties()); const c = this.showName === "crossName" ? o.get("name") : this.showName === "signalId" ? o.get("signalId") : `${o.get("name")}(${o.get("signalId")})`, T = o.get("brand"), f = o.get("isOnline"), N = o.get("isMalfunction"), d = k(T, f, N); if (n > h) return A(f); if (n > u) return S(f); if (n > m) return this.changeStyle ? D(d) : S(f); const w = O.get(o); if (w && w.label === c && w.iconKey === d) return w.styles; const P = this.changeStyle ? _(d) : S(f)[0], Y = new g({ text: new z({ text: c, font: '12px "Microsoft YaHei"', textAlign: "center", textBaseline: "bottom", offsetY: this.changeStyle ? -28 : -8, fill: B, stroke: R }), zIndex: 2 }), E = [P, Y]; return O.set(o, { label: c, iconKey: d, styles: E }), E; }); } createCrossFeature(e) { var i; return e.brand = (i = e.brand) == null ? void 0 : i.toLowerCase(), new F({ geometry: new v([e.x, e.y]), type: "signal-cross", id: e.crossId, brandLabel: this.getBrandLabel(e.brand), isOnlineLabel: this.getOnlineLabel(e.isOnline), isMalfunctionLabel: this.getMalfunctionLabel(e.isMalfunction), ...e }); } getClusterStyle(e) { const t = e.clusterSymbolSize, i = new Z({ src: "/GisViewerAssets/Images/cross/gis_xhj_blue.png", scale: t / 32 // 近似缩放 }), a = -(t + 10), r = new z({ text: String(e.count ?? 0), font: "16px Arial Unicode MS", fill: new y({ color: [255, 255, 255, 255] }), backgroundFill: new y({ color: [2, 72, 200, 1] }), backgroundStroke: new C({ color: [2, 72, 200, 0.5], width: 2 }), padding: [1, 2, 1, 2], offsetY: a, textAlign: "center", justify: "center", textBaseline: "middle" }); return [new g({ image: i }), new g({ text: r })]; } // private formatCrossName(name?: string) { // return (name || '').replace(/与/g, '/'); // } getBrandLabel(e) { const t = (e ?? "").toLowerCase(); return t === "scats" ? "SCATS" : t === "gc" ? "国产" : e ?? ""; } getOnlineLabel(e) { return e ? "在线" : "离线"; } getMalfunctionLabel(e) { return e ? "故障" : "正常"; } showClusterResult(e) { this.source.clear(), e.forEach((t) => { if (t.id !== -1 && t.center && t.symbolSize) { const i = new F({ geometry: new v([t.center.x, t.center.y]), type: "signal-cluster", count: t.count, clusterSymbolSize: t.symbolSize }); this.source.addFeature(i); } else t.items.forEach((i) => { const a = this.createCrossFeature({ ...i.properties, x: i.x, y: i.y }); this.source.addFeature(a); }); }), this.crossLayer.changed(); } highlight(e, t) { var a; if (this.showStyle === "cluster") { const r = this.allLocations.filter((s) => s.properties[e] === t); if (r.length > 0) { this.locations = r, this.calculateCluster(); const s = [ 1 / 0, 1 / 0, -1 / 0, -1 / 0 ]; return r.forEach((h) => { s[0] = Math.min(s[0], h.x), s[1] = Math.min(s[1], h.y), s[2] = Math.max(s[2], h.x), s[3] = Math.max(s[3], h.y); }), s; } return null; } const i = []; if (this.source.getFeatures().forEach((r) => { r.get(e) === t ? (r.setStyle(void 0), i.push(r)) : r.setStyle(new g({})); }), i.length > 0) { const r = (a = i[0].getGeometry()) == null ? void 0 : a.getExtent(); if (r) { const s = [...r]; return i.slice(1).forEach((h) => { var m; const u = (m = h.getGeometry()) == null ? void 0 : m.getExtent(); u && (s[0] = Math.min(s[0], u[0]), s[1] = Math.min(s[1], u[1]), s[2] = Math.max(s[2], u[2]), s[3] = Math.max(s[3], u[3])); }), s; } } return null; } clearHighlight() { if (this.showStyle === "cluster") { this.locations = [...this.allLocations], this.calculateCluster(); return; } this.source.getFeatures().forEach((e) => { e.setStyle(void 0); }); } } export { re as default };