Monthly Archives: 8月 2013

OpenLayers Library fileの作成について[Chapter 61]

====== OpenLayersを使ってみる。[Chapter 61] ======
[[http://blog.godo-tys.jp/2013/08/31/4048/|Web Map Applicationの作成[Chapter 60] ]]に引き続き、OpenLayers Library fileの作成について学んでみます。
この章で、OpenLayers Tutorialが終了します。

この章以降は、
* ゼロからFlickrを使用して、Web Map Applicationを構築する。
* Applicationの配置と開発することの意味について議論する。
* OpenLayers Library fileを作成する方法について。 -> **今回はここ**
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== OpenLayers Library fileの作成 =====
OpenLayers.js library fileを作成してみましょう。
本Tutorialの全体にわたって、OpenLayers.jsと呼ばれるファイルを無意識のうちに使ってきました。そして、このOpenLayersが提供する機能(class、function、methodなど)を利用してきました。

==== file sizeを小さくする。 ====
使用しているOpenLayers.js fileの容量はversion 2.12で、約728のKBです。
なるべくならば、容量を少なくしたjavascriptを使うべきですが、versionが上がるほどにfile sizeは大きくなっていくことが多いもの事実です。
例えば、OpenLayers.jsは
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_61/image01.jpg}}

にように機能の異なるlaibrary fileがあります。
Debug版では3MBになろうかと言うsizeになります。mobileはスマホやタブレット対応のOpenLayersになります。
mobileのjsを使った例が、[[http://openlayers.org/dev/examples/mobile-jq.html#mappage|moblide OpenLayers example]]にあります。目を通しておくと良いですね。

本章では、できるだけ容量を小さくしてlibrary load時間を短縮し、かつ機能的にも十分であるlibrary fileをつくるために、提供されているOpenLayers.jsをそのまま使うのでなく、カスタマイズしたOpenLayers.jsの作成を行ってみます。

==== Using the OpenLayers build file ====
OpenLayers archive fileをダウンロードする場合、その内部にbuildフォルダーがあります。
ここでは、ms4wを使っていますので、OpenLayersは**C:¥ms4w¥apps¥openlayers-2.12**内にinstallされ、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_61/image01.jpg}}
のfolder構成になっています。

そして、**build**フォルダー内に、**build.py**と呼ばれるファイルがあります。それは、設定ファイルに基づいたOpenLayers.jsファイルを作成するpython scriptです。
**build**フォルダーは、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_61/image02.jpg}}
のbuild folder内のfile構成になっています。
OpenLayersのjavascript codeがすべて単一のファイルに含まれているので、libraryをこの方法で作ってやることは、単一のファイル構造と呼ばれます。

したがって、applicaiotnが必要とするclassだけを含んでいるOpenLayers.jsファイルを作成するようにconfig scriptを作成すれば、容量の小さなOpenLayers.js libraly fileを作成することができます。

==== Configuring the build script ====
configuration scriptを実行する場合、OpenLayers.jsファイルを作成する場合に[include]や[exclude]の設定などのfileを捜します。
OpenLayersがデフォルトで使う2つの設定ファイルがあります。

– full.cfg : 構造スクリプトにすべてを含めさせます。
– lite.cfg : WMSあるいはtiled layerを作成するために単なるclassの必要最低限量を含んでいて、controlを含みません。

これらのファイルのうちの1つのcopyすることにより、自分のファイルを作成することができます。
カスタマイズ用のconfiguration ファイルを作成する場合、full.cfgまたはlite.cfgのファイルからの[first]と呼ばれたセクションを少なくとも含まなければなりません。

その[include]セクションは、どのファイルをOpenLayers.js出力ファイルに加えなければならないか明示します。
もしブランクであれば、ファイルがすべて含まれるでしょう。
そうでなければ、このセクションの中で指定されたファイルだけが含まれます。
ここでどのファイルを含まなければならないか知るために、使用するapplicationでのOpenLayersのクラス(例えば新しいOpenLayers.Classnameを呼ぶ場合)を見ることで必要なfileを設定しなければなりません。
その[exclude]セクションは、最終のconfiguration fileに含まれないクラスです。

==== building a Config file ====
1.Directory内のlite.cfg fileをcopyして、example_1.cfgとrenameします。

2.example_1.cfgをtext editor等で修正します。例えば、


# Config File
[first]
OpenLayers/SingleFile.js
OpenLayers.js
OpenLayers/BaseTypes.js
OpenLayers/BaseTypes/Class.js
OpenLayers/Util.js
[last]
[include]
OpenLayers/Map.js
OpenLayers/Layer/WMS.js
OpenLayers/Control/LayerSwitcher.js
OpenLayers/Control/Navigation.js
OpenLayers/Control/Scale.js
[exclude]

のようなconfiguration fileとします。

==== Running the build script ====
OpenLayers.jsファイルをbuildするために、私たちはbuild.py scriptを実行しなければなりません。
これは、pythonが必要になります。[[http://www.python.org/|python]]が必要になります。versionは2.6あるいは2.7のバージョンが必要になります。ここでは、**C:¥Python27**でpython 2.7.5がinstallされているものとします。

Python scriptが実行される時、設定ファイルを捜し、設定ファイルをもとに結合したOpenLayers.jsファイルをbuildして、自動的にクラス依存性を解決してくれます。
最終的には、結合したjavascript codeを圧縮(余白および不必要なキャラクターを削除する)し、directoryにOpenLayers.js fileを作成します。

Linux上で、scriptを実行するために、build ディレクトリーにcdして
**./build.py config_file.cfg**
のコマンドを入力します。
ここでconfig_file.cfgはオプションです。
もし含まれていなければ、full.cfgファイルが使用されます。

Windowsにおいては、build ディレクトリーにcdして、cmdコマンドプロンプトを使用し、実行することができます、同じ方法をファイルします。
例えば、
**C:¥ms4w¥apps¥openlayers-2.12¥build¥build.py config_file.cfg**
のようなコマンドを実行することでOpenLayers.js library fileが作成されます。
ここでconfig_file.cfgはオプションです。
もし含まれていなければ、full.cfgファイルが使用されます。

==== running the Build script ====
1.作成したconfiguration fileのあるfolderからcommandを実行してください。
**./build.py example_1.cfg**

2.scriptが何を行っているかを確認するために実行した後に出力を見るべきです。
このexample_1.cfgの場合、合計34ファイルをmergeしました。また、最終のfile sizeは160KB強となります。それはオリジナルの728KBからの大きな縮小となります。

===== 今回のまとめ =====
OpenLayers.jsをカスタマイズしてbuildする方法について学びました。必要な機能だけを取り出せば、libraryの容量を小さくすることができるので、mobile環境でのOpenLayersの利用もmemoryを気にせずに使うことができます。
今回でOpenLayer Tutorialは終了となります。今後は、blogの内容を元にducuwikiでTutorialをまとめる予定です。

このTurotialは基礎編ですので、OpenLayersの応用については、[[http://www.packtpub.com/openlayers-create-gis-web-applications-cookbook/book|OpenLayers Cookbook]]が参考になります。 ただし、あまり馴染みのないJavaScript libraryのdojo.jsを使っていますが、それほど難しいcodeではないので、十分に理解でききると思います。

そして、[[http://www.packtpub.com/openlayers-create-gis-web-applications-cookbook/book|OpenLayers Cookbook]]の使えそうなexampleについて、今後はいくつかblogに書き留めておく予定です。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

Web Map Applicationの作成[Chapter 60]

====== OpenLayersを使ってみる。[Chapter 60] ======
[[http://blog.godo-tys.jp/2013/08/30/4003/|Proxy Hostを使ったreal time dataの使い方について[Chapter 59] ]]に引き続き、Web Map Applicationの機能追加をやってみます。
この章で、OpenLayers Tutorialのexample codeはすべて終了します。

この章以降は、
* ゼロからFlickrを使用して、Web Map Applicationを構築する。 -> **今回はここ**
* Applicationの配置と開発することの意味について議論する。
* OpenLayers Library fileを作成する方法について。
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== Proxy hostを使ったrela time data =====
前章の[[http://blog.godo-tys.jp/2013/08/30/4003/|Proxy Hostを使ったreal time dataの使い方について[Chapter 59] ]]では、リアル・タイムのデータにアクセスするためにproxy hostを使いました。

しかし、kmlを呼び出す際に**tags : bird**とhard cordingしているため、他のtagsに変更ができません。そこで、汎用性を持たせるために、tagsに値を任意で指定できるように変更してみましょう。
htmlへの値のinputは




で行い、show data buttonをclickすることでPOSTされます。

==== tagsの変更ができるWeb Map Application code ====
Proxy hostを使って、Flickr dataをloadして、tagsを任意に変更する簡単なexample codeを作成してみましょう。以下のcodeを入力します。
保存先は、c:¥ms4w¥apache¥htdocs¥openlayer2_12¥chapter11¥にしておきます。
ファイル名は、chapter11_ex5_final.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() {
				//specify proxyhost
				OpenLayers.ProxyHost = '/cgi-bin/proxy.cgi?url=';

				//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 : 'http://api.flickr.com/services/feeds/geo/',
						params : {
							'format' : 'kml',
							'tags' : 'bird'
						},
						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, {
				})
				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();
				}

				//-------------------------------
				//HTML Related
				//-------------------------------
				//Function to be called that updates vector layer when submit
				//  is clicked
				function update_vector_layer() {
					//Change URL based on input tags
					vector_layer.protocol.options.params['tags'] = document.getElementById('input_tags').value

					//Refresh the layer with the new params
					vector_layer.refresh();

					//Lastly, clear out the div that shows photo info
					document.getElementById('photo_info_wrapper').innerHTML = '';
				}

				//Add events to HTML input element
				document.getElementById('input_submit').addEventListener('click', update_vector_layer, false);

			}

		</script>
	</head>

	<body onload='init();'>
		<div id='map_element' style='width: 600px; height: 400px;'></div>
		<div id='input_wrapper' style='position:absolute; left:610px; top:0;'>
			<input type='text' id='input_tags' value='bird' />
			<input type='button' id='input_submit' value='Show Data' />
		</div>
		<div id='photo_info_wrapper'></div>
	</body>
</html>

今回は、[[http://blog.godo-tys.jp/2013/08/30/4003/|ProxyHostを使ったreal time dataの使い方について[Chapter 59] ]]のcodeに追加しています。

まず、tagの変更があった場合、Vector layerをreloadして新しいdataを追加するために、

//-------------------------------
//HTML Related
//-------------------------------
//Function to be called that updates vector layer when submit
// is clicked
function update_vector_layer() {
//Change URL based on input tags
vector_layer.protocol.options.params['tags'] = document.getElementById('input_tags').value

//Refresh the layer with the new params
vector_layer.refresh();

//Lastly, clear out the div that shows photo info
document.getElementById('photo_info_wrapper').innerHTML = '';
}

のようにfunction update_vector_layerを追加して、’tags’でtextboxの値を読み取ります。

そして、HTMLが入力されたときのeventを

//Add events to HTML input element
document.getElementById('input_submit').addEventListener('click', update_vector_layer, false);

のように定義します。

また、HTMLで




のように

ブロックにtextとbuttonを配置して、tagsを読み込むようにします。

保存後、FireFoxを立ち上げて、http://localhost/openlayer2_12/chapter11/chapter11_ex5_final.htmlと入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_60/image01.jpg}}

ようにmapの右上にtextとbuttonに表示されます。
textに**fish**と入力して、show data buttonをclickして、cluster makerをclickすると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_60/image02.jpg}}

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

また、textに**cat**と入力して、show data buttonをclickして、cluster makerをclickすると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_60/image03.jpg}}

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

===== 今回のまとめ =====
tagsの変更をinteractiveに変更し、ProxyHostを使ったWeb Map Applicationについて学びました。これを応用すれば外部サイトからkmlデータなどを呼び出してmapに描画することができるので、interactiveなApplicationを作成することができます。
次回は、OpenLayers Library fileの作成にを学んでいきます。
いよいよ最後の章です。時間がかかりましたが、とりあえずはTutorialの終了となります。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

ProxyHostを使ったreal time dataの使い方について[Chapter 59]

====== OpenLayersを使ってみる。[Chapter 59] ======
[[http://blog.godo-tys.jp/2013/08/29/3996/|Web Map Applicationの機能追加について[Chapter 58] ]]に引き続き、proxy hostを使ったWeb Map Applicationの作成について学んでいきます。

この章以降は、
* ゼロからFlickrを使用して、Web Map Applicationを構築する。 -> **今回はここ**
* Applicationの配置と開発することの意味について議論する。
* OpenLayers Library fileを作成する方法について。
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== Proxy hostを使ったrela time data =====
いままではflickr_data.kmlデータはthird party siteのものです。そしてダウンロードするで利用することができました。

ここでは行うことは、リアル・タイムのデータにアクセスすることです。
これをするために、ProxyHostを使用する必要があります。
ProxyHostは、[[http://blog.godo-tys.jp/2013/08/17/3755/]]で学びました。本質的に私たちに要求するように(proxyして働いて)あるserver side scriptに要求することにより、AJAXのドメイン要求制約の裏をかく方法です。

==== getting dynamic data ====
1. 単に2つのcodeを加えるだけで、proxyを使うことができます。
2. 最初に、私たちは、proxyhostのURLを定義する必要があります。
それはCGI scriptであり、python scriptです。
CGI scriptは、C:¥ms4w¥apps¥openlayers-2.12¥examples¥proxy.cgiを使います。
proxy.cgiを使用する場合は、必ずpythonのinstallが必要です。今回はpython2.7.2を[[http://www.python.jp/download/|ここからversion.2.7.5]]をdownloadしてinstallしました。
今回は、ms4wを使っているので、C:¥ms4w¥Apache¥cgi-binにproxy.cgiをcopyしておきます。
各自環境でProxyHostのURLを変更して、ProxyHostを指定してください:
OpenLayers.ProxyHost=’/cgi-bin/proxy.cgi?url=’;

今回使用するproxy.cgiは以下のpythonのcodeになります。
また、Windows環境で動かすので、proxy.cgiの1行目を**#!C:/Python27/python.exe -u**に変更しておきます。pythonの位置については各自の環境に合わせてください。

#!C:/Python27/python.exe -u

"""This is a blind proxy that we use to get around browser
restrictions that prevent the Javascript from loading pages not on the
same server as the Javascript.  This has several problems: it's less
efficient, it might break some sites, and it's a security risk because
people can use this proxy to browse the web and possibly do bad stuff
with it.  It only loads pages via http and https, but it can load any
content type. It supports GET and POST requests."""

import urllib2
import cgi
import sys, os

# Designed to prevent Open Proxy type stuff.

allowedHosts = ['www.openlayers.org', 'openlayers.org', 
                'labs.metacarta.com', 'world.freemap.in', 
                'prototype.openmnnd.org', 'geo.openplans.org',
                'sigma.openplans.org', 'demo.opengeo.org',
                'www.openstreetmap.org', 'sample.azavea.com',
                'v2.suite.opengeo.org', 'v-swe.uni-muenster.de:8080', 
                'vmap0.tiles.osgeo.org', 'www.openrouteservice.org',
                'maps.wien.gv.at', 'api.flickr.com']

method = os.environ["REQUEST_METHOD"]

if method == "POST":
    qs = os.environ["QUERY_STRING"]
    d = cgi.parse_qs(qs)
    if d.has_key("url"):
        url = d["url"][0]
    else:
        url = "http://www.openlayers.org"
else:
    fs = cgi.FieldStorage()
    url = fs.getvalue('url', "http://www.openlayers.org")

try:
    host = url.split("/")[2]
    if allowedHosts and not host in allowedHosts:
        print "Status: 502 Bad Gateway"
        print "Content-Type: text/plain"
        print
        print "This proxy does not allow you to access that location (%s)." % (host,)
        print
        print os.environ
  
    elif url.startswith("http://") or url.startswith("https://"):
    
        if method == "POST":
            length = int(os.environ["CONTENT_LENGTH"])
            headers = {"Content-Type": os.environ["CONTENT_TYPE"]}
            body = sys.stdin.read(length)
            r = urllib2.Request(url, body, headers)
            y = urllib2.urlopen(r)
        else:
            y = urllib2.urlopen(url)
        
        # print content type header
        i = y.info()
        if i.has_key("Content-Type"):
            print "Content-Type: %s" % (i["Content-Type"])
        else:
            print "Content-Type: text/plain"
        print
        
        print y.read()
        
        y.close()
    else:
        print "Content-Type: text/plain"
        print
        print "Illegal request."

except Exception, E:
    print "Status: 500 Unexpected Error"
    print "Content-Type: text/plain"
    print 
    print "Some unexpected error occurred. Error text was:", E

3. 次に、Flickrのurlをproxy host中の許可されたホスト変数に加える必要があります。
proxy.cgiを編集して、Flickr URLをallowedHosts(OpenLayersによって提供されるファイルのトップの近くの)のリストに加えます。
最後のアイテムの後にコンマを加えて、次のように、’api.flickr.com’をリストに加えます。
**allowedHosts=[…, ‘api.flickr.com’]**

4. 最後に、vector layerが指すURLを変更します。
Vector layerの中のprotocol objectでは、urlを変更し、URL呼び出しに追加される追加のGET変数を指定するparamsオブジェクトを加える必要があります。
この場合、Formatとtagのparamsを指定します。
例としては、

protocol: new OpenLayers.Protocol.HTTP({
url: 'http://api.flickr.com/services/feeds/geo/',
params: {'format':'kml', 'tags':'bird'},

のように修正します。

5. 以上で完了です。これでreal timeでdataをloadすることができます。

==== Proxy hostを使ったWeb Map Application code ====
Proxy hostを使って、Flickr dataをloadする簡単なexample codeを作成してみましょう。以下のcodeを入力します。
保存先は、c:¥ms4w¥apache¥htdocs¥openlayer2_12¥chapter11¥にしておきます。
ファイル名は、chapter11_ex4_proxy_host.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() {
				//specify proxyhost
				OpenLayers.ProxyHost = '/cgi-bin/proxy.cgi?url=';

				//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 : 'http://api.flickr.com/services/feeds/geo/',
						params : {
							'format' : 'kml',
							'tags' : 'bird'
						},
						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>

今回は、proxy hostを

//specify proxyhost
OpenLayers.ProxyHost = '/cgi-bin/proxy.cgi?url=';

のように追加します。

次に、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 : 'http://api.flickr.com/services/feeds/geo/',
params : {
'format' : 'kml',
'tags' : 'bird'
},
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ファイルをurlとparamsから呼び出して、formatでkmlをloadします。
この**url : ‘http://api.flickr.com/services/feeds/geo/’**は外部ファイルがあるurl siteになります。
protocolの内部で、KML classからのformar objectをセット・アップし、それぞれのイメージに関連したattributeにアクセスすることができるように、**extractAttributes : true**とします。
最後に、strategies : […]でFixed()とCluster()を設定します。

保存後、FireFoxを立ち上げて、http://localhost/openlayer2_12/chapter11/chapter11_ex4_proxy_host.htmlと入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_59/image01.jpg}}

ようにkml fileのpoint dataが読み込まれてmapに表示されます。
Map上のcluster pointにmouse overすると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_59/image02.jpg}}

のようにkml fileのattributeの内容がmapの下に表示されます。
他のcluster pointにmouse overしても
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_59/image03.jpg}}

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

===== 今回のまとめ =====
ProxyHostを使ったWeb Map Applicationについて学びました。これを応用すれば外部サイトからkmlデータなどを呼び出してmapに描画することができるので、interactiveなApplicationを作成することができます。
次回は、今回のproxy hostを使ったreal timeのWeb Map Applicationの機能拡張を学んでいきます。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

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

====== OpenLayersを使ってみる。[Chapter 58] ======
[[http://blog.godo-tys.jp/2013/08/28/3969/|Flickerを使ったWeb Map Applicationを作る。[Chapter 57] ]]に引き続き、proxy hostを使ったWeb Map Applicationの機能追加について学んでいきます。

この章以降は、
* ゼロからFlickrを使用して、Web Map Applicationを構築する。 -> **今回はここ**
* Applicationの配置と開発することの意味について議論する。
* OpenLayers Library fileを作成する方法について。
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

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

一般的に 2つの基本的な方法があります。
– Interactivityに地図を追加する。
– 「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として使用するので、



で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 += "" + cluster[i].attributes.name + "
" + "" + cluster[i].attributes.Snippet + "


";
}
}

//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と入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_58/image01.jpg}}

ようにkml fileのpoint dataが読み込まれてmapに表示されます。
Map上のcluster pointにmouse overすると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_58/image02.jpg}}

のようにkml fileのattributeの内容がmapの下に表示されます。
他のcluster pointにmouse overしても
{{http://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間違いや勘違いも多々出てくると考えられます。
それは違うじゃん!!とかいろんな意見をいただければと思います。
そこんところ ヨロシク~~!!

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

Flickerを使ったWeb Map Applicationを作る。[Chapter 57]

====== OpenLayersを使ってみる。[Chapter 57] ======
ついに、**OpenLayers Tutprial**の**最終章の第11章**です。
[[http://blog.godo-tys.jp/2013/08/27/3937/|OpenLayersのRule classとFilter classについて-2[Chapter 56] ]]に引き続き、Flickerを使ったWeb Map Applicationの作成について学んでいきます。

この章以降は、
* ゼロからFlickrを使用して、Web Map Applicationを構築する。 -> **今回はここ**
* Applicationの配置と開発することの意味について議論する。
* OpenLayers Library fileを作成する方法について。
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== Strategiesの開発 =====
本章では、third party site(Flickr)のデータをロードするWeb Map Applicaitonの開発を行います。
ここでは、interactive developmentで、まずは小さいapplicatopnから出発して、徐々に機能を追加して有用なものへと拡張してWeb Map Applicationを構築していきます。

Interactive developmentは重要で、ポピュラーで、有効な方法です。
考えかたとしては、単純なものを作成し、それに追加作業を行い、次に、それを改善するということです。
Web ApplicaiotnではInteractive developmentは、system開発においては有用な方法であります。

他に、strategyはmodule programingです。
このmodule programingが意味することは、できるだけ個別の(あるいはmoduleごとの)ものを保存しようとするということです。
そうすることによって、一旦componentでの作業を行っていれば、後でそれについて心配する必要はありません。

===== Flickerを使ったWeb Map Application =====
OpenLayersは非常に柔軟であるので、third party siteを利用してapplicationを作るのは簡単です。
共有のgeospatialなデータは、geospatiallyに埋め込まれたデータを自由に提示するFlickrとtwitterのようなサービスと共に、よりポピュラーになっています。
Dataを視覚化することができることは、いろいろな意味で理解するのを助けます。
OpenLayersを使用すると、地図にgeospatialなデータを置き、データに関するより明瞭なshapeやpictureを得ることができます。

Flickrは非常に強健なdevelopment APIを提供していますが、単にサイトへのアクセスを提供するURL呼び出しによってFlickrと接続する事ができます。
Siteは、データに関する情報を提供します。また、異なる種類のsite(例えば特定のユーザのsiteあるいは結合したすべてのユーザのためのsite)を得ることができます。

siteの呼び出しは簡単です。
URLへの呼び出しを行い、あるパラメーターを指定します。
例として、 BaseのURLは**http://api.flickr.com/services/feeds/geo/?format=kml**です。

Formta parameterは多くのJSON、RSS、SQLなどが使えます。
ここでは、本章の中でKMLとJSONを使用します。
このURLを呼ぶ時、求めるformatでfileは戻ってきます。Fileの中身は、最新の写真に関する情報を含んでいて、それら(URLの中のgeoはそのためにあります)に地理情報などに関連します。

FlickrのAPIドキュメンテーションは[[http://www.flickr.com/service/api/]]で見つけることができます。
Flickr siteに関してより多くの情報は[[http://www.flickr.com/services/feeds/]]で見つけることができます。

Flickrからデータを引き入れて、地図にそれを表示するWeb Map Applicationを作成しましょう。

まずは、Flickr dataを使いながら、interactive developmentで徐々に機能をついかしていきましょう。

==== Flickr dataの取得 ====
今回使用するfileは
– [[http://api.flickr.com/services/feeds/geo/?format=kml&tags=bird|Flickr data]]とします。
– flickr_data.kmlとして、c:¥ms4w¥apache¥htdocs¥openlayer¥chapter11¥に保存します。
– 保存したflickr_data.kmlをtext editorなどで開いてtagについて確認しておきます。

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

 
&lt;!DOCTYPE html&gt;
&lt;html lang='ja'&gt;
	&lt;head&gt;
		&lt;meta charset='utf-8' /&gt;
		&lt;script type='text/javascript' src='http://localhost/openlayers/OpenLayers.js'&gt;&lt;/script&gt;
		&lt;script src=&quot;http://maps.google.com/maps/api/js?sensor=false&quot;&gt;&lt;/script&gt;
		&lt;script type='text/javascript'&gt;
			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
				// Googlemaps
				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
						})
					}),
					strategies : [new OpenLayers.Strategy.Fixed()]
				});
				map.addLayer(vector_layer);

				//Create a style object to be used by a StyleMap object
				var vector_style = new OpenLayers.Style({
					'fillColor' : '#669933',
					'fillOpacity' : .8,
					'strokeColor' : '#aaee77',
					'strokeWidth' : 3,
					'pointRadius' : 8
				});

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

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

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

			}

		&lt;/script&gt;
	&lt;/head&gt;

	&lt;body onload='init();'&gt;
		&lt;div id='map_element' style='width: 600px; height: 400px;'&gt;&lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;

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



で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
})
}),
strategies : [new OpenLayers.Strategy.Fixed()]
});
map.addLayer(vector_layer);

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

次に、vector_style_mapを追加して、

//Create a style object to be used by a StyleMap object
var vector_style = new OpenLayers.Style({
'fillColor' : '#669933',
'fillOpacity' : .8,
'strokeColor' : '#aaee77',
'strokeWidth' : 3,
'pointRadius' : 8
});

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

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

vector_layer.styleMapのstyleを作成します。

保存後、FireFoxを立ち上げて、http://localhost/openlayers/chapter11/chapter11_ex1.htmlと入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_57/image01.jpg}}

ようにkml fileのpoint dataが読み込まれてmapに表示されます。

次に、kml fileのpoint styleを画像に変更してみましょう。

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

&lt;!DOCTYPE html&gt;
&lt;html lang='ja'&gt;
	&lt;head&gt;
		&lt;meta charset='utf-8' /&gt;
		&lt;script type='text/javascript' src='http://localhost/openlayers/OpenLayers.js'&gt;&lt;/script&gt;
		&lt;script src=&quot;http://maps.google.com/maps/api/js?sensor=false&quot;&gt;&lt;/script&gt;
		&lt;script type='text/javascript'&gt;
			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()]
				});
				map.addLayer(vector_layer);

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

			}

		&lt;/script&gt;
	&lt;/head&gt;

	&lt;body onload='init();'&gt;
		&lt;div id='map_element' style='width: 600px; height: 400px;'&gt;&lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;

ここで、前のcodeと違う点は、

//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()]
});
map.addLayer(vector_layer);

ここで、**extractStyles : true**を指定しています。
formatの指定は必ずコンマを含めて、vector_layerを作成します。

保存後、FireFoxを立ち上げて、http://localhost/openlayers/chapter11/chapter11_ex2_extractStyles.htmlと入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_57/image02.jpg}}

extractStylesを使用して、defaultのオレンジのpointから実際のアップロードされた写真となりました。
このpropertyが使用される場合、KML file中のstylr定義は各featureのstyle porpertyに適用されます。
OpenLayersは、KML fileからstyle情報を解析し、必要なstyle定義を生成します。

詳細は、[[http://dev.openlayers.org/apidocs/files/OpenLayers/Format/KML-js.html|OpenLayers.Format.KML]]のpropertyを参考にしてください。

===== 今回のまとめ =====
Flickerを使ったWeb Map Applicationの作成について学びました。
次回も、Flickerを使ったWeb Map Applicationの作成について追加項目を学んでいきます。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

OpenLayersのRule classとFilter classについて-2[Chapter 56]

====== OpenLayersを使ってみる。[Chapter 56] ======

[[http://blog.godo-tys.jp/2013/08/26/3926/|OpenLayersのRule classとFilter classについて-1[Chapter 55] ]]に引き続き、OpenLayersのFilter subcalssついて基本を学んでいきます。

この章以降は、
* いかにOpenLayersのVector layerのstyleを表示するか?
* Style classをその使い方について
* Ruleとfilterの使い方
* Filter classの使い方 -> **今回はここ**
について順番に学んでいきます。
この章で、第10章が終了します。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== OpenLayers.Filter class =====
Filter classは、ruleが適用されるべきかどうか確かめるようにfeatuer attribute propertyのロジックをコントロールします。
前の例でのように、単一のfilterを使用することができます。あるいは、filterをともに(例えば、property1が500を超えるもので、別のproperty2が200未満である場合)組み合わせることができます。

Filterはさらに、(spatial)がfeatureがgeometry objectと交差するかどうかチェックすることもできます。これらの物事をすべてするために、filter class(Layer classおよび他のclassのsubclassをどのように使用するかに似ている)のsubclassを使用します。

==== Filter Subclasses ====
Filterには4つのsubclassがあります。それは、**Comparison**、 **FeatureId**、 **Logical**と**Spatial**です。
ここでは、Spatialについて学びます。

=== Feature.Spatial ===
Feature.Spatial classは、地理情報に基づいたfeatureをfilterすることを可能にします。
Vector layerを作成する場合、このclassが使用されます。
WFSプロトコルを使用するVector layerを作成していれば、これは非常に有用なfilterです。

Spatial filterを作成する場合、typeと値を指定する必要があります。
値は、{OpenLayers.Bounds}あるいは{OpenLayers.Geometry}のタイプのどちらかになります。
いくつかのtypeはさらに距離およびdistanceUnitsパラメーターを考慮する必要があります。
typeのうちのいくつかを見ましょう。
* OpenLayers.Filter.Spatial.BBOX : Specifies features to match that fall inside a bounding box, set by an {OpenLayers.Bounds} object in the value property
* OpenLayers.Filter.Spatial.CONTAINS : Used to check if an {OpenLayers.Geometry} object specified by the value property contains a feature
* OpenLayers.Filter.Spatial.DWITHIN : Specifies if a feature is within some distance specified by the distance property
* OpenLayers.Filter.Spatial.INTERSECTS : Used to check if a feature intersects an {OpenLayers.Geometry} object specified in the value property
* OpenLayers.Filter.Spatial.WITHIN : Used to check if a feature is completely within an {OpenLayers.Geometry} object specified in the value property

Spatial filterを使用する呼び出しは、次のようになります:

var my_vector_layer = new OpenLayers.Layer.Vector(
'My WFS Layer',
{
protocol: new OpenLayers.Protocol.WFS({
url: wfs_server
}),
filter: new OpenLayers.Fitler.Spatial({
type: OpenLayers.Filter.Spatial.BBOX,
value: new OpenLayers.Bounds(-180,-90,0,0),
projection: new OpenLayers.Projection('EPSG:4326')
})
});

詳細は、[[http://dev.openlayers.org/docs/files/OpenLayers/Filter/Spatial-js.html|Filter.Spatial]]を参考にしてください。

===== 今回のまとめ =====
OpenLayersの簡単なStyleのrule classとfiler classについて基本を学びました。
次回は、いよいよ最終の第11章です。第11章では、Web Map Applicationについての基本を学んでいきます。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

OpenLayersのRule classとFilter classについて-1[Chapter 55]

====== OpenLayersを使ってみる。[Chapter 55] ======

[[http://blog.godo-tys.jp/2013/08/25/3898/|OpenLayersのStyleのruleとfilterついて-2[Chapter 54] ]]に引き続き、OpenLayersのRule calssとFilter calssついて基本を学んでいきます。

この章以降は、
* いかにOpenLayersのVector layerのstyleを表示するか?
* Style classをその使い方について
* Ruleとfilterの使い方
* Filter classの使い方 -> **今回はここ**
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== OpenLayers.Rule class =====
Objectを特色とするために適用されるスタイルのタイプについて非常に明確になりたい場合、それをする最良の方法はrule classの使用によります。
Rule classを作成する場合、filter object、featureに適用するべきsymbolizer、およびruleの名前を指定するオプションを指定します。

Rule objectはstyle objectに適用されます。また、多くのstyle objectに関するruleを持つことができます。
Rule objectを作成するためのsyntax、以前に言及された次のような形です:

var my_rule = new OpenLayers.Rule({
filter: new OpenLayers.Filter({}),
symbolizer: { key:values }
});
style_object.addRules([my_rule]);

Style objectへの多数のruleを作成し適用するのがそれほど難しくはありません。
前例では、単一のfilterをrule objectに使用しました。しかし、OpenLayersは、feature styleに対するより多くを制御するために多数のfilterを指定することができます。

Ruleがfeatureに適用されるかどうか判断する際に仕事をするのはfilterです。
したがって、filter classへの注視、およびfeature styleをもっとカスタマイズするために、rule classを使用することになります。

===== OpenLayers.Filter class =====
Filter classは、ruleが適用されるべきかどうか確かめるようにfeatuer attribute propertyのロジックをコントロールします。
前の例でのように、単一のfilterを使用することができます。あるいは、filterをともに(例えば、property1が500を超えるもので、別のproperty2が200未満である場合)組み合わせることができます。

Filterはさらに、(spatial)がfeatureがgeometry objectと交差するかどうかチェックすることもできます。これらの物事をすべてするために、filter class(Layer classおよび他のclassのsubclassをどのように使用するかに似ている)のsubclassを使用します。

==== Filter Subclasses ====
Filterには4つのsubclassがあります。それは、**Comparison**、 **FeatureId**、 **Logical**と**Spatial**です。

=== Filter.Comparison ===
Comparison classはここまで使用しているfilter classです。
名前が意味するように、このclassはfilter objectの指定されたparameterに基づいたpropertyを比較する時に使います。
Comparisonは、type propertyによって指定されます。
さらに、filterの値(lowerBoundaryとupperBoundaryのような異なるpropertyを使用します)を使用することをチェックするために値を指定しなければなりません。
最後に、さらにfeatureの中でチェックするpropertyを指定しなければなりません。

例えば、前の例からのrule_pop_low規則の中で使用されるフィルタ・オブジェクトを見ましょう:

var rule_pop_mid = new OpenLayers.Rule({
filter: new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.GREATER_THAN,
property: 'population',
value: 1500
}),

ここで、GREATER_THANのComparison typeを行ってくれるようにOpenLayersに依頼します。それはfeatureのpopulation propertyを見て、人口の値が1500より大きい場合、ruleと一致します。

== Filter.Comparison Value property ==
Filter.Comparison objectにはすべてある程度の伴う値propertyが必要です。
Filter Comparison typeはほとんどすべて、GREATER_THANタイプのように、単に値propertyを使用します。
他のものは、Comparison typeのように、lowerBoundaryとupperBoundaryのpropertyを使用します。
Filterが捜すべき値を指定しなかった場合は、filterは作動しません。

== Filter Comparison types ==
別段の定めがない限り、Comparison typeはそれぞれ値propertyを持ちます。
値propertyは別段の定めがない限り{Integer}タイプです。

== Filter Type: BETWEEN ==
**BETWEEN**: propertyが2つの値の間にあるかどうかチェックします。
lowerBoundが500で、upperBoundが1500である場合、値は、中間の値および500〜1500を含んでいることになります。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.BETWEEN,
property: 'population',
lowerBoundary:500,
upperBoundary:1500
});

== Filter Type: EQUAL_TO ==
**EQUAL_TO**: propertyが指定された値と等しい場合にチェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: 'population',
value: 1337
});

== Filter Type: GREATER_THAN ==
**GREATER_THAN**: propertyがより大きい場合にチェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.GREATER_THAN,
property: 'population',
value: 1000
});

== Filter Type: GREATER_THAN_OR_EQUAL_TO ==
**GREATER_THAN_OR_EQUAL_TO**: propertyが指定された値以上である場合チェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
property: 'population',
value: 1000
});

== Filter Type: LESS_THAN ==
**LESS_THAN**: propertyが未満で指定された値である場合チェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN,
property: 'population',
value: 1000
});

== Filter Type: LESS_THAN_OR_EQUAL_TO ==
**LESS_THAN_OR_EQUAL_TO**: propertyが未満で、あるいは含んで指定された値である場合チェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO,
property: 'population',
value: 1000
});

== Filter Type: LIKE ==
**LIKE**: propertyが値(それはこの場合{String}である)を含んでいる場合にチェックします。
例えば、もしpropertyの値が「village」で、指定する値が「village」ならば、それは一致するでしょう。
指定する値はさらにあります、1つの、正規表現それは一致し続けるために様々な特殊文字の中でできることを意味します。
例えば、*は、任意の文字の0以上の実例と一致するでしょう。
あるstringがproperty内に含まれるかどうかただ確かめたければ、単に正規表現とは何かどうかについて心配せずに、値をそのストリングにセットすることができます。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: 'settlement_type',
value: 'village'
});

== Filter Type: NOT_EQUAL_TO ==
**NOT_EQUAL_TO**: propertyがある値と等しくないか。(それは{Integer}タイプです)どうかチェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
property: 'population',
value: 1000
});

=== Filter.FeatureId ===
これは、FeatureIdに基づいたfeatureをfilterするでしょう。
特にWFSサービスあるいはSLDで働く場合、これは有用です。
WFSで、FeatureIDはユニークなfeatureとして載せる方法です。
WFSサーバーは、featureのユニークにそれを識別するFeatureIDを含んでいるデータを返します。
SLDは、さらにユニークなFeatureIDによってfeatureを識別することができます。
特定のfeatureのIDを知っていれば、これは有用になりえます。
FeatureID filterを使用する場合、それは配列として与えることができます:

var my_filter = new OpenLayers.Filter.FeatureId({
fids: ['fid1', 'fid2']
});

=== Feature.Logical ===
既にrule filterを適用する例を学びましたが、別のfilter objectにfilter objectを適用することもでききます。
それは、filterを備えた論理演算子を使用することで可能になります。これは、実際に複雑なfilterをとても容易に作成することができます。
使用することができる3つのタイプの論理演算子があります:
* OpenLayers.Filter.Logical.AND: Checks if multiple filters match
* OpenLayers.Filter.Logical.OR: Checks if at least one of the multiple filters match
* OpenLayers.Filter.Logical.NOT: If the filter does not match

論理的なfilterを作成するために、単にtype(それは上に3つの論理演算子のうちの1つである)、および他のfilter objectを含んでいるfilterの配列を指定します。

var my_logical_filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN,
property: 'population',
value: 1000
}),
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: 'settlement_type',
value: 'village'
})
]
});

上記のfilterはAND論理演算子および2つのcomparison filterを使用します。
結果は、この論理的なフィルタが両方のcomparison filter(settlement_typeが「village」で人工が1000未満)と一致するfeatureだけと一致するものをfilterしています。

===== logical filtersを使ったexample code =====
Rulesとfiltersを使った簡単なexample codeを作成してみましょう。以下のcodeを入力します。
保存先は、c:¥ms4w¥apache¥htdocs¥openlayer¥chapter10¥にしておきます。
ファイル名は、chapter10_ex5_customRules.htmlで保存します。

 
&lt;!DOCTYPE html&gt; 
&lt;html lang='ja'&gt; 
&lt;head&gt; 
    &lt;meta charset='utf-8' /&gt; 
		&lt;script type='text/javascript' src='http://localhost/openlayers/OpenLayers.js'&gt;&lt;/script&gt;
    &lt;script type='text/javascript'&gt;

    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 wms_layer = new OpenLayers.Layer.WMS(
            'OpenLayers WMS',
            'http://vmap0.tiles.osgeo.org/wms/vmap0',
            {layers: 'basic'},
            {}
        );
        map.addLayer(wms_layer);
        
        //Add vector layer
        vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer'
					);
					map.addLayer(vector_layer);

				var settlement_values = {
					0 : 'village',
					1 : 'city',
				}

        //Create some points
        for(var i=0; i&lt;20; i++){
            vector_layer.addFeatures([new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Point(
                    (Math.floor(Math.random() * 360) - 180),
	                (Math.floor(Math.random() * 180) - 90)
	            ),
	            {
                    'population': Math.floor(Math.random() * 2000),
					'settlement_type': settlement_values[(Math.floor(Math.random() * 2))]
                }
            )]);
        }     

        //Create a style object
        var vector_style = new OpenLayers.Style();
                
        var filter_village_low_pop = new OpenLayers.Filter.Logical({
            type: OpenLayers.Filter.Logical.AND,
            filters: [
                new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.LESS_THAN,
                    property: 'population',
                    value: 1000
                }),
				 new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.LIKE,
                    property: 'settlement_type',
                    value: 'village'
                })
            ]
        });

			var filter_village_high_pop = new OpenLayers.Filter.Logical({
            type: OpenLayers.Filter.Logical.AND,
            filters: [
                new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.BETWEEN,
                    property: 'population',
                    lowerBoundary: 1000,
					upperBoundary: 1500
                }),
				 new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.LIKE,
                    property: 'settlement_type',
                    value: 'village'
                })
            ]
        });
		
			var filter_city = new OpenLayers.Filter.Logical({
            type: OpenLayers.Filter.Logical.OR,
            filters: [
                new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.GREATER_THAN,
                    property: 'population',
                    value: 1500
                }),
				 new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.LIKE,
                    property: 'settlement_type',
                    value: 'city'
                }),
            ]
        });
		

			//ADD RULES
			//We'll use three rules to check for population size
			var rule_village_low_pop = new OpenLayers.Rule({
				filter : filter_village_low_pop,
				symbolizer : {
					fillColor : '#ababab',
					fillOpacity : .8,
					pointRadius : 8,
					strokeColor : '#454545',
					strokeWidth : 2
				}
			});

			var rule_village_high_pop = new OpenLayers.Rule({
				filter : filter_village_high_pop,
				symbolizer : {
					fillColor : '#FFFA93',
					fillOpacity : .8,
					pointRadius : 8,
					strokeColor : '#AFAB57',
					strokeWidth : 4,
				}
			});

			var rule_city = new OpenLayers.Rule({
				filter : filter_city,
				symbolizer : {
					fillColor : '#BD1922',
					fillOpacity : .8,
					pointRadius : 16,
					strokeColor : '#812B30',
					strokeWidth : 6,
					fontSize : '.8em',
					fontColor : '#efefef',
					label : '${population}'
				}
			});

			//Add the rules to the style object
			vector_style.addRules([rule_village_low_pop, rule_village_high_pop, rule_city]);

			//Create a style map object
			var vector_style_map = new OpenLayers.StyleMap({
				'default' : vector_style
			});

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

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

			}

		&lt;/script&gt;
&lt;/head&gt;

&lt;body onload='init();'&gt;
    &lt;div id='map_element' style='width: 600px; height: 400px;'&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

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

//Create a map with an empty array of controls
map = new OpenLayers.Map('map_element');

//Create a base layer
var wms_layer = new OpenLayers.Layer.WMS(
'OpenLayers WMS',
'http://vmap0.tiles.osgeo.org/wms/vmap0',
{layers: 'basic'},
{}
);
map.addLayer(wms_layer);

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

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

//Add vector layer
vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer');
map.addLayer(vector_layer);

var settlement_values = {
0 : 'village',
1 : 'city',
}

settlement_valuesを定義します。

次に、Pointの座標を

//Create some points
for(var i=0; i<20; i++){ vector_layer.addFeatures([new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point( (Math.floor(Math.random() * 360) - 180), (Math.floor(Math.random() * 180) - 90) ), { 'population': Math.floor(Math.random() * 2000), 'settlement_type': settlement_values[(Math.floor(Math.random() * 2))] } )]); }

randomに20カ所を作成するようにして、addFeaturesでvector_layerに追加します。
Attributeにpopulationとsettlement_typeを設定します。

次に、Styleを、

//Create a style object
var vector_style = new OpenLayers.Style();

var filter_village_low_pop = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LESS_THAN,
property: 'population',
value: 1000
}),
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: 'settlement_type',
value: 'village'
})
]
});

var filter_village_high_pop = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,
filters: [
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.BETWEEN,
property: 'population',
lowerBoundary: 1000,
upperBoundary: 1500
}),
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: 'settlement_type',
value: 'village'
})
]
});

var filter_city = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.OR,
filters: [
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.GREATER_THAN,
property: 'population',
value: 1500
}),
new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.LIKE,
property: 'settlement_type',
value: 'city'
}),
]
});

filter_village_low_pop、filter_village_high_pop、filter_cityでfilterを作成します。
Comparison subclassを使って場合分けを行います。

そして、ruleを追加します。

//ADD RULES
//We'll use three rules to check for population size
var rule_village_low_pop = new OpenLayers.Rule({
filter : filter_village_low_pop,
symbolizer : {
fillColor : '#ababab',
fillOpacity : .8,
pointRadius : 8,
strokeColor : '#454545',
strokeWidth : 2
}
});

var rule_village_high_pop = new OpenLayers.Rule({
filter : filter_village_high_pop,
symbolizer : {
fillColor : '#FFFA93',
fillOpacity : .8,
pointRadius : 8,
strokeColor : '#AFAB57',
strokeWidth : 4,
}
});

var rule_city = new OpenLayers.Rule({
filter : filter_city,
symbolizer : {
fillColor : '#BD1922',
fillOpacity : .8,
pointRadius : 16,
strokeColor : '#812B30',
strokeWidth : 6,
fontSize : '.8em',
fontColor : '#efefef',
label : '${population}'
}
});


のようにrule_village_low_pop、rule_village_high_pop、rule_cityの3パターンのruleを定義します。
それぞれのruleはfilterで定義したilter_village_low_pop、filter_village_high_pop、filter_cityを使います。

そして、addRules functionに、

//Add the rules to the style object
vector_style.addRules([rule_village_low_pop, rule_village_high_pop, rule_city]);

3つのrule objectを適用します。

最後に、vector_style_mapを追加して、

//Create a style map object
var vector_style_map = new OpenLayers.StyleMap({
'default' : vector_style
});

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

vector_layer.styleMapのstyleを作成します。

保存後、FireFoxを立ち上げて、http://localhost/openlayers/chapter10/chapter10_ex5_customRules.htmlと入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_55/image01.jpg}}

ようにStyleMapで定義されたvector layerが追加されて、ruleとfilterに従ったpoint dataが読み込まれてmapに表示されます。

===== 今回のまとめ =====

OpenLayersの簡単なStyleのrule classとfiler classについて基本を学びました。
是非、ruleの値をいろいろと変更して、ruleについて学んでみましょう。
次回も、rule classとfiler classについて基本を学んでいきます。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

OpenLayersのStyleのruleとfilterついて-2[Chapter 54]

====== OpenLayersを使ってみる。[Chapter 54] ======

[[http://blog.godo-tys.jp/2013/08/24/3891/|OpenLayersのStyleのruleとfilterついて-1[Chapter 53] ]]に引き続き、OpenLayersのStyleMapのruleとfilterついて基本を学んでいきます。

この章以降は、
* いかにOpenLayersのVector layerのstyleを表示するか?
* Style classをその使い方について
* Ruleとfilterの使い方 -> **今回はここ**
* Filter classの使い方
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== Rules and filters =====
これまでのところ、単純にstyleを指定するためにproperty上の1〜1つのmatchingを行ってきました。属性置換で、直接値を交換しました。
addUniqueValueRulesで、propertyが何かと等しいかどうかで評価するため、あまり柔軟性を持っていません。

Ruleとfilterの使用によって、非常に柔軟にstyleをセットすることができます。
例えば、ある値未満の、あるいはその値以上のpropertyがある場合、featureをある方法と称するようなproperty上の比較を行うことができます。
多くの異なるタイプの比較(より大きな、未満で、等しい、など)をcheckし、かつfilterに互いと対話させるためにfilterを作成することができます。

===== どのようにfilterを使うか? =====
Filter objectはrule objectに属します。
Rule objectはstyle objectに属します。
Style objectはそれぞれ多くのruleを持つことができます。また、ruleはそれらのfilterがどのように定義されるかに依存して、互いと対話することができます。

Cuntom ruleおよびfilterを使用するために、style objrctに関連づけさせる必要があります。
Ruleを定義し、かつそれがsyule objectに関連づけさせる、一般的なsyntaxは、

**var my_rule = new OpenLayers.Rule({
filter: new OpenLayers.Filter({}),
symbolizer: { key:values }
});
style_object.addRules([my_rule]);**

Filter objectは、ruleがどのように適用される事(propertyがある値より大きいかどうかチェックするように)決めます。
Filterを備えた多くの複雑なことをすることができるように、次節でfilter classをより詳細に学びます。

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

 
&lt;!DOCTYPE html&gt;
&lt;html lang='ja'&gt;
	&lt;head&gt;
		&lt;meta charset='utf-8' /&gt;
		&lt;script type='text/javascript' src='http://localhost/openlayers/OpenLayers.js'&gt;&lt;/script&gt;
		&lt;script type='text/javascript'&gt;
			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 wms_layer = new OpenLayers.Layer.WMS(
					'OpenLayers WMS', 
					'http://vmap0.tiles.osgeo.org/wms/vmap0', {
					layers : 'basic'
				}, {});
				map.addLayer(wms_layer);

				//Add vector layer
				vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer');
				map.addLayer(vector_layer);

				//Create some points
				for (var i = 0; i &lt; 20; i++) {
					vector_layer.addFeatures([
						new OpenLayers.Feature.Vector(
							new OpenLayers.Geometry.Point(
								(Math.floor(Math.random() * 360) - 180), 
								(Math.floor(Math.random() * 180) - 90)), {
						'population' : Math.floor(Math.random() * 2000)
					})]);
				}

				//Create a style object
				var vector_style = new OpenLayers.Style();

				//ADD RULES
				//We'll use three rules to check for population size
				var rule_pop_low = new OpenLayers.Rule({
					filter : new OpenLayers.Filter.Comparison({
						type : OpenLayers.Filter.Comparison.LESS_THAN,
						property : 'population',
						value : 500
					}),
					symbolizer : {
						fillColor : '#ababab',
						fillOpacity : .8,
						pointRadius : 8,
						strokeColor : '#454545',
						strokeWidth : 2
					}
				});

				//Medium pop
				var rule_pop_mid = new OpenLayers.Rule({
					filter : new OpenLayers.Filter.Comparison({
						type : OpenLayers.Filter.Comparison.BETWEEN,
						property : 'population',
						lowerBoundary : 500,
						upperBoundary : 1500
					}),
					symbolizer : {
						fillColor : '#aaee77',
						fillOpacity : .8,
						pointRadius : 14,
						strokeColor : '#669933',
						strokeWidth : 5
					}
				});

				//High pop
				var rule_pop_high = new OpenLayers.Rule({
					filter : new OpenLayers.Filter.Comparison({
						type : OpenLayers.Filter.Comparison.GREATER_THAN,
						property : 'population',
						value : 1500
					}),
					symbolizer : {
						fillColor : '#BD1922',
						fillOpacity : .8,
						pointRadius : 20,
						strokeColor : '#812B30',
						strokeWidth : 5
					}
				});

				//Add the rules to the style object
				vector_style.addRules([rule_pop_low, rule_pop_mid, rule_pop_high]);

				//Create a style map object
				var vector_style_map = new OpenLayers.StyleMap({
					'default' : vector_style
				});

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

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

			}

		&lt;/script&gt;
	&lt;/head&gt;

	&lt;body onload='init();'&gt;
		&lt;div id='map_element' style='width: 600px; height: 600px;'&gt;&lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;

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

//Create a map with an empty array of controls
map = new OpenLayers.Map('map_element');

//Create a base layer
var wms_layer = new OpenLayers.Layer.WMS(
'OpenLayers WMS',
'http://vmap0.tiles.osgeo.org/wms/vmap0',
{layers: 'basic'},
{}
);
map.addLayer(wms_layer);

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

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

//Add vector layer
vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer');
map.addLayer(vector_layer);

//Create some points
for (var i = 0; i < 20; i++) { vector_layer.addFeatures([ new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point( (Math.floor(Math.random() * 360) - 180), (Math.floor(Math.random() * 180) - 90)), { 'population' : Math.floor(Math.random() * 2000) })]); }

のように vector_layerを定義します。
Pointの座標はrandamに20カ所を作成するようにして、addFeaturesでvector_layerに追加します。
Attributeにpopulationを設定します。

次に、Styleを、

//Create a style object
var vector_style = new OpenLayers.Style();

vector_styleで定義します。

そして、ruleを追加します。

//ADD RULES
//We'll use three rules to check for population size
var rule_pop_low = new OpenLayers.Rule({
filter : new OpenLayers.Filter.Comparison({
type : OpenLayers.Filter.Comparison.LESS_THAN,
property : 'population',
value : 500
}),
symbolizer : {
fillColor : '#ababab',
fillOpacity : .8,
pointRadius : 8,
strokeColor : '#454545',
strokeWidth : 2
}
});

//Medium pop
var rule_pop_mid = new OpenLayers.Rule({
filter : new OpenLayers.Filter.Comparison({
type : OpenLayers.Filter.Comparison.BETWEEN,
property : 'population',
lowerBoundary : 500,
upperBoundary : 1500
}),
symbolizer : {
fillColor : '#aaee77',
fillOpacity : .8,
pointRadius : 14,
strokeColor : '#669933',
strokeWidth : 5
}
});

//High pop
var rule_pop_high = new OpenLayers.Rule({
filter : new OpenLayers.Filter.Comparison({
type : OpenLayers.Filter.Comparison.GREATER_THAN,
property : 'population',
value : 1500
}),
symbolizer : {
fillColor : '#BD1922',
fillOpacity : .8,
pointRadius : 20,
strokeColor : '#812B30',
strokeWidth : 5
}
});

のようにrule_pop_low、rule_pop_mid、rule_pop_highの3パターンのruleを定義します。
それぞれのruleはfilter : new OpenLayers.Filter.Comparison{...}で定義しています。
そして、typeでfilterの区分をpopulationを元にfilteringします。
symbolizer : {...}がfilterにかけられたfeatureのstyleになります。
filter classについては次節で詳しく学びます。

そして、addRules functionに、

//Add the rules to the style object
vector_style.addRules([rule_pop_low, rule_pop_mid, rule_pop_high]);

3つのrule objectを適用します。

最後に、vector_style_mapを追加して、

//Create a style map object
var vector_style_map = new OpenLayers.StyleMap({
'default' : vector_style
});

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

vector_layer.styleMapのstyleを作成します。

保存後、FireFoxを立ち上げて、http://localhost/openlayers/chapter10/chapter10_ex5_customRules.htmlと入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_54/image01.jpg}}

ようにStyleMapで定義されたvector layerが追加されて、ruleに従ったpoint dataが読み込まれてmapに表示されます。

===== 今回のまとめ =====

OpenLayersの簡単なStyleのruleとfilterについて基本を学びました。
是非、ruleの値をいろいろと変更して、ruleについて学んでみましょう。
次回は、rule classとfiler classについて基本を学んでいきます。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

OpenLayersのStyleのruleとfilterついて-1[Chapter 53]

====== OpenLayersを使ってみる。[Chapter 53] ======

[[http://blog.godo-tys.jp/2013/08/23/3879/|OpenLayersのStyleMapのAttribute replacementについて[Chapter 52] ]]に引き続き、OpenLayersのStyleMapのruleとfilterついて基本を学んでいきます。

この章以降は、
* いかにOpenLayersのVector layerのstyleを表示するか?
* Style classをその使い方について
* Rule classの使い方 -> **今回はここ**
* Filter classの使い方
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== Rules and filters =====
Ruleとfilterのclassの使用によりobjectをデザインすることができます。
これらの2つのclassは、いくつかの任意の「rule」に基づいた異なるfeatureに異なるstyleを適用することを可能にします。
Propertyのうちの1つ(あるいはさらに)を選び、値と一致する場合に、styleを適用するためにfeatureのattibite propertyを使用することができます。

===== どのようにruleに従うか? =====
Ruleは、ある条件が生じる場合、symbolizerを適用することを可能にします。
それらの条件はrule classによって扱われます。
多数のruleおよびfilterを持ち、それらと共に論理演算子(ORとANDのような)をさらに使用することができます。Ruleを使用することには2つの方法があります。

1番目はStyleMap classのaddUniqueValueRules methodを使用することです。
これは単純なpropertyの一致を可能にすることで使用します。

2番目の方法は少し複雑になりますが、custom およびfilter objectを使用することです。addUniqueValueRulesを使用する方法について学んだ後、この方法を学びます。

===== addUniqueValueRulesを使う =====
Ruleを使用する最も容易な方法はStyleMap clasのaddUniqueValueRules方法を使用することです。
それは、値検査を行い、propertyの値に依存する異なるstyleを適用することを可能にします。
より具体的に、考えみましょう。
Featureはそれぞれ、「village」、「city」あるいは「metropolis」のような値と共に、settlement_typeと呼ばれるattribute propertyを持っています。

さらにstyleにpointが、それがどのタイプであるか、そしてそれらに違った色をつけて、ポイント半径をより大きくし、ストローク・サイズを変更したいなどのstyleを決めます。
addUniqueValueRulesを使用することで、属性置換、また各featureの持つ値を埋め込むことができます。

===== addUniqueValueRules functionを呼び出す =====
最初に、addUniqueValueRules関数を呼ぶための一般的なsyntaxを見ましょう:

style_map_object.addUniqueValueRules(intent, property, symbolizer_lookup, context);**

addUniqueValueRulesの引数を順にみていきます。

=== Intent parameter ===
最初のIntent parameterは一般的に’default’となります。

=== Property parameter ===
2番目のparameterであるpropertyはcheckしたいfeatureのpropertyです。例えば、先ほど例としてあげた’setelement_type’のようなものです。

=== Symbolizer_lookup parameter ===
symbolizer_lookup parameterはobjectを含んでいるkeyで、ruleが一致する場合に使用する値でペアで使います。
Keyは、propertyの中で渡された値を指定します。また、値は、propertyがその値と一致する場合に適用するべきsymbolizerを指定します。
例えば、それがコードにどのように現われるか:

var symbolizer_lookup = {
'village': {pointRadius:5, strokeWidth:2},
'city': {pointRadius:10, strokeWidth:4}
}

Featureのsetelement_type propertyが「village」である場合、これは「village」symbolizerを適用し、propertyが「city」である場合、「city」スタイルsymbolizerを適用します。
symbolizerは、既にStyleMap objectに関係しているどんなdefault symbolizerでも拡張するでしょう。
結局、重要なことには、探索するpropertyがsymbolizer_objectに存在しなければ、featureはstyleを定義することができません。

=== Context parameter ===
最後のparameterであるContextは、propertを照合するobjectを指定する、optionの(通常含まれていなかった)objectです。

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

 
&lt;!DOCTYPE html&gt;
&lt;html lang='ja'&gt;
	&lt;head&gt;
		&lt;meta charset='utf-8' /&gt;
		&lt;script type='text/javascript' src='http://localhost/openlayers/OpenLayers.js'&gt;&lt;/script&gt;
		&lt;script type='text/javascript'&gt;
			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 wms_layer = new OpenLayers.Layer.WMS(
					'OpenLayers WMS', 
					'http://vmap0.tiles.osgeo.org/wms/vmap0', {
					layers : 'basic'
				}, {});
				map.addLayer(wms_layer);

				//Add vector layer
				vector_layer = new OpenLayers.Layer.Vector('Setelement Vector Layer');
				map.addLayer(vector_layer);

				var setelement_values = {
					0 : 'hut',
					1 : 'village',
					2 : 'city',
					3 : 'metropolis',
					4 : 'facebook'
				}

				//Create some points
				for (var i = 0; i &lt; 10; i++) {
					vector_layer.addFeatures([
						new OpenLayers.Feature.Vector(
							new OpenLayers.Geometry.Point(
								(Math.floor(Math.random() * 360) - 180), 
								(Math.floor(Math.random() * 180) - 90)), {
						'settlement_type' : setelement_values[
							(Math.floor(Math.random() * 5)
						)]
					})]);
				}

				//Create a style map object
				var vector_style_map = new OpenLayers.StyleMap({});

				//ADD RULES
				//We need to create a 'lookup table' that contains the desired values
				//  and corresponding symbolizer
				var symbolizers_lookup = {
					'hut' : {
						'fillColor' : '#ababab',
						'fillOpacity' : .8,
						'pointRadius' : 4,
						'strokeColor' : '#454545',
						'strokeWidth' : 2
					},
					'village' : {
						'fillColor' : '#FFFA93',
						'fillOpacity' : .8,
						'pointRadius' : 8,
						'strokeColor' : '#AFAB57',
						'strokeWidth' : 4
					},
					'city' : {
						'fillColor' : '#aaee77',
						'fillOpacity' : .8,
						'pointRadius' : 12,
						'strokeColor' : '#669933',
						'strokeWidth' : 5
					},
					'metropolis' : {
						'fillColor' : '#BD1922',
						'fillOpacity' : .8,
						'pointRadius' : 16,
						'strokeColor' : '#812B30',
						'strokeWidth' : 6
					},
					'facebook' : {
						'fillColor' : '#336699',
						'fillOpacity' : .8,
						'pointRadius' : 26,
						'strokeColor' : '#003366',
						'strokeWidth' : 2
					}
				}

				//Now, call addUniqueValueRules and pass in the symbolizer lookups
				vector_style_map.addUniqueValueRules('default', 'setelement_type', symbolizers_lookup);

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

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

			}

		&lt;/script&gt;
	&lt;/head&gt;

	&lt;body onload='init();'&gt;
		&lt;div id='map_element' style='width: 600px; height: 400px;'&gt;&lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;

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

//Create a map with an empty array of controls
map = new OpenLayers.Map('map_element');

//Create a base layer
var wms_layer = new OpenLayers.Layer.WMS(
'OpenLayers WMS',
'http://vmap0.tiles.osgeo.org/wms/vmap0',
{layers: 'basic'},
{}
);
map.addLayer(wms_layer);


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

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

//Add vector layer
vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer');
map.addLayer(vector_layer);

のように vector_layerを定義します。

次に、propertyを定義します。

var setelement_values = {
0 : 'hut',
1 : 'village',
2 : 'city',
3 : 'metropolis',
4 : 'facebook'
}

setelement_valuesで5区分の定義をします。

次に、vector_layerに

//Create some points
for (var i = 0; i < 10; i++) { vector_layer.addFeatures([ new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point( (Math.floor(Math.random() * 360) - 180), (Math.floor(Math.random() * 180) - 90)), { 'setelement_type' : setelement_values[ (Math.floor(Math.random() * 5) )] })]); }

Pointの座標はrandomに10カ所を作成するようにして、addFeaturesでvector_layerに追加します。
Attributeにsetelement_typeをrandomに設定します。

次に、style map objectを

//Create a style map object
var vector_style_map = new OpenLayers.StyleMap({});

のようにvector_style_mapを定義します。

そして、ruleを

//ADD RULES
//We need to create a 'lookup table' that contains the desired values
// and corresponding symbolizer
var symbolizers_lookup = {
'hut' : {
'fillColor' : '#ababab',
'fillOpacity' : .8,
'pointRadius' : 4,
'strokeColor' : '#454545',
'strokeWidth' : 2
},
'village' : {
'fillColor' : '#FFFA93',
'fillOpacity' : .8,
'pointRadius' : 8,
'strokeColor' : '#AFAB57',
'strokeWidth' : 4
},
'city' : {
'fillColor' : '#aaee77',
'fillOpacity' : .8,
'pointRadius' : 12,
'strokeColor' : '#669933',
'strokeWidth' : 5
},
'metropolis' : {
'fillColor' : '#BD1922',
'fillOpacity' : .8,
'pointRadius' : 16,
'strokeColor' : '#812B30',
'strokeWidth' : 6
},
'facebook' : {
'fillColor' : '#336699',
'fillOpacity' : .8,
'pointRadius' : 26,
'strokeColor' : '#003366',
'strokeWidth' : 2
}
}

のようにvector_style_mapに追加します。setelement_valuesで定義した数だけ定義します。

そして、addUniqueValueRulesに、

//Now, call addUniqueValueRules and pass in the symbolizer lookups
vector_style_map.addUniqueValueRules('default', 'setelement_type', symbolizers_lookup);

のようにparameterを与えます。

最後に、styleMapを

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

のようにvector_style_mapで定義します。

保存後、FireFoxを立ち上げて、http://localhost/openlayers/chapter10/chapter10_ex3_attriute_replacement.htmlと入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_53/image01.jpg}}

ようにStyleMapで定義されたvector layerが追加されて、ruleに従ったpoint dataが読み込まれてmapに表示されます。

===== 今回のまとめ =====

OpenLayersの簡単なStyleのruleとfilterについて基本を学びました。
是非、ruleの値をいろいろと変更して、ruleについて学んでみましょう。
次回も、StyleMap classのRuleとfilerについて基本を学んでいきます。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**

OpenLayersのStyleMapのAttribute replacementについて[Chapter 52]

====== OpenLayersを使ってみる。[Chapter 52] ======

[[http://blog.godo-tys.jp/2013/08/22/3870/|OpenLayersのStyleMap classについて-2[Chapter 51] ]]に引き続き、OpenLayersのStyleMapのAttribute replacementについて基本を学んでいきます。

この章以降は、
* いかにOpenLayersのVector layerのstyleを表示するか?
* Style classをその使い方について -> **今回もここ**
* Rule classの使い方
* Filter classの使い方
について順番に学んでいきます。

[[http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book|OpenLayers 2.10 Beginner’s Guide]]なる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

===== Attribute replacement =====
容易であるが強力なものとして、feature styleのAttribute replacementと言うものがあります。
それは、変数のように、layerのstyle定義の中でfeatureのattribueを使用する方法です。
symbolizerを作成する場合、次のformatで任意のpropertyの値をセットすることができます:

**${variable_name}**

variable_nameがあるところに、featureに含まれていたpropertyの名前はpropertyに帰着します。
例えば、featureがすべて任意の整数値を備えた「size」と呼ばれる属性特性を持っているとしましょう。
もし各featureのsize propertyにpointRadiusをセットしたければ、次のように使用します:

**{ ‘pointRadius’: ${size} }**

そのとき起こるのは、featureがそれぞれデザインされる場合、${size}がfeatureのattribute.size property(1つが存在する場合)と置き換わるということです。

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

 
&lt;!DOCTYPE html&gt;
&lt;html lang='ja'&gt;
	&lt;head&gt;
		&lt;meta charset='utf-8' /&gt;
		&lt;script type='text/javascript' src='http://localhost/openlayers/OpenLayers.js'&gt;&lt;/script&gt;
		&lt;script type='text/javascript'&gt;
			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 wms_layer = new OpenLayers.Layer.WMS('OpenLayers WMS', 
					'http://vmap0.tiles.osgeo.org/wms/vmap0', {
					layers : 'basic'
				}, {});
				map.addLayer(wms_layer);

				//Add vector layer
				vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer');
				map.addLayer(vector_layer);

				//Create some points
				for (var i = 0; i &lt; 10; i++) {
					vector_layer.addFeatures([
						new OpenLayers.Feature.Vector(
							new OpenLayers.Geometry.Point(
								(Math.floor(Math.random() * 360) - 180), 
								(Math.floor(Math.random() * 180) - 90)), {
						//Attributes go here
						size : 5 + (Math.floor(Math.random() * 20)),
						label : 'F' + i,
						strokeWidth : (Math.floor(Math.random() * 10))
					})]);
				}

				//Create a style object to be used by a StyleMap object
				var vector_style = new OpenLayers.Style({
					'cursor' : 'pointer',
					'fillColor' : '#787878',
					'fillOpacity' : .8,
					'fontColor' : '#343434',
					'label' : '${label}',
					'pointRadius' : '${size}',
					'strokeColor' : '#232323',
					'strokeDashstyle' : 'solid',
					'strokeWidth' : '${strokeWidth}'
				});

				//create a select style
				var vector_style_select = new OpenLayers.Style({
					'fillColor' : '#ffffff',
					'fillOpacity' : .9,
					'label' : 'X',
					'pointRadius' : 16,
					'strokeColor' : '#343434',
					'strokeDashstyle' : 'solid',
					'strokeWidth' : 4
				});

				//Create a style map object and set the 'default' intent to the
				//  style object we just created
				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);
				map.addControl(select_feature_control);

				//Activate the control
				select_feature_control.activate();

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

			}

		&lt;/script&gt;
	&lt;/head&gt;

	&lt;body onload='init();'&gt;
		&lt;div id='map_element' style='width: 600px; height: 600px;'&gt;&lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;

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

//Create a map with an empty array of controls
map = new OpenLayers.Map('map_element');

//Create a base layer
var wms_layer = new OpenLayers.Layer.WMS(
'OpenLayers WMS',
'http://vmap0.tiles.osgeo.org/wms/vmap0',
{layers: 'basic'},
{}
);
map.addLayer(wms_layer);


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

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

//Add vector layer
vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer');
map.addLayer(vector_layer);

//Create some points
for (var i = 0; i < 10; i++) { vector_layer.addFeatures([ new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point( (Math.floor(Math.random() * 360) - 180), (Math.floor(Math.random() * 180) - 90)), { //Attributes go here size : 5 + (Math.floor(Math.random() * 20)), label : 'F' + i, strokeWidth : (Math.floor(Math.random() * 10)) })]); }

のように vector_layerを定義します。
Pointの座標はrandamに10カ所を作成するようにして、addFeaturesでvector_layerに追加します。
Attributeにsize、label、strokeWidthを設定します。

そして、StyleMap objectを

//Create a style object to be used by a StyleMap object
var vector_style = new OpenLayers.Style({
'cursor' : 'pointer',
'fillColor' : '#787878',
'fillOpacity' : .8,
'fontColor' : '#343434',
'label' : '${label}',
'pointRadius' : '${size}',
'strokeColor' : '#232323',
'strokeDashstyle' : 'solid',
'strokeWidth' : '${strokeWidth}'
});

//create a select style
var vector_style_select = new OpenLayers.Style({
'fillColor' : '#ffffff',
'fillOpacity' : .9,
'label' : 'X',
'pointRadius' : 16,
'strokeColor' : '#343434',
'strokeDashstyle' : 'solid',
'strokeWidth' : 4
});

のようにvector_style(未選択状態)とvector_style_select(選択状態)を定義します。
defualt状態の'label' : '${label}'、'pointRadius' : '${size}'、'strokeWidth' : '${strokeWidth}'をattributeの値に置き換えます。

そして、vector_style_mapに、

//Create a style map object and set the 'default' intent to the
// style object we just created
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;

StyleMapを作成します。ここで、'default': vector_style、'select' : vector_style_selectとしてstyleMapとします。
そして、vector layerをvector_layer.styleMapとして作成します。

最後に、controlを追加して、activateします。

//Add a select feature control
var select_feature_control = new OpenLayers.Control.SelectFeature(vector_layer);
map.addControl(select_feature_control);

//Activate the control
select_feature_control.activate();

保存後、FireFoxを立ち上げて、http://localhost/openlayers/chapter10/chapter10_ex3_attriute_replacement.htmlと入力すると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_52/image01.jpg}}

ように'default'のStyleMapで定義されたvactor layerが追加されて、point dataが読み込まれてmapに表示されます。attibuteがcircle内に表示されます。

point featureをselectすると、
{{http://blog.godo-tys.jp/wp-content/gallery/openlayers_52/image02.jpg}}

ように'select'のStyleMapで定義されたcircle featureに変わります。

===== 今回のまとめ =====

OpenLayersの簡単なStyleMapのAttribute replacementについて基本を学びました。
是非、attributeの値をいろいろと変更して、replacementについて学んでみましょう。
次回も、StyleMap classのRuleとfilerについて基本を学んでいきます。

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

**[[http://blog.godo-tys.jp/openlayer-tutorial/|OpenLayers Tutorialの目次に戻る。]]**