Web AppBuilderカスタムウィジェット(2) CSVを読み込んで地図に表示する方法

Web AppBuilder for ArcGIS(Developer Edition)のカスタムウィジェットで、手元のCSVをアップロードして、地図上に表示するための開発の2回めです。

シリーズ一覧

今回のゴール

前回は、UIを作るところまででした。

パネル例

今回のゴールは

  1. CSVファイルをJavaSccriptオブジェクトに変換
  2. さらにArcGIS API for JavaScriptのGraphicオブジェクトに変換
  3. 最後に地図上のポイントとして表示する

ところまでやります。

上の「参照」ボタンクリックで、CSV内の緯度、経度の位置に赤い□が表示されるはず。

1.CSVファイルをJavaSccriptオブジェクトに変換

こんな感じのCSVを用意します。エンコーディングはUTF-8で。

タイトル,緯度,経度
場所1,35.624928,139.730359
場所2,35.952509,139.643341

読み込んだ後はJavaScriptのオブジェクト配列に。

_x, _yは後で地図上のポイントにするために緯度、経度が必要なので、プログラムで操作しやすいように決まった名前のプロパティとしてつけています。

(緯度、経度など決まった名前の列があったら、それぞれy座標、x座標とみなして、_y, _xプロパティにセット)

オブジェクト配列に詰め替えたところ

この部分のコードにはArcGIS API特有の部分はないので、最後のコードの「parseCsv」関数を参照。

2.さらにArcGIS API for JavaScriptのGraphicオブジェクトに変換

読取ボタンをクリックすると、以下のdojo.hitchパラメータの関数が呼びだされ、FileReaderでテキストを読み、1.で示した処理でオブジェクト配列にしています。

this.own(
    on(button, 'click', dojo.hitch(this, function(evt) {
        var reader = new FileReader();
        var widgetObj = this;
        reader.onload = function(){
            var text = reader.result;
            var dataArray = widgetObj.parseCsv(text);
            var dataArrayLength = dataArray.length;
            widgetObj.myLayer.clear();
            for (var i = 0; i < dataArrayLength; i++)
                widgetObj.addObjToLayer(dataArray[i]);
        };
        reader.readAsText(file.files[0]);
    }))
);

dojo.hitchに渡したコールバック関数内では、thisで元のウィジェット自身を指すようになります。クリックされたボタンでなく。このthisをwidgetObj変数にとっておいて、ファイル読み込みコールバック内でウィジェットにアクセスできるようにしているのです。

オブジェクトの各オブジェクトに対し、ウィジェットのaddObjToLayer関数を読んでGraphicオブジェクトにしています。

addObjToLayer: function(obj) {
    // 緯度、経度をそれぞれ_y,_xプロパティに持っているオブジェクトを受け取り
    // Graphicオブジェクトに変換したうえで自前のGraphicLayerに追加する
    var geometry = new Point(obj["_x"], obj["_y"],  new SpatialReference({ wkid: 4326 }));
    var g = new graphic(geometry, this.myLayerSymbol, obj);
    this.myLayer.add(g);
}

Graphicオブジェクトは図形の形状、色合いやアイコンなどの見栄え、属性情報などを持つオブジェクトで、Mapに追加したLayerオブジェクトに追加することで地図上に表示されます。

なお、JavaScript APIのバージョン3.16と4で、配置が微妙に変わっているようなので注意。

https://developers.arcgis.com/javascript/3/jsapi/graphic-amd.html (3.16)

3.16はesri/graphicでアクセスなのに対し、現状最新の4はesri/Graphicでアクセスみたいです。

2016/5月に落としてきたWeb AppBuilderでは3.16を参照しているようなので、そっちでコード書きました。

3.最後に地図上のポイントとして表示する

といっても追加自体は上のサンプルコードに含まれています。

なので、上のコードに出てきていない部分を書いておきます。

まずWidgetのプロパティとして以下を準備。

myLayer: null,  //  このウィジェットで扱うGraphicLayer
myLayerSymbol: new SimpleMarkerSymbol().setStyle(
SimpleMarkerSymbol.STYLE_SQUARE).setColor(
new Color([255,0,0,0.5])),

myLayerSymbolには図形を地図上で表示する際に使う色合いや透明度、線の太さなどを定義しています。今回は属性に応じて変更などしないことにしたので、ウィジェット内で決め打ちで1つ作りました。Graphicオブジェクト作成時にこのsymbolを指定しています。

myLayerはstartup中で以下のように初期化。初期化した後で地図に追加しています。WidgetBaseがプロパティとして地図への参照を持っているので、それを継承して作る各ウィジェットでは、this.mapで地図オブジェクトにアクセスできます。

this.myLayer = new GraphicsLayer();
this.map.addLayer(this.myLayer);

GraphicsLayerは単純に図形を地図上に表示したい時に使います。バージョン3まではFeatureLayerの継承元だったのですが、4で関係なくなりましたね。

コード例(Widget.js)

前回と変更したWidget.jsのみですが。

Widget