功能需求:

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

常规做法:

分省市雨量站的数目通过统计表的形式在页面端展示,位置根据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();
            }

源码下载

最新文章

  1. Chrome出了个小bug:论如何在Chrome下劫持原生只读对象
  2. 【Ural】1519. Formula 1
  3. 使用antd UI组件有感
  4. 宠物收养所(bzoj1208)
  5. JS的prototype的共享机制分析
  6. 11g RMAN Restore archivelog用法
  7. async/await的实质理解
  8. Android中退出多个Activity的两个经典方法
  9. 最近一年多我总结的常用mate标签-常用mate标签
  10. go generate 生成代码
  11. Bzoj4817:[SDOI2017]树点涂色
  12. 关闭windows系统的危险端口,命令行
  13. 《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常
  14. Vue小案例 之 商品管理------创建页面与部分数据
  15. 讨论下python中全局变量的使用
  16. easyui表单校验
  17. vs code编辑器使用教程指南
  18. nyoj 三个水杯
  19. Asp.net Core2.0, 基于 claims 实现权限验证
  20. 再谈javascript图片预加载技术

热门文章

  1. 请求库之requests
  2. 执行用例,并生成报告——discover,HTMLRunner
  3. angularJS 中的传参
  4. return false 和 return true
  5. Linux中top和free命令(6/15)
  6. 网络管理常用命令(6/14) -netstat命令详解
  7. try-catch-finally的问题
  8. rest_framework解析器组件源码流程
  9. vuex初使用
  10. 多线程、多进程、协程、IO多路复用请求百度