ITに関するさまざまなトピックを紹介するサイトです
このコンテンツはお使いのブラウザには対応しておりません。
新しいバージョンのブラウザでアクセスしてください。

OpenStreetMapをWebページに組み込む

OpenStreetMapは、アカウント登録すれば誰でも編集することができ、自由に利用できる地図です。
OpenLayersを使ってOpenStreetMapの地図情報を閲覧する地図を、このページに組み込みました。
OpenLayersは、Web地図機能を提供するオープンソースのJavaScriptライブラリです。
上の地図はほぼ「東京都文京区」をカバーする範囲をみることができます。(一部欠けています)
設定した境界の外側に地図を移動させることはできません。
また、ズームレベルは3段階のみに設定してあって、それ以外には拡大・縮小できません。
  2018年11月、地図のタイル画像を新しいデータから生成したものに更新しました。
OpenStreetMapは誰でも利用できる地図を作成することを目的としていますが、何をしてもよいということではないので、地図編集にあたってのルール、特に著作権に関わる部分の扱いについては十分注意が必要です。

Mapシステムの構成

OpenStreetMapの地図情報を利用するのは自由なのですが、そのサーバリソースまで自由に使えるわけではありません。
他の一般的なWeb地図サービスが単位時間当たり一定回数のアクセスまでしか許可しないとか、有償でサービスを提供しているのは、サービスを提供するために多大なサーバリソースが必要となり、その運用コストを無視できないからです。(OpenStreetMap以外のWeb地図サービスでは地図情報のライセンスも関係してきます)
地図情報はタイル状の画像として表示されますが、それを提供するサーバをタイルサーバと言います。
OpenStreetMapのタイルサーバを利用できるサービスを提供しているところがいくつかありますが、無償で利用できるのは一定のアクセス数までで、それ以外は有償になります。しかし、それでは他のWeb地図サービスと変わりません。
そこで、別の手段として、自前でタイルサーバを用意するという方法があります。

タイルサーバの形態にもいくつかの方式がありますが、一番単純なのはあらかじめ地図情報をレンダリングしてタイル画像ファイルを生成しておき、それをWebサーバに静的に配置しておく方式です。
広い範囲をカバーする地図を提供するとなると画像ファイルの容量が膨大になり、現実的ではなくなりますが、地域を限定した狭い範囲の地図を提供するだけならば、選択肢として検討する価値があると思います。
自由に編集できる(=日々更新される)OpenStreetMapの地図情報を取り込むにはタイル画像ファイルを定期的に更新する必要があるわけですが、この方式のデメリットととして、その手順が煩雑なこと、最新情報を取り込むまでのタイムラグが長くなりがちなことが挙げられます。
メリットもあります。構成が単純なので、複数サーバで負荷分散する構成も作りやすいです。単一サーバで試験的にサービスを提供するなら、自由度の小さいホスティング環境でも十分です。
タイル画像ファイルを生成するための環境構築と生成手順については、このサイト内の以下のページをご覧ください。
以下では、タイル画像ファイルの生成処理が済んでいると仮定して、地図を提供するためのWebページの構成とOpenLayersでの地図表示処理について説明します。

地図部品の配置

OpenLayersライブラリはOpenLayersのサイトを参照して利用することもできますが、ここではダウンロードして自分のWebサイト内に配置していています。
以下に、このWebページの地図表示に利用している部品の配置図を示します。
OpenStreetMapWithMyTiles.htmlと同じ階層に「ol」ディレクトリを配置し、「ol」ディレクトリ配下に「img」ディレクトリ、「theme」ディレクトリ、「tiles」ディレクトリとOpenLayers.jsファイルを配置します。
このWebページのHTMLファイルは、 "OpenStreetMapWithMyTiles.html"です。

同じ階層に"ol"ディレクトリを作成し、OpenLayers関連のファイルをここに配置しています。

地図のタイル画像ファイルは"tiles"ディレクトリ配下にありますが、これも"ol"ディレクトリに配置しました。
タイル画像ファイルのディレクトリとファイル名は、以下のような構成になっています。
tiles/{ズームレベル}/{X座標}/{Y座標}.png

地図表示のためのJavaScriptコードと関連するCSS定義はHTMLファイル内に記述しています。
(当初、別ファイルに記述していましたが、レスポンス改善を目的として、HTMLファイル内に取り込みました)

OpenLayersライブラリ取得

OpenLayersのサイトからライブラリを取得します。
OpenLayers OpenLayers: Home
ページの先頭にStableの最新版ライブラリのダウンロードリンクがあるので、これをダウンロードします。
このページで利用しているバージョンは2.13.1です。
".tar.gz"形式と".zip"形式があります。
圧縮を解凍し、一番上の階層にあるOpenLayers.jsimgディレクトリ、themeディレクトリを取り出して配置します。
JSファイルはライト版やモバイル版などいくつかあるので、適宜使い分けてください。地図表示をカスタマイズする際は、各版のデバッグ用(OpenLayers.debug.jsなど)を使用するとよいと思います。

地図表示制御コード

ファイルのリンク

HTMLファイルから関連のファイルをリンクしている部分は以下のようになります。
<link rel="stylesheet" href="ol/theme/default/style.css" type="text/css">
<script src="ol/OpenLayers.js"></script>
"theme"ディレクトリ配下にあるOpenLayersのstyle.cssも読み込むようにしてください。

JavaScriptコード

地図を表示するために記述したJavaScriptコードについて説明します。

まず、Mapオブジェクトを生成します。
var map = new OpenLayers.Map("map",
		{projection: new OpenLayers.Projection("EPSG:900913")});
コンストラクタの第1パラメータには、地図を表示するHTML要素のid属性を指定します。(HTML要素のオブジェクト参照でも可)
第2パラメータにはオプションを指定します。ここでは投影法を指定しています。配置したタイル画像の投影法が球面メルカトルのものだったので、そのコードを指定してProjectionオブジェクトを生成し、指定しています。

次に、レイヤオブジェクトを生成してMapに登録します。
var osmLayer = new OpenLayers.Layer.OSM("Bunkyo-ku",
		"ol/tiles/${z}/${x}/${y}.png");
osmLayer.displayOutsideMaxExtent = false;
map.addLayer(osmLayer);
OpenStreetMapのタイルを使用するレイヤを生成するためには、OpenLayers.Layer.OSMオブジェクトを生成します。OpenLayers.Layer.OSMクラスは、XYZ形式のタイルをサポートするOpenLayers.Layer.XYZクラスのサブクラスです。
コンストラクタの第1パラメータにはレイヤ名称を指定します。
第2パラメータにはタイル画像ファイルのパスを指定します。HTMLファイルからの相対パスを指定しています。"tiles"配下の記述は固定です。
このページの地図は、定めた境界の外側に移動できないように制限させるので、displayOutsideMaxExtentプロパティをfalseに設定しています。

次に、地図の境界を設定しています。設定する境界は、用意したタイル画像のエリアの境界です。
var proj = new OpenLayers.Projection("EPSG:4326");
var bounds = new OpenLayers.Bounds();
bounds.extend(new OpenLayers.LonLat(139.7277, 35.6969).transform(proj, map.getProjectionObject()));
bounds.extend(new OpenLayers.LonLat(139.7779, 35.7372).transform(proj, map.getProjectionObject()));
map.restrictedExtent = bounds;
境界となる矩形の東西南北の座標を指定して、Boundsオブジェクトを生成しますが、緯度・経度の座標は球面メルカトルに変換する必要があります。
対角の2座標をextend関数で指定しています。(ここでは西南の角と東北の角)
境界を表すBoundsオブジェクトが設定できたら、MapオブジェクトのrestrictedExtentプロパティにセットします。
なお、この設定はMapにレイヤを追加した後に実行する必要があります。

次に、ズームレベルの制限を設定しています。
map.isValidZoomLevel = function(zoomLevel) {
	return ( (zoomLevel != null) && (zoomLevel >= 15) && (zoomLevel <= 17) );
};
制限を設定する方法がなかなか見つかりませんでしたが、MapクラスのisValidZoomLevel関数をオーバーライドする方法を見つけました。
(ズームレベルに関するプロパティ設定でできるかもしれません。いろいろやってみて、ダメでしたが・・・)

最後に、地図の初期表示の中心点とズームレベルを指定します。
map.setCenter(bounds.getCenterLonLat(), 16);

他のWeb地図サービスと同様に、複数レイヤを切り替えたり、マーカーを表示させたりするなど、OpenLayersはたくさんの機能を備えています。

CSS定義

HTML内のCSS定義では地図を表示する位置などを設定していますが、地図の表示スタイルに関する指定もあります。
div.olControlAttribution {
	right: 5px;
	bottom: 5px;
	padding: 2px;
	background-color: rgba(255, 255, 255, 0.7);
	border-radius: 4px;
}
地図の右下に表示してあるOpenStreetMapのライセンス表記の位置のCSS定義がおかしかったので(バグ?)、設定を変更しました。ついでに半透明背景色と角丸も設定しました。

当サイトでは、第三者配信による広告サービスを利用しています。 このような広告配信事業者は、ユーザーの興味に応じた商品やサービスの広告を表示するため、当サイトや他サイトへのアクセスに関する情報(氏名、住所、メール アドレス、電話番号は含まれません)を使用することがあります。 このプロセスの詳細やこのような情報が広告配信事業者に使用されないようにする方法については、こちらをクリックしてください。