Maps.meは世界中の地図を無料でダウンロードして使えます。普通の用途であればこれで十分ですが、現時点では地図に等高線が無いので山登りには不向きです。そこで、以前に構築したMaps.me地図自作環境を使って等高線付き地図を作成してみました。これがあれば、ちょっとした山登りにも使えるようになるはずです。
スマホで地形図を表示したい
Maps.meはオフラインで使えるしナビゲーション機能もあるので愛用しています。しかし提供されている地図は地形図ではないなので街中はともかくとして山登りにはちょっと使いにくいと思います(登山道は表示されるが地形が分からない)。幸いというか、Maps.meでは地図の生成ツール一式が公開されているので、これを使ってMap.me向け等高線入り地図を作ってしまおう、というのが本記事の趣旨です。
私の場合、電波の届かない山奥でスマートフォンはデジカメ用途がメインですがオフライン状態でも地形図が使えればGPSのバックアップとしても使えます。今回の記事で作った地図をいれてやれば用途が広がる・・・ハズです。
環境
実験に供するのは私が通話専用として使っているガラホです。
- 端末:SHARP AQUOSケータイ2(NP601SH)
- OS:Android 5.5.1 (ビルド番号:S0010)
- 地図アプリ:MAPS.ME 8.1.3-Google (Data verson:180316)
等高線付き地図を作る
(事前準備1)環境構築
Maps.meの地図作成環境については以下の記事を参照ください。
(事前準備2)必要なデータを用意する
さて、等高線付きの地図を自作するにあたって元となるデータを用意します。地図のベース部分は通常通りOpenStreetMapを使わせていただくとして、等高線はOpenStreetMapに含まれていないので以前にGarmin向け地図を作ったときのデータを流用することにしました。
- 地図情報:OpenStreetMap
- 等高線:国土地理院・基盤地図情報の数値標高モデル(DEM10B)を元に作成したもの
これから等高線を作ってみようという人は、phyghtmapを利用して数値標高モデルにSRTM1(SRTM3は解像度が荒いのでSRTM1をお勧めします)を使うのが簡単かと思います。DEM10Bを使う方が綺麗な等高線が得られますが作業行程が少々面倒になります。以下の記事が参考になるかと思います。
この記事では次のファイルを用意しました。
- 地図ファイル:japan-latest.pbf (Geofabrikから最新版をダウンロード)
- 等高線ファイル:japan-contour.o5m
- 海岸線ファイル:WorldCoasts.geom (Maps.me地図環境構築の記事で作ったもの)
(step1-1).地図と等高線を結合する
データの用意が出来たら、以下のようにしてひとつのファイルに結合します(私の環境ではosmconvertのバージョンが古かったので最新版のバイナリをダウンロードして使用しました)。
$ wget http://m.m.i24.cc/osmconvert64 $ chmod +x ./osmconvert64 $ ./osmconvert64 japan-latest.pbf japan-contour.o5m --modify-way-tags="ele= to name=" --out-o5m -o=japan-latest-contour.o5m
ここでは結合と同時に"--modifty-way-tags"を使ってタグ"ele"を"name"に変換しています。これは、Maps.meでは特定のタグ(主には"name","int_name","ref"等)しか地図上に表示出来ないからです(元々ガーミン向けに作った"japan-contour.o5m"は各等高線の高度情報を"ele"に格納していました)。出力フォーマットは次項以降で使用するMaps.me側ツールにあわせて"o5m"形式としました。
本来は"ele"のまま高度を読み込めるようにする方が意味合い的に正しいと思うのですが、対応するにはMaps.meのプログラムを修正する必要があります。そうなると手軽に試せなくなくなるので今回は暫定策としてデータ側をプログラムに合わせることにしました。
注意点として、osmconvertは複数のpbf形式ファイルを読み込むことが出来ません。等高線ファイルをo5m形式で用意したのはそのためです。pbf形式ファイルが複数ある場合は事前にo5mに変換してください。
# (ex) $ ./osmconvert64 file.osm.pbf --out-o5m -o=file.o5m
完了するとかなり大きいサイズのファイルが出来ていると思います。
(step1-2).Maps.meのスタイル設定を修正する
Maps.meでは地図要素(例えば道路、川など)をどのように描画するかを設定をファイルから読み込んでいます。現時点(2018/05/02)でMaps.meには等高線という要素が無いので、たとえ地図データに等高線が含まれていても描画されません。そこで、表示スタイルに等高線を追加してやります。
スタイルはMapCSSで記述されていて、Maps.meプロジェクトの以下パスに格納されています。
- omim/data/styles/
次のファイルを作成/修正して等高線とラベル(標高)の設定を追加します。"style-clear"が通常表示で"style-night"は夜間表示用になります。
- (新規作成) omim/data/styles/clear/include/contour.mapcss
- (新規作成) omim/data/styles/clear/include/contour_label.mapcss
- (修正) omim/data/styles/clear/style-clear/colors.mapcss
- (修正) omim/data/styles/clear/style-clear/style.mapcss
- (修正) omim/data/styles/clear/style-dark/colors.mapcss
- (修正) omim/data/styles/clear/style-dark/style.mapcss
- (修正) omim/data/mapcss-mapping.csv
omim/data/styles/clear/include/contour.mapcss
/* ~~~~ CONTENT OF CONTOUR ~~~~~ 1.Z-INDEX CONTOUR 2.WORLD LEVEL CONTOUR 4-9 ZOOM 3.CONTOUR 10-22 ZOOM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* 1.Z-INDEX CONTOUR */ line[contour] {z-index: 3000; color: @contour_line;} /* 2.WORLD LAVEL CONTOUR 4-9 ZOOM */ line|z4-9[contour] {opacity: 0;} /* 3.CONTOUR 10-22 ZOOM */ line|z10-12[contour] {opacity: 0;} line|z13-14[contour][contour_ext=elevation_major] {width: 1; opacity: 0.8;} line|z13-14[contour][contour_ext=elevation_medium] {width: 0.8; opacity: 0.5;} line|z15-[contour][contour_ext=elevation_major], line|z15-[contour][contour_ext=elevation_medium] {width: 2; opacity: 0.8;} line|z15-[contour][contour_ext=elevation_minor] {width: 0.8; opacity: 0.5;}
omim/data/styles/clear/include/contour_label.mapcss
/* ~~~~ CONTENT OF CONTOUR ~~~~~ 1.Z-INDEX CONTOUR 2.WORLD LEVEL CONTOUR 4-9 ZOOM 3.CONTOUR 10-22 ZOOM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* 1.Z-INDEX CONTOUR */ line[contour] {z-index: 3000;} /* 2.WORLD LAVEL CONTOUR 4-9 ZOOM */ /* 3.CONTOUR 10-22 ZOOM */ line|z13-15[contour][contour_ext=elevation_major] {text: name; text-color: @label_medium; text-position: line;font-size: 8; text-halo-opacity: 0.9;text-halo-radius: 1;text-halo-color: @label_halo_light;} line|z16-[contour][contour_ext=elevation_major], line|z16-[contour][contour_ext=elevation_medium] {text: name; text-color: @label_medium; text-position: line;font-size: 8; text-halo-opacity: 0.9;text-halo-radius: 1;text-halo-color: @label_halo_light;}
omim/data/styles/clear/style-clear/colors.mapcss
omim/data/styles/clear/style-night/colors.mapcss
$ git diff colors.mapcss diff --git a/data/styles/clear/style-clear/colors.mapcss b/data/styles/clear/style-clear/colors.mapcss index 3b7ce37..c554bf6 100644 --- a/data/styles/clear/style-clear/colors.mapcss +++ b/data/styles/clear/style-clear/colors.mapcss @@ -175,3 +175,7 @@ @shield: #FFFFFF; @shield_outline: #000000; /* blue - #2E89B0; #687E94; #598DBE; */ + +/* Contour */ +@contour_line: #663300; +
omim/data/styles/clear/style-clear/style.mapcss
omim/data/styles/clear/style-night/style.mapcss
$ git diff style.mapcss diff --git a/data/styles/clear/style-clear/style.mapcss b/data/styles/clear/style-clear/style.mapcss index e443b50..054ec89 100755 --- a/data/styles/clear/style-clear/style.mapcss +++ b/data/styles/clear/style-clear/style.mapcss @@ -7,6 +7,8 @@ @import("../include/Roads_label.mapcss"); @import("../include/Icons.mapcss"); @import("../include/Subways.mapcss"); +@import("../include/contour.mapcss"); +@import("../include/contour_label.mapcss"); canvas
次に"mapscss-mapping.csv"を修正します。各行末尾はユニークなIDが連番で振られているので重複しないように修正してください。
omim/data/mapcss-mapping.csv
$ git diff mapcss-mapping.csv diff --git a/data/mapcss-mapping.csv b/data/mapcss-mapping.csv index 8840cfb..baadb72 100644 --- a/data/mapcss-mapping.csv +++ b/data/mapcss-mapping.csv @@ -1207,3 +1207,7 @@ sponsored|partner4;1206; sponsored|partner5;1207; event|fc2018;1208; event|fc2018_city;1209; +contour;1210; +contour|contour_ext|elevation_major;[contour][contour_ext=elevation_major];;name;int_name;1211; +contour|contour_ext|elevation_medium;[contour][contour_ext=elevation_medium];;name;int_name;1212; +contour|contour_ext|elevation_minor;[contour][contour_ext=elevation_minor];;name;int_name;1213;
修正が完了したら次のスクリプトを実行してください。記述ミスがあるとエラーが発生しますので、その際は問題箇所を修正してから再度スクリプトを実行します。
$ omim/tools/unix/generate_symbols.sh
(step1-3).地図を生成する
以下のスクリプトを実行して地図を生成します。かなり時間がかかるので気長に待ってください(私の環境では1日で終わりませんでした)。
$ TARGET=./target REGIONS=$(ls omim/data/boarders/Japan*.poly) PLANET=japan-latest-contour.o5m COASTS=WorldCoasts.geom NS=raw omim/tools/unix/generate_planet.sh -r [2018/05/03 12:26:20]: STATUS Start Using tool: /media/kiri/data/git/suke-blog/omim/../omim-build-release/generator_tool [2018/05/03 12:26:43]: STATUS Step 3: Generating intermediate data for all MWMs [2018/05/03 13:35:09]: STATUS Step 4: Generating features of everything into ./target [2018/05/04 07:13:34]: STATUS Step 5: Building all MWMs of regions and of the whole world into ./target [2018/05/04 07:35:21]: STATUS Step 6: Using freshly generated *.mwm to create routing files [2018/05/04 17:45:52]: STATUS Step 7: Updating resource lists [2018/05/04 17:45:53]: STATUS Step 8: Testing data ./test_planet.sh: line 110: 64047 Aborted (core dumped) "$(dirname "$GENERATOR_TOOL")/routing_integration_tests" "--data_path=$FTARGET/../" "--user_resource_path=$OMIM_PATH/data/" "--suppress=online_cross_tests.*" 2>&1 [2018/05/04 17:51:23]: STATUS Done
生成されたファイルサイズはこんな感じになりました。NS=rawオプションを指定しているので中間生成ファイルがでかいです。地図本体(*.mww)は合計で3.3GByteくらいかな。
$ du -bhc ./target 6.0G ./target/intermediate_data/tmp 143G ./target/intermediate_data 1.9M ./target/logs 20M ./target/borders 4.0K ./target/symlinked_copy 146G ./target 146G total
自作地図をスマートフォンに転送する
地図が完成したら後は自作地図をスマートフォンの既存地図に上書きすればよいのですが、今回のように元々無かった要素(=等高線)を追加した場合は次の要素を更新する必要があります。
- 地図データ(*.mwm)
- 地図データ定義(classificator.txt, types.txt, colors.txt)
- 表示スタイル定義(drules_proto_*.bin)
(step2-1).地図を上書きする
まず自作した地図を転送します。Maps.meの地図データ保存先にある同名のファイルを上書きすればOKです。地図はバージョン毎にサブディレクトリに保存されているので、一番新しいディレクトリに上書きしてください。
# (ex)Android端末のSDカードをマウントしてから $ cp ./target/*.mwm /media/kiri/SD-CARD/Android/data/com.mapswithme.maps.pro/files/MapsWithMe/180316/
転送先が分からない場合は以下のようにMaps.meの設定を見ると表示されます。SDカードスロットが無い機種の場合は項目自体が無いかもしれないので、その場合はUSB接続するなりして地図ファイル(*.mwm)がある場所を探してみてください。
(step2-2).地図データ定義を上書きする
次に地図データ定義を変更します。これが重要で、地図を生成したときに使用した定義と地図データが一致しないとMaps.meが正常に動作しません。大抵はクラッシュすると思います。私が確認した限りでは以下のファイルが地図データ定義として読み込まれるようです。
(これらは"generate_styles.sh"を実行した際に自動生成されます。基本的には"omim/data/mapcss-mapping.csv"をいじると地図データ定義の更新が必要になるはずです)。
- omim/data/classificator.txt
- omim/data/types.txt
- omim/data/colors.txt
定義ファイルそのものは、通常はアプリケーションに付属しているものが読み込まれます。これを上書きするには所定のパスに定義ファイルを配置すればよいのですが、AndroidとiOSで若干やり方が異なります。
Androidの場合
まず、以下のようにして定義ファイルをzipで1つにまとめます。このとき"-0"を指定して圧縮しないようにしてください。私の環境では圧縮するとMaps.meが起動しなくなりました。
$ zip -0j classificator_mod.zip omim/data/classificator.txt omim/data/types.txt omim/data/colors.txt
次にAndroid端末のOBBディレクトリにファイルを転送します。このとき拡張子を*.zipから*.obbに変更しています。
$ adb push classificator_mod.zip /storage/emulated/legacy/Android/obb/com.mapswithme.maps.pro/classificator_mod.obb
私の端末ではこれでいけましたが、環境によってはパスが異なるかもしれません。転送出来ないようなら以下のパスも試してみてください。
- /storage/emulated/legacy/Android/obb/com.mapswithme.maps.pro/
- /storage/emulated/0/Android/obb/com.mapswithme.maps.pro/
- /sdcard/Android/obb/com.mapswithme.maps.pro/
これでも無理なようであれば、アプリケーション起動時のログをadbで取得するとパスが分かります。
以下、ログの抜粋です。
2018-04-27 18:37:28.339 main: I/MapsmeCore: platform/Platform.cpp:195 SetSettingsDir() Settings path = /storage/emulated/0/MapsWithMe/ 2018-04-27 18:37:28.349 main: I/MapsmeCore: platform/string_storage_base.cpp:26 StringStorageBase() Settings path: /storage/emulated/0/MapsWithMe/settings.ini 2018-04-27 18:37:28.354 main: I/MapsmeCore: platform/Platform.cpp:128 Initialize() Flavor name: google 2018-04-27 18:37:28.356 main: I/MapsmeCore: platform/Platform.cpp:129 Initialize() Build type name: release 2018-04-27 18:37:28.357 main: I/MapsmeCore: platform/Platform.cpp:152 Initialize() Apk path = /data/app/com.mapswithme.maps.pro-1/base.apk 2018-04-27 18:37:28.359 main: I/MapsmeCore: platform/Platform.cpp:153 Initialize() Writable path = /storage/sdcard1/Android/data/com.mapswithme.maps.pro/files/MapsWithMe/ 2018-04-27 18:37:28.360 main: I/MapsmeCore: platform/Platform.cpp:154 Initialize() Temporary path = /storage/emulated/0/Android/data/com.mapswithme.maps.pro/cache 2018-04-27 18:37:28.365 main: I/MapsmeCore: platform/Platform.cpp:155 Initialize() OBB Google path = /storage/emulated/0/Android/obb/com.mapswithme.maps.pro/ 2018-04-27 18:37:28.367 main: I/MapsmeCore: platform/Platform.cpp:156 Initialize() OBB Google files = [0: ]
iOSの場合
こちらは最新のMaps.meが動作する端末が無くて試せていません。ソースコードを見た感じだと、iTune等を使ってテキストファイル3つをそのままデータディレクトリに転送してやれば読み込めそうです。試してみてください。
(step2-3).表示スタイル定義を上書きする
次に表示スタイル定義を書き換えます。通常はアプリケーション付属のものが読み込まれますが、以下のようにすると今回新しく作成したスタイルを優先して読み込んでくれます。
手順
- Maps.meの地図データ保存先に"styles"ディレクトリを作成
- 作成したディレクトリに次の内容をコピー
転送するファイル/ディレクトリ
- omim/data/rouources-*
- omim/data/drules_proto_clear.bin
- omim/data/drules_proto_dark.bin
(step2-4).キャッシュを削除する
必要なファイルの転送が終わったら、Maps.meを起動する前にキャッシュを削除しておきます。これをやらないと原因不明のエラーに悩まされることがあるので、特にclassificator.txt以下の地図定義を更新した際には必ず行うようにしてください。
(step2-5).Maps.meを起動して確認する
長々と手順を連ねてきましたが、お付き合い頂いた方はお疲れ様です。ようやく起動です。地図をある程度拡大すると等高線が描画されると思います。
AQUOSケータイ2で奈良県の行者還岳付近を表示したところを画面キャプチャしてみました。
(*1)この地形図の等高線は国土地理院・基盤地図情報の数値標高モデル(DEM10B)を元に作成したものです。
所感
Maps.meに等高線を追加するという試み、如何だったでしょうか。作業手順はそれほど難しいものでもありません(ただ処理時間は長いです)ので興味のある方は試してみてください。個人的には普段持ち歩いているスマートフォンで等高線付き地図が見れるのはそれなりに便利なのではないかと思います。
いずれGarminの地図データと同じように許可を得て公開しようかと考えていますので、作るのが面倒という方はしばしお待ちください。今回はあまり需要のあるネタではないかと思いますが楽しんでいただけたら幸いです。
(2018/05/19追記)
この記事で作成した地形図を公開しました。興味のある方はお試しください。
参考
この記事は以下の内容を参考に記載させていただきました。
- OpenStreetMap Wiki - MapCSS/0.2
https://wiki.openstreetmap.org/wiki/MapCSS/0.2 - Qiita @niusounds - APK拡張ファイル
https://qiita.com/niusounds/items/e9a676819e8f58df8456 - DROWSY DOG'S DIARY - [android] APK Expansion Files
http://ka-zoo.net/2014/08/android-apk-expansion-files/ - Kludge Factory - Androidの拡張ファイルから動画を再生する
https://tyfkda.github.io/blog/2014/06/22/android-zip-movie.html