码迷,mamicode.com
首页 > 编程语言 > 详细

FK JavaScript之:ArcGIS JavaScript API之地图动画

时间:2016-08-14 16:06:44      阅读:304      评论:0      收藏:0      [点我收藏+]

标签:

地图要素动画应用场景:动态显示地图上的要素的属性随着时间的改变而改变,并根据其属性的变化设置其渲染.比如:某水域项目中,随着时间的变化,动态展现水域的清淤进度

本文目的:对ArcGIS JavaScript 官网示例中的代码进行分析注解.下述代码对官网示例进行了部分调整

示例网址1:

示例网址2:

示例中csv文件

以下为代码注释:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!--The viewport meta tag is used to improve the presentation and
        behavior of the samples on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>LLC动态图测试</title>
    <link rel="stylesheet" href="http://**.**.**.**/arcgis_js_api/library/3.15/3.15/esri/css/esri.css">
    <style>
        html, body, #mainWindow {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;
        }

        body {
            background-color: white;
            overflow: hidden;
            font-family: "Trebuchet MS";
        }

        #loading {
            background: #fff;
            height: 100%;
            overflow: hidden;
            position: absolute;
            width: 100%;
            z-index: 100;
        }

        #loadingMessage {
            color: #000;
            margin: 0 auto;
            padding: 150px 0 0 0;
            text-align: center;
            width: 200px;
        }

        .shadow {
            -moz-box-shadow: 0 0 5px #888;
            -webkit-box-shadow: 0 0 5px #888;
            box-shadow: 0 0 5px #888;
        }

        #map {
            background-color: white;
        }

        #feedback {
            background: #fff;
            color: #000;
            font-family: arial;
            height: auto;
            left: 30px;
            margin: 5px;
            padding: 10px;
            position: absolute;
            text-align: center;
            top: 30px;
            visibility: hidden;
            width: 200px;
            z-index: 10;
        }

        #currentYear {
            display: inline-block;
            height: 25px;
            text-align: center;
            width: 50px;
        }

        #play, #pause {
            cursor: pointer;
            display: none;
            width: 50px;
        }

        #legend {
            padding: 10px 0 0 0;
        }

            #legend table table td {
                text-align: left;
            }

        /* animate color transition when years change */
        /*The LLC Guess:the CSS name seems to be useless,maybe you can edit it arbitrary*/
        /*以下为地图的显示样式,相关内容查询svg,path[]中的内容,即为要素分类的类别*/
        #counties_layer path {
            transition: fill 1.15s, fill-opacity 1.15s, stroke 1.15s, stroke-opacity 1.15s;
            -webkit-transition: fill 1.15s, fill-opacity 1.15s, stroke 1.15s, stroke-opacity 1.15s;
        }

            #counties_layer path[data-relgrowth="no-data"] {
                stroke: rgb(255, 255, 255);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="zero-or-less"] {
                fill: rgb(175, 141, 195); /* purple */
                fill-opacity: 1;
                stroke: rgb(175, 141, 195);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="lt-US"] {
                fill: rgb(225, 236, 231); /* light */
                fill-opacity: 1;
                stroke: rgb(225, 236, 231);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="gt-US"] {
                fill: rgb(127, 191, 123); /* green */
                fill-opacity: 1;
                stroke: rgb(127, 191, 123);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="llcStyle"] {
                fill: rgb(0, 0, 0); /* green */
                fill-opacity: 1;
                stroke: rgb(127, 191, 123);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="1"] {
                fill: rgb(0, 0, 0); /* green */
                fill-opacity: 1;
                stroke: rgb(127, 191, 123);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="2"] {
                fill: rgb(255, 0, 0); /* green */
                fill-opacity: 1;
                stroke: rgb(127, 191, 123);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="3"] {
                fill: rgb(0, 255, 0); /* green */
                fill-opacity: 1;
                stroke: rgb(127, 191, 123);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="4"] {
                fill: rgb(0, 0, 255); /* green */
                fill-opacity: 1;
                stroke: rgb(127, 191, 123);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="5"] {
                fill: rgb(255, 255, 0); /* green */
                fill-opacity: 1;
                stroke: rgb(127, 191, 123);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }

            #counties_layer path[data-relgrowth="6"] {
                fill: rgb(0, 255, 255); /* green */
                fill-opacity: 1;
                stroke: rgb(127, 191, 123);
                stroke-width: 1pt;
                stroke-opacity: 1;
            }
    </style>

    <script type="text/javascript" src="http://**.**.**.**/arcgis_js_api/library/3.15/3.15/init.js"></script>
    <script>
        require([
          "esri/map",
          "esri/layers/FeatureLayer",
          "esri/dijit/Legend",
          "esri/InfoTemplate",

          "esri/renderers/ClassBreaksRenderer",
          "esri/symbols/SimpleFillSymbol",
          "esri/symbols/SimpleLineSymbol",

          "dojo/_base/array",
          "esri/Color",
          "dojo/_base/fx",
          "dojo/_base/lang",
          "dojo/Deferred",

          "dojo/dom",
          "dojo/dom-construct",
          "dojo/dom-style",
          "dojo/number",
          "dojo/on",
          "dojo/parser",
          "dojo/string",

          "dojox/data/CsvStore",
          "dijit/layout/BorderContainer",
          "dijit/layout/ContentPane",
          "dojo/domReady!"
        ], function (Map, FeatureLayer, Legend, InfoTemplate,
          ClassBreaksRenderer, SimpleFillSymbol, SimpleLineSymbol,
          arrayUtils, Color, fx, lang, Deferred,
          dom, domConstruct, domStyle, number, on, parser, string,
          CsvStore) {
            parser.parse();
            var map, layer, currentYear = 1971, currentUSPgr, timer;

            map = new Map("map", {
                basemap: "gray",
                center: [120.2, 30.542],
                zoom: 11,
                slider: false
            });
            map.on("load", function () {
                //加载csv数据.csv中为美国人口数据表,之后通过fip与矢量数据进行关联
                loadCSV().then(function (csvData) {
                    //神奇的JavaScript this. 绑定setYear的上下文对象为csvData,所以,在函数中,this就是csvData
                    setYear = lang.hitch(csvData, setYear);
                    //年份设置为1971年
                    setYear(1971);
                    //添加图层(该方法大体上相当于将featureLayer与csv中的表进行了连接处理)
                    layer = addCounties(csvData);
                });
            });

            // set up play/pause buttons
            //播放/暂停按钮事件绑定
            on(dom.byId("pause"), "click", function () {
                domStyle.set(this, "display", "none");
                domStyle.set("play", "display", "inline-block");
                pause();
            });
            on(dom.byId("play"), "click", function () {
                domStyle.set(this, "display", "none");
                domStyle.set("pause", "display", "inline-block");
                play();
            });

            function addCounties(csvData) {
                var content = "<b>河流名称</b>: ${河流名称}                      <br><b>清淤量</b>: ${清淤量}                      <br><b>FKRATE</b>: ${rate} "; // \
                // <br><National Average: ${NATLAVG}";
                var infoTemplate = new InfoTemplate("${河流名称} FK河段", content);
                //FeatureLayer URL
                var url = "http://**.**.**.**/arcgis/rest/services/DQ/DQDestilingTemp/MapServer/6";
                var counties = new FeatureLayer(url,
                  {
                      id: "counties",
                      infoTemplate: infoTemplate,
                      outFields: ["河流名称", "FID", "SILTVOLUME"],
                      styling: false
                  });

                counties.on("load", function () {
                    on.once(counties, "update-end", function () {
                        //设置地图渲染器,此渲染器不用于地图渲染,只用于生成图例,所以"FID"字段只是写着玩玩
                        var renderer = createRenderer(currentYear, "FID", csvData);
                        counties.setRenderer(renderer);
                        createLegend(counties);
                        domStyle.set("pause", "display", "inline-block");
                        //开始动画
                        play();
                    });
                    fadeOutLoading();
                });

                if (counties.surfaceType === "svg") {
                    counties.on("graphic-draw", function (evt) {
                        //下述代码进行要素与csv表的关联操作
                        var attrs = evt.graphic.attributes;
                        var joinKey = attrs && attrs.FID; //关联用的字段,先用FID表示了
                        var relgrowth = "no-data";

                        if (joinKey && csvData[joinKey] && csvData[joinKey][currentYear]) {
                            //根据csv表中的数据,获取相应年份的人口数据,计算人口增长率
                            var countyPgr = getGrowthRate(csvData[joinKey][currentYear - 1], csvData[joinKey][currentYear], 1);
                            //console.log(countyPgr);
                            //根据增长率的不同,进行分类渲染
                            if (countyPgr <= 0.5 && countyPgr > 0)
                                relgrowth = "1";
                            else if (countyPgr > 0.5 && countyPgr <= 1)
                                relgrowth = "2";
                            else if (countyPgr > 1 && countyPgr <= 1.25)
                                relgrowth = "3";
                            else if (countyPgr > 1.25 && countyPgr <= 1.5)
                                relgrowth = "4";
                            else if (countyPgr > -5 && countyPgr <= -0.5)
                                relgrowth = "5";
                            else
                                relgrowth = "6";
                        }
                        var qyl;
                        if (joinKey != undefined && csvData[joinKey] != undefined && csvData[joinKey][currentYear] != undefined)
                            qyl = csvData[joinKey][currentYear];
                        //此处可以将某年某月的数据关联到图层的属性中
                        attrs.清淤量 = qyl;
                        attrs.rate = countyPgr;
                        //此处是配色的关键字段!此处内容与上面配置的样式表相对应
                        evt.graphic.getNode().setAttribute("data-relgrowth", relgrowth);
                    });
                }

                map.addLayer(counties);
                return counties;
            }

            function loadCSV() {
                //加载csv中的数据.可以略过,处理结果就是将csv中的表加载到了csvData中,其他函数可以根据FID,时间获取某年月的数据
                var dfd = new Deferred();

                var csvStore = new CsvStore({
                    url: "DesiltingTemp.csv"
                });

                csvStore.fetch({
                    onComplete: function (items, request) {  //process csv data and create in memory object store.
                        var store = request.store;
                        var minYearPopulation = 1970;
                        var maxYearPopulation = 2006;
                        var counties = {};

                        counties.minVal = Infinity;
                        counties.maxVal = -Infinity;

                        arrayUtils.forEach(items, function (item) {
                            //var countyFips = store.getValue(item, "county_fips");
                            //var stateFips = store.getValue(item, "state_fips");
                            //var fips = string.pad(stateFips, 2, "0") + string.pad(countyFips, 3, "0");
                            var fips = store.getValue(item, "FID");
                            var population = {};

                            population.maxVal = -Infinity;

                            for (var year = minYearPopulation; year <= maxYearPopulation; year++) {
                                var fieldName = "pop" + year;
                                var popValue = parseInt(store.getValue(item, fieldName), 10);
                                population[year] = popValue;
                                population.maxVal = (popValue > population.maxVal) ? popValue : population.maxVal;
                                counties.minVal = (popValue < counties.minVal) ? popValue : counties.minVal;
                                counties.maxVal = (popValue > counties.maxVal) ? popValue : counties.maxVal;
                            }

                            counties[fips] = population;
                        });
                        dfd.resolve(counties);
                    },
                    onError: function (err) {
                        console.log("Error loading CSV: ", err.message, err);
                    }
                });
                return dfd;
            }

            function getGrowthRate(pt1, pt2, t2_t1) {
                return ((Math.log(pt2) - Math.log(pt1)) / (t2_t1)) * 100;
            }

            function setYear(year) {
                //设置当前年份
                //由于函数调用时有如下代码setYear = lang.hitch(csvData, setYear); so this就是csvData
                var csvData = this;
                currentYear = year;
                currentUSPgr = getGrowthRate(csvData["0"][currentYear - 1], csvData["0"][currentYear], 1);
                dom.byId("currentYear").innerHTML = currentYear;

                if (layer) {
                    layer.renderer._currentYear = year;
                    //添加renderer分类对象,对分类渲染来说没有实际意义
                    addBreaks(layer.renderer);
                    //重绘.根据官网资料,该方法不通过服务器重绘
                    layer.redraw();
                    //恢复之前的地图弹窗
                    var sel = map.infoWindow.getSelectedFeature();
                    if (sel && map.infoWindow.isShowing) {
                        map.infoWindow.setFeatures([sel]);
                    }
                }
            }

            function changeYear(incr) {
                //更改地图的当前年份
                var year;
                if (incr < 1) {
                    year = (currentYear === 1971) ? 2006 : currentYear + incr;
                    setYear(year);
                }
                else if (incr > 0) {
                    year = (currentYear === 2006) ? 1971 : currentYear + incr;
                    setYear(year);
                }
            }

            function play() {
                //动画播放
                if (!timer) {
                    timer = setInterval(function () {
                        changeYear(1);
                    }, 1250);
                }
            }

            function pause() {
                clearInterval(timer);
                timer = null;
            }

            function createRenderer(startYear, joinField, data) {
                // renderer is used for the legend
                //The LLC Says:This Method is only used for the legend,actually,the breaks info of the renderer is not used for the layer to display.
                //so the attibuteField of the ClassBreaksRenderer is meaningless
                //var tColor=[0,0,0];
                //该Renderer只用来生成图例,不用以分类渲染
                var renderer = new ClassBreaksRenderer(null, "FID");
                renderer._currentYear = startYear;
                renderer._data = data;
                addBreaks(renderer);
                // console.log("renderer with breaks", renderer);
                return renderer;
            }

            function createLegend(layer) {
                //创建图例
                var legendDijit = new Legend({
                    map: map,
                    layerInfos: [
                      {
                          "layer": layer,
                          "title": "Population Change"
                      }
                    ]
                }, "legend");
                legendDijit.startup();
                domStyle.set("feedback", "visibility", "visible");
            }

            function addBreaks(renderer) {
                // console.log("addBreaks", renderer);
                var currentYear = renderer._currentYear,
                  data = renderer._data,
                  totalGrowth = getGrowthRate(data[0][currentYear], data[0][currentYear - 1], 1),
                  roundedTotalGrowth = number.round(totalGrowth, 2);

                renderer.clearBreaks();

                var negative = [175, 141, 195];
                var flat = [20, 236, 231];
                var positive = [127, 191, 123];

                renderer.addBreak({
                    minValue: -Infinity,
                    maxValue: 0,
                    symbol: new SimpleFillSymbol().setColor(new Color(negative))
                      .setOutline(new SimpleLineSymbol().setColor(new Color(negative))),
                    label: "Decrease"
                });

                renderer.addBreak({
                    minValue: 0,
                    maxValue: roundedTotalGrowth,
                    symbol: new SimpleFillSymbol().setColor(new Color(flat))
                      .setOutline(new SimpleLineSymbol().setColor(new Color(flat))),
                    label: "Flat"
                });

                renderer.addBreak({
                    minValue: roundedTotalGrowth,
                    maxValue: Infinity,
                    symbol: new SimpleFillSymbol().setColor(new Color(positive))
                      .setOutline(new SimpleLineSymbol().setColor(new Color(positive))),
                    label: "Increase"
                });
            }

            function fadeOutLoading() {
                var fade = fx.fadeOut({
                    node: "loading",
                    onEnd: function () {
                        domConstruct.destroy(dom.byId("loading"));
                    }
                });
                fade.play();
            }
        });
    </script>
</head>

<body>
    <div id="loading">
        <div id="loadingMessage">
            正在加载清淤量数据
            <br>
            <img src="assets/loading_gray_circle.gif">
        </div>
    </div>
    <div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="‘design‘: ‘headline‘, ‘gutters‘: false">
        <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="‘region‘: ‘center‘">
            <div id="feedback" class="shadow">
                Year:
                <span id="currentYear">
                    <img src="assets/loading_gray_circle.gif">
                </span>
                |
                <!--div id="play">></div-->
                <span id="play">Play</span>
                <!--div id="pause">||</div-->
                <span id="pause">Pause</span>
                <div id="legend"></div>
            </div>

        </div> <!-- end map div -->
    </div> <!-- end border container div -->
</body>
</html>

 

FK JavaScript之:ArcGIS JavaScript API之地图动画

标签:

原文地址:http://www.cnblogs.com/DayDreamEveryWhere/p/5770349.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!