Arcgis api for JavaScript 4.6 點聚合分析
阿新 • • 發佈:2019-01-25
建立物件:
var clusterLayer = new ClusterLayer({ "view":mapManager.view, "map":mapManager.map, "data": photoInfo.data, "id": clusterAnalysis.layerId, "labelColor": "#000", "labelOffset": 0, "symbolArray":[symbolManager.clusterGreen,symbolManager.clusterBlue,symbolManager.clusterRed], "graphicSym":symbolManager.clusterBlue });
執行點聚合:
//執行聚合
clusterLayer.excuseClusterEvent();
設定地圖縮放事件:
view.watch("zoom",function(){
showProgressbar("點聚合","正在努力中,請耐心等待...");
clusterAnalysis.clusterLayer.changeExtentEvent();
$('#progressBarWin').window('close');
});
設定地圖點選事件:
on(mapManager.view, 'click', lang.hitch(this, function(evt) { var screenPoint = {x: event.x,y: event.y}; view.hitTest(screenPoint).then(function (response) { if (response.results.length) { var graphic = response.results[0].graphic; data = clusterLayer.onClick(graphic); } }); }));
將聚合圖層新增到地圖:
map.add(clusterLayer);
下面的ClusterLayer物件:
define([ "dojo/_base/declare", "dojo/_base/array", "esri/Color", "dojo/_base/connect", "esri/geometry/SpatialReference", "esri/geometry/Point", "esri/Graphic", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/TextSymbol", "esri/geometry/support/webMercatorUtils", "esri/PopupTemplate", "esri/layers/GraphicsLayer", "esri/layers/mixins/ScaleRangeLayer" ], function ( declare, arrayUtils, Color, connect, SpatialReference, Point, Graphic, SimpleMarkerSymbol, TextSymbol,webMercatorUtils, PopupTemplate, GraphicsLayer,ScaleRangeLayer ) { return GraphicsLayer.createSubclass([ScaleRangeLayer],{ declaredClass : "ClusterLayer", properties : { view:null,//當前檢視,必須 map:null,//當前地圖,必須 id:"clusters",//圖層id,必須 data:[],//聚類資料,必須 field : "clusterCount",//聚類的欄位 distance:100,//距離 labelColor:"#FFF",//標註顏色,預設為白色 labelOffset : -4,//標註偏移,預設為-4 resolution:null, clusters : null, singles : null, //單個物件,點選時出現 showSingles : true, symbolArray : null,//graphic樣式陣列 singleSym:null,//單個graphic樣式 graphicSym:null,//要素高亮樣式 singleTemplate : new PopupTemplate({ "title": "{type}", "description": "{material}" }), spatialReference : null,//空間參考 maxSingles : 1000//單個叢集最大數 }, /** * @description 初始化 * @creator 王培珍 * @createtime 2018-02-06 */ init:function(){ this.clusters = []; this.singles = []; this.spatialReference = this.view.spatialReference; if(this.symbolArray == null){ var red = new SimpleMarkerSymbol("circle", 20, null, new Color("green")); var blue = new SimpleMarkerSymbol("circle", 20, null, new Color("blue")); var green = new SimpleMarkerSymbol("circle", 20, null, new Color("red")); this.symbolArray = [red, blue,green]; } }, /** * @description 執行點聚合事件 * @creator 王培珍 * @createtime 2018-02-06 */ excuseClusterEvent: function() { //判斷當前是否存在該id的圖層,若有,刪除 var layer = this.map.findLayerById(this.id); if(layer != undefined || layer != null) this.map.remove(layer); //初始化 this.init(); //清除當前圖層上的圖形 this.clear(); //設定Resolution this.setResolution(); //建立聚合圖形 this.clusterGraphics(); var div = this.inherited(arguments); return div; }, /** * @description 設定Resolution * @creator wpz * @createtime 2018-02-06 */ setResolution: function() { var e = this.view.extent; var rightTop = new Point(e.xmax, e.ymax, this.spatialReference); //右上角 var leftBottom = new Point(e.xmin, e.ymin, this.spatialReference); //左下角 var rightTopPoint = webMercatorUtils.geographicToWebMercator(rightTop); var leftBottomPoint = webMercatorUtils.geographicToWebMercator(leftBottom); this.resolution = (rightTopPoint.x - leftBottomPoint.x) / this.view.width; }, /** * @description 地圖縮放處理事件 * @creator wpz * @createtime 2018-02-06 */ changeExtentEvent:function(){ //清除當前圖層上的圖形 this.clear(); //設定Resolution this.setResolution(); //建立聚合圖形 this.clusterGraphics(); }, /** * @description 移除縮放事件 * @creator wpz * @createtime 2018-02-06 */ removeZoomEnd: function() { this.inherited(arguments); }, /** * @description 新增聚合叢集 * @creator wpz * @createtime 2018-02-06 */ add : function(p) { //判斷點是否落在現有叢集中,若沒有,則新建一個新叢集 if (p.declaredClass) { this.inherited(arguments); return; } //把新資料新增到data中 this.data.push(p); //是否新增到叢集中 var clustered = false; for (var i = 0; i < this.clusters.length; i++) { var c = this.clusters[i]; //判斷兩點之間是否屬於同一叢集 if (this.clusterTest(p, c)) { //新增新點到現有叢集 this.clusterAddPoint(p, c); //更新叢集圖形資訊 this.updateClusterGeometry(c); //更新叢集label資訊 this.updateLabel(c); clustered = true; break; } } //如果沒有新增到叢集中,則建立新叢集 if (!clustered) { this.clusterCreate(p); p.attributes.clusterCount = 1; this.showCluster(p); } }, /** * @description 清楚當前所有叢集 * @creator wpz * @createtime 2018-02-06 */ clear : function() { var layer = this.map.findLayerById(this.id); if (layer != undefined || layer != null) layer.removeAll(); // Summary: Remove all clusters and data // points. this.inherited(arguments); this.clusters.length = 0; }, /** * @description 清除單個叢集 * @creator wpz * @createtime 2018-02-06 */ clearSingles : function(singles) { var s = singles || this.singles; arrayUtils.forEach(s, function(g) { this.remove(g); }, this); this.singles.length = 0; }, /** * @description 點選叢集事件 * @creator wpz * @createtime 2018-02-06 */ onClick : function(e) { this.clear(); //清除單個要素 this.clearSingles(this.singles); //獲取當前叢集的資料 var singles = []; for (var i = 0, il = this.data.length; i < il; i++) { if (e.attributes.clusterId == this.data[i].attributes.clusterId) { singles.push(this.data[i]); } } //判斷單個叢集長度是否有大於單個叢集最大長度 if (singles.length > this.maxSingles) { alert("對不起,當前叢集長度大於" + this.maxSingles + "個,請放大到更大級別再進行查詢當個叢集!"); return null; } else { //停止地圖點選 //e.stopPropagation(); //this.view.popup.content = "<div style='background-color:DarkGray;color:white'> miles.</div>"; //this.map.infoWindow.show(e.graphic.geometry); this.addSingles(singles); return singles; } }, /** * @description 建立聚合圖形 * @creator wpz * @createtime 2018-02-06 */ clusterGraphics : function() { for (var j = 0, jl = this.data.length; j < jl; j++) { var point = this.data[j]; var clustered = false; var numClusters = this.clusters.length; for (var i = 0; i < this.clusters.length; i++) { var c = this.clusters[i]; //判斷兩點之間是否屬於同一叢集 if (this.clusterTest(point, c)) { //新增新點到現有叢集 this.clusterAddPoint(point, c); clustered = true; break; } } //如果沒有新增到叢集中,則建立新叢集 if (!clustered) { this.clusterCreate(point); } } //顯示所有叢集 this.showAllClusters(); }, /** * @description 判斷兩點之間是否屬於同一個叢集 * @creator wpz * @createtime 2018-02-06 */ clusterTest : function(p, cluster) { var c_latlng; var p_latlng; if (this.spatialReference.isWebMercator) { //地圖 為WebMercator座標系 c_point = new Point(cluster.x, cluster.y, this.spatialReference); p_point = new Point(p.x, p.y, this.spatialReference); } else { //地圖為非WebMercator座標系,則需轉換為墨卡託座標系 c_latlng = new Point( parseFloat(cluster.x), parseFloat(cluster.y), this.spatialReference); p_latlng = new Point(parseFloat(p.x), parseFloat(p.y), this.spatialReference); c_point = webMercatorUtils .geographicToWebMercator(c_latlng); p_point = webMercatorUtils .geographicToWebMercator(p_latlng); } var distance = (Math.sqrt(Math.pow( (c_point.x - p_point.x), 2) + Math.pow((c_point.y - p_point.y), 2)) / this.resolution); return (distance <= this.distance); }, /** * @description 新增新點到現有叢集 * @creator wpz * @createtime 2018-02-06 */ clusterAddPoint : function(p, cluster) { //新增新點到現有叢集 var count, x, y; count = cluster.attributes.clusterCount; x = (p.x + (cluster.x * count)) / (count + 1); y = (p.y + (cluster.y * count)) / (count + 1); cluster.x = x; cluster.y = y; //建立這個叢集的新範圍 if (p.x < cluster.attributes.extent[0]) { cluster.attributes.extent[0] = p.x; } else if (p.x > cluster.attributes.extent[2]) { cluster.attributes.extent[2] = p.x; } if (p.y < cluster.attributes.extent[1]) { cluster.attributes.extent[1] = p.y; } else if (p.y > cluster.attributes.extent[3]) { cluster.attributes.extent[3] = p.y; } //統計這個叢集有多少個點 cluster.attributes.clusterCount++; //判斷是否包含attributes欄位,若無,賦值 if (!p.hasOwnProperty("attributes")) { p.attributes = {}; } //給這個屬性一個clusterId值 p.attributes.clusterId = cluster.attributes.clusterId; }, /** * @description 建立一個新叢集 * @creator wpz * @createtime 2018-02-06 */ clusterCreate : function(p) { var clusterId = this.clusters.length + 1; if (!p.attributes) { p.attributes = {}; } p.attributes.clusterId = clusterId; //建立一個新叢集 var cluster = { "x" : p.x, "y" : p.y, "attributes" : { "clusterCount" : 1, "clusterId" : clusterId, "extent" : [ p.x, p.y, p.x, p.y ] } }; this.clusters.push(cluster); }, /** * @description 顯示所有叢集 * @creator wpz * @createtime 2018-02-06 */ showAllClusters : function() { var array = this.groupData(); for (var i = 0; i <this.clusters.length; i++) { var c = this.clusters[i]; if(c.attributes.clusterCount > array[0]){ this.singleSym = this.symbolArray[0]; }else if(c.attributes.clusterCount > array[1]){ this.singleSym = this.symbolArray[1]; }else{ this.singleSym = this.symbolArray[2]; } this.showCluster(c); } }, /** * @description 獲取分組組值陣列 * @creator wpz * @createtime 2018-02-06 */ groupData:function(){ //獲取最大最小值 var max = this.clusters[0].attributes.clusterCount; var min = this.clusters[0].attributes.clusterCount; for (var i = 0; i <this.clusters.length; i++) { var count = this.clusters[i].attributes.clusterCount; if(max < count) max = count; else if(min > count) min = count; } //組距 var dValue = (max - min)/3; return [(max - dValue),(min + dValue)]; }, /** * @description 顯示叢集 * @creator wpz * @createtime 2018-02-06 */ showCluster : function(c) { var point = new Point(c.x, c.y, this.spatialReference); if(this.singleSym == null) this.singleSym = new SimpleMarkerSymbol("circle", 20, null, new Color("red")); //新增點圖形 this.add(new Graphic(point, this.singleSym,c.attributes)); //新增文字到指定位置 var label = new TextSymbol(c.attributes.clusterCount.toString()) label.color = new Color(this.labelColor); label.xoffset = 0; label.yoffset = this.labelOffset; this.add(new Graphic(point, label,c.attributes)); }, /** * @description 新增單個點 * @creator wpz * @createtime 2018-02-06 */ addSingles : function(singles) { //新增單個點到地圖上 arrayUtils.forEach(singles, function(p) { var g = new Graphic(new Point(p.x, p.y,this.spatialReference),this.graphicSym, p.attributes,this.singleTemplate); this.singles.push(g); if (this.showSingles) { this.add(g); } }, this); }, /** * @description 更新叢集圖形 * @creator wpz * @createtime 2018-02-06 */ updateClusterGeometry : function(c) { var cg = arrayUtils.filter(this.graphics,function(g) { return !g.symbol && g.attributes.clusterId == c.attributes.clusterId; }); if (cg.length == 1) { cg[0].geometry.update(c.x, c.y); } else { console.log("didn't find exactly one cluster geometry to update: ",cg); } }, /** * @description 更新叢集Label * @creator wpz * @createtime 2018-02-06 */ updateLabel : function(c) { //找到已存在的叢集label var label = arrayUtils.filter(this.graphics,function(g) { return g.symbol && g.symbol.declaredClass == "esri.symbol.TextSymbol" && g.attributes.clusterId == c.attributes.clusterId; }); if (label.length == 1) { //更新叢集Label this.remove(label[0]); var newLabel = new TextSymbol(c.attributes.clusterCount); newLabel.color = new Color(this.labelColor); newLabel.xoffset = 0; newLabel.yoffset = this.labelOffset; this.add(new Graphic(new Point(c.x,c.y, this.spatialReference), newLabel, c.attributes)); } else { console.log("didn't find exactly one label: ",label); } } }); });