OpenStreetMapのデータからosmiumを使って鉄道だけを抽出しPostGISに入力する方法(宇都宮周辺の鉄道データを使った例)

作成日
キーワード
GIS OpenStreetMap osm osmium-tools PostGIS

以前、「OpenStreetMapのデータから鉄道だけを抽出してGeoJSONで出力する方法」の記事で、OSMのデータからrailwayのデータのみを抽出してGeoJSONに書き出す手順を書きました。

ところで「「OpenStreetMapから鉄道路線データを落とせない」と愚痴っていたら、社内の人から「OSMに鉄道データ入っていますよ」と言われて、愕然とした件」に書かれているように、OSMのデータから抽出した鉄道や道路等のデータをPostGISに入力できたほうが便利なようです。

ここでは、APIサーバー等で使用するために、OSMのデータから抽出した鉄道や道路のデータを、GeoJSON等を介さず、直接PostGISに入力してみます。

宇都宮周辺だけのOSMデータの用意

先ず、日本全体のOpenStretMapのデータ(japan-latest.osm.pbf)から、宇都宮周辺に絞ったデータを抽出します。

OpenStreetMapのデータをosmiumを使用して指定した範囲で抽出する方法」の内容に沿って、宇都宮周辺を次のようなGeoJSONで定義し、utunomiya.jsonというファイルに保存します。

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.77630615234375,
              36.697603754877754
            ],
            [
              139.7563934326172,
              36.530053615692154
            ],
            [
              139.80857849121094,
              36.391993080763974
            ],
            [
              139.96925354003906,
              36.38149043210595
            ],
            [
              140.16014099121094,
              36.415756993900885
            ],
            [
              140.2027130126953,
              36.527294814546245
            ],
            [
              140.19790649414062,
              36.627100703563116
            ],
            [
              140.17730712890625,
              36.721273880045004
            ],
            [
              140.01800537109375,
              36.72787819497748
            ],
            [
              139.77630615234375,
              36.697603754877754
            ]
          ]
        ]
      }
    }
  ]
}

japan-latest.osm.pbfから上のGeoJSONの範囲でOpenStreetMapを抽出するために、次のようにosmiumコマンドを実行します。

osmium extract \
    --strategy complete_ways \
    --set-bounds --polygon utunomiya.json \
    -o utunomiya.osm.pbf \
    japan-latest.osm.pbf

この結果、宇都宮周辺だけのOSMデータとして、utunomiya.osm.pbfが得られます。

Osmium-toolsを使用し宇都宮周辺のosm.pbfからの鉄道データを抽出しPostGISの形式で出力

次に、宇都宮周辺のOpenStreetMapのデータ(utunomiya.osm.pbf)から、タグがrailwayのデータだけを抽出します。

OpenStreetMapのデータから鉄道だけを抽出してGeoJSONで出力する方法」の手順に沿って、次のようにosmiumコマンドを実行します。

osmium tags-filter utunomiya.osm.pbf \
    w/railway \
    -o utunomiya-railway.osm.pbf

この結果、宇都宮周辺の鉄道のデータがutunomiya-railway.osm.pbfという名前のプロトコルバッファー形式のファイルとして得られます。

このデータを、osmiumコマンドを次のように使用してPostGISに直接入力可能なファイルに変換します。

osmium export -f pg \
  -o utunomiya-railway.pg \ 
  utunomiya-railway.osm.pbf

変換後のutunomiya-railway.pgの内容は、次のようなPostGISのgeometry型とPostgreSQLのJSONB型の2カラム分の内容を1行ごとに詰めたテキストファイルとなっています。

0101000020E6100000EB1C03B2577F61400557D4BBD3504240	{"local_ref":"1","name":"宝積寺","name:en":"Hoshakuji","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E61000000458E4D70F7C61406071DD39393F4240	{"local_ref":"1","name":"雀宮","name:en":"Suzumenomiya","name:ja":"雀宮","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E61000000A6FC5B4657E6140C47762D68B5C4240	{"railway":"level_crossing"}
0101000020E6100000B0A250600B7C614074A4E9A2D73E4240	{"railway":"level_crossing"}
0101000020E61000000006DDB90B7C6140B2193B3CDF3E4240	{"railway":"switch"}
0101000020E610000035B22B2DA37E6140C9EDF208C9584240	{"railway":"level_crossing"}
0101000020E610000056B77A4EFA7E61401B88C0ECF9544240	{"railway":"level_crossing"}
0101000020E6100000EF2E617E387E61404E226706964C4240	{"local_ref":"2","name":"岡本","name:en":"Okamoto","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E6100000267F411CB57E61408242F3EFE94D4240	{"railway":"level_crossing"}
0101000020E610000002E8418BB68161404B28D8DA56554240	{"railway":"level_crossing"}
0101000020E610000079FDEEC2BB826140CB3D6E090A554240	{"railway":"level_crossing"}
0101000020E6100000D2EA9A7FEA8261404BE5ED08A7544240	{"railway":"level_crossing"}
0101000020E61000006A036674F684614009CB338A40534240	{"name":"烏山","name:en":"Karasuyama","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E6100000913BB6AF0D836140136635B808544240	{"name":"大金","name:en":"Ogane","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E610000031395A7A597F614081165CBDD4504240	{"local_ref":"3","name":"宝積寺","name:en":"Hoshakuji","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E6100000FDF50A0B6E84614057AF22A303534240	{"name":"滝","name:en":"Taki","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E6100000D99B734B468061405E00D01731534240	{"name":"下野花岡","name:en":"Shimotsuke-Hanaoka","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E61000006B96708DF48061405ABC581822544240	{"name":"仁井田","name:en":"Niita","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E610000046370C30BD836140E1EAA5CE48524240	{"name":"小塙","name:en":"Kobana","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E6100000BCF957A0A78161404F46F01A4F554240	{"name":"鴻野山","name:en":"Konoyama","public_transport":"stop_position","railway":"stop","train":"yes"}
0101000020E61000003163658FEB846140D9603CDE3F524240	{"railway":"level_crossing"}

OSMから抽出した鉄道のデータをPostGISに入力

宇都宮周辺の鉄道データをPostGISに入力できる形式で書き出したutunomiya-railway.pgファイルを、実際にPostGISに入力します。

先ず、localhostで動作しているPostGISのデータベースにpsqlコマンド使って接続します。

psql -U postgres -h localhost

次に、psqlの接続の中で、次のSQLとコマンドを実行します。

ここでは、「map」という名前のデータベースの中に「utunomiya」という名前のテーブルを作成し、その中にutunomiya-railway.pgの内容を登録しています。

create database map;
\c map
create extension postgis;
create table utunomiya (
    geom geometry,
    tags jsonb
);
\copy utunomiya from 'utunomiya-railway.pg'

この結果、次の図1のようにOpenStreetMapから抽出したrailwayのデータがPostGISのutunomiyaテーブルの中に登録されます。

図1: OpenStreetMapのosm.pbfから抽出した宇都宮周辺のrailwayのデータをPostGISに入力できた様子

utunomiyaテーブルのgeomカラムはPostGISのgeometry型、tagsカラムはPostgreSQLのJSONB型となっているので、一般的なPostgreSQLのSQLを使用して加工することができます。

例えば、JSONB型のtagsカラムの中からキーがrailwayとnameのものの値だけを抜き出してrailwayカラムとnameカラムとして得るには、次のようなSQLを実行します。

select geom, tags->>'railway' as railway,
tags->>'name' as name
from utunomiya;

この結果、図2のようにgeometry、railway、nameのカラムのデータが得られます。

図2: OpenStreetMapのosm.pbfから抽出した宇都宮周辺のrailwayのデータをPostGISに入力し、SQLで加工している様子

PostGISの中の宇都宮周辺の鉄道のgeometryをQGISで表示

これまでの手順で、PostGISのmapデータベースのutunomiyaテーブルに、OpenStreetMapから抽出した鉄道のデータのgeometryとtagsが入力できました。

QGISでmapデータベースに接続し、utunomiyaテーブルのgeometryを国土地理院の淡色タイルの上に重ねて表示すると、図3のように、実際に宇都宮周辺の鉄道のデータだけを抽出できたことが確認できました。

宇都宮ライトレールのデータが表示されていることも確認できました。

図3: OpenStreetMapのデータから抽出した宇都宮周辺のrailwayのみのデータをQGISで表示した様子