1. 程式人生 > >關於arcgis api for js 聚合效果的進階

關於arcgis api for js 聚合效果的進階

大多數能搜到的都是官方的版本,在此,我介紹一下關於聚合功能的進階。

主要是幾個配置。

對比官方的聚合效果:

這種是預設的效果 ,最底層的聚合是一個黑點,顯然運用到具體的專案中會不滿足一些需求 ,如果底層是圖片,然後根據資料的不同型別 ,顯示不同的圖片的話,就無法實現,鑑於暫時沒有相對的參考資料,由於自身專案需要運用到arcgis地圖來代替高德地圖,所以有了這份程式碼。

這介紹樣例程式碼前,需要了解如何實現官網的聚合基礎。

樣例專案效果:

很明顯,底層有三種不同的圖片。

相關的程式碼修改如下:

一.官網程式碼 修改版

clphotoInfo.data = arrayUtils.map(resp, function(p) {
          var latlng = new  Point(parseFloat(p.longi), parseFloat(p.lati), wgs);
          var webMercator = webMercatorUtils.geographicToWebMercator(latlng);
          var attributes = {
            "compname": p.compname,
            "vehino": p.vehino,
             "vin": p.vehisim,
            "color": p.mdtno,
            "time": p.dateTime,
            "owner": p.ownname,
            "x": p.longi,
            "y": p.lati,
            "onoffstate":p.onoffstate,
            "carStatus":p.carStatus,
            "newtype":"1"
          };
          return {
            "x": webMercator.x,
            "y": webMercator.y,
            "attributes": attributes
          };
 });
這端程式碼是官網程式碼的修改版   其中
onoffstate
carStatus
newtype
是後期新增的屬性用於修改原始碼js需要的判斷

二.原始碼  /extras/ClusterLayer.js

修改1:

_singleSym:function(p){
    // symbol for single graphics
var sms = SimpleMarkerSymbol;
var type;
if(p.attributes.carStatus == "1"){
       if(p.attributes.onoffstate == "1"){
    }
    return new 
sms({"url":type, "height":15, "width":15, "type":"esriPMS", "angle": 0}); },
此修改是點選聚合後顯示的單個點的顯示修改。

修改2:

_showAllClusters: function () {  
    var tp;  
if (map.spatialReference.isWebMercator()) {  
        //mapWebMercator座標系  
tp="webm";  
}  
    else {  
        //map為非WebMercator座標系  
tp="nowebm";  
} if(map.getZoom() == 10){
此修改顯示所有點可以做根據地圖的放大程度做相關的調整。

修改3:

_clusterCreate: function(p,c) {
    var clusterId = this._clusters.length + 1;
// console.log("cluster create, id is: ", clusterId);    
    // p.attributes might be undefined    
if ( ! p.attributes ) {    
        p.attributes = {};    
}    
    p.attributes.clusterId = clusterId;    
// create the cluster    
var cluster = {     
        "x": p.x,    
"y": p.y,    
"attributes" : {    
            "clusterCount": 1,    
"clusterId": clusterId,
"onoffstate":c.attributes.onoffstate,
"newtype":c.attributes.newtype,
"carStatus":c.attributes.carStatus,
"extent": [ p.x, p.y, p.x, p.y ]    
        }    
    };    
this._clusters.push(cluster);    
},    

所有的點,帶上具體的屬性,這個配置關乎到下面另外一個原始碼js的修改,具體需要可以看我給出的樣例參照。,

attributes

裡面是官網程式碼 修改版裡對應的需要的配置項。

修改4:

_setMap: function(map, surface) {    
    // calculate and set the initial resolution    
    //      this._clusterResolution = map.extent.getWidth() / map.width; // probably a bad default...
    //this._clusterGraphics();
this._newMap();
// connect to onZoomEnd so data is re-clustered when zoom level changes    
this._zoomEnd = connect.connect(map, "onZoomEnd", this, function() {    
        // update resolution    
        //        this._clusterResolution = this._map.extent.getWidth() / this._map.width;
if (map.spatialReference.isWebMercator()) {
            this._clusterResolution = map.extent.getWidth() / map.width; // probably a bad default...
}  
        else {  
            //WGS 84座標,轉換為web Mercator
var latlng1 = new Point(map.extent.xmax, map.extent.ymax, map.spatialReference); //右上角
var latlng2 = new Point(map.extent.xmin, map.extent.ymin, map.spatialReference); //左下角  
var webMercator1 = webMercatorUtils.geographicToWebMercator(latlng1);  
var webMercator2 = webMercatorUtils.geographicToWebMercator(latlng2);  
this._clusterResolution = (webMercator1.x - webMercator2.x) / map.width;  
}  
        this.clear();    
this._clusterGraphics();    
});    
// GraphicsLayer will add its own listener here    
var div = this.inherited(arguments);    
return div;    
},
代替
this._clusterGraphics();

方法,

this._newMap();
是新的進入地圖時候就進行聚合,而不是打出所有的點。

方法內容如下:

_newMap:function () {
    if (map.spatialReference.isWebMercator()) {
        this._clusterResolution = map.extent.getWidth() / map.width; // probably a bad default...
}
    else {
        //WGS 84座標,轉換為web Mercator
var latlng1 = new Point(map.extent.xmax, map.extent.ymax, map.spatialReference); //右上角
var latlng2 = new Point(map.extent.xmin, map.extent.ymin, map.spatialReference); //左下角
var webMercator1 = webMercatorUtils.geographicToWebMercator(latlng1);
var webMercator2 = webMercatorUtils.geographicToWebMercator(latlng2);
this._clusterResolution = (webMercator1.x - webMercator2.x) / map.width;
}
    this.clear();
this._clusterGraphics();
},

該js只需要4廚修改。

三.原始碼  /arcgis_js_api/library/3.14/esri/renderers/ClassBreaksRenderer.js

原始碼是這樣的,預設聚合是顯示預設的圖形

getSymbol: function (a) {
    var b = a;
return (a = this.breaks[this.getBreakIndex(a)]) ? this._symbols[a[0] + "-" + a[1]] : this.defaultSymbol
},
預設的圖形是官網樣例程式碼中給出的

var defaultSym = new SimpleMarkerSymbol().setSize(4);

所有的點都是預設的,但是你需要修改樣例,根據不同的屬性,如下修改

getSymbol: function (a) {
    var b = a;
return (a = this.breaks[this.getBreakIndex(a)]) ? this._symbols[a[0] + "-" + a[1]] : this._getNewSymbol(b)
},

寫一個方法定義你需要的圖片。

_getNewSymbol:function (a) {
    var type = "";
if(a.attributes.newtype != "1"){
        if(a.attributes.onoffstate == "1"){
    }
    this.defaultSymbol.url=type;
return this.defaultSymbol;
},
同樣的判斷內容不給出了,對應屬性可以做具體的修改。

具體程式碼貼出來了,相關的判斷可以自己修改。type的url是根據你的具體業務情況,做相關的修改。

到這裡差不多多有對於聚合效果的修改已經全部修改完成。

如有疑問可以加qq:1715548493做相關的提問 ,備註好arcgis即可,很樂意一起探討更深入的arcgis的應用。