プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

map フォーマットファイルを自分で作成する方法について

Androidアプリ『避難所検索@伊勢』では、オフラインマップを使っています。 このオフラインマップでは、 Mapsforge というライブラリを利用して地図を表示しており、 Mapsforge では OpenStreetMap のデータを map フォーマットというファイル形式で読み込み・表示します。

map フォーマットのファイルは、

Mapsforge Download Server

このサイトからダウンロードできます。明記はされていませんが、定期的に更新しているようです。

ただ、こちらのサイトの map ファイルは国または都市単位で、残念ながら日本は国単位でしかないので、サイズが非常に大きくなっています(japan.map で約 800MB!)。

スマホのストレージはそんなに潤沢じゃないので、これだと、アプリに同梱するにせよ、オンライン時にダウンロードするにせよ、扱いが難しくなってきます。

そこで、『避難所検索@伊勢』では、伊勢市近辺のみのオフライン地図データを作成して、それをアプリに同梱しています。

ここでは、メモがてら、オフラインマップファイルの作成の際にやったことをまとめておきます。

Webサービス

最初にWebサービスで任意の範囲の mapファイルをダウンロードできるものがないか探しました。

すると、BBBike というサイトが OpenStreetMap のファイルのダウンロードサービス(正しくは抽出サービス、というのかな?)を提供してくれています。

extract.bbbike.org

このサービスでは、指定した範囲に含まれる OpenStreetmap のデータを抽出(ダウンロード)することができます。また、ダウンロードできるファイル形式には、.map を始め、 .pbf など多種多様なものがあります(.pbf というのが、標準的な OpenStreetMap データのバイナリ形式フォーマットのようです)。

ということで、このサイトにアクセスして、ファイル形式を指定して、抽出完了通知を受け取るメールアドレスを入力して、ダウンロードしたい範囲を指定します。

しばらくすると、入力したメールアドレス宛に、ダウンロード準備ができたよ、と通知が来るので、メールに記載のリンクをクリックして、データを落とします。 zipファイル形式になっているので、解凍すると、中にお目当ての.mapファイルがあります。

なお、BBBike の抽出サービスについての詳細は下記サイトなどをご参考にしてください。

Help | BBBike extracts

OpenStreetMapの地図情報からタイル画像を生成する - GiBlockラボ

(参考)BBBike について

あと、元々の BBBike というサイトは、サイトのトップページに

Welcome to BBBike, your cycle route planner! We'll help you find a nice, safe and short bicycle route in your city and around. Please choose your city:

とあるように、自転車向けに最適なルートを提供するというサービスのサイトのようです。元々、ベルリンを対象に始まり、それが他の都市にも広がったもようです。 日本だと、東京ぐらいしか入ってないですね。伊勢も入れてくれないかなー。

実は

実はこれで問題ないかと思いきや、このファイルを使って mapsforge で表示させると、なんと、海が真っ白になってしまいます。

f:id:junichim:20170707221930p:plain

最初はよくわからなかったのですが、いろいろ調べてみると mapsforge のやり方として、海岸線のデータを個別に持ったりしているのではなく、レンダリング時に海をうまいこと描画しているようです(ちょっと中途半端な理解なんでこれ以上なんともいえないです)。

なので、海へ対応するためには、それなりの手順を踏む必要があり、そのことが mapsforge のサイトに記載されていました。下記ページにあるような手順が必要とのことです。

mapsforge/MapCreation.md at master · mapsforge/mapsforge · GitHub

また、この際に、map-writer というのを使って書き出すようです。

mapsforge/Getting-Started-Map-Writer.md at master · mapsforge/mapsforge · GitHub

『こんなややこしいのやるの嫌だなー』と思いつつ、もう少し調べると、既に mapsforge のサイトに答えがありました。 mapcreator というツールが用意されており、これを使うと、上記ページに記載されている手順を python スクリプトで自動的に実行してくれるようです。

github.com

ということで、この mapcreator を使ってみたので(わかる範囲で)使い方を書いておきます。

mapcreator

準備

mapcreator のページ(一番下あたり)見ると、いろいろと準備が必要とあります。 詳細な手順は覚えていないのですが、 Windows10 (64bit, Anniversary Update) 上の BoW (Ubuntu 14.04.5 相当)で環境構築した際には、以下のものをインストールしています。

mapcreator

git clone https://github.com/mapsforge/mapsforge-mapcreator.git

Osmosis

wget http://bretth.dev.openstreetmap.org/osmosis-build/osmosis-latest.tgz
mkdir osmosis
mv osmosis-latest.tgz osmosis
cd osmosis
tar xvfz osmosis-latest.tgz
rm osmosis-latest.tgz

map-writer, Osmosisのプラグインとして動作

mkdir ~/.openstreetmap/osmosis/plugins
cd ~/.openstreetmap/osmosis/plugins
wget http://search.maven.org/remotecontent?filepath=org/mapsforge/mapsforge-map-writer/0.8.0/mapsforge-map-writer-0.8.0-jar-with-dependencies.jar

Osmosisのプラグインとして設定するには、特定のディレクトリに配置すればよいようです。詳細は下記リンク先等を参考にしてください。

mapsforge/Getting-Started-Map-Writer.md at master · mapsforge/mapsforge · GitHub

Osmosis/Detailed Usage 0.45 - OpenStreetMap Wiki

GDAL, ダウンロードページのUbuntuを参照, こちらのページに行きついた

sudo apt-get install python-software-properties
sudo add-apt-repository ppa:ubuntugis/ppa

sudo apt-get install python-gdal
sudo apt-get install gdal-bin

Shapely

sudo apt-get install python-pip
sudo apt-get install python-software-properties
sudo apt-get install libgeos-c1v5
sudo pip install Shapely

その他(ヘッダファイルなど)

sudo apt-get install python-dev
sudo apt-get install libgeos-dev

設定ファイル

入力となる .pbf ファイルですが、 mapcreator のサイトには、地球全体の.pbfファイル(planet.osm に対応する.pbf)を使って試しなさい、とありますが、数十GBもあるので、とてもじゃないけど扱いたくありません。 なので、.pbfファイルは抽出したい領域より少し大きめにとったものを BBBike のサイトからダウンロードしておきます。

ちなみに、.pbf ファイルはBBBikeからダウンロードするほかに、 Geofabrik 社のダウンロードサイトからも取得することができます。こちらのデータは定期的に更新されており、国別・地域別に提供されています。日本だと、地方(関東や関西など)別に提供されています。ちなみに関西で、約130MBありましたので、こちらのデータを使う場合はデータサイズにお気を付けください。

次に設定ファイルを編集します。基本的には、mapcreatorのページに説明があるので、それに従います。 あれこれいうより、実際に設定したxmlファイルを示します。

ise_config.xml

<?xml version="1.0" encoding="UTF-8"?>
<mapcreator-config xmlns="http://mapsforge.org/mapcreator" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://mapsforge.org/mapcreator https://raw.githubusercontent.com/mapsforge/mapsforge-mapcreator/master/resources/mapcreator.xsd"
    default-map-start-zoom="14" map-staging-path="maps"
    pbf-staging-path="data" polygons-path="polygons" map-target-path="mymaps" logging-path="logs" initial-source-pbf="ise.pbf"
    poi-staging-path="pois"
    poi-target-path="/productfiles/mapsforge/pois"
    osmosis-path="/home/mor/osmosis/bin/osmosis"
    preferred-language="ja"
    default-preferred-language="en">
    <!-- Asia -->
    <part name="ise" create-pbf="false" create-map="true" type="hd" map-start-lat="34.377" map-start-lon="136.517"/>

</mapcreator-config>

このファイルの意図としては、伊勢市周辺のデータを抽出して、.mapファイル(のみ)を作成するというものです。設定方法によっては.pbfファイルも一緒に作成できるようですが、今回は使っていません。

上記のxmlファイル中にパスを指定するタグ(xml中の~pathのタグ)がいくつかありますが、それぞれの意味は次の通りのようです。

  • osmosis-path, インストールしたOsmosis のbinフォルダ中の osmosis ファイルを指定
  • map-staging-path, 作業途中でmapファイル保存に使うフォルダ
  • pbf-staging-path, .pbf ファイルを保存するフォルダ。またスクリプト動作時に自動的に土地データ(http://openstreetmapdata.com/data/land-polygons)をダウンロードおよび展開する際に使用するフォルダ
  • polygons-path, 設定ファイルの part タグの name 属性に対応するポリゴンデータを格納するフォルダ
  • map-target-path, 最終的に.mapファイルが出力されるフォルダ(map-staging-pathと同じだと実行時に、コピーできないと怒られます)
  • logging-path, ログフォルダ
  • initial-source-pbf, 処理対象となる.pbfファイル名

ここで、 polygons-path に格納するポリゴンデータ(ポリゴンファイル)ですが、このファイルに定義した範囲が抽出の対象となるようです。 今回は下記の様に矩形で定義しました。

ise.poly

polygon
1
   136.517   34.585
   136.928   34.585
   136.928   34.377
   136.517   34.377
   136.517   34.585
END
END

なお、抽出元の.pbfファイルは、地図の北を上側にして矩形の左下と右上を、(経度、緯度)で表すと

(136.517, 34.377) - (136.928, 34.585)

の範囲を対象としたものになっています。

また、設定ファイル(上記の例だと ise_config.xml)の part タグの map-start-lat, map-start-lon はこのポリゴンで指定される領域内を指す必要があるそうです。

なお、ポリゴンファイルは、設定ファイルの part タグの入れ子の階層およびname属性と対応している必要があるので、注意してください。まあ、mapcreatorをcloneした状態で、xml/example-config.xml ファイルをみれば大体想像がつくとおみます。

上記の例の場合は、polygons-pathフォルダの直下に ise.poly ファイルを配置しています。

実行

上記の設定ができれば、さっそく実行してみます。

python mapcreator.py -c xml/ise_config.xml

実行が始まると、土地データ(http://openstreetmapdata.com/data/land-polygons)のダウンロードが始まります。全世界のデータっぽくて、このときで約460MBのサイズがありました。 無事にダウンロードが終わると処理が行われていきます。ちなみに、このファイルのことを調べると、ここでも『ポリゴン』という用語が出てきますが、先ほどのmapcreatorの設定ファイルで出てきている polygons-path のポリゴンとは別のものを指していると思いますので、ご注意ください。

内部の処理は詳細に追いかけていませんが、ログファイルを見て、特にエラーが出力されていず、終了しており、mapファイルが作られていればOKなのかと思います。

出来上がった map ファイルをmapsforgeで表示すると、今回は正しく海が表示されました。

おわりに

範囲を狭くしたmapファイルを作ることがこんなに大変だと思いませんでした。ちょっとやられた感があります。

とはいえ、OpenStreetMap のデータをあれこれ調べ始めると、結構楽しそうだな、とも感じてます。 どっかで仕事に絡めて調べてみたいなー。