UNPKG

gisviewer-vue3-arcgis

Version:

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

293 lines (292 loc) 10.3 kB
import { Point as c } from "@arcgis/core/geometry"; import y from "@arcgis/core/Graphic"; import C from "@arcgis/core/layers/GraphicsLayer"; class S { constructor(e) { this.maxClusterSymbolSize = 50, this.minClusterSymbolSize = 25, this.clusterRadius = 120, this.minClusterPoints = 2, this.zoomWatchHandle = null, this.countBackgroundColor = [2, 72, 200], this.countFontColor = [255, 255, 255], this.locations = [], this.clusteredLocations = [], this.clusterMarkUrl = "", this.currentStyle = "cluster", this.view = e, this.clusterLayer = new C(), this.view.map.add(this.clusterLayer); } /** * 将地理位置转换为屏幕坐标 */ locationToScreen() { this.clusteredLocations = [], this.locations.forEach((e) => { const s = this.view.toScreen( new c({ x: e.x, y: e.y }) ); s.x > 0 && s.y > 0 && (e.properties.screenX = s.x, e.properties.screenY = s.y, e.visited = !1, e.clusterId = void 0, this.clusteredLocations.push(e)); }); } /** * 添加聚类点到视图 * @param params */ addClusterPoints(e) { var r; this.locations = e.points, e.countBackgroundColor && (this.countBackgroundColor = e.countBackgroundColor), e.countFontColor && (this.countFontColor = e.countFontColor), this.scaleThreshold = e.scaleThreshold, this.clusterMarkUrl = ((r = e.clusterSymbol) == null ? void 0 : r.url) || "/GisViewerAssets/Images/cross/gis_xhj_blue.png", this.locations = this.locations.filter((t) => t.x !== null && t.y !== null && !isNaN(t.x) && !isNaN(t.y)), this.locations.forEach((t) => { t.x = Number(t.x), t.y = Number(t.y), t.symbol || (t.symbol = e.pointSymbol || { type: "simple-marker", style: "circle", color: "#3388ff", size: 8, outline: { color: "#ffffff", width: 1 } }); }), this.zoomWatchHandle || (this.zoomWatchHandle = this.view.watch("stationary", () => { if (this.view.stationary) if (this.scaleThreshold) { if (this.view.scale < this.scaleThreshold && this.currentStyle === "cluster") this.currentStyle = "normal", this.clusterLayer.removeAll(), this.locations.forEach((t) => { const i = new y({ geometry: new c({ x: t.x, y: t.y }), attributes: { ...t, ...t.properties, type: "clusterPoint", id: t.id }, symbol: t.symbol }); this.clusterLayer.add(i); }); else if (this.view.scale > this.scaleThreshold) { this.currentStyle = "cluster", this.locationToScreen(); const t = this.doPixelCluster( this.clusterRadius, this.minClusterPoints ); this.showClusters(t); } } else { this.locationToScreen(); const t = this.doPixelCluster( this.clusterRadius, this.minClusterPoints ); this.showClusters(t); } })), this.locationToScreen(); const s = this.doPixelCluster( this.clusterRadius, this.minClusterPoints ); this.showClusters(s); } removeAllClusterPoints() { var e; (e = this.zoomWatchHandle) == null || e.remove(), this.zoomWatchHandle = null, this.clusterLayer.removeAll(); } showClusters(e) { this.clusterLayer.removeAll(); let s = Number.MIN_VALUE, r = Number.MAX_VALUE; e.forEach((t) => { t.count > 1 && (r = Math.min(r, t.count), s = Math.max(s, t.count)); }), e.forEach((t) => { if (t.id !== -1) { let i = r === s ? (this.maxClusterSymbolSize + this.minClusterSymbolSize) / 2 : this.minClusterSymbolSize + (t.count - r) / (s - r) * (this.maxClusterSymbolSize - this.minClusterSymbolSize); i *= 0.75; const n = (t.count.toString().length * 8 + 6) / 2, u = new y({ geometry: new c({ x: t.center.x, y: t.center.y }), attributes: { count: t.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: i, colorLocked: !0, anchorPointUnits: "Relative", frame: { xmin: -16, ymin: -16, xmax: 16, ymax: 16 }, markerGraphics: [ // 数量文本框 { type: "CIMMarkerGraphic", geometry: { rings: [ [ [-n, 40], [n, 40], [n, 20], [-n, 20], [-n, 40] ] ] }, symbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [...this.countBackgroundColor, 255] }, { type: "CIMSolidStroke", enable: !0, width: 5, color: [...this.countBackgroundColor, 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: [...this.countFontColor, 255] } ] }, verticalAlignment: "Center" }, textString: "" } ], scaleSymbolsProportionally: !0, respectFrame: !0 }, // 聚合图标 { type: "CIMPictureMarker", enable: !0, anchorPoint: { x: 0, y: 0 }, anchorPointUnits: "Relative", size: i, rotateClockwise: !0, textureFilter: "Picture", url: this.clusterMarkUrl } ] } } } }); this.clusterLayer.add(u); } else t.items.forEach((i) => { const o = new y({ geometry: new c({ x: i.x, y: i.y }), attributes: { ...i, ...i.properties, type: "clusterPoint", id: i.id }, symbol: i.symbol }); this.clusterLayer.add(o); }); }); } /** * 获取邻居点 * @param locations * @param index * @param eps * @returns */ getNeighbors(e, s) { return this.clusteredLocations.filter((r) => r.id === e.id || r.visited ? !1 : this.getDistance(e, r) <= s); } /** * 两点间的像素距离 * @param point1 * @param point2 * @returns */ getDistance(e, s) { return Math.sqrt( Math.pow(e.properties.screenX - s.properties.screenX, 2) + Math.pow(e.properties.screenY - s.properties.screenY, 2) ); } /** * 从聚类结果中创建聚类对象 * @param locations * @returns */ createClusters() { const e = {}, s = []; for (const t of this.clusteredLocations) t.clusterId === void 0 || t.clusterId === -1 ? s.push(t) : (e[t.clusterId] || (e[t.clusterId] = []), e[t.clusterId].push(t)); const r = Object.keys(e).map((t, i) => { const o = e[Number(t)], l = o.length, n = o.reduce((h, a) => h + a.x, 0), u = o.reduce((h, a) => h + a.y, 0), m = n / l, d = u / l; return { id: Number(t), items: o, count: l, center: { x: m, y: d } }; }); return s.length > 0 && r.push({ id: -1, items: s, count: s.length, center: null }), r; } /** * 按照像素距离聚类 * @param locations * @param eps * @param minPoints * @returns */ doPixelCluster(e, s) { let r = 0; for (let t = 0; t < this.clusteredLocations.length; t++) { const i = this.clusteredLocations[t]; if (i.visited) continue; i.visited = !0; const o = this.getNeighbors(i, e); o.length < s ? i.clusterId = -1 : (o.forEach((l) => { l.visited = !0, l.clusterId = r; }), i.clusterId = r, r++); } return this.createClusters(); } } export { S as default };