2009年12月31日木曜日

OpenLayers 43 Click Handler

OpenLayers Click Handler Example(click-handler.html)を参考に Click Handler を試してみます。

HTML ファイルを新規作成します。
「openlayersTokyoproj」 を右クリックして 新規 -> HTML ファイル をクリック。
「HTML ファイル」ウィンドウの「ファイル名(任意:openlayers_clickhandler.html)」に入力して「完了」ボタンをクリック。
「charset」を「utf-8」にします。
click-handler.html をすべて選択し、コピーしたら openlayers_clickhandler.html に貼り付けます。

コードを次のようにします。ちょっと修正と解説。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>OpenLayers43 Click Handler</title>

<link rel="stylesheet" href="./theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="./examples/style.css" type="text/css" />
<!-- map と表のスタイル -->
<style type="text/css">
#map {
width: 340px;
height: 170px;
border: 1px solid gray;
}
#west {
width: 350px;
}
#east {
position: absolute;
left: 370px;
top: 3em;
}

table td {
text-align: center;
margin: 0;
border: 1px solid gray;
}
textarea.output {
text-align: left;
font-size: 0.9em;
width: 250px;
height: 65px;
overflow: auto;
}
</style>


<!-- OpenLayers ライブラリ -->
<script src="./lib/Firebug/firebug.js"></script>
<script src="./lib/OpenLayers.js"></script>

<!-- Proj4js ライブラリ -->
<script type="text/javascript" src="./lib/proj4js/lib/proj4js-compressed.js"></script>
<script type="text/javascript" src="./lib/proj4js/lib/projCode/tmerc.js"></script>
<script type="text/javascript" src="./lib/proj4js/lib/defs/EPSG2456.js"></script>


<script type="text/javascript">
/* Click Handler 設定:
* OpenLayers.Control.Click は 初期設定とOpenLayers.Handler.Click の
* 実行部分で構成されているクラスオブジェクトに使用しているようです。
*/
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: { // 初期設定値
'single': true,
'double': false,
'pixelTolerance': 0,
'stopSingle': false,
'stopDouble': false
},
// 初期設定
initialize: function(options) {
this.handlerOptions = OpenLayers.Util.extend(
{}, this.defaultHandlerOptions
);
OpenLayers.Control.prototype.initialize.apply(
this, arguments
);
this.handler = new OpenLayers.Handler.Click(
this, {
'click': this.onClick, // クリックしたとき
'dblclick': this.onDblclick // ダブルクリックしたとき
}, this.handlerOptions
);
},

onClick: function(evt) {
var output = document.getElementById(this.key + "Output");
// toggle の key('single'など)+ Output = singleOutput
var msg = "click " + evt.xy;
// "click " + evt.xy(XY 座標)= click x=***,y=***
output.value = output.value + msg + "\r\n";
// output.value + msg + "\r\n" = singleOutput click x=***,y=***\r\n
},

onDblclick: function(evt) {
var output = document.getElementById(this.key + "Output");
var msg = "dblclick " + evt.xy;
output.value = output.value + msg + "\n";
}

});


var map, controls;

function init(){
// 東京都用 map の設定
options = {
projection: new OpenLayers.Projection("EPSG:2456"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
maxResolution: 'auto',
units: 'meters',
maxExtent: new OpenLayers.Bounds(-279000,1054000,-185000,1104000)
};
map = new OpenLayers.Map("map", options);
// ここまで
// 東京都のレイヤ
layer1 = new OpenLayers.Layer.WMS( "Tokyo Height WMS",
"http://192.168.1.6/cgi-bin/mapserv?",
{
map: '/home/user/mapfile/tokyo_bmi_pgis_img.map',
layers: 'height',
format: 'image/png'
});
layer2 = new OpenLayers.Layer.WMS( "Tokyo Kukaku Sen WMS",
"http://192.168.1.6/cgi-bin/mapserv?",
{
map: '/home/user/mapfile/tokyo_bmi_pgis_img.map',
layers: 'kukaku',
transparent: true,
format: 'image/png'
});
map.addLayers([layer1, layer2]);

// ここまで

controls = {
"single": new OpenLayers.Control.Click({
// メソッドが "single" のとき、オブジェクトとして作成された
// OpenLayers.Control.Click を初期定義
handlerOptions: {
"single": true
}
}),
"double": new OpenLayers.Control.Click({
handlerOptions: {
"single": false,
"double": true
}
}),
"both": new OpenLayers.Control.Click({
handlerOptions: {
"single": true,
"double": true
}
}),
"drag": new OpenLayers.Control.Click({
handlerOptions: {
"single": true,
"pixelTolerance": null // ポインタが 0 ピクセル以上移動後(?)
}
}),
"stopsingle": new OpenLayers.Control.Click({
handlerOptions: {
"single": true,
"stopSingle": true // これを on にする前に on にした "single" ハンドラは無効
}
}),
"stopdouble": new OpenLayers.Control.Click({
handlerOptions: {
"single": false,
"double": true,
"stopDouble": true // これを on にする前に on にした "double" ハンドラは無効
}
})
};


var props = document.getElementById("props"); // ?
// 例えば、key("single") をコントロールに追加
var control;
for(var key in controls) {
control = controls[key];
// only to route output here
control.key = key;
map.addControl(control);
}

map.addControl(new OpenLayers.Control.LayerSwitcher()); // 追加
map.addControl(new OpenLayers.Control.MousePosition()); // 追加
map.addControl(new OpenLayers.Control.ScaleLine()); // 追加

map.zoomToMaxExtent();
} // End of function init()


// ボタンの状態を判断して on/off の切り替えをし、singleStatus の ボタン
// (スイッチ)の表示を切り替えして、テキストエリア内を空にする。
function toggle(key) {
var control = controls[key];
if(control.active) {
control.deactivate();
} else {
control.activate();
}
var status = document.getElementById(key + "Status");
status.innerHTML = control.active ? "on" : "off";
var output = document.getElementById(key + "Output");
output.value = "";
}
</script>
</head>


<body onload="init()">
<h1 id="title">Click Handler Example</h1>
<div id="west">
<div id="tags"></div>
<p id="shortdesc">
This example shows the use of the click handler.
</p>
<div id="map" class="smallmap"></div>
<p>
The click handler can be used to gain more flexibility over handling
click events. The handler can be constructed with options to handle
only single click events, to handle single and double-click events,
to ignore clicks that include a drag, and to stop propagation of
single and/or double-click events. A single click is a click that
is not followed by another click for more than 300ms. This delay
is configured with the delay property.
</p>
<p>
The options to stop single and double clicks have to do with
stopping event propagation on the map events listener queue
(not stopping events from cascading to other elements). The
ability to stop an event from propagating has to do with the
order in which listeners are registered. With stopSingle or
stopDouble true, a click handler will stop propagation to all
listeners that were registered (or all handlers that were
activated) before the click handler was activated. So, for
example, activating a click handler with stopDouble true after
the navigation control is active will stop double-clicks from
zooming in.
</p>
</div>


<div id="east">
<table>
<caption>Controls with click handlers (toggle on/off to clear output)</caption>
<tbody>
<tr>
<td>single only</td>
<td><button id="singleStatus" onclick="toggle('single')">off</button></td>
<td><textarea class="output" id="singleOutput"></textarea></td>
</tr>
<tr>
<td>double only</td>
<td><button id="doubleStatus" onclick="toggle('double')">off</button></td>
<td><textarea class="output" id="doubleOutput"></textarea></td>
</tr>
<tr>
<td>both</td>
<td><button id="bothStatus" onclick="toggle('both')">off</button></td>
<td><textarea class="output" id="bothOutput"></textarea></td>
</tr>
<tr>
<td>single with drag</td>
<td><button id="dragStatus" onclick="toggle('drag')">off</button></td>
<td><textarea class="output" id="dragOutput"></textarea></td>
</tr>
<tr>
<td>single with stop</td>
<td><button id="stopsingleStatus" onclick="toggle('stopsingle')">off</button></td>
<td><textarea class="output" id="stopsingleOutput"></textarea></td>
</tr>
<tr>
<td>double with stop</td>
<td><button id="stopdoubleStatus" onclick="toggle('stopdouble')">off</button></td>
<td><textarea class="output" id="stopdoubleOutput"></textarea></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>



メモ:JavaScript の初期化処理について

OpenLayers.Control.prototype.initialize.apply(
this, arguments
);

prototype プロパティ: クラス側でまとめてメソッドのテーブルを持つ。
initialize: コントロール生成時に呼び出される初期化メソッド。
apply メソッド: JavaScriptのFunctionオブジェクトで定義されているもので、メソッド実行時のthis参照を指定できる。
arguments プロパティ: 関数の内部からその引数を参照するために使う配列オブジェクトのプロパティ

0 件のコメント: