2016-02-21

データベースの空間検索機能の利用 - 国土数値情報 (医療機関)

FME のワークスペースでは、ジオメトリ間の空間的な関係に基づくデータの抽出 (いわゆる「空間検索」) を行うために SpatialRelator や SpatialFilter などのトランスフォーマーを使うことができます。
しかし、トランスフォーマーによる検索は、ソースデータに含まれる全てのフィーチャーを読み込んでから条件に該当するものを抽出する仕組みであるため、例えばウェブアプリケーションのインターフェースを通じてユーザーが検索範囲を指定するたびにその範囲に含まれるフィーチャーを抽出する場合など、異なる条件によって繰り返し行われることが想定される検索処理については、あまり効率が良い方法とは言えません。そのような場合には、空間データをサポートするデータベースにソースデータを格納しておき、データベースの空間検索機能を利用することが妥当と考えられます。

ここでは、国土数値情報 (医療機関) で提供される点データを PostGIS データベースに格納したうえで、パラメーターとして指定された矩形領域に含まれる医療機関のデータをデータベースから抽出し、GeoJSON 形式に変換するワークスペース例を掲げます。

データベースからのデータ抽出と GeoJSON への変換は、ウェブアプリケーションからのリクエストがあったタイミングで FME Server が Data Streaming サービスとして実行し、結果をアプリケーションに返すという使い方を想定します。
また、出力先のデータフォーマットやスキーマはアプリケーション側の仕様に応じて決定すべきものです。この例では、Google Maps JavaScript API を使用したアプリケーションで利用することを想定し、それに適している GeoJSON としました。

FME 2016.0.1.0 build 16174


FMEワークスペース例1: 国土数値情報 (医療機関) XML -> PostGISデータベース
まず、国土数値情報 (医療機関) XML データを PostGIS データベースに格納するためのワークスペースを作成、実行します。出力先の PostGIS データベースが FME Server からアクセスできる場所にあるものであれば、このワークスペースは FME Desktop で実行しても構いません。












[XML] リーダー: gml:Point要素 (GML形式のジオメトリ) と ksj:MedicalInstitution要素 (属性) の読込
FeatureMerger: Point要素の id 属性をキーとして、属性を結合
StringConcatenator: 診療科目 (3属性) を全角空白区切りで結合した文字列を作成
StringReplacer: 複数の診療科目間の区切り文字 (全角空白) をカンマに置換
AttributeTrimmer: 診療科目連結文字列末尾の余分なカンマを削除
GeometryReplacer: Point要素 (GML) に基づいてジオメトリ (ポイント) を作成
AttributeKeeper: 必要な属性のみを残す (必須ではないが分かり易くするため)
[POSTGIS] ライター: KSJ_MedicalInstitution データベースの institutions テーブルにデータを格納

国土数値情報 (医療機関) XML データでは、gml:Point 要素にポイントジオメトリ、ksj:MedicalInstitution 要素に医療機関の属性が記述されており、gml:Point 要素の id 属性をキーとして医療機関の属性が関連づけられます。XML リーダーではそれらのXML要素をフィーチャータイプとして読み込み、FeatureMreger でポイントの id をキーとして結合しました。

ksj:MedicalInstitution 要素の子要素として診療科目を記述している要素があり、診療科目が複数ある場合は全角空白区切りで列挙され、さらに、診療科目が多数ある場合 (全角空白区切りで列挙したときに Shift JIS コードで254バイトを超える場合) は最大で3つのXML要素に分けて記述されています。XMLドキュメントをパースする際には個別の診療科目ごとにXML要素があった方が都合が良いのですが、国土数値情報はXMLデータと同時に Esri Shapefile 形式のデータも配布しているため、Shapefile データのスキーマに準じたものと推測されます。

それはさておき、PostGIS データベースの text 型フィールドならば格納できる文字数は実用上無制限なので、このワークスペース例では、全ての診療科目をカンマ区切りで列挙した文字列に変換したうえで、services フィールドに格納することとしました。StringConcatenator, StringReplacer, AttributeTrimmerは、カンマ区切りの診療科目文字列を作成するためのものです。
注: データベースの設計としては診療科目は別のテーブルに格納した方が望ましいかも知れませんが、ワークスペースを簡潔にするためにここでは1テーブルに全ての属性を格納しています。

国土数値情報の点データは GML の gml:Point 要素で記述されているので、GeometryReplacer (Geometry Encoding: GML) によってそのXML要素からポイントを作成することができます。

国土数値情報 (医療機関) では各医療機関を医療法に基づいて次の3種類に分類しており、それらはコード1~3で識別されます。この区分による検索を行うことも想定し、データベースの inst_class フィールドにコードを格納しました。
1: 病院
2: (一般)診療所
3: 歯科診療所


FMEワークスペース例2: PostGISデータベース -> GeoJSON
次に、PostGISデータベースから指定された領域に含まれる医療機関データを抽出して GeoJSON形式に変換するワークスペースを作成し、FME Server にアップロードして Data Streaming サービスで実行するための設定をします。














[POSTGIS]リーダー: PostGISデータベースから検索条件に該当する医療機関フィーチャーを抽出する。
Creator: フィーチャーを1個作成する。
FeatureMerger: Creator が作成したフィーチャーを無条件で医療機関フィーチャーに結合する。
[GEOJSON]ライター: データベースから抽出された医療機関フィーチャーを GeoJSON 形式で出力する。
[TEXTLINE]ライター: 検索条件に該当する医療機関がひとつもないことを示す JSON オブジェクトを出力する。

基本的には、POSTGIS リーダーによって抽出された医療機関フィーチャーを単純に GeoJSON 形式で出力しているだけですが、アプリケーションからのリクエストに応じて結果を返すことを想定する場合には、指定された検索条件に該当する医療機関がひとつもなかったときに何を返すかを定義しておく必要があります。

このワークスペース例では、Creator によってひとつフィーチャーを作成し、POSTGIS リーダーから読み込まれた医療機関フィーチャーに無条件に結合しています。こうしておくと、検索条件に該当する医療機関フィーチャーがひとつもなかった場合に Creator で作成されたフィーチャーが FeatureMerger の Unreferenced ポートから出力されるので、そのときに限り特定の JSON オブジェクト (例えば {"id": "no_data"}) を TEXTLINE ライターで出力することによって、アプリケーション側ではそれが返されたときのアクション (メッセージボックスを表示するなど) を定義することができます。

PostGIS データベースの検索機能を利用するには、検索条件とする値をワークスペースが受け取るための公開パラメーターを定義するとともに、POSTGIS リーダーにそれらを渡すための設定が必要です。それについては後述します。


結果: 地理的な範囲を指定して医療機関を検索するウェブアプリケーション例
医療機関の種類を選択し、Google Maps 上で矩形領域を描画すると、その種類・範囲を検索条件としてワークスペース例2を実行し、結果 (ポイント) を表示します。Google Maps JavaScript APIJavaScript Library for FME Server を使用しました。
注: ローカルサーバーでのテスト結果をキャプチャしたものであり、インターネット上では公開していません。




















ワークスペース例2: PostGIS データベースの検索機能を利用するための設定

空間データをサポートするデータベース用のリーダーには Envelope (データを抽出する範囲) を指定するためのパラメーターがあり、また、空間/非空間ともにデータベース用のリーダーフィーチャータイプにはフィールド値によるデータの抽出条件を指定するための WHERE Clause パラメーター (SQL 文の WHERE 句に相当する) があります。検索条件としてこれらのパラメーターに値を設定してワークスペースを実行した場合は、データベースの検索機能を利用して比較的効率よく検索条件に該当するデータを抽出することができます。

これらのパラメーターに設定すべき値をアプリケーション側から受け取るためのインターフェースとしてワークスペースの Published Parameters (公開パラメーター) を定義することにより、アプリケーション側で検索条件を指定できるようになります。

(1) 公開パラメーターの定義
この例では、Published Parameters (公開パラメーター) を次のように定義しました。
MINX, MINY, MAXX, MAXY: データを抽出する範囲の矩形領域を規定する座標値
INST_CLASS_CSV: 抽出すべき医療機関の種類を示すカンマ区切りのコード













(2) POSTGIS リーダーパラメーター (Search Envelope)
POSTGIS リーダーのデータ抽出範囲を指定するためのパラメーター (Minimum X/Y, Maximum X/Y) を、上記の公開パラメーターにリンクします。






















(3) POSTGIS リーダーフィーチャータイプパラメーター (WHERE Clause)
医療機関の種類 (カンマ区切りのコード) を受け取るパラメーターは、リーダーフィーチャータイプの WHERE Clause から参照します。この設定は Navigator ウィンドウでもできます。


















ワークスペースで以上のような設定をしておけば、アプリケーション側でユーザーが指定した検索条件を FME Server JavaSctipt API のメソッドを通じてワークスペースに渡して実行することができるようになります。

0 件のコメント:

コメントを投稿