GIS奮闘記

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

スポンサーリンク

ArcGIS API for JavaScript でレイヤーにフィルターをかける方法

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

www.gis-py.com

完成イメージ

ちょっと見づらいのですが、実行ボタンを押下すると「神奈川」レイヤーの「SIKUCHOSON」フィールドが「横須賀市」のフィーチャが抽出されます。

f:id:sanvarie:20200211215003p:plain

f:id:sanvarie:20200211215212p:plain

フィルターを解除する場合は、「フィルター」項目を空白にして実行ボタンを押下します。

f:id:sanvarie:20200211215305p:plain

実行環境

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

フィルター処理について解説

FeatureLayer クラスの definitionExpression プロパティを使用してフィルター処理を行います。getActiveField() メソッドで選択しているフィールドのオブジェクトを取得し、それを利用してフィルター用の式を作成しています。

// 選択したフィールドを取得
function getActiveField() {
    var ddFieldList = document.getElementById("ddFieldList");
    var selectedIndex = ddFieldList.options.selectedIndex;
    return ddFieldList.options[selectedIndex].field;
}

// フィルター処理
function filterFeatures() {
    var txtSearch = document.getElementById("txtSearch");
    var featureLayer = getActiveLayer();

    // 空だったらフィルター解除
    if (txtSearch.value == "") {
        featureLayer.definitionExpression = txtSearch.value
    } else {
        var activeField = getActiveField();
        var type = activeField.type;
        var expression;

        if (type = "string"){
            expression = activeField.name + "=" + "'" + txtSearch.value + "'";
        } else {
            expression = activeField.name + "=" + txtSearch.value;
        }
        featureLayer.definitionExpression = expression;
    }      
}

サンプルコード

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

<!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;
    }
    #searchBox {
        width:100px;
        right:0;
        position: absolute;
        background-color: rgba(255,255,255);
        color: black;
    }

    </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;
            o.field = field;
            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;
     }

     // 選択したフィールドを取得
     function getActiveField() {
        var ddFieldList = document.getElementById("ddFieldList");
        var selectedIndex = ddFieldList.options.selectedIndex;
        return ddFieldList.options[selectedIndex].field;
     }

     // フィルター処理
     function filterFeatures() {
        var txtSearch = document.getElementById("txtSearch");
        var featureLayer = getActiveLayer();

        // 空だったらフィルター解除
        if (txtSearch.value == "") {
            featureLayer.definitionExpression = txtSearch.value
        } else {
            var activeField = getActiveField();
            var type = activeField.type;
            var expression;

            if (type = "string"){
                expression = activeField.name + "=" + "'" + txtSearch.value + "'";
            } else {
                expression = activeField.name + "=" + txtSearch.value;
            }
            featureLayer.definitionExpression = expression;
        }      
     }
      
     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>
        <label>フィルター</label>
        <input type = 'text' id = 'txtSearch' class = 'searchBox'>
        <button id="executeFilter" type="button" onClick="filterFeatures()">実行</button>
    </div>
</body>
</html>

他のレイヤーにもフィルターをかけてみました。

f:id:sanvarie:20200211220406p:plain

f:id:sanvarie:20200211220510p:plain

いい感じですね!

機能的には大したことはないと思いますが、地道に勉強してみようと思います。やはりこれからは Web GIS の時代なので、ArcGIS API for JavaScript について覚えておいて損は無いかと思います。本ブログでは ArcGIS API for JavaScript について色々紹介しているので、興味のある方は以下エントリーをぜひ読んでみてください。

www.gis-py.com

www.gis-py.com

www.gis-py.com

本日は以上です。