2016-06-16

GeoJSON の変換 - 国土地理院「ベクトルタイル提供実験」地形分類

GeoJSON は JSON (JavaScript Object Notation) の仕様に基づく地理空間データフォーマットです。GML などの XML ベースのフォーマットよりも軽量 (同じ情報量に対するデータサイズが小さい) であるとともに、JavaScript で扱い易いため、ネットワーク経由で地理空間データを配信するために広く利用されています。OGC (Open Geospatial Consortium) の規格ではありませんが、ウェブアプリケーションで地理空間データを扱う場合の事実上の標準フォーマットと言って良いと思います。

FME では、XML と同様に Fragmentation (断片化) と Flattening (平坦化) という2つの手法によって、任意の JSON ドキュメントからメンバーや値を抽出することができます。断片化、平坦化については「XMLの読込 - 断片化と平坦化」も参照してください。

ここでは、国土地理院「ベクトルタイル提供実験」において GeoJSON 形式で公開されている「地形分類」データについて、一般のGISソフトウェア等で利用可能なデータ (ジオメトリと属性) に変換するワークスペース例を掲げます。

データは、国土地理院「ベクトルタイル提供実験」地形分類 (GitHub) に掲載されているサンプルデータの URL から直接読み込むこととします。

なお、「地理院タイルデータの取得 - 西之島付近噴火活動 正射画像の例」「ベクタージオメトリの色 - 国土地理院「地形分類」」で地理院タイルデータを取得・変換する JpGsiTileFetcher カスタムトランスフォーマーを紹介しましたが、その実装においてベクトルタイルを取得・変換する部分は、基本的には今回のワークスペース例と同じです。

FME 2016.1.0.1 build 16494


FMEワークスペース例





















Creator: 処理開始用のフィーチャーを1個作成する。
HTTPCaller: HTTPプロトコル (Get メソッド) によってサンプル GeoJSON ドキュメントを取得する。
JSONFragmenter: GeoJSON ドキュメントを断片化して個別のフィーチャーに分解する。
JSONFlattener: 各フィーチャーを平坦化して "geometry" と "properties" メンバーを抽出する。
GeometryReplacer: "geometry" メンバーに基づいてジオメトリ (ポリゴン) を作成する。
JSONFlattener_2: "properties" メンバーを平坦化して下位のメンバー (属性) "code" を抽出する。

2017-08-25: FME 2017.1.1 では JSONFragmenter に Fragment as Format パラメーターが追加されました。そのパラメーターに "GEOJSON" を選択することにより、GeoJSON ドキュメントに基づいてジオメトリと属性を持つフィーチャーを作成することができます。
FME 2017.1.1 のワークスペース例は、本文末尾に掲載します。

HTTPCaller は、Request URL パラメーターに指定した URL に対して HTTP Method パラメーターで選択したメソッドのリクエストを発行し、レスポンスとして得られたデータを属性 (_response_body) に格納します。この場合は、サンプルデータとして提供されている「地形分類」 GeoJSON ドキュメントが _response_body に格納されます。

ひとつの GeoJSON ドキュメントには "features" という名前の配列が含まれており、その要素としてひとつ以上のフィーチャーオブジェクトが格納されています。各フィーチャーオブジェクトには "goemetry" と "properties" というメンバーオブジェクトが含まれており、それらによってフィーチャーのジオメトリと属性セットが表されます。

国土地理院「ベクトルタイル提供実験」地形分類データ (GeoJSON) の構造
分かり易くするために改行、インデントをつけました。
{
    "type": "FeatureCollection",
    "features": [
        {
            "geometry": {
                "type": "Polygon",
                "coordinates": [ <座標値の配列。詳細略> ]
            },
            "type": "Feature",
            "properties": {
                "code": 10714
            }
        },
        {
            "geometry": {
                "type": "Polygon",
                "coordinates": [ <座標値の配列。詳細略> ]
            },
            "type": "Feature",
            "properties": {
                "code": 11000
            }
        },
        <中略>
    ]
}

断片化 JSONFragmenter

JSONFragmenter の JSON Query パラメーターに次のクエリを設定することにより、このJSON オブジェクトを "features" 配列に格納されている個別のオブジェクト (フィーチャー) に分解することができます。
----------
JSON Query: json["features"][*]
----------
ここで、'json' は JSON ドキュメントのルートを示し、それに続く [ ] で下位の各階層のどのメンバー/要素を処理の対象とするかを指定することができます。[*] (アスタリスク) はその階層における任意のメンバー/要素を示すので、このクエリによって、"features" 配列の全ての要素 (フィーチャー) を JSON オブジェクトの断片として取り出すことができます。本記事作成時点で公開されていたサンプルデータには、58個のフィーチャーが格納されていました。

"features" 配列の要素 (JSON オブジェクトの断片)
{
    "geometry": {
        "type": "Polygon",
        "coordinates": [ <座標値の配列。詳細略> ]
    },
    "type": "Feature",
    "properties": {
        "code": 10714
    }
}

平坦化 JSONFlattener (1)

JSONFlattener によってオブジェクト (フィーチャー) を平坦化して "geometry" オブジェクトと "properties" オブジェクトを属性として抽出するとともに、Attributes to Expose パラメーターでそれらの名前を指定することにより、ワークベンチのインターフェース上に現しました。

Recursively Flatten Objects/Arrays を Yes に設定すると、下位にある全てのオブジェクト/配列を再帰的に平坦化して属性として抽出できますが、ここでは No に設定し、再帰的な平坦化は行いません。

GeoJSON フォーマットで記述されている "geometry" オブジェクトは次の GeometryReplacer によって直接ジオメトリデータに変換することができるので、その下位にある "coordinates" 配列のひとつひとつの要素 (ジオメトリを構成する個々の頂点の座標値) を個別の属性として抽出する必要はないためです。"properties" オブジェクトの平坦化 (個別属性の抽出) は、2番目の JSONFlattener で行います。

ジオメトリの作成 GeometryReplacer と平坦化 JSONFlattener (2)

GeometryReplacer (Geometry Encoding: GeoJSON) によって "geometry" オブジェクトをジオメトリデータ (この例ではポリゴン) に変換し、2番目の JSONFlattener によって "properties" オブジェクトを平坦化して下位のメンバー = 個別属性 (この例では "code" のみ) を抽出しました。GeometryReplacer と 2番目の JSONFlattener は順不同です。


変換結果: FME Data Inspector による表示



























座標系について

上記ワークスペース例で作成されるフィーチャーには、座標系が定義されません。

GeoJSON の仕様(2017-08-25 注参照)では、"crs" という名前のメンバーオブジェクトによって空間参照系 (coordinate reference system) を定義することもできるのですが、 サンプルデータには "crs" は含まれていませんでした。"crs" が省略されている場合は、デフォルトの地理空間参照系 = WGS84 測地系 (十進緯度経度) であると解釈すべきとされています。

したがって、上記ワークスペース例に CoordinateSystemSetter を追加して WGS84 緯度経度の座標系 (LL84) を設定すれば、地理空間データとして完全になります。

2017-08-25 注: GeoJSONの最新の仕様では、"crs"メンバーについての規定は削除されており、ジオメトリの座標はWGS84測地系の十進緯度経度で記述することに統一されています。


GEOJSON リーダーによる GeoJSON ドキュメントの読込

FME は GeoJSON フォーマットに対応するリーダー/ライターを備えているので、JSONFragmenter, JSONFlattener などのトランスフォーマーを使わずに GEOJSON リーダーだけでジオメトリデータの作成、属性の抽出を行うこともできます。その場合は、座標系 ("crs" メンバーが省略されている場合は LL84) も自動的に設定されます。

FMEワークスペース例
上: GEOJSON リーダー, 下: FeatureReader トランスフォーマー
FeatureReader では、Format として GEOJSON を指定することにより、GEOJSON リーダーと同じモジュールによるデータ読込処理が行われます。
















どちらも Dataset として URL を指定することにより、ウェブサーバーにアクセスして GeoJSON ドキュメントを読み込むこともできます。

この場合、見かけ上はウェブサーバー上のデータを直接読んでいるように見えますが、実際は、一旦 GeoJSON ファイルをダウンロードして作業用の一時フォルダに保存し、それを読み込むという仕組みであるため、ディスクにアクセスするためのオーバーヘッドがかかります。

HTTPCaller によってレスポンスとして得られた GeoJSON ドキュメントを属性に格納し (ファイルには保存せず)、いくつかのトランスフォーマーで変換した方が効率が良い可能性があるので、性能が重視されるプロジェクトでは、実行環境において計測したうえでどの方法を採用するか決定すべきでしょう。


2017-08-25: FME 2017.1.1 では、JSONFragmenter (Fragment as Format: GEOJSON) だけで、GeoJSON ドキュメントに基づいてジオメトリと属性を持つフィーチャーを作成することができます。

FMEワークスペース例 (FME 2017.1.1 build 17539)


0 件のコメント:

コメントを投稿