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


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

    本文目的:对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>
  • 相关阅读:
    STP RSTP
    数组与文字处理
    3 算法、控制结构
    2 变量、运算符、位运算
    1
    小程序点击变换,
    小程序授权demo
    小程序获取参数
    小程序是否转发群还是个人(转发功能)
    小程序分享转发功能实现demo
  • 原文地址:https://www.cnblogs.com/DayDreamEveryWhere/p/5770349.html
Copyright © 2020-2023  润新知