2015-07-20

データベースとの連携 - データベースからのデータ抽出

データベースを利用することの利点のひとつとして、さまざまな条件でのデータ抽出がし易いということが挙げられます。FMEでデータベースからデータを抽出するには、リーダーを使用する他、SQL文によるクエリ(問い合わせ)によって行うこともできます。
ここでは、「データベースとの連携 - データベースへのデータ移行」において国土数値情報「鉄道時系列」データを移行して作成した PostGIS データベース "KSJ_Railroad2" からデータを抽出するワークスペース例を掲げます。
FME 2015.1.0.3 build 15485

1. リーダーによるデータ抽出 - WHARE Clause パラメーター

FMEがサポートする DBMS (データベース管理システム) については、それぞれに対応するリーダーがあり、それによってデータベースからデータを読み込むことができます。

FMEワークスペース例1: [POSTGIS] リーダーによるデータ抽出














リーダーをワークスペースに追加する際に、データベースに接続するためのパラメーターを設定するとともに、データベーステーブルを選択します。
データベース接続用のパラメーターの構成は DBMS によって異なります。PostgreSQL/PostGIS のパラメーターについては、「データベースとの連携 - データベースへのデータ移行」で説明した [POSTGIS] ライターのパラメーターを参照してください。

[POSTGIS] リーダーの追加: Add Reader画面, パラメーター設定画面, テーブル選択画面













この設定でリーダーをワークスペースに追加すると、キャンバスには RailroadSection, Station テーブルに対応するリーダーフィーチャータイプが現れ、それらに Inspector を接続して実行すると、データベースに格納されている全てのフィーチャー(レコード)が読み込まれることが確認できます。

データベース用のリーダーフィーチャータイプでは、WHERE Clause パラメーターでデータの抽出条件を設定することができます。抽出条件の書き方は SQL SELECT 文における WHERE 句の構文と同じです。
例えば、2000年における鉄道の整備状況を表すデータを抽出するには、リーダーフィーチャータイププロパティ設定画面で WHERE Clause パラメーターを次のように設定します(Navigator ウィンドウでも設定できます)。

[POSTGIS] リーダーフィーチャータイププロパティ設定画面 Format Parameters タブ
WHERE Clause: 設置期間_開始 <= 2000 and 2000 <= 設置期間_終了















WHERE Clause パラメーターを設定せずに全てのレコードを読み込み、データフロー内で Tester 等によってフィルタリングすることもできますが、通常は、WHERE Clause ではじめからデータを絞り込んだ方が効率が良くなります。

2000年に固定するのではなく、ワークスペースを実行するときに任意の年次を指定したいという場合は、年次の値をユーザーパラメーターとして設定できるようにしておくと便利です。
まず、Navigator ウィンドウの User Parameters/Published Parameters を右クリックして Add/Edit User Parameter 画面を開き、次のようにパラメーターを定義します。

[YEAR] パラメーター定義












そして、2つのリーダーフィーチャータイプの WHERE Clause パラメーターを次のように変更します。

[POSTGIS] リーダーフィーチャータイププロパティ設定画面 Format Parameters タブ
WHERE Clause: 設置期間_開始 <= $(YEAR) and $(YEAR) <= 設置期間_終了















ここで、"$(YEAR)" は、"YEAR" パラメーターを参照していることを表しており、ワークスペースの実行時にその値に置き換えられます。"YEAR" パラメーターにある年次を指定してから実行すれば、その年次の鉄道整備状況を表すデータが抽出できるというわけです。


2. SQL文によるデータ抽出: SQLCreator トランスフォーマー

ソースデータセットがデータベースである場合は、SQLCreator を使って SQL SELECT文によってデータを抽出することもできます。

FMEワークスペース例2: SQLCreator によるデータ抽出
















SQLCreator パラメーター設定 (鉄道路線)














Dataset グループでは、リーダーと同様にデータベース接続用のパラメーターを設定し、SQL Statement パラメーターで、データを抽出するためのSQL文を定義します。リーダーフィーチャータイプの WHERE Clause パラメーターと同様に、ここでもユーザーパラメーターを参照することができます。
-----
(YEAR年における鉄道路線抽出用のSQL文)
select * from "RailroadSection"
where 設置期間_開始 <= $(YEAR) and $(YEAR) <= 設置期間_終了
-----
(YEAR年における鉄道駅抽出用のSQL文)
select * from "Station"
where 設置期間_開始 <= $(YEAR) and $(YEAR) <= 設置期間_終了
-----
Attributes to Expose パラメーターで、インターフェースに表示させる属性名を設定します。この例では全てのフィールド名を設定しています。

SQLCreator には入力ポートがなく、ワークスペースを実行するとパラメーターの設定に基づいてデータベースからデータを抽出し、フィーチャー(レコード)をひとつずつ出力します。リーダーと同じにように働き、実行結果もリーダーを使用したワークスペース例1と全く同じになります。


3. SQL文によるデータ抽出: SQLExecutor トランスフォーマー

データ抽出条件が比較的単純で、かつ、1回の実行時にひとつの条件でデータを抽出するだけで良いという場合は、リーダーを使うのがシンプルで良いと思います。しかし、次のシナリオ例のように、異なる条件によって何度かデータを抽出するとともに、それらの結果に対して加工もしたいというような場合など、データフローの途中で SQLExecutor によってデータを抽出するのが効果的なこともあります。
=====
[シナリオ]
新幹線の路線(「事業者種別」 = 1 の路線)について、1960年代, 1970年代, 1980年代, 1990年代, 2000年代の10年ごとの区分で、各年代に「設置期間_開始」が含まれる区間を抽出する。
異なる年代の間で重複する区間については1本のラインにし、最も早い「設置期間_開始」の年代に区分する。
ラインに年代区分別の色を与え、KML形式のファイルに出力する。
=====

FMEワークスペース例3: SQLExecutor によるデータ抽出












Creator: 年代の区分数 = 5個のフィーチャーを作成する。
AttributeCreator: 各年代の開始年と終了年翌年の値を求めて属性に格納する。
SQLExecutor: データベースから各年代に「設置期間_開始」が含まれる新幹線の路線を抽出する。
LineOnLineOverlayer: 重複する区間をひとつのラインに統合する。
ListSorter: 元のラインの属性を格納したリストの要素を「設置期間_開始」の昇順でソートする。
ListIndexer: リストの先頭の要素(「設置期間_開始」が最も早いもの)をその区間の属性とする。
KMLStyler: KMLの表示スタイル(年代区分別の色)を設定する。
[OGCKML] ライター: KMLファイルに出力する。

結果: Google Earth による表示
















Creator で年代の区分数 = 5個のフィーチャーを作成して出力順を表す属性 i (0から始まる連番)を与え、AttributeCreator で i に基づいて各年代の開始年と終了年翌年の値を求めてそれらを属性 yearBeg, yearEnd に格納します。これで、ひとつのフィーチャーがひとつの年代区分を表すことになります。

SQLExecutor パラメーター設定





















SQL Statement パラメーターに次のSQL文を設定することによって、入力フィーチャー(年代区分)ごとに、その yearBeg から yearEnd の前年の間に「設置期間_開始」が含まれる新幹線の路線のデータを抽出します。
-----
select 路線名, 設置期間_開始, geom from "RailroadSection"
where 事業者種別 = 1
and @Value(yearBeg) <= 設置期間_開始 and 設置期間_開始 < @Value(yearEnd)
-----
SQLExecutor のSQL文では、@Value(属性名) によって入力フィーチャーの属性値をSQL文に埋め込むことができます。また、geom は空間データを格納しているフィールド名です。このフィールドの値を抽出することにより、ジオメトリが作成されます。ただし、前出 SQLCreator のSQL文のように * (アスタリスク) によって全てのフィールドの値を抽出する場合は書く必要はありません。
Combine Attributes パラメーターで "Keep Initiator Attributes if Conflict" を選択し、出力フィーチャーにはデータベースから抽出した属性だけでなく、Initiator ポートから入力されたフィーチャーの属性 (yearBeg, yearEnd) も付加されるようにしました。yearBeg (年代の開始年) によって年代が識別されます。

LineOnLineOverlayer は、入力されたラインのうち重複する区間を分離してひとつのラインに統合し、元のラインが持っていた属性を List Name パラメーターに指定した名前のリストに格納します。
ListSorter によってそのリストの要素を「設置期間_開始」の昇順でソートしたうえで、ListIndexer によって先頭の要素を取り出しました。これにより、複数の年代で重複していた区間は最も早い年代に区分できます。

もう少し工夫すると、年代区分別に5回データを抽出するのではなく、次のSQL文により1回の問い合わせで済ますこともでき、これを採用するならば SQLCreator を使うことになります。
-----
select 路線名, 設置期間_開始, geom,
case
    when 設置期間_開始 < 1970 then 1960
    when 設置期間_開始 < 1980 then 1970
    when 設置期間_開始 < 1990 then 1980
    when 設置期間_開始 < 2000 then 1990
    else 2000
end as "yearBeg"
from "RailroadSection" where 事業者種別 = 1 and 設置期間_開始 < 2010
-----

注: PostgreSQL/PostGIS データベース用のSQL文では、英大文字が含まれるテーブル名やフィールド名は二重引用符で囲む必要があります。これはFMEの仕様ではなく、PostgreSQL/PostGISの仕様であり、他のDBMS (データベース管理システム) のデータベース用のSQL文については適用されません。

0 件のコメント:

コメントを投稿