• Arcgis for JS扩展GraphicLayer实现区域对象的聚类统计与展示


    功能需求:

    分省市统计并展示全国雨量站的数目与位置。


    常规做法:

    分省市雨量站的数目通过统计表的形式在页面端展示,位置根据XY坐标信息将雨量站标绘在图上。

    优化做法:

    去掉统计图的展示方式,直接将各省市雨量站的数量信息与位置信息展示在图上,如下图所示:


    雨量站的分省市统计与展示


    处理思路:

    首先,提取各省/市的中心点或者省会城市X与Y坐标信息,在本实例中使用的是省会城市的XY坐标信息,用来显示各省市雨量站的分布。

    接着,分省/市统计各省市雨量站的个数,并将其根据个数分颜色、大小将其展示在图上。

    最后,点击单个圆圈在地图上标绘详细的雨量站的位置信息,并将其缩放至该省/市。


    解决问题:

    统计信息的清晰展示与数据的请求速度。


    比较:

    优化做法直接将统计信息与位置信息展示在地图上,在视觉效果上,提高了地图的交互性与美观程度,简单明了;在数据请求上,优化做法只需统计个数,不需要详细的信息,更不需要将所有的站点在地图上展示,每点击一次,再去请求数据,大大提高了程序的效率与速度。


    实现代码:

    1、数据

    首先,在数据库中查询分省市雨量站的统计情况,返回JSON格式的到前台,数据格式如下:

    [
    	{id:1,name:"1",x:1,y:1,count:10},
    	{id:2,name:"2",x:2,y:2,count:20},
    	{id:3,name:"3",x:3,y:3,count:30},
    	{……}
    	{id:n,name:"n",x:n,y:n,count:n}
    ]
    接着,点击每一个点的时候去请求该省/市的详细雨量站的信息,返回的依然是JSOn格式的,格式如上。

    2、扩展GraphicLayer

    为了操作方便,将GraphicLayer进行了扩展,扩展的时候主要有以下几个主要点:a、将统计数按照XY坐标展示在图上;b、点击单个点的时候标绘详细的雨量站的位置分布信息。

    源代码如下:

    define([
        "dojo/_base/declare",
        "dojo/_base/array",
        "esri/Color",
        "dojo/_base/connect",
    
        "esri/SpatialReference",
        "esri/geometry/Point",
        "esri/graphic",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/TextSymbol",
    
        "esri/dijit/PopupTemplate",
        "esri/layers/GraphicsLayer"
    ], function (
        declare, arrayUtils, Color, connect,
        SpatialReference, Point, Graphic, SimpleMarkerSymbol, TextSymbol,
        PopupTemplate, GraphicsLayer
        ) {
        return declare([GraphicsLayer], {
            constructor: function(options) {
                // 参数:
                //   data:  Object[]
                //     Array of objects. Required. Object are required to have properties named x, y and attributes. The x and y coordinates have to be numbers that represent a points coordinates.
                //   field:  string?
                //     The field of cluster.
                //   showSingles:  Boolean?
                //     Optional. Whether or graphics should be displayed when a cluster graphic is clicked. Default is true.
                //   labelColor:  String?
                //     Optional. Hex string or array of rgba values used as the color for cluster labels. Default value is #fff (white).
                //   labelOffset:  String?
                //     Optional. Number of pixels to shift a cluster label vertically. Defaults to -5 to align labels with circle symbols. Does not work in IE.
                //   singleSymbol:  MarkerSymbol?
                //     Marker Symbol (picture or simple). Optional. Symbol to use for graphics that represent single points. Default is a small gray SimpleMarkerSymbol.
                //   spatialReference:  SpatialReference?
                //     Optional. Spatial reference for all graphics in the layer. This has to match the spatial reference of the map. Default is 102100. Omit this if the map uses basemaps in web mercator.
                //   singleTemplate:  PopupTemplate?
                //     PopupTemplate</a>. Optional. Popup template used to format attributes for graphics that represent single points. Default shows all attributes as "attribute = value" (not recommended).
    
                //聚类数据
                this._clusterData = options.data || [];
                this._clusters = [];
                //标注颜色,默认为白色
                this._clusterLabelColor = options.labelColor || "#000";
                //标注偏移,默认为-5
                this._clusterLabelOffset = (options.hasOwnProperty("labelOffset")) ? options.labelOffset : -5;
    
                this._showSingles = options.hasOwnProperty("showSingles") ? options.showSingles : true;
                //单个对象
                this._singles = []; //点击时出现
                // 单个的样式
                var SMS = SimpleMarkerSymbol;
                this._singleSym = options.singleSymbol || new SMS("circle", 6, null, new Color(options.singleColor,0.6));
                //空间参考
                this._sr = options.spatialReference || new SpatialReference({ "wkid": 4326 });
    
                this._singleTemplate = options.singleTemplate || new PopupTemplate({ "title": "", "description": "{*}" });
            },
            // 重构esri/layers/GraphicsLayer方法
            _setMap: function(map, surface) {
                this._clusterGraphics();
                // GraphicsLayer will add its own listener here
                var div = this.inherited(arguments);
                return div;
            },
            _unsetMap: function() {
                this.inherited(arguments);
            },
            clearSingles: function(singles) {
                // Summary:  Remove graphics that represent individual data points.
                var s = singles || this._singles;
                console.log(s);
                arrayUtils.forEach(s, function(g) {
                    console.log(g);
                    this.remove(g);
                }, this);
                this._singles.length = 0;
            },
            onClick: function(e) {
                // stop the click from bubbling to the map
                e.stopPropagation();
                this.clearSingles(this._singles);
                var g = e.graphic;
                console.log(g);
                var sonData = city;
                for(var i= 0,  sl=sonData.length;i<sl;i++){
                    if(sonData[i].propy===g.attributes.propy){
                        var pt = new Point(sonData[i].x,sonData[i].y, this._sr);
                        var sg = new Graphic(pt, this._singleSym, sonData[i], this._singleTemplate);
                        clusterLayer.add(sg);
                        this._singles.push(sg);
                    }
                }
                map.infoWindow.setFeatures(this._singles);
                map.infoWindow.show(g.geometry);
            },
            //添加聚类图形
            _clusterGraphics: function(){
                for(var i= 0, jl=this._clusterData.length;i<jl;i++){
                    var point = this._clusterData[i];
                    this._addPoint(point);
                }
            },
            //添加点
            _addPoint: function(p){
                var pt = new Point(p.x, p.y,this._sr);
                this.add(
                    new Graphic(
                        pt,
                        null,
                        p
                    )
                );
                if(p.pcitycount>1){
                    // show number of points in the cluster
                    var font  = new esri.symbol.Font()
                        .setSize("10pt")
                        .setWeight(esri.symbol.Font.WEIGHT_BOLD);
                    var label = new TextSymbol(p.pcitycount)
                        .setColor(new Color(this._clusterLabelColor))
                        .setOffset(0, this._clusterLabelOffset)
                        .setFont(font);
                    this.add(
                        new Graphic(
                            pt,
                            label,
                            p
                        )
                    );
                }
            }
        });
    });

    3、在程序中导入包,并引用

            var dojoConfig = {
                paths: {
                    extras: location.pathname.replace(//[^/]+$/, "") + "/extras"
                }
            };

    引用的方式为:

            require([
                ......,
                "extras/ZonalClusterLayer",
                "dojo/domReady!"
            ], function(
                ......,
                ZonalClusterLayer
            ){

    4、新建ZonalClusterLayer,分类进行渲染,并将之添加到地图上。

                    clusterLayer = new ZonalClusterLayer({
                        "data": capital,
                        "id": "clusters",
                        "labelColor": "#fff",
                        "labelOffset": -4,
                        "singleColor": "#0ff"
                    });
                    var defaultSym = new SimpleMarkerSymbol().setSize(4);
                    var renderer = new ClassBreaksRenderer(defaultSym, "pcitycount");
    
                    /*var picBaseUrl = "images/";
                     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", 80, 80).setOffset(0, 15);*/
                    var style1 = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 10,
                            new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
                                    new Color([255,200,0]), 1),
                            new Color([255,200,0,0.8]));
                    var style2 = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 16,
                            new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
                                    new Color([255,125,3]), 1),
                            new Color([255,125,3,0.8]));
                    var style3 = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 18,
                            new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
                                    new Color([255,23,58]), 1),
                            new Color([255,23,58,0.8]));
                    var style4 = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 20,
                            new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
                                    new Color([204,0,184]), 1),
                            new Color([204,0,184,0.8]));
                    var style5 = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 22,
                            new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
                                    new Color([0,0,255]), 1),
                            new Color([0,0,255,0.8]));
                    renderer.addBreak(0, 2, style1);
                    renderer.addBreak(2, 5, style2);
                    renderer.addBreak(5, 10, style3);
                    renderer.addBreak(10, 15, style4);
                    renderer.addBreak(15, 20, style5);
    
                    clusterLayer.setRenderer(renderer);
                    map.addLayer(clusterLayer);
    5、一些无关紧要的东西

    在地图上点击,清楚详细结果:

                    // close the info window when the map is clicked
                    map.on("click", cleanUp);
                    // close the info window when esc is pressed
                    map.on("key-down", function(e) {
                        if (e.keyCode === 27) {
                            cleanUp();
                        }
                    });

                function cleanUp() {
                    map.infoWindow.hide();
                    clusterLayer.clearSingles();
                }
    

    源码下载



  • 相关阅读:
    CSS HACK:IE6、IE7、IE8、Firefox兼容性问题解决方案
    C# @符号的多种使用方法
    16个Javascript的Web UI库、框架及工具包
    【分享】20个很不错的UI图标集资源
    JQuery/AjaX/Javascript/DIV+CSS资源下载地址
    发个csdn泄露账户查询地址,没下数据库的童鞋来查一下自己
    【总结】CSS透明度大汇总
    C#综合揭秘——细说事务
    ASP.NET获取客户端、服务器端基础信息集合
    收集的网络上大型的开源图像处理软件代码(提供下载链接)
  • 原文地址:https://www.cnblogs.com/lzugis/p/6539874.html
Copyright © 2020-2023  润新知