google-code-prettify

星期二, 1月 27, 2015

[ArcGIS Server API for JavaScript] 利用 Label Layer 改變圖層 Label 的顯示


話說 ArcGIS Server for Javascript 怎麼改變圖層 Label 文字的顯示?

口白:
主要是跟 ArcGIS Server for Javascript API 所發生的糾葛?
卜朧共生命中對 GIS Coding 命運的糾結?
或是一場命中註定的糾纏?
結果如何?讓我們看下去....

Html:
<!DOCTYPE html>
<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">
    <title></title>
    <link rel="stylesheet" href="http://js.arcgis.com/3.12/esri/css/esri.css">
    <script src="http://js.arcgis.com/3.12/"></script>
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>
說明:
 1. 引用 CSS 需插入  
    <link rel="stylesheet" href="http://js.arcgis.com/3.12/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.12/esri/css/esri.css">

 2. 引用 Javascript 需插入  <script src="http://js.arcgis.com/3.12/"></script> 其中已包含了Dojo框架囉

 3. <body> 標籤中 加入 class 樣式定義為 "claro" 如: <body class="claro">

 4. 加入 div 區塊 當作地圖區塊 ,如:<div id="map"></div>


CSS:
      html, body, #map {
        height: 100%; width: 100%; margin: 0; padding: 0;
      }

說明:
 1. 定義 html、body、map 區塊的 CSS 樣式

JavaScript:
      var map;
      require([
        "esri/map",
        "esri/geometry/Extent",
        "esri/layers/FeatureLayer",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",
        "esri/symbols/TextSymbol",
        "esri/renderers/SimpleRenderer",
        "esri/layers/LabelLayer",
        "esri/Color",
        "dojo/domReady!"
      ], function(
        Map, Extent, FeatureLayer,
        SimpleLineSymbol, SimpleFillSymbol, TextSymbol, SimpleRenderer,
        LabelLayer,
        Color
      ) {
        // load the map centered on the United States
        var bbox = new Extent({"xmin": -1940058, "ymin": -814715, "xmax": 1683105, "ymax": 1446096, "spatialReference": {"wkid": 102003}});
        map = new Map("map", {
          extent: bbox
        });

        /**/
        var labelField = "STATE_NAME" ;

        // create a renderer for the states layer to override default symbology
        var statesColor = new Color("#666");
        // 定義線段樣式 "solid"
        //var statesLine = new SimpleLineSymbol("solid", statesColor, 1.5);
        // 定義線段樣式 esri.symbol.SimpleLineSymbol.STYLE_NULL 不顯示
        var statesLine = new SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_NULL, statesColor, null );
        var statesSymbol = new SimpleFillSymbol("solid", statesLine, null);
        var statesRenderer = new SimpleRenderer(statesSymbol);
        // create a feature layer to show country boundaries
        var statesUrl = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3";
        var states = new FeatureLayer(statesUrl, {
          id: "states",
          outFields: [labelField]
        });
        states.setRenderer(statesRenderer);
        map.addLayer(states);

        // create a text symbol to define the style of labels
        var statesLabel = new TextSymbol().setColor(statesColor);
        statesLabel.font.setSize("14pt");
        statesLabel.font.setFamily("arial");
        var statesLabelRenderer = new SimpleRenderer(statesLabel);
        var labels = new LabelLayer({ id: "labels" });
        // tell the label layer to label the countries feature layer
        // using the field named "admin"
        labels.addFeatureLayer(states, statesLabelRenderer, "{" + labelField + "}");
        // add the label layer to the map
        map.addLayer(labels);
    
        /*
        var labelField1 = "OTHER";

        // create a renderer for the states layer to override default symbology
        var statesColor1 = new Color("#000");
        var statesLine1 = new SimpleLineSymbol("solid", statesColor1, 1.5);
        var statesSymbol1 = new SimpleFillSymbol("solid", statesLine1, null);
        var statesRenderer1 = new SimpleRenderer(statesSymbol1);
        // create a feature layer to show country boundaries
        var statesUrl1 = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3";
        var states1 = new FeatureLayer(statesUrl1, {
          id: "states"
          ,
          outFields: [labelField1]
        });
        states1.setRenderer(statesRenderer1);
        map.addLayer(states1);

        // create a text symbol to define the style of labels
        var statesLabel1 = new TextSymbol().setColor(statesColor1);
        statesLabel1.font.setSize("12pt");
        statesLabel1.font.setFamily("arial");
        var statesLabelRenderer1 = new SimpleRenderer(statesLabel1);
        var labels1 = new LabelLayer({ id: "labels1" });
        // tell the label layer to label the countries feature layer
        // using the field named "admin"
        //labels1.addFeatureLayer(states1, statesLabelRenderer1, "{" + labelField1 + "}");
        labels.addFeatureLayer(states1, statesLabelRenderer1, "{" + labelField1 + "}");
        // add the label layer to the map
        map.addLayer(labels);
        */
      });

說明:
 1. 定義 弱型別的變數 map
     require 是 Dojo 方法,利用該方法 載入'esri/map', 'esri/geometry/Extent', 'esri/layers/FeatureLayer', 'esri/symbols/SimpleLineSymbol', 'esri/symbols/SimpleFillSymbol', 'esri/symbols/TextSymbol', 'esri/renderers/SimpleRenderer', 'esri/layers/LabelLayer', 'esri/Color', 'dojo/domReady!'

 2. 載入模組後,需用定義對應的變數來接收該模組,
     Map, Extent, FeatureLayer, SimpleLineSymbol, SimpleFillSymbol, 
     TextSymbol, SimpleRenderer,LabelLayer,Color

 3. function(Map...略...) {...略...}  用一個 拋棄式的函數 裡面定義 map 變數,
     透過傳入的 Map 類別可以 宣告成一個 esri/map 的物件
     (new Map 宣告方法 就要查 https://developers.arcgis.com/javascript/jsapi/map-amd.htmlnew Map(divId, options?)  第一個參數是 divId ,
     所以要對應 html 中 要顯示地圖 的 div ID(<div id="map"..略...),
     第二個參數是個 Object ,範例中所定義的屬性有 extent,
     extent:源自於 Extent(http://goo.gl/HEZmf8) 類別,
     所以我們定義一個弱型別的變數 bbox 來接 Extent(http://goo.gl/HEZmf8) 類別物件。

 4. 定義弱型別變數 labelField ,並定義它屬性為 STATE_NAME,這是我們預設要顯示的 Label 文字欄位。

 5. 透過傳入的 Color 類別,宣告成一個 esri/Color 的物件
     (new Color 宣告方法 就要查 https://developers.arcgis.com/javascript/jsapi/color-amd.html),
     利用所定義弱型別變數 statesColor 承接,目的是定義顯示線條、文字顏色。

 6. 透過傳入的 SimpleLineSymbol 類別,宣告成一個 esri/symbols/SimpleLineSymbol 的物件
     (new SimpleLineSymbol 宣告方法 就要查 https://developers.arcgis.com/javascript/jsapi/simplelinesymbol-amd.html),
     利用所定義弱型別變數 statesLine 承接,目的是定義簡單線條符號(顏色、粗細、樣式)

 7. 透過傳入的 SimpleFillSymbol 類別,宣告成一個 esri/symbols/SimpleFillSymbol 的物件
     (new SimpleFillSymbol 宣告方法 就要查 https://developers.arcgis.com/javascript/jsapi/simplelinesymbol-amd.html),
     利用所定義弱型別變數 statesSymbol 承接,目的是定義填充線條(顏色、粗細、樣式)

 8. 透過傳入的 SimpleRenderer 類別,宣告成一個 esri/renderers/SimpleRenderer 的物件
     (new SimpleRenderer 宣告方法 就要查 https://developers.arcgis.com/javascript/jsapi/simplerenderer-amd.html),
     利用所定義弱型別變數 statesRenderer 承接,目的是定義顯示物件

 9. 定義弱型別變數 statesUrl,
     屬性值:http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3 ,
     定義為 ArcGIS Server Rest 服務位址

10. 透過傳入的 FeatureLayer 類別,宣告成一個 esri/layers/FeatureLayer 的物件
     (new FeatureLayer 宣告方法 就要查 https://developers.arcgis.com/javascript/jsapi/featurelayer-amd.html),
      利用所定義弱型別變數 states 承接。
      利用 states.setRenderer(statesRenderer)函數,來設定 FeatureLayer 的樣式。

11. 將 states 的 FeatureLayer ,透過 map.addLayer(states)  函數,把圖層加到 map。

12. 透過傳入的 TextSymbol 類別,宣告成一個 esri/symbols/TextSymbol 的物件
     (new TextSymbol 宣告方法 就要查 https://developers.arcgis.com/javascript/jsapi/textsymbol-amd.html),
      利用所定義弱型別變數 statesLabel 承接。
      利用 statesLabel.font.setSize("14pt") 函數,來設定字型的大小,
      利用 statesLabel.font.setFamily("arial") 函數,來設定字型集。

13. 透過傳入的 SimpleRenderer 類別,宣告成一個 esri/renderers/SimpleRenderer 的物件(同 8.),
     利用所定義弱型別變數 statesLabelRenderer 承接,目的是定義顯示 Label 物件

14. 透過傳入的 LabelLayer 類別,宣告成一個 esri/layers/FeatureLayer 的物件
     (new LabelLayer 宣告方法 就要查 https://developers.arcgis.com/javascript/jsapi/labellayer-amd.html),
      利用所定義弱型別變數 labels 承接。
      利用 labels.addFeatureLayer() 函數,來添加參考其標記要素層。

15. 將 labels 的 LabelLayer ,透過 map.addLayer(labels)  函數,把圖層加到 map。

console: ( 打開 debug 模式,來修改 label吧 )
// 將顯示的 Label 欄位改為 OTHER
map._layers.labels._featureLayerInfos[0].LabelExpressionInfo='{OTHER}';
map._layers.states._outFields[0]='OTHER';
map._layers.states.displayField='OTHER';
map.getLayer('states').refresh();

// 將顯示的 Label 欄位改為 STATE_NAME
map._layers.labels._featureLayerInfos[0].LabelExpressionInfo='{STATE_NAME}';
map._layers.states._outFields[0]='STATE_NAME';
map._layers.states.displayField='STATE_NAME';
map.getLayer('states').refresh();

JSBin Demo(http://goo.gl/nU8WeM)
參考文獻︰: ArcGIS API for JavaScript Sandbox 、label layer

沒有留言 :

張貼留言