2015-08-21

HTML文書の取得と変換

ウェブ上で公開されているデータの多くはファイルダウンロードの方法によって提供されていますが、中にはウェブページ (HTML文書) に記述されたテキストとして提供されているものもあります。
一般的なウェブブラウザはディスプレイに表示されたテキストのコピーをサポートしているので、ウェブページに記述されているデータをテキストエディタやExcelスプレッドシートなどに貼り付けることができます。しかし、頻繁に更新されるデータを継続的に取得したいという場合には、コピー&ペーストの累積的な手間 (コスト) も無視できません。
FMEでは、HTTPCallerによってGET, POSTなどのHTTPリクエストを発行してそのレスポンスを取得できるので、これを利用することにより、HTML文書の取得とデータの変換を自動化できる可能性があります (注)。
ここでは、防災科学技術研究所ウェブサイトで公開されている「Hi-net自動処理震源リスト」 HTML文書の取得と変換を行うワークスペース例を掲げます。
FME 2015.1.1.0 build 15515

注: 個々のウェブサイトに固有のアクセスに関する制約や文書の構造に依存する部分があるので、どのサイトであっても必ず自動化できるとは言えません。

=====
防砂科学技術研究所「Hi-net自動処理震源リスト」の取得から任意のフォーマットでの出力が可能なテーブルへの変換までを自動化する。

ソースデータ:
防災科学技術研究所ウェブサイトで公開されている「Hi-net自動処理震源リスト」 (HTML文書内に記述された固定長フォーマットのテーブル)

ウェブブラウザによるHi-net自動処理震源リストの表示例 (スクリーンショットの一部)












・Hi-net地震観測システムによる自動処理結果 (前日・当日) の震源要素が記述されており、逐次更新される。
・アクセスするにはユーザー登録をし、ユーザー名、パスワードによるログインが必要。
=====

FMEワークスペース例

























Creator: 処理を開始するためのフィーチャー (initiator) を1個作成する。
1. Hi-net自動処理震源リスト (HTML文書) を取得する。
2. HTML文書をXHTML文書に変換のうえリスト本体 (改行区切りの行の集合) を抽出する。
3. テーブルを各行に分割する。
4. 各行を列 (属性値) に分割して適切な属性名を与える。
AttributeRemover: 不要な属性を削除する。

結果: 2015年8月21日午前9時ごろに取得したデータ
上記ワークスペースに VertexCreator を追加し、座標に基づいてポイントを作成しました。
OriginTime: 震源時, OTerr: 震源時誤差(秒),
Lat: 緯度(度), Yerr: 南北誤差, Long: 経度(度), Xerr: 東西誤差(km),
Dep: 深さ(km), Derr: 深さ誤差(km), Mag: マグニチュード




















1. Hi-net自動処理震源リスト (HTML文書) を取得する
3つの HTTPCaller を使い、次の手順によって震源リストページ (HTML文書) を取得しました。これは、ウェブブラウザでログインページにアクセス、ログインしてから震源リストページに移動するという手順と全く同じです。

(1) ログインページにアクセスしてセッションを開始 (GETメソッド)
(2) ログインページにユーザー名とパスワードを送信してログイン (POSTメソッド)
(3) 震源リストページにアクセスし、そのレスポンスとしてHTML文書を取得 (GETメソッド)

ログインの仕組みはサイト固有のもので、ログインページのソースを見るだけで分かる場合と、そうでない場合があります。Hi-net自動処理震源リストは前者だったのでスムースにログインできましたが、後者の場合にはサイト管理者にログインのロジックを開示してもらえるということが自動化の大前提になります。
なお、一般公開ページならば (3) だけでHTML文書が取得できます。

以下は、HTML文書からデータ部分を抽出して任意のフォーマットでの出力が可能なテーブルに変換する処理です。

2. HTML文書をXHTML文書に変換のうえリスト本体 (改行区切りの行の集合) を抽出する
HTML文書にはデータ以外の要素も含まれるため、そこから必要なデータの部分のみを抽出する必要があります。
この例では、HTMLToXHTMLConvertor によってHTML文書をXMLとして解析が可能なXHTML文書に変換したうえで、XMLFragmenter によって震源リスト本体 (改行区切りの固定長フォーマット行の集合) を抽出しました。
関連記事: XMLの読み込み - 断片化と平坦化

3. テーブルを各行に分割する
リスト本体は改行区切りの行の集合 (ひとつの文字列) なので、それを各行に分割して1行1フィーチャー (レコード) に変換します。これは、次の2つのトランスフォーマーで行えます。
AttributeSplitter: 改行文字で分割して各行をリスト属性に格納
ListExploder: リスト属性を展開して1行1フィーチャーに変換
関連記事: 文字列の分割とリスト属性の展開

4. 各行を列 (属性値) に分割して適切な属性名を与える
Tester によって先頭の行 (ヘッダ) を除外した後、AttributeSplitter によって行を列に分割して各列の値をリスト属性に格納し、AttributeCreator によってリストの各要素をそれぞれ適切な名前の属性にコピーしました。リスト属性の要素を非リスト属性に変換するのには、AttributeCopier や AttributeRenamer も使えます。

HTTPCallerはHTML文書の取得だけでなく、ウェブサーバーからのファイルのダウンロードにも使えます。
e-Stat (政府統計の総合窓口) や国土数値情報ダウンロードサービスではデータカタログ情報をXMLあるいはJSON形式で取得するためのAPIの公開が始められていますが、FMEではXMLもJSONも解析できるので、HTTPCallerを使ってカタログ情報の取得からデータダウンロードまでを自動化するワークスペースも作成できそうです。

文字列の処理は複雑に見えるかも知れませんが、変換前の文字列の構造になんらかの規則性があれば、分割、連結、置換などひとつひとつは単純な処理を組み合わせることによってどのようにでも変換できます。そして、一般的なテーブルへの変換までができてしまえば、任意のフォーマットのファイルあるいはデータベースに出力したり、位置情報があればそれに基づいてジオメトリを作成したりすることは容易です。

2015-08-19

CSVに基づくラスターの作成 - 500mメッシュ地形分類

「文字列で記述された位置情報に基づくジオメトリの作成」では文字列で記述された座標値に基づいて矩形ポリゴンを作成するワークスペース例、「メッシュデータのラスター化 - 土地利用細分メッシュ」ではベクター (ポリゴン) データをラスターに変換するワークスペース例を掲載しましたが、それらで使用したトランスフォーマー (2DBoxReplacer, 3DForcer, NumricRasterizer) を組み合わせると、文字列で記述された位置情報からラスターを作成することも可能になります。
ここでは、防災科学技術研究所ウェブサイトで公開されている「500mメッシュ地形分類データ」 (CSV) に基づいてラスターを作成するワークスペース例を掲げます。
FME 2015.1.1.0 build 15515

=====
防災科学技術研究所ウェブサイトで公開されている「500mメッシュ地形分類」 データ (CSV) に基づき、地形分類番号、増幅率の値を画素値とするラスターを作成し、1次メッシュ区画単位の Geotiff 形式ファイルに出力する。

ソースデータ:
防災科学技術研究所 > 地震災害関連ページで公開されている「500mメッシュ地形分類データ」 (CSV形式)
500mメッシュ (1/2細分メッシュ) 区画ごとに、位置座標 (メッシュ区画左下、右上の座標)、標高、地形分類番号、増幅率が記述されている。
データは1次メッシュ区画ごとの CSV ファイルに格納されており、ファイル名先頭4文字が1次メッシュコードである。
CSV テーブルにヘッダ (列名を記述した行) はなく、各列の意味、及び、地形分類番号についてはダウンロードファイル同梱のフォーマット説明文書 (pdf) に記載されている。
=====

FMEワークスペース例
















[CSV] リーダー: 500mメッシュ地形分類データ CSV データを読み込む。
AttributeRenamer: 属性名を変更する (必須ではないが分かり易くするため)。
SubstringExtractor: ソースファイル名 (fme_basename) から1次メッシュコードを抽出する。
2DBoxReplacer: メッシュ区画の左下、右上座標から矩形ポリゴンを作成する。

3DForcer: 地形分類番号をZ値とする3Dポリゴンに変換する。
NumericRasterizer: 3Dポリゴンに基づいてラスターを作成する。
[GEOTIFF] ライター (1): 地形分類番号ラスターを Geotiff ファイルに出力する。

3DForcer_2: 増幅率をZ値とする3Dポリゴンに変換する。
NumericRasterizer_2: 3Dポリゴンに基づいてラスターを作成する。
[GEOTIFF] ライター (2): 増幅率ラスターを Geotiff ファイルに出力する。

結果: FME Data Inspector による表示 (1次メッシュ 5339, 5340, 5439, 5440 区画をモザイク)
左: 地形分類番号 (作成したデータは色情報を持ちませんが、表示する際にパレットを設定して色をつけました)
右: 増幅率 (濃 < 淡)














「500mメッシュ地形分類」 CSVテーブルにはヘッダ (列名の行) がないため、[CSV] リーダーでは1行目からデータを読み込んでいます。ヘッダがない場合、[CSV] リーダーは各列にデフォルトの属性名 (col0, col1, ...) を与えます。また、ファイル名から1次メッシュコードを抽出する都合上、フォーマット属性のひとつ "fme_basename" (拡張子を除くファイル名が格納される) を現しておきました。 
AttributeRenamer は必須ではありませんが、分かり易い属性名に変更しておいた方が何かと便利です。
SubstringExtractor では、ファイル名の先頭4文字 = 1次メッシュコードを抽出して "_primaryMesh" 属性に格納しました。

データにはメッシュ区画の左下、右上の座標 (経度、緯度) が記録されているので、2DBoxReplacer によってメッシュ区画を現す矩形ポリゴンを作成することができます。
その後、データフローを2方向に分岐し、それぞれのフローで 3DForcer によってラスターの画素値とすべき値 (地形分類番号: 0~8 の整数値、増幅率: 実数値) をZ値とする3Dポリゴンに変換したうえで、NumericRasterizer によってラスターを作成します。

NumericRasterizer パラメーター設定画面
左: 地形分類番号、右: 増幅率
























Interpretation Type パラメーターで画素のビット深度を、地形分類番号については 8bit 符号なし整数 (UInt8)、増幅率については 64bit 浮動小数点数 (Real64) に設定したことを除き、2つの NumericRasterizer のパラメーター設定は同じです。
Group By パラメーターに1次メッシュコードを格納した "_primaryMesh" 属性を指定することにより、1次メッシュ区画ごとにラスターを作成することができます。

最後に2つの [GEOTIFF] ライターを追加し、地形分類番号、増幅率別のフォルダにラスターをファイルに出力します。
ライターフィーチャータイププロパティ画面で出力先フィーチャータイプ名 (Raster File Name) に "_primaryMesh" 属性を指定することで、出力先のファイル名が1次メッシュコードになります。

[GEOTIFF] ライターフィーチャータイププロパティ画面 (地形分類番号フォルダ)















煩雑になるのでワークスペース例からは省きましたが、標高を画素値とするラスターも同様に作成することができます。また、ベクター (ポリゴン) データをサポートするGISフォーマット用のライターを追加し、2DBoxReplacer にそのライターフィーチャータイプを接続すれば、メッシュポリゴンをGISデータファイルに出力することもできます。

2015-08-17

境界ラインに基づく面の作成

面の境界 (boundary) を表すラインデータがあれば、AreaBuilder によってその境界内部の面を作成 (復元) することができます。
ここでは、特定の行政区画について、基盤地図情報の行政区画界線データに基づき、出典地図情報レベル (出典地図の縮尺) 別に面データを作成するワークスペース例を掲げます。
FME 2015.1.10 build 15515

=====
基盤地図情報の行政区画界線データに基づき、C県K市 (団体コード 12217) の行政区画の面を出典地図情報レベル別に作成する。

ソースデータ:
基盤地図情報ダウンロードサービスサイトよりダウンロードしたC県K市の行政区画界線、行政区画代表点データ。
出典地図情報レベル (2500 または 25000) は、行政区画界線、代表点ともに orgGILvl 属性に格納されている。
団体コードは、代表点の admCode 属性に格納されている。
=====

FMEワークスペース例

















[GML] リーダー: 基盤地図情報行政区画線 (AdmBdry) と行政区画代表点 (AdmPt) を読み込む。
Tester: 対象とする行政区画 (admCode = 12217) の代表点を抽出する。
AreaBuilder: 出典地図情報レベル (orgGILvl) 別に面を作成する。
SpatialFilter: 対象とする行政区画の面を抽出するとともに、代表点の属性を面に結合する。
AttributeKeeper: 不要な属性を削除する (必要な属性のみ残す)。
Inspector: 結果を FME Data Inspector で表示する。

結果: C県K市の一部
境界は出典地図情報レベルによって異なる (水色: 2500, 黄色: 25000)














FME は基盤地図情報の応用スキーマ定義ファイル "FGD_GMLSchemaV4.0.xsd" をバンドルしており、基本項目については特別なパラメーター設定などをせずに [GML] リーダーで読み込むことができます。
リーダーを追加するとき、Add Reader 画面で Dataset として行政区画界線 (ファイル名に AdmBdry が含まれる) と行政区画代表点 (同 AdmPt) のデータファイルを選択し、OK ボタンで閉じたときに表示されるフィーチャータイプ選択画面で AdmBdry と AdmPt を選択すると、それらのフィーチャータイプがキャンバスに現れます。

Select Feature Types 画面 (Add Reader を OK で閉じたときに AdmBdry と AdmPt を選択)

















AreaBuilder は、端点同士で接しているラインがある領域を取り囲んでいる場合、それらのラインを境界とする面を作成します。

AreaBuilder 処理イメージ (FME ヘルプより引用)










基盤地図情報の行政区画界線データファイルには、出典地図情報レベル (orgGILvl: 2500 または 25000) が異なるラインデータが格納されていますが、Group By パラメーターに orgGILvl 属性を設定することによってレベル別に面を作成することができます。

AreaBuilder パラメーター設定画面























行政区画代表点 (AdmPt) については、まず、Tester で対象とするC県K市 (admCode = 12217) の代表点のみを抽出しました。そのうえで、SpatialFilter によってその代表点が含まれる面を選択します。
SpatialFilter は、Candidate ポートから入力したフィーチャーのうち、Filter ポートから入力したフィーチャーとの間で Tests to Perform パラメーターに指定した空間的関係 (この例では Within) があったものを Passed ポート、関係がなかったものを Failed ポートから出力します (「ジオメトリ間の空間的関係」参照)。
また、Merge Attributes パラメーターに Yes (デフォルト) を設定した場合は、Passed ポートから出力するフィーチャーに関係があった Filter フィーチャーの属性を付加します。これにより、代表点が持っている市区町村名 (name) と団体コード (admCode) 属性を面に付加しました。

SpatialFilter パラメーター設定画面


























基盤地図情報の行政区画線データでは、同じ出典地図情報レベルのラインは必ず端点同士で接しているので、AreaBuilder で簡単に面を作成することができましたが、ラインの端点同士が接していることが保証されないデータでも、Snapping Type 及び Snapping Tolerance パラメーターの設定によって近接する端点を一致させたり、Intersector または TopologyBuilder によって交点で分割するといった前処理を加えたりすれば、AreaBuilder によって面が作成できるケースはあります。

紙地図に基づいて新たな面データを作成するような場合に、デジタイズの工程では境界ライン (属性なし) と代表点 (属性あり) を作成しておき、AreaBuilder と SpatialFilter によって面データに変換するという手順も考えられます。

2015-08-12

TIN (不規則三角網) の作成

不規則に分布する多数の地点についてある現象の観測値が与えられたとき、その現象の全体的な傾向を可視化したり任意の地点の値を推定したりするために、観測地点を頂点 (Z = 観測値) とする TIN (Triangulated Irregular Network: 不規則三角網) を作成するのが有効な場合があります。
FME では、TINGenerator または SurfaceModeller トランスフォーマーによって 3D ジオメトリや点群 (ポイントクラウド) に基づいて TIN を作成することができます。
ここでは、原子力規制委員会が公表している空間線量率の測定結果について、TINGenerator によって TIN を作成するワークスペース例を掲げます。
FME 2015.1.1.0 build 15515

=====
2011年3月以降、福島第一原子力発電所周辺の地域において不規則に分布する地点で測定された空間線量率についてCSV形式で整理された表に基づき、各年の測定結果を TIN に変換する。
・測定地点ごとに、年数回の測定結果のうち各年最後の測定結果をその年の値とする。
・同じ1/10細分メッシュ区画に含まれる地点は同一の測定地点であるとみなす。

ソースデータ:
放射線モニタリング情報 原子力規制委員会
モニタリング結果 > 環境モニタリング一般等 > 空間線量率等 > 空間線量率、積算線量
空間線量率の測定結果
・東京電力株式会社福島第一原子力発電所の20km圏内の空間線量率の測定結果(電力会社による測定) (CSV)
・東京電力株式会社福島第一原子力発電所の20km以遠の空間線量率の測定結果 (CSV)
ダウンロードファイル名: inside_20km_airdose.csv, outer_20km_airdose.csv
2011年3月以降の測定日順で、各測定地点の測定日、座標 (緯度, 経度)、地上1m高さの空間線量率等が記録されている。
=====

FMEワークスペース例

















[CSV] リーダー: 測定結果を記録した CSV テーブル (2表: 20km圏内, 20km以遠) を読み込む。
VertexCreator: 測定地点座標 (X, Y)、測定結果 (Z) に基づき 3D ポイントを作成する。
JpMeshCodeExtractor: 各測定地点の 1/10 細分メッシュコードを取得する。
SubstringExtractor: 測定日 (年月日文字列) から年 (先頭4文字) を抽出する。
Sorter: CSV行番号の降順 (測定日が新しい順) でソートする。
DuplicateRemover: 測定地点 (1/10細分メッシュ) 別・年別に最初に現れるポイントを抽出する。
Reprojector: 投影座標系に変換する。
Scaler: Z 座標値 (空間線量率測定結果) を 100 倍する (可視化したときに起伏を強調するため)。
TINGenerator: 年別の TIN を作成する。
Inspector: FME Data Inspector で結果 (TINの辺、三角形、サーフェスモデル) を表示する。

結果: FME Data Inspector による 3D 表示 (3種類×4年分の個別表示結果を合成した画像)
上段: TINの辺 (3Dライン), 中段: 三角形 (3Dポリゴン) によるTINの表現, 下段: TINサーフェス



















ソースデータには、2011年3月以降、各測定地点の年数回の測定結果が記録されていますが、一部の測定地点では、測定日によってデータに記述されている座標が若干異なるものがあります。また、福島第一原子力発電所の20km圏内のデータでは地点を特定するための属性がありません。
そこで、このワークスペース例では、同一の1/10細分メッシュ区画内にある地点は同一の測定地点であるとみなすことにし、次の手順で測定地点 (1/10細分メッシュ) 別・年別に、各年最後の測定結果のポイントを抽出しました。

(1) [CSV] リーダーフィーチャータイプ: csv_line_number を現す (Expose)。
csv_line_number は [CSV] リーダーが各フィーチャーに与えるフォーマット属性のひとつで、CSVテーブルの行番号を格納します。CSVテーブルには測定日の順にデータが記録されているので、行番号の順 = 測定日の順とみなすことができます。

(2) VertexCreator: 測定地点と測定値を表す 3D ポイントを作成する。
X: 経度, Y: 緯度, Z: 空間線量率測定値

(3) JpMeshCodeExtractor: 1/10細分メッシュコードを取得する。
JpMeshCodeExtractor は FME Store で公開しているカスタムトランスフォーマーで、入力フィーチャーのジオメトリの最初の頂点を含むメッシュ区画のメッシュコードをフィーチャーに属性 (_meshcode) として付加します。
参考: FMEサポート | 国内データ変換のサポート

(4) SubstringExtractor: 測定日 (年月日文字列) から年 (先頭4文字) を抽出する。
各レコードの測定日フィールドには測定日が yyyy/m/d 形式の文字列で記録されているので、その先頭4文字を抽出してフィーチャーに属性 (_year) として付加します。

(5) Sorter: CSV行番号 (csv_line_number) の降順でフィーチャーをソートする。
これにより、フィーチャーの順番が測定日の降順 (新しい順) になります。

(6) DuplicateRemover: _meshcode, _year の重複を削除する。
測定日の降順でソートしたので、これによって測定地点 (1/10細分メッシュコードが同じ地点) ごとに、各年最後のフィーチャーが Unique ポートから出力されます。

DuplicateRemover の Unique ポートから出力されるポイントについて、Reprojector によって投影座標系に変換、可視化したときに起伏が強調されるように Scaler によって Z 座標 (空間線量率測定結果) を 100 倍してから、TINGenerator によって TIN を作成します。

TINGenerator は、入力フィーチャーのジオメトリ各頂点を頂点とするドロネー三角形を生成し、それらの辺 (3Dライン) を TINEdges ポート、三角形 (3Dポリゴン) を Triangles ポート、TINサーフェスを TINSurface ポート、頂点 (3Dポイント) を VertexPoints ポートから出力します。

TINGenerator パラメーター設定画面

















Group By: _year
年別に TIN を作成するため、年を格納した属性 (_year) を指定しました。

Surface Tolerance: 0
0 を指定すると全てのポイントが TIN の頂点として使われます。
このパラメーターに 0 より大きい値を設定した場合は、次のルールによってポイントの「間引き」が行われます。
  • ポイントの位置 (x, y) が、先に入力されたポイントによって形成された TIN の 2D 凸包 (Convex Hull) の外部にあるとき、そのポイントは TIN の頂点として追加される。
  • そうでないときは、
    • 入力ポイントの Z 座標値と、先に入力されたポイントによって形成された TIN 上の入力ポイントの位置 (x, y) における Z 値 (内挿補間値) の差を求める。
    • その差が Surface Tolerance パラメーターに設定された値よりも大きければ入力ポイントは TIN の頂点として追加され、そうでなければ破棄される。

ワークスペース例では結果を FME Data Inspector で表示しただけですが、適当なフォーマットのライターをワークスペースに追加すれば、結果をファイルに出力することができます。

2015-08-08

ジオメトリの空間的関係の判定と属性結合

SpatialRelator トランスフォーマーを使うことにより、次の表に掲げるジオメトリ間の空間的関係の判定とそれに基づく属性の結合を行うことができます。

Spatial Relations空間的関係
INTERSECTS CONTAINS 含む 交わる (離れていない)
CROSSES 横切る
EQUALS 等しい
OVERLAPS 重なる
TOUCHES 接する
WITHIN 含まれる

ジオメトリ間の空間的関係としての INTERSECTS (交わる) は、CONTAINS, CROSSES, EQUALS, OVERLAPS, TOUCHES, WITHIN のうちのひとつ以上が成り立つ関係を指し、線と線または線と面の境界が交差している関係を指す CROSSES (横切る) とは区別します。
ここでは、国土数値情報の「鉄道 - 駅」 データ (線) と「行政区域」データ (面) の空間的関係に基づき、各駅に行政区域コードと所在地 (都道府県名, 郡・政令都市名, 市区町村名) の属性を与えるワークスペース例を掲げます。
FME 2015.1.1.0 build 15515

=====
国土数値情報「鉄道 - 駅」データ (線) の各駅に、所在する市区町村の「行政区域コード」と「所在地」属性を追加したデータを作成する。
1) 駅が市区町村に含まれる、または、市区町村の境界を横切る場合に、その市区町村に所在するものとする。
2) 「所在地」は、都道府県名、郡・政令都市名、市区町村名を半角スペース区切りで連結した文字列とする。
3) 複数の市区町村にまたがる駅の行政区域コードと所在地は、関係がある全ての市区町村のそれらの値をカンマ区切りで連結した文字列とする。
4) どの市区町村とも空間的関係がない駅の所在地は最も近い市区町村であるとみなす。

ソースデータ: 国土数値情報ダウンロードサービスサイトよりダウンロードした次のデータ。
(1) 鉄道駅: 「鉄道 (平成26年度)」の「駅」 (線) データ (Shapefile 形式, 全国1ファイル)
(2) 行政区域: 「行政区域 (平成27年1月1日時点)」 (面) データ (Shapefile 形式, 都道府県別47ファイル)
=====

FMEワークスペース例





















[SHAPE] リーダー (鉄道駅): 国土数値情報「鉄道 - 駅」 (面) データを読み込む。
AttributeRenamer: 属性名を変更する。

[SHAPE] リーダー (行政区域): 国土数値情報「行政区域」 (面) データを読み込む。
AttributeRenamer_2: 属性名を変更する。
StringConcatenator: 都道府県名, 郡・政令都市名, 市区町村名をカンマ区切りで連結した文字列を作成し、「所在地」属性に格納する。
StringReplacer: 「所在地」属性文字列中の1個以上の連続するカンマをスペースに置換する。
AttributeTrimmer: 「所在地」属性文字列の前後の余分なスペースを削除する。
AttributeKeeper: 不要な属性を削除する (必要な属性のみ残す)。

SpatialRelator: 空間的関係 (CROSSES, WITHIN) がある市区町村の属性を鉄道駅に結合する。
TestFilter: 空間的関係がある市区町村数 (複数, 1, 0) に応じてデータフローを分岐する。

(複数の市区町村と空間的関係があった鉄道駅について)
ListConcatenator: 複数の行政区域コードをカンマ区切りで連結し、「行政区域コード」属性を更新する。
ListConcatenator_2: 複数の所在地をカンマ区切りで連結し、「所在地」属性を更新する。

(どの市区町村とも空間的関係がなかった鉄道駅について)
NeighborFinder: 最も近い市区町村の属性を鉄道駅に与える。

[MITAB] ライター: MapInfo (TAB) 形式ファイルに出力する。

結果: JR東日本上野駅~日暮里駅付近 (FME Data Inspector による表示)
・駅 (青色の線) は、分かり易いように若干量のバッファ (面) に変換してから表示したものです。
・背景画像は MapQuest Web Map Tile Service (Open Street Map) を利用しました。


















国土数値情報「行政区域」データの属性テーブルには都道府県名、郡・政令都市名、市区町村名のフィールドがありますが、政令都市以外の市の「郡・政令都市名」、東京23区の「市区町村名」はブランク (空文字列) です (東京23区の区名は「郡・政令都市名」フィールドに記録されている)。
そのため、都道府県名、郡・政令都市名、市区町村名をスペース区切りで連結しただけでは、政令都市以外の市では都道府県名と市名の間にスペースが2個はさまり、東京23区では末尾に余分なスペースが付加されてしまいます。
これを回避するため、まず、StringConcatenator で都道府県名、郡・政令都市名、市区町村名をカンマ区切りで連結しておき、StringReplacer で1個以上の連続するカンマを半角スペース1個で置き換え、末尾の余分なスペースを AttributeTrimmer で削除しました。

左: StringConcatenator, 右: StringReplacer パラメーター設定画面
StringReplacer パラメーター
Text to Match: ,+  (1個以上の連続するカンマと一致する正規表現)
Replacement Text:   (半角スペース1個)
Use Regular Expressions: yes  (正規表現を使用する)














SpatialRelator は2つの入力ポート - Requestor と Supplier を持ち、Requestor フィーチャーに対する Supplier フィーチャーの空間的関係を判定し、その結果を属性として付加した Requestor を出力します。ひとつ以上の Supplier と空間的関係があった Requestor には、 関係があった Supplier の属性も結合されます。

SpatialRelator パラメーター設定画面





















Tests to Perform: CROSSES WITHIN
Requestor (鉄道駅) が Supplier (行政区域) に含まれる (WITHIN)、または、Supplier (行政区域) の境界を横切る (CROSSES) かどうかを調べます。
鉄道駅 (線) が行政区域 (面) に接する場合も「所在」の定義に含むという場合には、TOUCHES を加えるか、または、INTERSECTS を選択します。

List Name: _relationships
Tests to Perform パラメーターで指定した空間的関係があった全ての Supplier (行政区域) の属性 (行政区域コード、所在地) を、このパラメーターに指定した名前の構造化リスト (_relationshipts{}.<属性名>) に格納して Requestor (鉄道駅) に付加します。
構造化リストについては「文字列の分割とリスト属性の展開」の補足を参照してください。

Related Suppliers Count Attribute: _related_candidates
Tests to Perform パラメーターで指定した空間的関係があった Supplier (行政区域) の数を、このパラメーターに指定した名前の属性 (_related_candidates) に格納して Requestor (鉄道駅) に付加します。


TestFilter によって、SpatialRelator から出力される鉄道駅フィーチャーを "_related_candidates" 属性の値に応じて次の3つの出力ポートに振り分けます。
[Multiple] 複数の市区町村と空間的関係があった駅 (If 1 < _related_candidates)
[Single] ひとつ市区町村だけと空間的関係があった駅 (Else If 0 < _related_candidates)
[None] どの市区町村とも空間的関係がなかった駅 (Else)

TestFilter パラメーター設定画面




















[Multiple] ListConcatenator によって複数の市区町村の行政区域コード、所在地をカンマ区切りで連結してからライターフィーチャータイプに接続

ListConcatenator パラメーター設定画面 (左: 行政区域コード連結, 右: 所在地連結)














[Single] そのままライターフィーチャータイプに接続

[None] NeighborFinder によって最も近い市区町村の属性を結合したうえでライターフィーチャータイプに接続
実データでは2駅がこのケースに該当しました。行政区域 (面) データが存在しない海上にある駅と思われます。

NeighborFinder パラメーター設定画面 (デフォルトの設定)

























NeighborFinder は、デフォルトでは2つの入力ポート - Base と Candidate を持ち、最も近い Candidate フィーチャーの属性を結合した Base フィーチャーを Matched ポートから出力します。このワークスペース例ではデフォルトの設定で使いました。
この他にも NeighborFinder にはさまざまな機能、使い方がありますが、それらについては別の記事で取り上げたいと思います。

2015-08-07

面と面の重なりの抽出

AreaOnAreaOverlayer トランスフォーマーによって複数の面が重なり合う部分を抽出し、元の面を重なり合った部分とそうでない部分に分割し、重なり合った部分を重複のないひとつの面に変換することができます。

AreaOnAreaOverlayer 処理イメージ (FME Desktop Help / FME Transformers より)







このトランスフォーマーを使い、台風の降雨による浸水域を表すポリゴンを浸水回数別のポリゴンに変換するワークスペース例を掲げます。
FME 2015.1.1.0 build 15515

=====
台風の降雨による浸水域 (時期別) のポリゴンデータに基づき、浸水回数別のポリゴンを作成する。
分割後のポリゴンには、浸水回数 (重なり合った時期別浸水域の数) 、それらの時期 (年月日) をカンマ区切りで連結した文字列を属性として与える。

ソースデータ:
国土交通省 国土調査「土地分類調査・水調査 > GISデータのダウンロード」ページよりダウンロードした土地分類基本調査「土地履歴調査 GIS データ」のうち、「災害履歴図 (風水害)」データ (Shapefile 形式ポリゴン)
過去の複数回の台風の降雨による浸水域が記録されている。
属性定義はダウンロードファイル同梱の「土地履歴調査の公開用数値地図データ仕様について」 (PDF) 参照
=====

FMEワークスペース例
















[SHAPE] リーダー: 「災害履歴図 (風水害)」 Shape ファイルを読み込む。
Tester: "name" (災害種別等) 属性が「浸水域」に該当するフィーチャーを抽出する。
AreaOnAreaOverlayer: 浸水域ポリゴンを、相互に重なり合う部分とそうでない部分に分割する。
ListSorter: 元の浸水域の属性を格納したリスト要素を "date" (年月日) 属性でソートする。
ListConcatenator: 元の浸水域の "date" 属性をカンマ区切りで連結した文字列属性を作成する。
[SHAPE] ライター: 処理後の浸水域フィーチャーを Shapefile 形式のファイルに出力する。

結果: 浸水回数 (重なり合った時期別浸水域の数) 別に色分け表示した例 (FME Data Inspector)
防災計画検討の参考になるかも知れません。
















結果: 属性テーブル (FME Data Inspector)
count: 浸水回数 (重なり合った時期別浸水域の数), date: カンマ区切りの浸水時期 (年月日)























AreaOnAreaOverlayer は、入力フィーチャーのジオメトリ (面) が重なり合う部分を抽出して重なり合った部分とそうでない部分に分割し、重なり合った部分を重複のないひとつの面に変換します。
分割後のフィーチャーには、重なり合った面の数を格納した属性が付加されるとともに、List Name パラメーターを指定した場合は、元の面が持っていた全ての属性を格納したリスト属性 (構造化リスト) も付加されます。
構造化リストについては、「文字列の分割とリスト属性の展開」の補足も参照してください。

AreaOnAreaOverlayer パラメーター設定画面


















Overlap Count Attribute: count
重なり合った面の数 (重なりがなかった部分では「1」) を格納する属性名を指定します。

List Name: _list
元の面が持っていた属性を格納するリスト属性名を指定します (オプション)。

AreaOnAreaOverlayer の List Name パラメーターを設定したので、入力フィーチャーが持っていた全ての属性が構造化リスト "_list{}.<元の属性名>" に格納され、処理後のフィーチャーに付加されます。
ListSorter によってその要素を "date" (年月日) の昇順でソートしたうえで、ListConcatenator によって年月日をカンマ区切りで連結した文字列を作成し、"date" 属性に格納しました。

複数のジオメトリを重ね合わせて行う処理を一般にオーバーレイ (overlay) と言っており、ジオメトリタイプに応じて次のトランスフォーマーが用意されています。詳細についてはそれぞれのヘルプを参照してください。

PointOnPointOverlayer 点と点のオーバーレイ
PointOnLineOverlayer 点と線のオーバーレイ
PointOnAreaOverlayer 点と面のオーバーレイ
LineOnLineOverlayer 線と線のオーバーレイ
LineOnAreaOverlayer 線と面のオーバーレイ
AreaOnAreaOverlayer 面と面のオーバーレイ

2015-08-03

集約と集計

複数のフィーチャーを束ねてひとつのフィーチャーにまとめることを「集約」 (aggregate) と言います。複数のシングルパートのジオメトリをひとつのマルチパートのジオメトリに変換することは、集約の典型例です。

FME では Aggregator トランスフォーマーによって集約が行えますが、このトランスフォーマーはジオメトリを集約するだけでなく、集約前のフィーチャーが持っていた属性値の集計等を行うオプション機能も持っています。

ここでは、国土数値情報「人口集中地区 (DID)」データ  (ポリゴン) を使い、各人口集中地区のシングルパートポリゴンを市区町村ごとのマルチパートポリゴンに集約するのとあわせて、人口集中地区の人口、面積を市区町村単位で集計して集約後のフィーチャーに付加するワークスペース例を掲げます。

FME 2015.1.1.0 build 15515

=====
国土数値情報「人口集中地区 (DID)」データに基づき、市区町村ごとに DID 人口、面積を集計する。

ソースデータ:
国土数値情報ダウンロードサービスサイトよりダウンロードした「人口集中地区 (DID)」データ (Shapefile 形式ポリゴン)

各DIDには、属性としてユニークなIDが与えられている。
飛び地があるDIDは複数のシングルパートポリゴンに分割されているが、各パートの人口、面積等の属性にはそのDID全体の値が格納されている (パートごとの値ではない)。
次の表の千葉市中央区の DID (DIDid=121011) は 3 つのパートに分割されている例であり、千葉市花見川区は1市区町村内に複数の DID (DIDid=121021, 121022, 121023, 121024) がある例である。

ソースデータ: FME Data Inspector による表示 (平成22年 千葉県の例)














=====

FMEワークスペース例












[SHAPE] リーダー: 国土数値情報「DID」データ (シングルパートポリゴン) を読み込む。
AttributeRenamer: 属性名を変更する。
DuplicateRemover: DIDid がユニークなフィーチャーと重複するフィーチャーに分離する。
AttributeCreator: DIDid が重複するフィーチャーの人口、面積の値を 0 にする。
Aggregator: 市区町村ごとにジオメトリを集約するとともに、人口、面積を集計する。
Sorter: 市区町村コード順にソートする。
[MITAB] ライター: MapInfo (TAB) 形式のファイルに出力する。

結果: FME Data Inspector による表示 (平成22年 千葉県の例)






















後述するように Aggregator は集約前のフィーチャーの属性値を集計する機能を持っていますが、国土数値情報「人口集中地区 (DID)」データでは、ひとつのDIDが複数のフィーチャー (パート) に分かれている場合に、各パートの人口等の属性にはパートごとの値ではなくそのDID全体の値が格納されているため、そのまま集計すると過大な値になってしまいます (Nパートの DID の人口等の値はN倍になる)。
これを回避するために、このワークスペース例では、DuplicateRemover によって、入力順に初めて現れるIDを持つフィーチャー (Unique) と2回目以降のフィーチャー (Duplicate) に分離し、AttributeCreator によって2回目以降のフィーチャーの人口と面積の値を 0 にしました。

このような前処理をしたうえで、Aggregator によって入力フィーチャーを集約します。

Aggregator パラメーター設定画面


























Group By: 市区町村コード 市区町村名
「市区町村コード」と「市区町村名」によって入力フィーチャーをグループ化します。

Mode: Geometry - Assemble One Level
入力フィーチャーが持っているジオメトリをグループ (市区町村) ごとに1階層で集約します (シングルパートポリゴンを市区町村ごとのマルチパートポリゴンにする)。

Keep Input Attributes: No
Group By パラメーターに指定した属性以外は維持しません。

Attributes to Sum: DID人口 DID面積
入力フィーチャーの「DID人口」属性と「DID面積」属性の値をグループ (市区町村) ごとに集計し、集約後のフィーチャーに属性として付加します。その属性名は、集約前のフィーチャーが持っていた属性名と同じになります。

なお、フィーチャーの入力順が Group By パラメーターで指定した属性値の昇順または降順であることが保証される場合は、Input is Ordered by Group パラメーターを Yes に設定することで効率が良くなります。また、その場合の出力順はグループの入力順と同じになるので、Sorter を省くことができます。

Aggregator の 属性処理オプション
Aggregator パラメーター設定画面の Attribute Accumulation グループでは、属性の処理について次のようなオプションが設定できます。

Keep Input Attributes:
"Yes" を選択したときは、入力フィーチャーの属性が集約後のフィーチャーに引き継がれます。グループ内で異なる値が現れる属性については、入力順で最初の値が維持されます。
"No" を選択したときは、Group By パラメーターに指定した属性以外の属性が破棄されます。
ただし、いずれの場合でも、後述の連結、集計等を行った属性には、連結、集計等の結果が格納されます。

FME 2016.1 以降では、Accumulation Mode パラメーターによって、Keep Input Attributes パラメーターと同等の設定ができます。新旧パラメーターの選択肢は、次の表に示すように対応しています。
Keep Input Attributes (FME 2016.0 以前) 選択肢Accumulation Mode (FME 2016.1 以降) 選択肢
NoDrop Incoming Attributes
YesMerge Incoming Attributes
(該当なし)Get Attributes from One Representative Feature
FME 2016.1 で追加された "Get Attributes from One Representative Feature" を指定した場合は、同一グループに属する入力フィーチャーのうち、最初に入力されたものの属性のみが集約後のフィーチャーに引き継がれます。

List Name:
リスト属性名を指定したときは、グループ内の全てのフィーチャーの属性を格納した構造化リストが集約後のフィーチャーに付加されます。「構造化リスト」については「文字列の分割とリスト属性の展開」の補足を参照してください。

Attributes to Concatenate (連結):
このパラメーターで指定した属性については、グループ内の全てのフィーチャーの属性値を "Separator Character" で指定した区切り文字(列) で連結した文字列を作成し、集約後のフィーチャーに属性として付加します。その属性名は、パラメーターに指定した属性名と同じになります (以下のパラメーターについても同じ)。

Attributes to Sum (集計):
このパラメーターで指定した属性については、グループ内の全てのフィーチャーの属性値の合計を求め、集約後のフィーチャーに属性として付加します。

Attributes to Average (平均):
このパラメーターで指定した属性については、グループ内の全てのフィーチャーの属性値の平均値を求め、集約後のフィーチャーに属性として付加します。

Attribute to Average, Weighted by Area (面積加重平均):
このパラメーターで指定した属性については、グループ内の全てのフィーチャーの属性値の面積加重平均値を求め、集約後のフィーチャーに属性として付加します。
※入力フィーチャーのジオメトリタイプが Area である場合のみ

同じ属性を連結、集計、平均、面積加重平均の2つ以上に同時に指定することは想定されておらず、その場合の結果は仕様として明示されていません。同じ属性について複数の処理をしたいときは、事前に AttributeCopier によって別の名前の属性に値をコピーし、異なる属性名によってそれらの処理を行ってください。

=====
2015-08-04追記: リスト属性 (構造化リスト) を利用した別案

Aggregator の List Name パラメーターにリスト属性名を指定して集約前のフィーチャーの全属性を構造化リストに格納し、リスト操作によって集計をする方法もあります。

FMEワークスペース例
















Aggregator: 市区町村ごとにフィーチャーを集約し、集約前のフィーチャーの属性を構造化リストに格納する。
ListDuplicateRemover: リストから DIDid が重複する要素を削除する。
ListSummer: DID人口を集計する。
ListSummer_2: DID面積を集計する。

ListDuplicateRemover は、指定したリスト属性から重複する要素を削除してユニークな要素のみにします。このトランスフォーマーによって構造化リストのメンバー (この例では "_list{}.DIDid") から重複要素を削除した場合には、そのリストの他のメンバー ("_list{}.DID人口", "_list{}.DID面積" など) からも対応する要素が削除されます。
ListSummer は、Source List Name パラメーターに指定されたリスト属性 (構造化リストの場合はそのメンバー) の全要素の合計値を求めて、Sum Attribute パラメーターに指定された名前の属性に格納します。数値として解釈できない要素の値は 0 と見なされます。