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 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)
日本地図領域は矩形ではなく、多角形で指定した方がより正確になる。
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;
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を使ってダウンロードする例を以下に示す[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
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 の取得を分割すると、単独では、閉ループが完成しなくなるのが面倒である。