Web Map Applicationの機能追加について[Chapter 58]

OpenLayersを使ってみる。[Chapter 58]

Flickerを使ったWeb Map Applicationを作る。[Chapter 57] に引き続き、proxy hostを使ったWeb Map Applicationの機能追加について学んでいきます。

この章以降は、

  • ゼロからFlickrを使用して、Web Map Applicationを構築する。 → 今回はここ
  • Applicationの配置と開発することの意味について議論する。
  • OpenLayers Library fileを作成する方法について。

について順番に学んでいきます。

OpenLayers 2.10 Beginner's Guideなる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

機能追加について

これまでのところ、fileに保存したFlickrのデータにアクセスして、地図に加えました。
実際にOpenLayersの視点から見て、データのロードすることは有用です。しかし、実際に十分な「Web Map Application」とは言えません。
したがって、より有用なWeb Map Applicationを構築する方法を考えましょう。

一般的に 2つの基本的な方法があります。

  1. Interactivityに地図を追加する。
  2. 「live」データを使用する。(kml fileを手動でdownloadすることなくApplicationに取り込む方法)

最初の部分に注目し、次に、Intractivityに地図を追加について考えてみましょう。

Adding interactivity

前の例において、extractStylesを使用したので、featureはそれぞれexternalGraphicなpropertyを受け取りました。しかし、重なり合っているため、地図上にどこか確かめるのは困難です。
そこで場所と写真の両方をうまく表示する方法を考えています。

Point featureの使用およびselectFeature Controlの利用を考えてみます。
Pointの場所が集中している場合も考えられるので、cluster strategiesを使用します。

Featureを選択する場合、何が起こらなければなりませんが、mouse clickした時にfeatureに関する情報を示す必要があるでしょう。また、その情報はFlickrの写真および任意の関連するattributeです。
したがって、今のところ単純にしておき、featureが選択されている場合、地図より下にFlickrの写真とattributeを示してみましょう。

Web Map Applicationの機能追加 code

Flickr dataを使ったselectFeatureの簡単なexample codeを作成してみましょう。以下のcodeを入力します。
保存先は、c:¥ms4w¥apache¥htdocs¥openlayer¥chapter11¥にしておきます。
ファイル名は、chapter11_ex3_interaction.htmlで保存します。

 
<!DOCTYPE html>
<html lang='ja'>
	<head>
		<meta charset='utf-8' />
		<script type='text/javascript' src='http://localhost/openlayers/OpenLayers.js'></script>
		<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
		<script type='text/javascript'>
			var map;
			var vector_layer;
			function init() {
				//Create a map with an empty array of controls
				map = new OpenLayers.Map('map_element');

				//Create a base layer
				var google_map = new OpenLayers.Layer.Google(
					'Google Layer', 
					{}
				);
				map.addLayer(google_map);

				//Add vector layer
				vector_layer = new OpenLayers.Layer.Vector('Flickr Data', {
					projection : new OpenLayers.Projection('EPSG:4326'),
					protocol : new OpenLayers.Protocol.HTTP({
						url : 'flickr_data.kml',
						format : new OpenLayers.Format.KML({
							extractAttributes : true,
							extractStyles : true
						})
					}),
					strategies : [new OpenLayers.Strategy.Fixed(), new OpenLayers.Strategy.Cluster()]
				});
				map.addLayer(vector_layer);

				//Let's style the features
				//Create a style object to be used by a StyleMap object
				var vector_style = new OpenLayers.Style({
					'fillColor' : '#669933',
					'fillOpacity' : .8,
					'fontColor' : '#f0f0f0',
					'fontFamily' : 'arial, sans-serif',
					'fontSize' : '.9em',
					'fontWeight' : 'bold',
					'label' : '${num_points}',
					'pointRadius' : '${point_radius}',
					'strokeColor' : '#aaee77',
					'strokeWidth' : 3
				},
				//Second parameter contains a context parameter
				{
					context : {
						num_points : function(feature) {
							return feature.attributes.count;
						},
						point_radius : function(feature) {
							return 9 + (feature.attributes.count)
						}
					}
				});

				var vector_style_select = new OpenLayers.Style({
					'fillColor' : '#cdcdcd',
					'fillOpacity' : .9,
					'fontColor' : '#232323',
					'strokeColor' : '#ffffff'
				})

				//Create a style map object and set the 'default' intent to the
				var vector_style_map = new OpenLayers.StyleMap({
					'default' : vector_style,
					'select' : vector_style_select
				});

				//Add the style map to the vector layer
				vector_layer.styleMap = vector_style_map;

				//Add a select feature control
				var select_feature_control = new OpenLayers.Control.SelectFeature(vector_layer, {
					hover : true
				})
				map.addControl(select_feature_control);
				select_feature_control.activate();

				//Functions to call for the select feature control
				function on_select_feature(event) {
					//Store a reference to the element
					var info_div = document.getElementById('photo_info_wrapper');

					//Clear out the div
					info_div.innerHTML = '';

					//Store the clusters
					var cluster = event.feature.cluster;

					//Loop through the cluster features
					for (var i = 0; i < cluster.length; i++) {
						//Update the div with the info of the photos
						info_div.innerHTML += "<strong>" + cluster[i].attributes.name + "</strong><br />" + "<img src='" + cluster[i].style.externalGraphic + "' />" + cluster[i].attributes.Snippet + "<br /><hr />";
					}
				}

				//on unselect function
				function on_unselect_feature(event) {
					//Store a reference to the element
					var info_div = document.getElementById('photo_info_wrapper');

					//Clear out the div
					info_div.innerHTML = '';
				}


				vector_layer.events.register('featureselected', this, on_select_feature);
				vector_layer.events.register('featureunselected', this, on_unselect_feature);

				if (!map.getCenter()) {
					map.zoomToMaxExtent();
				}

			}

		</script>
	</head>

	<body onload='init();'>
		<div id='map_element' style='width: 600px; height: 400px;'></div>
		<div id='photo_info_wrapper'></div>
	</body>
</html>

今回も、GooglemapをBase layerとして使用するので、

<script src="http://maps.google.com/maps/api/js?sensor=false"></script>

でGooglemaps ver.3のscriptを読み込みます。

codeでまずは、map objectを作成します。

//Create a map with an empty array of controls
map = new OpenLayers.Map('map_element');
 
//Create a base layer
// Googlemaps
var google_map = new OpenLayers.Layer.Google(
	'Google Layer',
	{}
);
map.addLayer(google_map);

google_mapをbase layerとして作成します。

次に、vector layerを追加します。

//Add vector layer
vector_layer = new OpenLayers.Layer.Vector('Flickr Data', {
	projection : new OpenLayers.Projection('EPSG:4326'),
	protocol : new OpenLayers.Protocol.HTTP({
		url : 'flickr_data.kml',
		format : new OpenLayers.Format.KML({
			extractAttributes : true,
			extractStyles : true
		})
	}),
	strategies : [new OpenLayers.Strategy.Fixed(), new OpenLayers.Strategy.Cluster()]
});
map.addLayer(vector_layer);

protocol : new OpenLayers.Protocol.HTTP(…)でkmlファイルを飛び出して、formatでkmlを。
protocolの内部で、KML classからのformar objectをセット・アップし、それぞれのイメージに関連したattributeにアクセスすることができるように、extractAttributes : trueとします。
最後に、strategies : […]でFixed()とCluster()を設定します。

次に、vector_styleを追加して、

//Let's style the features
//Create a style object to be used by a StyleMap object
var vector_style = new OpenLayers.Style({
	'fillColor' : '#669933',
	'fillOpacity' : .8,
	'fontColor' : '#f0f0f0',
	'fontFamily' : 'arial, sans-serif',
	'fontSize' : '.9em',
	'fontWeight' : 'bold',
	'label' : '${num_points}',
	'pointRadius' : '${point_radius}',
	'strokeColor' : '#aaee77',
	'strokeWidth' : 3
},
//Second parameter contains a context parameter
{
	context : {
		num_points : function(feature) {
			return feature.attributes.count;
		},
		point_radius : function(feature) {
			return 9 + (feature.attributes.count)
		}
	}
});
 
var vector_style_select = new OpenLayers.Style({
	'fillColor' : '#cdcdcd',
	'fillOpacity' : .9,
	'fontColor' : '#232323',
	'strokeColor' : '#ffffff'
})

のようにvector_style_selectのstyleを設定します。

次に、vector_style_mapを

//Create a style map object and set the 'default' intent to the
var vector_style_map = new OpenLayers.StyleMap({
	'default' : vector_style,
	'select' : vector_style_select
});
 
//Add the style map to the vector layer
vector_layer.styleMap = vector_style_map;

select時とunselect時のvector_layer.styleMapのstyleを作成します。

Controlを下記のように追加して、

//Add a select feature control
var select_feature_control = new OpenLayers.Control.SelectFeature(vector_layer, {
	hover : true
})
map.addControl(select_feature_control);
select_feature_control.activate();

controlをactiveにします。

次に、Feature select時とunselect時について、

//Functions to call for the select feature control
function on_select_feature(event) {
	//Store a reference to the element
	var info_div = document.getElementById('photo_info_wrapper');
 
	//Clear out the div
	info_div.innerHTML = '';
 
	//Store the clusters
	var cluster = event.feature.cluster;
 
	//Loop through the cluster features
	for (var i = 0; i < cluster.length; i++) {
		//Update the div with the info of the photos
		info_div.innerHTML += "<strong>" + cluster[i].attributes.name + "</strong><br />" + "<img src='" + cluster[i].style.externalGraphic + "' />" + cluster[i].attributes.Snippet + "<br /><hr />";
	}
}
 
//on unselect function
function on_unselect_feature(event) {
	//Store a reference to the element
	var info_div = document.getElementById('photo_info_wrapper');
 
	//Clear out the div
	info_div.innerHTML = '';
}

functionを定義します。
内容は、feature selectのmouse over時のinfo_div.innerHTMLにhtmlを作成します。
Unselect時には、info_div.innerHTML = ''となります。

そして最後に、eventの登録を

vector_layer.events.register('featureselected', this, on_select_feature);
vector_layer.events.register('featureunselected', this, on_unselect_feature);

のように、feature select時とunselect時を登録します。
保存後、FireFoxを立ち上げて、http://localhost/openlayers/chapter11/chapter11_ex1.htmlと入力すると、
blog.godo-tys.jp_wp-content_gallery_openlayers_58_image01.jpg

ようにkml fileのpoint dataが読み込まれてmapに表示されます。
Map上のcluster pointにmouse overすると、
blog.godo-tys.jp_wp-content_gallery_openlayers_58_image02.jpg

のようにkml fileのattributeの内容がmapの下に表示されます。
他のcluster pointにmouse overしても
blog.godo-tys.jp_wp-content_gallery_openlayers_58_image03.jpg

のようにkml fileのattributeの内容がmapの下に表示されます。

今回のまとめ

Flickerを使ったWeb Map Applicationの機能追加について学びました。
次回は、proxy hostを使ったreal timeのWeb Map Applicationの作成について学んでいきます。

また、本tutorialは、htmlやCSSやJavaScriptの基本的なことはある程度理解している前提で今後も話を進めていきます。また、誤字、脱字、spell間違いや勘違いも多々出てくると考えられます。
それは違うじゃん!!とかいろんな意見をいただければと思います。
そこんところ ヨロシク~~!!

OpenLayers Tutorialの目次に戻る。

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

WP-SpamFree by Pole Position Marketing

Social Widgets powered by AB-WebLog.com.