UNPKG

gisviewer-vue3-arcgis

Version:

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

594 lines (593 loc) 19.2 kB
import { Point as h } from "@arcgis/core/geometry"; import u from "@arcgis/core/Graphic"; import p from "@arcgis/core/layers/GraphicsLayer"; class x { constructor(e) { this.crossGraphicSymbol = { type: "cim", data: { type: "CIMSymbolReference", primitiveOverrides: [ { type: "CIMPrimitiveOverride", primitiveName: "textGraphic", propertyName: "TextString", valueExpressionInfo: { type: "CIMExpressionInfo", title: "Custom", expression: 'Replace($feature.name, "与", "/") + " " + $feature.signalId', returnType: "Default" } } ], symbol: { type: "CIMPointSymbol", symbolLayers: [ { type: "CIMVectorMarker", size: 32, colorLocked: !0, anchorPointUnits: "Relative", frame: { xmin: -16, ymin: -16, xmax: 16, ymax: 16 }, markerGraphics: [ { type: "CIMMarkerGraphic", primitiveName: "textGraphic", geometry: { x: 0, y: 0 }, symbol: { type: "CIMTextSymbol", height: 12, horizontalAlignment: "Center", offsetX: 0, offsetY: 18, haloSize: 1, haloSymbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [255, 255, 255, 255] } ] }, symbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [0, 0, 0, 255] } ] }, verticalAlignment: "Center" }, textString: "" } ], scaleSymbolsProportionally: !0, respectFrame: !0 }, { type: "CIMPictureMarker", enable: !0, anchorPoint: { x: 0, y: 0 }, anchorPointUnits: "Relative", size: 20, rotateClockwise: !0, textureFilter: "Picture", url: "/GisViewerAssets/Images/cross/gis_xhj_blue.png" } ] } } }, this.locations = [], this.clusteredLocations = [], this.filteredLocations = [], this.currentShowMode = "scatter", this.symbolScale = 5e3, this.oldScale = 0, this.clusterRadius = 120, this.minClusterPoints = 2, this.maxClusterSymbolSize = 50, this.minClusterSymbolSize = 25, this.view = e, this.crossLayer = new p(), this.view.map.add(this.crossLayer), this.oldScale = e.scale; } async addCrosses(e) { e.forEach((t) => { t.signals.forEach((i) => { i.longitude && i.latitude && !isNaN(i.longitude) && !isNaN(i.latitude) && this.locations.push({ id: i.id, x: i.longitude, y: i.latitude, visited: !1, filtered: !1, clusterId: void 0, properties: { ...i, districtId: t.id, districtName: t.name, subDistrictId: "", subDistrictName: "" } }); }), t.subDistricts.forEach((i) => { i.signals.forEach((s) => { s.longitude && s.latitude && !isNaN(s.longitude) && !isNaN(s.latitude) && this.locations.push({ id: s.id, x: s.longitude, y: s.latitude, visited: !1, filtered: !1, clusterId: void 0, properties: { ...s, districtId: t.id, districtName: t.name, subDistrictId: i.id, subDistrictName: i.name } }); }); }); }), this.zoomWatchHandle = this.view.watch("stationary", () => { if (this.view.stationary !== !1) { if (this.currentShowMode === "scatter") (this.oldScale < this.symbolScale && this.view.scale >= this.symbolScale || this.oldScale >= this.symbolScale && this.view.scale < this.symbolScale) && this.updateScatterSymbol(), this.oldScale = this.view.scale; else if (this.currentShowMode === "cluster") { this.locationToScreen(), console.time("cluster"); const t = this.doPixelCluster(this.clusterRadius); console.timeEnd("cluster"), this.showClusterResult(t); } } }); } /** * 清除所有路口 */ clearCrosses() { var e; this.crossLayer.removeAll(), this.locations = [], this.clusteredLocations = [], (e = this.zoomWatchHandle) == null || e.remove(); } /** * 更新散点符号 */ updateScatterSymbol() { this.crossLayer.graphics.forEach((e) => { e.symbol = this.getCrossSymbol(e.attributes); }); } /** * 将地理位置转换为屏幕坐标 */ locationToScreen() { this.clusteredLocations = [], this.locations.forEach((e) => { const t = this.view.toScreen( new h({ x: e.x, y: e.y }) ); e.filtered === !1 && t.x > 0 && t.y > 0 && (e.properties.screenX = t.x, e.properties.screenY = t.y, e.visited = !1, e.clusterId = void 0, this.clusteredLocations.push(e)); }); } /** * 显示聚合点 */ showCluster() { this.crossLayer.removeAll(), this.currentShowMode = "cluster", this.locationToScreen(); const e = this.doPixelCluster(this.clusterRadius); this.showClusterResult(e); } /** * 显示散点 */ showScatter() { this.crossLayer.removeAll(), this.currentShowMode = "scatter"; const e = []; this.locations.forEach((t) => { if (!t.filtered) { const i = new u({ geometry: { type: "point", longitude: t.x, latitude: t.y }, symbol: this.getCrossSymbol(t.properties), attributes: t.properties, popupTemplate: { title: "{name}信号机", content: [ { type: "fields", fieldInfos: [ { fieldName: "signalId", label: "信号机编号" }, { fieldName: "nodeId", label: "路口编号" }, { fieldName: "districtName", label: "区控名称" }, { fieldName: "subDistrictName", label: "子区名称" } ] } ] } }); e.push(i); } }), this.crossLayer.addMany(e); } /** * 隐藏路口 */ hideCrosses() { this.crossLayer.removeAll(); } filter(e) { this.locations.forEach((t) => { if (e.type === "district") t.filtered = t.properties.districtId !== e.id; else if (e.type === "subDistrict") t.filtered = t.properties.subDistrictId !== e.id; else if (e.type === "signal" && (t.filtered = t.id !== e.id, t.filtered)) return t.properties; }); } resetFilter() { this.locations.forEach((e) => { e.filtered = !1; }), this.currentShowMode === "scatter" ? this.showScatter() : this.currentShowMode === "cluster" && this.showCluster(); } /** * 根据当前比例尺更新路口符号 * @param attributes * @returns */ getCrossSymbol(e) { if (this.view.scale > this.symbolScale) return e.isKey ? { // 关键路口用星号图标 type: "picture-marker", url: "/GisViewerAssets/Images/icon_star.png", width: "20px", height: "20px" } : { // 普通路口用圆点 type: "simple-marker", style: "circle", color: [5, 116, 255, 0.8], size: 8, outline: { color: "white", width: 0 } }; { const t = e.isKey ? "/GisViewerAssets/Images/cross/gis_gjxklk_orange.png" : "/GisViewerAssets/Images/cross/gis_xhj_blue.png"; return { type: "cim", data: { type: "CIMSymbolReference", primitiveOverrides: [ { // 将textGraphic的TextString替换为graphic.attributes.name type: "CIMPrimitiveOverride", primitiveName: "textGraphic", propertyName: "TextString", valueExpressionInfo: { type: "CIMExpressionInfo", title: "Custom", expression: 'Replace($feature.name, "与", "/") + " " + $feature.signalId', returnType: "Default" } } ], symbol: { type: "CIMPointSymbol", symbolLayers: [ // 路口名称 { type: "CIMVectorMarker", size: 32, colorLocked: !0, anchorPointUnits: "Relative", frame: { xmin: -16, ymin: -16, xmax: 16, ymax: 16 }, markerGraphics: [ { type: "CIMMarkerGraphic", primitiveName: "textGraphic", geometry: { x: 0, y: 0 }, symbol: { type: "CIMTextSymbol", height: 12, horizontalAlignment: "Center", offsetX: 0, offsetY: 20, haloSize: 1, haloSymbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [255, 255, 255, 255] } ] }, symbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [0, 0, 0, 255] } ] }, verticalAlignment: "Center" }, textString: "" } ], scaleSymbolsProportionally: !0, respectFrame: !0 }, // 路口图标 { type: "CIMPictureMarker", enable: !0, anchorPoint: { x: 0, y: 0 }, anchorPointUnits: "Relative", size: 20, rotateClockwise: !0, textureFilter: "Picture", url: t } ] } } }; } } /** * 获取邻居点 * @param locations * @param index * @param eps * @returns */ getNeighbors(e, t) { return this.clusteredLocations.filter((i) => i.id === e.id || i.visited ? !1 : this.getDistance(e, i) <= t); } /** * 两点间的像素距离 * @param point1 * @param point2 * @returns */ getDistance(e, t) { return Math.sqrt( Math.pow(e.properties.screenX - t.properties.screenX, 2) + Math.pow(e.properties.screenY - t.properties.screenY, 2) ); } /** * 从聚类结果中创建聚类对象 * @param locations * @returns */ createClusters() { const e = {}, t = []; for (const s of this.clusteredLocations) s.clusterId === void 0 || s.clusterId === -1 ? t.push(s) : (e[s.clusterId] || (e[s.clusterId] = []), e[s.clusterId].push(s)); const i = Object.keys(e).map((s, r) => { const o = e[Number(s)], a = o.length, l = o.reduce((n, m) => n + m.x, 0), c = o.reduce((n, m) => n + m.y, 0), y = l / a, d = c / a; return { id: Number(s), items: o, count: a, center: { x: y, y: d } }; }); return t.length > 0 && i.push({ id: -1, items: t, count: t.length, center: null }), i; } /** * 按照像素距离聚类 * @param locations * @param eps * @param minPoints * @returns */ doPixelCluster(e) { let t = 0; for (let i = 0; i < this.clusteredLocations.length; i++) { const s = this.clusteredLocations[i]; if (s.visited) continue; s.visited = !0; const r = this.getNeighbors(s, e); r.length < this.minClusterPoints ? s.clusterId = -1 : (r.forEach((o) => { o.visited = !0, o.clusterId = t; }), s.clusterId = t, t++); } return this.createClusters(); } showClusterResult(e) { this.crossLayer.removeAll(); let t = Number.MIN_VALUE, i = Number.MAX_VALUE; e.forEach((s) => { s.count > 1 && (i = Math.min(i, s.count), t = Math.max(t, s.count)); }), e.forEach((s) => { if (s.id !== -1) { let r = i === t ? (this.maxClusterSymbolSize + this.minClusterSymbolSize) / 2 : this.minClusterSymbolSize + (s.count - i) / (t - i) * (this.maxClusterSymbolSize - this.minClusterSymbolSize); r *= 0.75; const l = (s.count.toString().length * 8 + 6) / 2, c = new u({ geometry: new h({ x: s.center.x, y: s.center.y }), attributes: { count: s.count }, symbol: { type: "cim", data: { type: "CIMSymbolReference", primitiveOverrides: [ { // 将textGraphic的TextString替换为graphic.attributes.name type: "CIMPrimitiveOverride", primitiveName: "textGraphic", propertyName: "TextString", valueExpressionInfo: { type: "CIMExpressionInfo", title: "Custom", expression: "$feature.count", returnType: "Default" } } ], symbol: { type: "CIMPointSymbol", symbolLayers: [ // 聚合数量 { type: "CIMVectorMarker", size: r, colorLocked: !0, anchorPointUnits: "Relative", frame: { xmin: -16, ymin: -16, xmax: 16, ymax: 16 }, markerGraphics: [ // 数量文本框 { type: "CIMMarkerGraphic", geometry: { rings: [ [ [-l, 40], [l, 40], [l, 20], [-l, 20], [-l, 40] ] ] }, symbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [2, 72, 200, 255] }, { type: "CIMSolidStroke", enable: !0, width: 5, color: [2, 72, 200, 128] } ] } }, // 数量文字 { type: "CIMMarkerGraphic", primitiveName: "textGraphic", geometry: { x: 0, y: 0 }, symbol: { type: "CIMTextSymbol", height: 16, horizontalAlignment: "Center", offsetX: 0, offsetY: 30, symbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [255, 255, 255, 255] } ] }, verticalAlignment: "Center" }, textString: "" } ], scaleSymbolsProportionally: !0, respectFrame: !0 }, // 聚合图标 { type: "CIMPictureMarker", enable: !0, anchorPoint: { x: 0, y: 0 }, anchorPointUnits: "Relative", size: r, rotateClockwise: !0, textureFilter: "Picture", url: "/GisViewerAssets/Images/cross/gis_xhj_blue.png" } ] } } } }); this.crossLayer.add(c); } else s.items.forEach((r) => { const o = new u({ geometry: new h({ x: r.x, y: r.y }), attributes: { ...r, ...r.properties, type: "clusterPoint", id: r.id }, symbol: this.crossGraphicSymbol, popupTemplate: { title: "{name}信号机", content: [ { type: "fields", fieldInfos: [ { fieldName: "signalId", label: "信号机编号" }, { fieldName: "nodeId", label: "路口编号" }, { fieldName: "districtName", label: "区控名称" }, { fieldName: "subDistrictName", label: "子区名称" } ] } ] } }); this.crossLayer.add(o); }); }); } } export { x as default };