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();
            }

源码下载

时间: 2024-10-07 06:29:59

Arcgis for JS扩展GraphicLayer实现区域对象的聚类统计与展示的相关文章

Arcgis for Js之Graphiclayer扩展详解

在前两节,讲到了两种不同方式的聚类,一种是基于距离的,一种是基于区域范围的,两种不同的聚类都是通过扩展esri/layers/GraphicsLayer方法来实现的.在本节,就详细的讲讲esri/layers/GraphicsLayer方法的扩展. 首先,在讲解扩展之前,先看看API中esri/layers/GraphicsLayer的一些参数和方法等. 1.创建一个GraphicLayer 在ESRI官方的API中,创建GraphicLayer有两种方式: 例如: 或者: 在第二种方式的opt

(转)Arcgis for Js之Graphiclayer扩展详解

http://blog.csdn.net/gisshixisheng/article/details/41208185 在前两节,讲到了两种不同方式的聚类,一种是基于距离的,一种是基于区域范围的,两种不同的聚类都是通过扩展esri/layers/GraphicsLayer方法来实现的.在本节,就详细的讲讲esri/layers/GraphicsLayer方法的扩展. 首先,在讲解扩展之前,先看看API中esri/layers/GraphicsLayer的一些参数和方法等. 1.创建一个Graph

Arcgis for Js实现graphiclayer的空间查询

本节讲的是Arcgis for Js的针对graphiclayer的空间查询,内容非常easy.代码例如以下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="initial-

Arcgis for Js之鼠标经过显示对象名的实现

在浏览地图时,移动鼠标经过某个对象或者POI的时候,能够提示该对象的名称对用户来说是很实用的,本文讲述在Arcgis for Js中,用两种不同的方式来实现该效果. 为了有个直观的概念,先给大家看看实现后的效果: 百度地图的效果 效果1 效果2 直观的看到了效果,下面说说在Arcgis for Js中实现的两种方式.在实现给效果的时候,有layer的两个事件,mouse-over和mouse-out事件,鼠标经过显示对象名称,鼠标移除清除显示. 1.通过TextSymbol和GraphicMar

Arcgis for Js实现graphiclayer的空间查询(续)

上文中,实现了简单的针对graphiclayer的空间查询工作,在本节,将更加详细的介绍针对graphiclayer的空间查询.首先,空间查询的方式:提供多种类型的空间查询,包括点周边.线周边.面内等多种方式:其次,图形绘制完成后状态的展示:再次,结果的显示.实现后的结果如下: 点周边--输入缓冲区距离 点周边--查询结果 线周边--输入缓冲区距离 线周边--查询结果 面内--矩形 面内--圆形 面内--多边形 首先,绘制图形. var drawToolbar = new esri.toolba

Arcgis for JS之Cluster聚类分析的实现(基于区域范围的)

原文:Arcgis for JS之Cluster聚类分析的实现(基于区域范围的) 咱们书接上文,在上文,实现了基于距离的空间聚类的算法实现,在本文,将继续介绍空间聚类之基于区域范围的实现方式,好了,闲言少叙,先看看具体的效果: 聚类效果 点击显示信息 显示单个聚类点 下面说说具体的实现思路. 1.数据组织 在进行数据组织的时候,因为是要按照区域范围的,所以必须得包含区域范围的信息,在本示例中,我用的数据依然是全国2000多个区县点的数据,并添加了省市代码,数据如下: 2.聚类思路 根据数据中“p

Ext JS学习第十天 Ext基础之 扩展原生的javascript对象(二)

此文来记录学习笔记: 今天继续说Ext.Array,Ext.Function,Ext.Date,Ext.Error ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ext.Ar

js框架设计1.2对象扩展笔记

需要一个新的功能添加到我们的命名空间上.这方法在JS中被叫做extend或者mixin,若是遍历属性用一下1.1代码,则会遍历不出原型方法,所以1.2介绍的是mass Framework里的mix方法. 类似juqery的$.extend(). 1.1代码 function extend(destination,source){ for(var property in source) destination[[property] = source[property]; return destin

Arcgis for JS之Cluster聚类分析的实现

原文:Arcgis for JS之Cluster聚类分析的实现 在做项目的时候,碰见了这样一个问题:给地图上标注点对象,数据是从数据库来 的,包含XY坐标信息的,通过graphic和graphiclayer 的方式添加到地图上,其中有一个对象的数量很多,上万了吧,通过上述的方式无法在地图上进行展示,就想到了聚类,当时由于技术和时间的关系,没有实现,最 近,稍微有点先下时间,就又想起这事,继续研究,终于,皇天不负有心人,出来了,出来的第一时间写出来,以便大家使用. 首先,看看实现后的效果: 初始化