トップOpenStreetMap >OSM Overpass API
OSM Overpass API

はじめに

Overpass APIは比較的に新しい。それまでの OSM API[4]よりも格段に強力である。

どんなことができるのかまずは少し触れてみた。

世界規模の少量のデータを入手するには最適であろう。 国名、国境などは比較的短時間にダウンロードできた。

しかし、サイズ制限とか使用頻度制限などがあるため、 やや詳細なデータとなると、限られた範囲でないとダウンロードできない。

日本地図でも低ズーム描画では例えば湖(natural=water,water=lake)などは、 面積の大きいもののみを抽出して、これを描画している。

しかし、データベーステーブルの way_area カラムは osm2pgsql がインポートの際に計算して付加したものであり、元々の osm データにあるわけではない。 したがって、Overpass API で広大な湖のデータだけを取り出すようなことはできないようである。

自分の場合、最新のデータが頻繁にほしいわけではないので、時間はかかるが asia-latest.osm.pbf などを手元のハードディスクにダウンロードしておくといいだろう。

しかし、PostgreSQL データベースへのインポートはサイズ的にも、時間的にもパソコンには荷が重い。 多分、osmosis にも Overpass API と仕様は異なるが、 何らかの抽出(フィルタリング)機能があったと思う。

Overpass APIで得た xml ファイルと osmosis で得た xml(またはpbf)ファイルのマージは osmosis で実行できるであろう。

Overpass APIの基本

インタフェースとしては Overpass XML と Overpass QL があるが、まずは記述が簡潔な後者を使ってみる。

Overpass APIは、単一のHTTP GETリクエストとなる。 例えば、次のようにすれば、おおむねドイツ・ボンにある郵便ポストすべてを検索し、xml形式で返される。

境界ボックスをこの例のように別の変数で設定する場合、経度、緯度の順になる。

https://lz4.overpass-api.de/api/interpreter?data=[bbox];node[amenity=post_box];out;&bbox=7.0,50.6,7.3,50.8

概ね日本地図領域の郵便ポストは

https://lz4.overpass-api.de/api/interpreter?data=[bbox];node[amenity=post_box];out;&bbox=122.5607,20.08228,154.4709,45.70648
で取り出せた。ファイルサイズは 1.6MB となった。

ついでに、全世界の place=country を取り出してみた。色んな言語で表記されているため、1.8MB強となった。 取り出すタグを絞ればサイズは小さくなる。

https://lz4.overpass-api.de/api/interpreter?data=node[place=country];out;

矩形範囲の指定

矩形範囲節は必ず低緯度、低経度、高緯度、高経度の順序である。

 (20.08228,122.5607,45.70648,154.4709)

日本地図領域は矩形ではなく、多角形で指定した方がより正確になる。

osm_idによるエリア指定[3]

way/relationの場合、osm_id に 2400000000, 3600000000 を加えた値を overpass_api での id とする。

例えば、英国の relation の osm_id は 62149 なので、次のようにすれば英国の place=city が得られる。

area(3600062149);
node["place"="city"](area);
out;

これは次と同じ結果を得る。

area["ISO3166-1"="GB"][admin_level=2];
node["place"="city"](area);
out;

out geom

way や relation で関連する node 情報を得るには out フォーマットを out geom とする。

https://lz4.overpass-api.de/api/interpreter?data=rel["ISO3166-1"="GB"][admin_level=2];out geom;

ファイルサイズは 1.8MB となった。

リソース管理オプション

クエリのデフォルトのタイムアウトは3分のようだ。また、メモリ使用量にも制限がある。 次の例では、タイムアウトを 15分、メモリ使用量を 1 GiB に設定している。

[timeout:900]
[maxsize:1073741824];
node(51.15,7.0,51.35,7.3);
out;

node を id で指定するときは node(id:1234,3456,7878) のように、「id:」を付ける。

タイムアウトやメモリ使用量の設定値に上限はないが、サーバーに拒否されることがある。

curl を使う場合

curlを使ってダウンロードする例を以下に示す[3]。この例では osm_id = 1 の node を得ている。

curl --globoff -o output.xml http://overpass-api.de/api/interpreter?data=node(1);out;

複数の node の場合はエリア指定との区別のために、接頭語 id を付けて node(id:1000,1001,1002,1003,1004,1005) とする[4]。

curl --globoff -o output.xml http://overpass-api.de/api/interpreter?node(id:1000,1001,1002,1003,1004,1005);out;

クエリが大きくなった場合はファイルにおく。

curl --globoff -o output.xml -d @c:/osm/query.txt http://overpass-api.de/api/interpreter

低ズーム世界地図レンダリング用データのダウンロード

curl --globoff -o /media/sf_gisdata/mapnik/world_osm.xml -d @/media/sf_gisdata/mapnik/overpass.xml http://overpass-api.de/api/interpreter

リクエストファイル overpass.xml は文字コード UTF-8N, 改行コード LF とする。

国名データのみダウンロード

これは数秒で済む。world_osm.xml のサイズは 1.8MBである。timeout、 element-limit は将来に備えてのもの。

<osm-script timeout="900" element-limit="1073741824"><!-- 60 minutes、1 GiB -->
  <query type="node">
    <has-kv k="place" v="country"/>
  </query>
  <print/>
</osm-script>

国境を含める

mode = "meta" により、ファイルサイズは約2倍の 472MB となった。 所要時間は8分22秒となった。

メタデータとはタイムスタンプ、バージョン、変更セット、ユーザー名とIDである。 地図レンダリングには使わないので、今後は meta を外す。

<osm-script timeout="900" element-limit="1073741824"><!-- 15 minutes、1 GiB -->
  <union>
    <query type="node">
        <has-kv k="place" v="country"/>
    </query>
    <query type="way">
      <has-kv k="boundary" v="administrative"/>
      <has-kv k="admin_level" v="2"/>
    </query>
    <query type="relation">
      <has-kv k="boundary" v="administrative"/>
      <has-kv k="admin_level" v="2"/>
    </query>
  </union>
  <union>
    <item/>
    <recurse type="down"/>
  </union>
  <print mode="meta"/>
</osm-script>

ここで、metaデータなしのファイルを osm2pgsql でデータベース osm に追加してみる。 インポートは 64秒で終わった。

osm2pgsql -W --slim --number-processes 3 -C 2800 --drop -c -d osm -p world_osm -U postgres \
-S /media/sf_gisdata/mapnik/myosm.style --tag-transform-script /media/sf_gisdata/mapnik/myosm.lua \
/media/sf_gisdata/mapnik/world_osm.xml

osm2pgsql -W --slim --number-processes 3 -C 1000 --drop -c -d osm -p central_america_osm -U postgres \
-S /media/sf_gisdata/mapnik/world_osm.style  /media/sf_gis/world_osm/central-america.osm.pbf
 world_osm_line             |       61
 world_osm_line_way_idx     |        2
 world_osm_point            |        3
 world_osm_point_way_idx    |        1
 world_osm_polygon          |        2
 world_osm_polygon_way_idx  |        0
 world_osm_roads            |       61
 world_osm_roads_way_idx    |        2

世界全体の海岸線データを Overpass APIで得る

wayオブジェクト natural=coastline については以下のようにして、Overpass API で入手できた[2023.1.22]。 2GB近いが、9分弱で得られた。

日本全体の osmファイルは 40GB近いので、それに比べれば、5%程度に過ぎないので、 パソコンで解析できる。

c:\gisa>curl --globoff -o c:/osm/world_coastline.xml -d @c:/osm/overpass_coastline.xml http://overpass-api.de/api/interpreter
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1953M    0 1953M    0   176  3764k      0 --:--:--  0:08:51 --:--:-- 4379k
<osm-script timeout="900" element-limit="2150000000"><!-- 60 minutes、約 2GB -->
  <query type="way">
    <has-kv k="natural" v="coastline"/>
  </query>
  <print/>
</osm-script>

このクエリでは、node の座標値は得られていない。 得ようとした場合、世界全体が対象ではメモリ不足となる。

後から node ID を指定して、node情報を得ることもできるが、 ノード数は 71M になるので、クエリを分ける必要があるだろう。

way の取得を分割すると、単独では、閉ループが完成しなくなるのが面倒である。

A.リファレンス

[1] JA:Overpass API
[2] JA:Overpass API/言語ガイド
[3] Loading Data from OpenStreetMap with Python and the Overpass API
[4] JA:Overpass API/Overpass QL
[5] https://wiki.openstreetmap.org/wiki/JA:API_v0.6

B.来歴