OpenLayersで地図を表示する

 Google Mapsによって、ウェブサイトに簡単に地図を加えることができるが、GoogleのAPIを使用している場合は、他のデータを表示する能力は限定される。自分自身のデータや、Google以外のデータを表示したい場合に、より多くのオプションを提供してくれるのが、オープンソースのJavaScriptライブラリ OpenLayers である。

 OpenLayersは最近、いくつかの著名な活動において利用されている。Djangoの開発者であるAdrian Holovaty氏らが運営する地域的ニュースサイトEveryBlockにも使用され、また、Barack Obama次期大統領の選挙キャンペーンにおいても、その米国大統領選を支援するための地図情報の一環として使用された。

 OpenLayersを最初に開発したのは、地理情報を扱う企業MetaCartaだが、現在ではBSDライセンスの下で公開されている。OpenLayersでは、Open Geospatial ConsortiumWeb Map Service(WMS)とWeb Feature Serviceの両プロトコルが実装されている。同ライブラリは積極的に開発が進められており、バージョン2.7が9月にリリースされた。

 OpenLayersを使用するには、これへのリンクを張るか、OpenLayersのウェブサイトからダウンロードする。

 OpenLayersは、GeoServerMapServerなどのパッケージを用いて個人が独自に提供するデータにも適用できるし、WMSを介して公開されているデータにも適用できる。表示するデータを持つWMSサーバを検索するための容易な方法は存在しないが、ExploreOurPla.netには検索可能なインデックスが提供されており、3万個以上もの一般アクセス可能なレイヤが含まれているという。

マップとレイヤ

 NASA OnEarthは、WMSを介してデータを公開している。中でも有名なのは、衛星画像Blue Marble Next Generation(BMNG)である。このデータにアクセスするには、WMSサーバのURLと使用したいマップレイヤの名称を知っている必要がある。本記事では、NASAのWMSサーバとBlue Marble Next Generationの画像を用いて、OpenLayersの使用方法を説明する。

 OpenLayersの最も簡単なマップは、1つのOpenLayers.Mapオブジェクトと、1つ以上のOpenLayers.Layersオブジェクトから構成される。以下に、ウェブページにBlue Marble画像を表示するための簡単なOpenLayersスクリプトと、それに付随するHTMLを示す。

<html>
	<head>
		<title>OpenLayers tutorial</title>
		<script src="http://openlayers.org/api/OpenLayers.js"></script>
		<script type="text/javascript">

			function setHTML(response) {
				document.getElementById('nodeList').innerHTML = response.responseText;
				}

			function init(){

				var options = {
					minResolution: "auto",
					minExtent: new OpenLayers.Bounds(-1, -1, 1, 1),
					maxResolution: "auto",
					maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
				};
				var map = new OpenLayers.Map('map', options );

				var NASAwms = new OpenLayers.Layer.WMS( "NASA WMS",
					"http://wms.jpl.nasa.gov/wms.cgi?", {layers: 'BMNG',
						format: 'image/png'},
					{isBaseLayer: true});

				map.addLayer(NASAwms);
				map.zoomToMaxExtent();

			}

		</script>

		<style type="text/css">
			#map {
				width: 500px;
				height: 250px;
				border: 1px solid black;
				}
		</style>
	</head>
	<body onload="init()">

	<div id="map"></div>
	<div id="nodeList"></div>

	</body>
</html>

openlayers1_thumb.png
OpenLayersで表示したNASAのBlue Marbleの画像

 これは、NASAのWMSサーバから画像を取得し、デフォルトのパンおよびズームコントロールとともに表示するための基本的なスクリプトである。このコードをコピーして、ページをウェブブラウザで開けば、青と緑の地球の衛星画像が表示される。

 単一のレイヤしか表示できないわけではない。NASAのBlue Marbleでは美しい衛星画像が提供されているが、境界線など詳細部分が欠けている。米国地質研究所(US Geological Survey)もWMSを介してデータを公開している。別のレイヤを作成すれば、States_Generalizedレイヤを用いて米国の州境界線を取得することができる。

 USGSによるStates_Generalizedレイヤを表示するためのコードを追加すると、先ほどのスクリプトは次のようになる。

		<script src="http://openlayers.org/api/OpenLayers.js"></script>
		<script type="text/javascript">

			function setHTML(response) {
				document.getElementById('nodeList').innerHTML = response.responseText;
				}

			function init(){

				var options = {
					minResolution: "auto",
					minExtent: new OpenLayers.Bounds(-1, -1, 1, 1),
					maxResolution: "auto",
					maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
				};
				var map = new OpenLayers.Map('map', options );

				var NASAwms = new OpenLayers.Layer.WMS( "NASA WMS",
					"http://wms.jpl.nasa.gov/wms.cgi?", {layers: 'BMNG',
						format: 'image/png'},
					{isBaseLayer: true});

				var USGSwms = new OpenLayers.Layer.WMS ("USGS WMS",
					"http://toposervices.cr.usgs.gov/wmsconnector/com.esri.wms.Esrimap/USGS_EDNA_geo?",
					{layers: 'States_Generalized', format: 'image/png'},
					{isBaseLayer:false});

				map.addLayer(NASAwms);
				map.addLayer(USGSwms);

				map.zoomToMaxExtent();

			}

		</script>

 ここでブラウザの表示を更新してみると、そこに表示される地図は期待していたものとは違っているかもしれない。そこには米国各州の境界線が白い背景上に表示されているだけである。最初のスクリプトでは、「isBaseLayer: true」というオプションでNASA画像をベースレイヤに設定した。他のレイヤはその上に重ねられるため、ベースレイヤを隠してしまう可能性がある。同時に両方のレイヤを表示するには、USGSレイヤのオプションに「transparent: true」を追加して、これを透明に表示しなければならない。

openlayers2_thumb.png
OpenLayersによるマルチレイヤのマップ

 ここでついでに、地図の初期表示状態を変更しておこう。米国の州境界線のレイヤを加えたので、米国を中心に表示するよう設定するとよいだろう。

 これを行うには、緯度と経度、および初期ズームレベルを設定する。ワシントンDCを中心とするには、latlonという2つの変数を作成し、それぞれの値を38.890000と-77.020000にする。次にzoomという変数を作成してその値を3とすれば、地図はワシントンDCを中心に拡大され、米国の東部海岸地区のほぼ全域を表示するサイズになる。

 map.zoomToMaxExtent();という行の代わりに、これらの変数を用いたmap.setCenter(new OpenLayers.LonLat(lon, lat), zoom);を入れると、上述の初期表示設定が完了する。

上記の変更を加えたスクリプトは、以下のようになる。

		<script src="http://openlayers.org/api/OpenLayers.js"></script>
		<script type="text/javascript">

			function setHTML(response) {
				document.getElementById('nodeList').innerHTML = response.responseText;
				}

			function init(){

				var lat = 38.890000;
				var lon = -77.020000;
				var zoom = 3;
				var options = {
					minResolution: "auto",
					minExtent: new OpenLayers.Bounds(-1, -1, 1, 1),
					maxResolution: "auto",
					maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
				};
				var map = new OpenLayers.Map('map', options );

				var NASAwms = new OpenLayers.Layer.WMS( "NASA WMS",
					"http://wms.jpl.nasa.gov/wms.cgi?", {layers: 'BMNG',
						format: 'image/png'},
					{isBaseLayer: true});

				var USGSwms = new OpenLayers.Layer.WMS ("USGS WMS",
					"http://toposervices.cr.usgs.gov/wmsconnector/com.esri.wms.Esrimap/USGS_EDNA_geo?",
					{layers: 'States_Generalized', format: 'image/png', transparent: true},
					{isBaseLayer:false});

				map.addLayer(NASAwms);
				map.addLayer(USGSwms);

				map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);

			}


		</script>

マーカー

 Google Mapsと同様にOpenLayersでは、地図上の興味のある地点にマーカーを配置することができる。これを行うための最も簡単な方法は、テキストレイヤを作成することである。

 テキストレイヤは、1つ以上の興味のある地点に関する緯度と経度、名称、説明、使用するアイコンが並んだ、タブ区切りテキストファイルを読んで表示する。地図に表示されたマーカーをクリックすると、その地点の名称と説明を示すテキストバブルが表示される。その表示はHTMLで制御することができる。もう一度マーカーをクリックすると、テキストバブルが閉じる。

 ワシントンDC、ニューヨーク、アトランタの各都市に、OpenLayersのデフォルトのアイコンをマーカーとして表示する、簡単なテキストレイヤファイルを以下に示す。

point	title	description	icon
38.905,-77.016	<h4>Washington DC</h4>	Population: 588,292
40.664,-73.938	<h4>New York</h4>	Population: 8,274,527
33.763,-84.423	<h4>Atlanta</h4>	Population: 519,145
 

このテキストをtextlayer.txtという名前のファイルに保存したとすると、地図上にこの情報を表示するためのコードは以下のようになる。

 
<script src="http://openlayers.org/api/OpenLayers.js"></script> <script type="text/javascript"> function init(){ var lat = 38.890000; var lon = -77.020000; var zoom = 3; var options = { theme: null, minResolution: "auto", minExtent: new OpenLayers.Bounds(-1, -1, 1, 1), maxResolution: "auto", maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90) }; var map = new OpenLayers.Map('map', options ); var NASAwms = new OpenLayers.Layer.WMS( "NASA WMS", "http://wms.jpl.nasa.gov/wms.cgi?", {layers: 'BMNG', format: 'image/png'}, {isBaseLayer: true}); var USGSwms = new OpenLayers.Layer.WMS ("USGS WMS", "http://toposervices.cr.usgs.gov/wmsconnector/com.esri.wms.Esrimap/USGS_EDNA_geo?", {layers: 'States_Generalized', format: 'image/png', transparent: true}, {isBaseLayer:false}); map.addLayers([NASAwms, USGSwms]); map.setCenter(new OpenLayers.LonLat(lon, lat), zoom); var textlayer = new OpenLayers.Layer.Text( "text", { location:"./textlayer.txt"} ); map.addLayer(textlayer); } </script>

コントロール

openlayers3_thumb.png
コントロールを配置したOpenLayersのマップ

 OpenLayersでは、地図に配置するコントロールを自由に選択することもできる。

 コントロールを地図に配置するには、OpenLayers.MapオブジェクトのaddControl()メソッドを使用するか、あるいはOpenLayers.Mapオブジェクト作成時にオプションにおいてコントロールのリストを指定することもできる。

 マップコントロールはすべて、OpenLayers.Controlクラスのサブクラスであり、OpenLayers.Control.PanZoom()によるパンおよびズームコントロール、OpenLayers.Control.LayerSwitcherによるレイヤ表示ボックス、OpenLayers.Control.ScaleLine()によるスケールバー、OpenLayers.Control.MousePosition()によるマウス位置の緯度と経度の自動表示などがある。

 デフォルトでは、マウス位置の緯度と経度、およびスケールバーのマイルとキロメートル表示は黒色のテキストで表示される。このままでは、Blue Marbleレイヤの海の濃い青色の上では見にくいが、CSSを用いてOpenLayersの要素の表示方法を制御することができる。まず、OpenLayersのデフォルトのCSSファイルにリンクし、そのデフォルト設定を自分のCSSでオーバーライドする。自分のCSSは、ウェブページ内に記述してもよいし、別のCSSファイルをリンクしてもよい。またマップのオプションにおいて、「theme: null」を指定する必要もある。

<html>
	<head>
		<title>OpenLayers tutorial</title>
		 <link rel="stylesheet" href="http://openlayers.org/api/theme/default/style.css" type="text/css" />

		<style type="text/css">
			p { width: 500px; }

			div.olControlMousePosition {
				font-family: Times;
				font-size: 0.75em;
				color: red;
				}

			div.olControlScaleLine {
				font-family: Times;
				font-size: 0.75em;
				color: red;
				}
		</style>
		<script src="http://openlayers.org/api/OpenLayers.js"></script>
		<script type="text/javascript">

			function init(){

				var lat = 38.890000;
				var lon = -77.020000;
				var zoom = 3;
				var options = {
					theme: null,
					minResolution: "auto",
					minExtent: new OpenLayers.Bounds(-1, -1, 1, 1),
					maxResolution: "auto",
					maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
					controls: [
						new OpenLayers.Control.LayerSwitcher({'ascending':false}),
						new OpenLayers.Control.MousePosition(),
						new OpenLayers.Control.PanZoom(),
						new OpenLayers.Control.ScaleLine()
						]
				};
				var map = new OpenLayers.Map('map', options );

				var NASAwms = new OpenLayers.Layer.WMS( "NASA WMS",
					"http://wms.jpl.nasa.gov/wms.cgi?", {layers: 'BMNG',
						format: 'image/png'},
					{isBaseLayer: true});

				var USGSwms = new OpenLayers.Layer.WMS ("USGS WMS",
					"http://toposervices.cr.usgs.gov/wmsconnector/com.esri.wms.Esrimap/USGS_EDNA_geo?",
					{layers: 'States_Generalized', format: 'image/png', transparent: true},
					{isBaseLayer:false});

				USGSwms.setVisibility(false);

				map.addLayers([NASAwms, USGSwms]);

				map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);

				var textlayer = new OpenLayers.Layer.Text( "text", { location:"./textfile.txt"} );
				map.addLayer(textlayer);

			}


		</script>

		<style type="text/css">
			#map {
				width: 500px;
				height: 250px;
				border: 1px solid black;
				}
		</style>
	</head>
	<body onload="init()">

	<div id="map"></div>
	<div id="nodeList"></div>

	</body>
</html>

Google Maps

 OpenLayersではGoogle Mapsからのデータも表示することができる。まずはGoogle Maps APIのキーを取得する必要がある。Google Maps用には、OpenLayers.Layer.Googleという独自のクラスがあり、デフォルトでは標準的なGoogleストリートマップを表示する。それ以外には、G_SATELLITE_MAPまたはG_HYBRID_MAPタイプを選択することができる。

		<script src="http://openlayers.org/api/OpenLayers.js"></script>
		<script src="http://maps.google.com/maps?file=api&v=2&key=your_key_here" type="text/javascript"></script>
		<script type="text/javascript">
			function setHTML(response) {

				document.getElementById('nodeList').innerHTML = response.responseText;
				}

			function init(){
 				var google = new OpenLayers.Layer.Google( "Google", { type: G_HYBRID_MAP } );

				var options = {
					minResolution: "auto",
					minExtent: new OpenLayers.Bounds(-1, -1, 1, 1),
					maxResolution: "auto",
					maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
				};
				var map = new OpenLayers.Map('map', options );

 			 	map.addLayer(google);
				map.zoomToMaxExtent();

			}

		</script>

まとめ

 今回紹介したのはOpenLayersの機能のほんの一部である。ここで紹介した例はすべて、OGCのWeb Map Serviceプロトコルを使用するものだったが、OpenLayersでは、Web Feature Serviceサーバ、GeoRSS、KMLファイルから取得した地物データを地図に表示する機能も提供されている。

Justin Palkは、ミシガン大学アンアーバ校にてコンピュータサイエンスの学士号を取得しており、ソフトウェア開発に2年間従事した後、ジャーナリストとして活動をしている。

Linux.com 原文(2008年12月24日)