clusterLayer点聚合进阶

在arcgis api for js中有一个clusterlayer,可以实现点聚合显示,以解决点过于密集导致的视觉效果差。clusterLayer是重写的graphicLayer。官方demo效果如下:

clusterLayer点聚合进阶_第1张图片

注意:已知api版本3.18--3.25均有bug,表现为点击单个点时属性信息不变,一直显示同一个点的属性信息,目前已知3.9版本没有该问题。

如果我们要将该方法应用到项目中,显然仅有官方demo效果是不够的,需要根据自己的需求来进行修改。

1.聚合距离修改。

可通过修改“distance” 属性实现。

2.聚合图形修改

聚合图形其实是根据聚合点个数clustercount来进行分类渲染,在官网示例中表现为红绿蓝泡泡图形。

            var defaultSym = new SimpleMarkerSymbol().setSize(4);
            var renderer = new ClassBreaksRenderer(defaultSym, "clusterCount");

            var picBaseUrl = "https://static.arcgis.com/images/Symbols/Shapes/";
            var blue = new PictureMarkerSymbol(picBaseUrl + "BluePin1LargeB.png", 32, 32).setOffset(0, 15);
            var green = new PictureMarkerSymbol(picBaseUrl + "GreenPin1LargeB.png", 64, 64).setOffset(0, 15);
            var red = new PictureMarkerSymbol(picBaseUrl + "RedPin1LargeB.png", 72, 72).setOffset(0, 15);
            renderer.addBreak(0, 2, blue);
            renderer.addBreak(2, 200, green);
            renderer.addBreak(200, 1001, red);

            clusterLayer.setRenderer(renderer);

以上是官方代码,可修改成自己的聚合符号。 如下

        var defaultSym = new SimpleMarkerSymbol().setSize(10);
        var renderer = new ClassBreaksRenderer( defaultSym,"clusterCount");
        var blue = new PictureMarkerSymbol( "../../../imgs/domain/blue.png", 32, 32).setOffset(0, 15);
        var green = new PictureMarkerSymbol("../../../imgs/domain/green.png", 64, 64).setOffset(0, 15);
        var red = new PictureMarkerSymbol("../../../imgs/domain/red.png", 72, 72).setOffset(0, 15);
        renderer.addBreak(0,20 , blue);
        renderer.addBreak(20, 200, green);
        renderer.addBreak(200, 1001, red);
        clusterLayer.setRenderer(renderer);

 其中defaultSym是在break断层(如果一开始是从2到20的话,那么0到2的渲染符号就是defaultSym)时的渲染图形,也是定义ClassBreaksRenderer必须要有的参数。

3.点击聚合符号显示的单个点符号修改。

_addSingles: function(singles) {
            // add single graphics to the map
            arrayUtils.forEach(singles, function(p) {
                var picSym;
                if(p.attributes.装备类型=="火箭"){
                    picSym = new PictureMarkerSymbol("../../../imgs/domain/hj.png", 28, 18)
                }
                else if(p.attributes.装备类型=="高炮"){
                    picSym = new PictureMarkerSymbol("../../../imgs/domain/gp.png", 28, 24)
                }
                else if(p.attributes.装备类型=="燃烧炉"){
                    picSym = new PictureMarkerSymbol("../../../imgs/domain/rsl.png", 20, 30)
                }
                else{
                    picSym = SimpleMarkerSymbol().setSize(4);
                }
                var g = new Graphic(
                    new Point(p.x, p.y, this._sr),
                    picSym,
                    p.attributes,
                    this._singleTemplate
                );
                this._singles.push(g);
                if ( this._showSingles ) {
                    this.add(g);
                }
            }, this);
            this._map.infoWindow.setFeatures(this._singles);
        }

每一个点是一个graphic,根据自己项目的要求,定义单个点的符号。

4.缩放到一定级别时,显示单点

官方代码不论如何缩放将一直显示聚合后的样式,如果想要放大到一定级别显示单个点,可在clusterLayer.js添加一个函数

showSingles:function()
        {
            var singles = [];
            for ( var i = 0, il = this._clusterData.length; i < il; i++) {

                    singles.push(this._clusterData[i]);
                }

            this._addSingles(singles);


        }

在每次缩放完,地图更新完后判断当前zoom级别,进行后续操作

map.on("update-end", function() {
                if(map.getZoom()>=11)
                {
                    map.getLayer("clusters").clear();
                    map.getLayer("clusters").showSingles();
                }
                else if(map.getZoom()<11)
                {
                    var defaultSym = new SimpleMarkerSymbol().setSize(10);
                    var renderer = new ClassBreaksRenderer( defaultSym,"clusterCount");
                    var blue = new PictureMarkerSymbol( "../../../imgs/domain/blue.png", 32, 32).setOffset(0, 15);
                    var green = new PictureMarkerSymbol("../../../imgs/domain/green.png", 64, 64).setOffset(0, 15);
                    var red = new PictureMarkerSymbol("../../../imgs/domain/red.png", 72, 72).setOffset(0, 15);
                    renderer.addBreak(0,20 , blue);
                    renderer.addBreak(20, 200, green);
                    renderer.addBreak(200, 1001, red);
                    map.getLayer("clusters").setRenderer(renderer);
                }
        });

5.clusterLayer.js的onclick函数

由于每次点击后,均执行this.clearSingles(this._singles);当放大到显示单点时会带来很多不便,所以考虑要执行清除单点时先进行缩放等级判断。

if(map.getZoom()<11){
                this.clearSingles(this._singles);
            }

          6.clusterLayer的resolution(分辨率)修改

点聚合是根据地图的x轴范围除以屏幕的范围来进行聚合,由于官方地图是平面坐标系,而实际使用中可能使用地理坐标系,所以需要将地图的x轴范围进行转换。

"resolution": map.extent.getWidth() / map.width//原代码
"resolution": (map.extent.xmax*20037508.34/180-map.extent.xmin*20037508.34/180) / map.width//更改后

7.PopupTemplate弹窗

此弹窗为点击地图上的要素弹出的详细信息窗口,可对其进行设置,使其显示图片等信息,由于实际应用中可能会加载数据库中的图片,sourceUrl就需要用到接口,所以不能单纯的仅使用图片地址进行加载。需要将接口写入sourceUrl,如下:

"sourceURL": '/pic?fileName='+'{图片1}',//接口+资源地址进行显示
"linkURL":"../../../views/domain/decision/siteImageDisplay.html"+"?img="+"{图片1}"//点击图片在另一页面查看大图

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(arcgis,api,for,js)