ArcGIS JS动态更新属性

效果展示

数据加载前
数据加载后

实现方案

打开 https://developers.arcgis.com/javascript/3/sandbox/sandbox.html?sample=layers_label ,在左侧代码区粘贴以下代码:

<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
    <!-- 
  ArcGIS API for JavaScript, https://js.arcgis.com
  For more information about the layers_label sample, read the original sample description at developers.arcgis.com.
  https://developers.arcgis.com/javascript/3/jssamples/layers_label.html  
  -->
    <title>Labeling features client-side</title>

    <!-- 3.9 版本无效,提示 FeatureLayer 没有 setLabelingInfo 方法 -->
    <!--<link rel="stylesheet" href="https://js.arcgis.com/3.9/js/esri/css/esri.css">-->
    <link rel="stylesheet" href="https://js.arcgis.com/3.39/esri/css/esri.css">
    <style>
        html,
        body,
        #map {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;
        }
    </style>

    <!--<script src="https://js.arcgis.com/3.9/"></script>-->
    <script src="https://js.arcgis.com/3.39/"></script>
    <script>
        var map;

        require([
            "esri/map",
            "esri/geometry/Extent",
            "esri/geometry/scaleUtils",
            "esri/layers/FeatureLayer",
            "esri/symbols/SimpleLineSymbol",
            "esri/symbols/SimpleFillSymbol",
            "esri/symbols/TextSymbol",
            "esri/renderers/SimpleRenderer",
            "esri/layers/LabelClass",
            "esri/Color",

            "dojo/domReady!"
        ], function (Map, Extent, scaleUtils, FeatureLayer,
            SimpleLineSymbol, SimpleFillSymbol,
            TextSymbol, SimpleRenderer, LabelClass, Color) {
            // load the map centered on the United States
            var bbox = new Extent({ "xmin": -1940058, "ymin": -814715, "xmax": 1683105, "ymax": 1446096, "spatialReference": { "wkid": 102003 } });

            //create the map and set the extent, making sure to "showLabels"
            map = new Map("map", {
                extent: bbox,
                showLabels: true //very important that this must be set to true!   
            });

            // create a renderer for the states layer to override default symbology
            var statesColor = new Color("#666");
            var statesLine = new SimpleLineSymbol("solid", statesColor, 1.5);
            var statesSymbol = new SimpleFillSymbol("solid", statesLine, null);
            var statesRenderer = new SimpleRenderer(statesSymbol);

            // create the feature layer to render and label
            var statesUrl = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3";
            var states = new FeatureLayer(statesUrl, {
                id: "states",
                outFields: ["*"]
            });
            states.setRenderer(statesRenderer);


            // create a text symbol to define the style of labels
            var statesLabel = new TextSymbol().setColor(statesColor);
            statesLabel.font.setSize("14pt");
            statesLabel.font.setFamily("arial");

            //this is the very least of what should be set within the JSON  
            var json = {
                "labelExpressionInfo": { "value": "{STATE_NAME}" },
            };

            //create instance of LabelClass (note: multiple LabelClasses can be passed in as an array)
            var labelClass = new LabelClass(json);
            //labelClass.maxScale=5000000; //标注显示的最大比例,超过就不显示
            //labelClass.minScale=10000000;//标记显示的最小比例,低于就不显示
            labelClass.symbol = statesLabel; // symbol also can be set in LabelClass' json
            console.log(states);
            states.setLabelingInfo([labelClass]);
            states.on("update-end", function () {
                // 输出当前 scale
                console.log(scaleUtils.getScale(map));
                setTimeout(function () {
                    for (var i = 0; i < states.graphics.length; i++) {
                        //输出其中一个graphic(面要素)的所有属性      
                        // console.log(states.graphics[i].attributes);
                        //自定义数据,在每个面要素中修改修改属性  
                        states.graphics[i].attributes["STATE_NAME"] = "CUSTOM" + i;
                    }
                    // 将新的要素重新渲染到图层
                    states.applyEdits(states.graphics, null, null);
                }, 1000)
            });

            map.addLayer(states);

        });
    </script>
</head>

<body>
    <div id="map"></div>
</body>

</html>

下面的版本省去了 applyEdits 产生的网络请求。

<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
    <!-- 
  ArcGIS API for JavaScript, https://js.arcgis.com
  For more information about the layers_label sample, read the original sample description at developers.arcgis.com.
  https://developers.arcgis.com/javascript/3/jssamples/layers_label.html  
  -->
    <title>Labeling features client-side</title>

    <!-- 3.9 版本无效,提示 FeatureLayer 没有 setLabelingInfo 方法 -->
    <!--<link rel="stylesheet" href="https://js.arcgis.com/3.9/js/esri/css/esri.css">-->
    <link rel="stylesheet" href="https://js.arcgis.com/3.39/esri/css/esri.css">
    <style>
        html,
        body,
        #map {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;
        }
    </style>

    <!--<script src="https://js.arcgis.com/3.9/"></script>-->
    <script src="https://js.arcgis.com/3.39/"></script>
    <script>
        var map;

        require([
            "esri/map",
            "esri/geometry/Extent",
            "esri/geometry/scaleUtils",
            "esri/layers/FeatureLayer",
            "esri/symbols/SimpleLineSymbol",
            "esri/symbols/SimpleFillSymbol",
            "esri/symbols/TextSymbol",
            "esri/renderers/SimpleRenderer",
            "esri/layers/LabelClass",
            "esri/Color",

            "dojo/domReady!"
        ], function (Map, Extent, scaleUtils, FeatureLayer,
            SimpleLineSymbol, SimpleFillSymbol,
            TextSymbol, SimpleRenderer, LabelClass, Color) {
            // load the map centered on the United States
            var bbox = new Extent({ "xmin": -1940058, "ymin": -814715, "xmax": 1683105, "ymax": 1446096, "spatialReference": { "wkid": 102003 } });

            //create the map and set the extent, making sure to "showLabels"
            map = new Map("map", {
                extent: bbox,
                showLabels: true //very important that this must be set to true!   
            });

            // create a renderer for the states layer to override default symbology
            var statesColor = new Color("#666");
            var statesLine = new SimpleLineSymbol("solid", statesColor, 1.5);
            var statesSymbol = new SimpleFillSymbol("solid", statesLine, null);
            var statesRenderer = new SimpleRenderer(statesSymbol);
            console.log(statesRenderer)

            // create the feature layer to render and label
            var statesUrl = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3";
            var states = new FeatureLayer(statesUrl, {
                id: "states",
                outFields: ["*"]
            });
            states.setRenderer(statesRenderer);


            // create a text symbol to define the style of labels
            var statesLabel = new TextSymbol().setColor(statesColor);
            statesLabel.font.setSize("14pt");
            statesLabel.font.setFamily("arial");

            //this is the very least of what should be set within the JSON  
            var json = {
                "labelExpressionInfo": { "value": "{STATE_NAME}" },
            };

            //create instance of LabelClass (note: multiple LabelClasses can be passed in as an array)
            var labelClass = new LabelClass(json);
            //labelClass.maxScale=5000000; //标注显示的最大比例,超过就不显示
            //labelClass.minScale=10000000;//标记显示的最小比例,低于就不显示
            labelClass.symbol = statesLabel; // symbol also can be set in LabelClass' json
           // console.log(states);
            states.setLabelingInfo([labelClass]);
            
            // 记录最新一次的更新指纹
            let len = 1;
            let xmin = 0;
            let ymin = 0;
            
            states.on("update-end", function () {
                // 输出当前 scale
                // console.log(states.graphics);
                
                // 如果当前状态的指纹与上一次记录的相同,说明要素没有更新
                if (states.graphics.length === 0) {
                  return;
                }
                if (len === states.graphics.length &&
                    xmin === states.graphics[0]._extent.xmin &&
                    ymin === states.graphics[len - 1]._extent.ymin
                ) {
                    return;
                }
                
                len = states.graphics.length;
                xmin = states.graphics[0]._extent.xmin;
                ymin = states.graphics[len - 1]._extent.ymin;
                
                console.log(scaleUtils.getScale(map));
                
                
                setTimeout(function () {
                    for (var i = 0; i < states.graphics.length; i++) {
                        //输出其中一个graphic(面要素)的所有属性      
                        // console.log(states.graphics[i].attributes);
                        //自定义数据,在每个面要素中修改修改属性  
                        states.graphics[i].attributes["STATE_NAME"] = "CUSTOM" + i;
                    }
                    // 将新的要素重新渲染到图层
                    //states.applyEdits(states.graphics, null, null);
                    // 省流方法,会再次触发本监听器
                    map.setExtent(map.extent);
                }, 1000)
            });

            map.addLayer(states);

        });
    </script>
</head>

<body>
    <div id="map"></div>
</body>

</html>

参考资料

最后更新于