ウィジェットの独自設定を行う画面を作成します。
Web AppBuilder for ArcGIS(Developer Edition)のカスタムウィジェットで、手元のCSVをアップロードして、地図上に表示するための開発の4回めです。
Table of Contents
シリーズ一覧
- Web AppBuilder for ArcGISカスタムウィジェットでパネルを表示する方法
- Web AppBuilderカスタムウィジェット(2) CSVを読み込んで地図に表示する方法
- Web AppBuilderカスタムウィジェット(3) 追加したレイヤーをレイヤーリストに表示する
- Web AppBuilderカスタムウィジェット(4) 管理者向けに設定画面を追加する
今回のゴール
レイヤーリストに表示するレイヤー名と、緯度、経度として判断する列名を設定して、配置先環境に合わせた設定ができるようにします。
ウィジェットを追加したとき、構成アイコンをクリックしたとき、以下の画面が開き、設定内容を保存します。
設定内容はソースコードから変数として参照するように変更します。
画面作成
まずは、設定を読むように、[Widgetパス]\manifest.jsonを編集。
{ "name": "CSVLoader", "2D": true, "3D": true, "platform": "HTML", "version": "2.0.1", "wabVersion": "2.0.1", "author": "渡部 潤司", "description": "CSVファイルに格納された緯度/経度を利用して、地図上にポイントを表示します。", "copyright": "(C) 2016 ハウスソフト", "license": "http://www.apache.org/licenses/LICENSE-2.0", "properties": { "inPanel":true, "hasLocale": true, "supportMultiInstance":false, "hasStyle":true, "hasConfig":true, "hasUIFile":true, "keepConfigAfterMapSwitched":false, "hasSettingPage":true, "hasSettingUIFile":true, "hasSettingLocale":true, "hasSettingStyle":false, "IsController":false } }
今回の修正点は、
- “hasSettingPage”:[Widgetパス]\setting\Setting.jsを持っているか否か (設定を処理するJavaScript)
- “hasSettingUIFile”:[Widgetパス]\setting\Setting.htmlを持っているか否か (設定画面)
- “hasSettingLocale”:[Widgetパス]\setting\nlsフォルダを持っているか否か (設定画面の多言語対応。必須ではないです)
- “hasConfig”:[Widgetパス]\setting\config.jsを持っているか否か (設定用変数を保持するファイル)
まず、設定値を持つconfig.js。JSON形式で設定変数を定義しておきます。レイヤ名と、緯度/経度として判断する列名のリスト(半角カンマ区切り)を設定することにしました。
{ "layerName": "CSV読込(設定)", "latColumnName": "Y,緯度,lat,latitude", "lonColumnName": "X,経度,lon,longitude" }
次に設定画面です。シンプルに入力フィールドを並べています。
data-dojo-attach-point=”layerName”の指定は、Dojo Toolkitの書き方でこうすると、ソースコード中からこの変数名に触れる用になります。this.layerName.set(‘value’, 設定値)と書くと、layerNameとつけたタグのvalue属性に設定値を書き込んでくれる。
<div style="width:100%;height:auto;"> <table> <tr> <td>${nls.layerName}:</td> <td><input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-attach-point="layerName"></input></td> </tr> <tr> <td>${nls.latColumnName}:</td> <td><input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-attach-point="latColumnName"></input></td> </tr> <tr> <td>${nls.lonColumnName}:</td> <td><input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-attach-point="lonColumnName"></input></td> </tr> </table> </div>
最後に、Setting.js。設定画面を開いた時に、保存された設定を画面に表示するためのsetConfig関数と、画面で設定した内容を保存するためのgetConfig関数が必須です。setConfigは自動で呼ばれるかと思ったのですが呼ばれなかったので、startupで明示的に呼ぶようにしています。
define([ 'dojo/_base/declare', 'dojo/on', 'dijit/_WidgetsInTemplateMixin', 'jimu/BaseWidgetSetting', ], function(declare, on, _WidgetsInTemplateMixin, BaseWidgetSetting) { return declare([BaseWidgetSetting, _WidgetsInTemplateMixin], { startup: function() { this.setConfig(this.config); }, getConfig: function() { var config = { layerName:this.layerName.value, latColumnName:this.latColumnName.value, lonColumnName: this.lonColumnName.value }; return config; }, setConfig: function(config) { this.config = config; this.layerName.set('value', this.config.layerName); this.latColumnName.set('value', this.config.latColumnName); this.lonColumnName.set('value', this.config.lonColumnName); } }); });
多言語対応
ウィジェット自体の多言語対応と同じように、settingフォルダ内にnlsフォルダを作ります。
定義した変数は上のhtmlファイルで${nls.layerName}のように参照されています。
[Widgetパス]\setting\strings.js
define({ root: { "layerName": "Layer Name", "latColumnName": "Latitude Column Name in Csv File", "lonColumnName": "Longitude Column Name in Csv File" }, "ja": 1 });
[Widgetパス]\setting\js\strings.js
define({ "layerName": "レイヤ名", "latColumnName": "緯度列の名前", "lonColumnName": "経度列の名前" })
追加したポイント全体を表示する
CSV内のポイントデータを追加する際に、x/y座標それぞれの最小値/最大値を取得しておいて、追加終了後に、追加データ数を表示してmapオブジェクトの表示領域を設定。
addObjsToLayer: function(objs) { // 緯度、経度をそれぞれ_y,_xプロパティに持っているオブジェクトを受け取り // Graphicオブジェクトに変換したうえで自前のGraphicLayerに追加する var xmin, xmax, ymin, ymax; for (var i = 0; i < objs.length; i++) { var x = objs[i]["_x"]; var y = objs[i]["_y"]; if (!xmin) { // 配列に含まれる緯度、経度それぞれの最小値、最大値を取得→最後に表示範囲を設定 xmin = xmax = x; ymin = ymax = y; } else { if (x < xmin) xmin = x; if (x > xmax) xmax = x; if (y < ymin) ymin = y; if (y > ymax) ymax = y; } var geometry = new Point(x, y, new SpatialReference({ wkid: 4326 })); var g = new graphic(geometry, this.myLayerSymbol, objs[i]); this.myLayer.add(g); } // 追加したアイテム全体を覆う領域を地図の表示領域とする var layerExtent = new Extent(xmin, ymin, xmax, ymax, new SpatialReference({ wkid: 4326 })); this.map.setExtent(layerExtent); }
結果
追加されたレイヤ名が設定したものに変わりました。
今回作ったウィジェット全体:CSVLoader_v0.4