GIS奮闘記

現役GISエンジニアの技術紹介ブログ。主にPythonを使用。

スポンサーリンク

ArcGIS API for JavaScript でレイヤーのフィールドをセレクトボックスに格納する方法

さて、本日も ArcGIS API for JavaScript について書いてみようと思います。前回のエントリーでは Web Map のレイヤーをセレクトボックスに格納する方法について書いてみました。今回はその続きです。レイヤーのセレクトボックスを選択した際にそのレイヤーのフィールドを別のセレクトボックスに格納するというものです。前回のエントリーに興味がある方はぜひ読んでみてください。

www.gis-py.com

完成イメージ

以下のように「レイヤー」「フィールド」セレクトボックスを作成します。

f:id:sanvarie:20200202200006p:plain

「レイヤー」セレクトボックスの選択時に「フィールド」セレクトボックスにそのレイヤーのフィールドを格納します。 f:id:sanvarie:20200202200059p:plain

f:id:sanvarie:20200202200241p:plain

実行環境

ArcGIS API for JavaScript 4.14
Google Chrome 最新版(2020/2/2 時点)

ポイントとなる処理

  1. Web Mapのレイヤーをセレクトボックスに格納する
  2. レイヤーセレクトボックス変更時の処理
  3. レイヤーのカラムを取得

WebMapのレイヤーをセレクトボックスに格納する

こちらは前回のエントリーでも紹介しましたが、大事な部分なので本エントリーでも紹介します。マップ読み込み時に map.when が実行され、その中で loadLayers() が実行され、「レイヤー」セレクトボックスにレイヤー名が格納されます。

// マップ読み込み時
map.when(() => {
    loadLayers(map.layers);
    var ddLayerList = document.getElementById("ddLayerList");
    ddLayerList.addEventListener("change", onLayerChange);
})

function loadLayers(layers) {
  var ddLayerList = document.getElementById("ddLayerList");
  layers.forEach(l => {
       let o = document.createElement("option");
       o.textContent = l.title;
       o.layer = l;
       ddLayerList.appendChild(o)
  });

  // 最初は未選択の状態にする
  ddLayerList.selectedIndex = -1;
}

レイヤーセレクトボックス変更時の処理

レイヤーセレクトボックス変更時に onLayerChange() が実行されるように設定します。設定は上記ソース参照(map.when でマップ読み込み時に addEventListener() で設定)

// レイヤーセレクトボックス変更時の処理
function onLayerChange(e) {
  var layer = getActiveLayer(); 
  getFieldName(layer);
}

// 選択したレイヤーを取得
function getActiveLayer() {
  var ddLayerList = document.getElementById("ddLayerList");
  var selectedIndex = ddLayerList.options.selectedIndex;
  return ddLayerList.options[selectedIndex].layer;
}

レイヤーのカラムを取得

最初に removeOptions() でセレクトボックスの要素を削除してから要素の追加を行います。

// レイヤーのカラムを取得
function getFieldName(layer) {
   var ddFieldList = document.getElementById("ddFieldList");
   // セレクトボックスの要素を削除
   removeOptions(ddFieldList);
   // セレクトボックスに要素を追加
   layer.fields.forEach(function(field){
       let o = document.createElement("option");
       o.textContent = field.name;
       ddFieldList.appendChild(o);
  });
}
// セレクトボックスの要素削除
function removeOptions(selectBox){
   var i;
   for(i = selectBox.options.length - 1 ; i >= 0 ; i--)
   {
       selectBox.remove(i);
   }
}

サンプルコード

以下に全コードを記載します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <style>
    html,
    body,
    #divMapView {
        padding: 0;
        margin: 0;
        width:100%;
        height:100%;
    }
    #divToolbar {
        top:0;
        width:100%;
        position: fixed;
        background:rgba(0,0,0,0.6);
        color: white;
    }

    </style>
    <title>レイヤー一覧</title>
    <link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/css/main.css">
    <script src="https://js.arcgis.com/4.14/"></script> 
    <script>
    
     // WebMapのレイヤーをセレクトボックスに格納する
     function loadLayers(layers) {
      var ddLayerList = document.getElementById("ddLayerList");
       layers.forEach(l => {
            let o = document.createElement("option");
            o.textContent = l.title;
            o.layer = l;
            ddLayerList.appendChild(o)
       });

       // 最初は未選択の状態にする
       ddLayerList.selectedIndex = -1;
     }

     // レイヤーセレクトボックス変更時の処理
     function onLayerChange(e) {
        var layer = getActiveLayer(); 
        getFieldName(layer);
     }

     // レイヤーのカラムを取得
     function getFieldName(layer) {
        var ddFieldList = document.getElementById("ddFieldList");

        // セレクトボックスの要素を削除
        removeOptions(ddFieldList);

        // セレクトボックスに要素を追加
        layer.fields.forEach(function(field){
            let o = document.createElement("option");
            o.textContent = field.name;
            ddFieldList.appendChild(o);
      });
     }

     // セレクトボックスの要素削除
     function removeOptions(selectBox){
        var i;
        for(i = selectBox.options.length - 1 ; i >= 0 ; i--)
        {
            selectBox.remove(i);
        }
     }

     // 選択したレイヤーを取得
     function getActiveLayer() {
        var ddLayerList = document.getElementById("ddLayerList");
        var selectedIndex = ddLayerList.options.selectedIndex;
        return ddLayerList.options[selectedIndex].layer;
     }
      
     require (["esri/WebMap", "esri/views/MapView"],
     (WebMap,MapView) => {
        const map = new WebMap({
            "portalItem" : {
                "id" : "adfcbd5d28174451b61ec8c0195af577"
            }
        });
        const mapView = new MapView({ 
            "container" : "divMapView",
            "map" : map
        })
        
        map.when(() => {
            loadLayers(map.layers);
            var ddLayerList = document.getElementById("ddLayerList");
            ddLayerList.addEventListener("change", onLayerChange);
        })
     })  
    </script>
</head>
<body>
    <div id = 'divMapView'></div>
    <div id = 'divToolbar'>
        <label>レイヤー</label>
        <select id = 'ddLayerList'>
        </select>
        <label>フィールド</label>
        <select id = 'ddFieldList'>
        </select>
    </div>
</body>
</html>

動きを確認してみると以下のようになるかと思います。

f:id:sanvarie:20200202201458p:plain

f:id:sanvarie:20200202201527p:plain

f:id:sanvarie:20200202201558p:plain

意外とすんなり完成しました。私は正直 Web プログラミングは得意ではないので、あまり複雑なことはできないのですが、拙いながらも一応目的は達成することができました。今後も ArcGIS API for JavaScript を使っていき、Web GIS の時代から取り残されないように頑張ろうと思います。本ブログでは ArcGIS API for JavaScript について色々紹介しているので、興味のある方は以下エントリーをぜひ読んでみてください。

www.gis-py.com

www.gis-py.com

www.gis-py.com

本日は以上です。