OpenLayers を使って iPhone 用の飲食店マップを作ってみた
はじめに
OpenStreetMap Advent Calendar に参加します。MapBox for iOS SDK やマピオンの API が紹介されていますが、私はそういうものを知らなかったので、素人なりに OpenLayers を使って iPhone で表示できる飲食店マップを作ってみた試みをご紹介します。(できた地図だけを見たい方は下の方にスクロールして、画像をクリックしてください。)
何をしたかったか
会議などを開催するときに、参加者向けに近隣のランチマップ/飲み屋マップを作りたいことってありますよね。そういうときに、
なんて3ステップで地図が簡単に作れるしくみがあるといいなぁ、などと夢想しながらも、いきなりそんな気の利いたものは作れないので、まず隗より始めよ、で手作業で飲み屋マップを作ってみました。
やったこと
楽をするために、まずは人の真似をしようということで、参考にさせてもらったのが 激辛商店街マップ|京都☆激辛商店街 向日市。 それから さくらのレンタルサーバ。これらは OpenLayers を使っているらしいので、OpenLayers のサイトにあるたくさんの例も参考にしながら作りました。javascript のみで動作するので、比較的簡単なようです。
残念なことに、OpenLayers は部分的にしか iOS をサポートしていません。実際、激辛マップを iPhone (iOS7 の Safari) で見ると、肝心の POI をタップしても、店の情報を見ることができません。これは
var pois = new OpenLayers.Layer.Text("My Points", { location:"text/sample.txt" }); map.addLayer(pois);
の部分がうまく動作しないためのようです。いろいろ試して
var pois = new OpenLayers.Layer.Vector("POIs", { strategies: [new OpenLayers.Strategy.BBOX({resFactor: 1.1})], protocol: new OpenLayers.Protocol.HTTP({ url: "text/sample2.txt", format: new OpenLayers.Format.Text() }) }); map.addLayer(pois);
ならばうまくいくことがわかりました。
次に iPhone で表示するために
<head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!-- スマートフォン用 --> <meta name="viewport" content="width=320, height=480, initial-scale=1.0, minimum-scale=1.0, maximum-scale=2.0, user-scalable=yes" />
という設定と
function check_smartphone() { var flg = (navigator.appVersion).indexOf("Mobile"); if (flg>0){ initial_zoom = 15; my_screen_width=320; <!-- location.href="index.html"; <!-- PC 用に書き換えるところ --> } else { initial_zoom = 16; my_screen_width = 700; location.href="index_PC.html"; <!-- PC 用に書き換えるところ --> } re_center(); }
というコードを仕込んで、ブラウザの名前に mobile が入っている場合は mobile 用のページのまま、そうでない場合は画面サイズの大きい PC 用のページに飛ばすようにしました。また、地図が画面いっぱいに表示されると、地図のスクロールはできてもページ全体のスクロールができなくなる問題に対処するために、
<div id="canvas" style="width:310px; height:400px"></div> <!-- PC 用に書き換えるところ -->
として、地図の左端に余白を残すようにしました。画面の左端をスライドすることで上下にスクロールができます。
もうひとつ工夫したのが
function re_center() { //map.zoomToMaxExtent(); //map.zoomTo(initial_zoom); var centLonLat = new OpenLayers.LonLat(139.68336129378946, 35.707380793896974) .transform( new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913") ); map.setCenter(centLonLat, initial_zoom); }
と
<form> <input type="button" value="東中野駅付近に戻す" onclick="re_center()" /> </form>
で、地図を初期位置に戻すボタンを付けてみたことです。地図を埋め込んだサイトで、私はよく地図をスクロールしすぎて迷子になってしまいますので(笑)。(更に地図スクロール範囲の制限もかけていますが。)
ひとまず出来たもの
こうして作ってみたのが下の画像のような 東中野〜中野ひとり飲みマップ です。とあるローカルコミュニティ向けの内輪の飲み屋紹介マップですが、中身は気にしないでください(笑)。
基本的には index.html, index_PC.html と text/sample2.txt のみで動作します。もとの example が Creative Commons License なので、このソースコードも同様に利用していただいて構いません。
どのくらい大変だったか、など
真似できる例を探すのに数日、コードを書くのに隙間時間で 1-2 日ぐらいだったかな。むしろベースマップを充実させるのに時間がかかっています。Bing トレース以外にも、表示する店の位置を再度確かめに行ったりしています。こういう利用が増えると、多くの人が OSM に POI を追加するモチベーションになるのではないでしょうか。
もしも OSM の POI が充実している場所では、POI を検索して開店時間などの条件に合う店だけピックアップしてマークできたりすると使いでがあるでしょうね。
まだ足りないこと
画面解像度の調整
現在は 320x480 pixel にしていますが、iPhone の機種を見分けて、解像度を上げられるといいなぁ。
POI 入力サポート機能
http://higashinakano.ikidane.com/admin.html に POI 入力サポート用のコードを置いていますが、まだまだ未完成です。