2014年9月9日火曜日

OpenLayers 3 を使ってみよう (その1:マウスクリックのイベント処理)

 これはOpenLayers 3 を使ってみよう(その0:はじめに:地理院地図を表示)からの続きである。
OpenLayers 3 を使ってみよう(その0:はじめに:地理院地図を表示)に目次がある。
ここでは OpenLayers 3.7.0 を使っている。
 前回(その0:はじめに:地理院地図を表示)では, OpenLayers 3 を用いて,地理院地図を web ページ上に表示する方法を記述した。
今回はマウスクリックによるイベント処理の例として,マウスでクリックした地点の座標を文字として表す方法を示そう。

 今回のルーチンは前回の web ページと javaScript にほんの少し手を加えるだけである。 やることは,マウスがクリックされた際に処理行うイベント処理を記載することである。 その中では,マウスクリックイベントで得られた座標情報を,メルカトル座標から WGS84 の座標に変換して,文字として表示させる,というものである。 その辺りについて見ていこう。

 まずは web ページの方のソースを見てみよう。 前回から変更があったところだけ色を変えてある。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="http://openlayers.org/en/v3.7.0/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.7.0/build/ol.js" type="text/javascript"></script>
<style type="text/css">
   div.fill {width: 100%; height: 100%;}
   body {padding: 0; margin: 0}
   html, body, #map {height: 100%; width: 100%;}

   .ol-attribution {
     padding: 3px;  position: absolute;  background-color:#ffffff;
     background-color:rgba(230,255,255,0.7);
     right: 3px;  bottom:5px;  font-size:12px;
   }
   .ol-attribution ul { padding: 0px;  line-height: 14px;  margin: 0px; }
   .ol-attribution li { line-height: inherit;  display: inline;  list-style: none outside none; }

   .ol-zoom .ol-zoom-out { margin-top: 202px; }
   .ol-zoomslider { background-color: transparent; top: 2.3em; }
   .ol-touch .ol-zoom .ol-zoom-out { margin-top: 212px; }
   .ol-touch .ol-zoomslider { top: 2.75em; }
</style>
<title>OpenLayers 3 Example: Mouse Click to String</title>
<script src="ol3ex1.js" type="text/javascript"></script>
</head>

<body onload="init_map()">
<div id="map_canvas" style="width: 100%; height: 97%; position:absolute; top:25px; left:0px; font-size:100%;"></div>
&nbsp;マウスがクリックされた座標:<span id="outStr"></span>
</body>
</html>
 今回変更したのは,地図を表示する「"map_canvas"」という id を持つ <div> にスタイルを追加したのと, その下に「"outStr"」という id を持つ <span> を追加した,という2点だけである。 <div> の方は,文字列を表示させるために,地図の上部に隙間を用意したかったので,スタイルを追加している。 <span> の方は,文字列を表示させる「場所」が欲しかったので配置してある。 <span> は <div> とほぼ同じで,それがあるからと言って,特に何をするでもない web の要素である。 つまり場所を用意しただけ,である。 <div> との違いは,<div> の場合は前後で改行されてしまうが,<span> は前後で改行がなされない,という点である。 この <span> の所に,座標の数値を出力する。

 次に JavaScript の方を見てみよう。 以下に JavaScript を記載する。 こちらも前回と違う部分のみ色を変えてある。
// ===================================================================
var center_lon = 135.100303888; // 中心の経度(須磨浦公園)
var center_lat = 34.637674639; // 中心の緯度(須磨浦公園)

var initZoom = 10; // ズームの初期値
var MinZoom  = 6;   // ズームの最小値(最も広い範囲)
var MaxZoom  = 17;  // ズームの最大値(最も狭い範囲)

var initPrecision = 8; // 座標表示の小数点以下の桁数の初期値
// *******************************************************************
function init_map() {
// 表示用の view 変数の定義。
    var view = new ol.View({ projection: "EPSG:3857",
        maxZoom: MaxZoom,
        minZoom: MinZoom
   })

// cyberJ(地理院地図)用の変数
    var cyberJ = new ol.layer.Tile({
        source: new ol.source.XYZ({
            attributions: [ new ol.Attribution({ html: "<a href='http://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>" }) ],
            url: "http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
            projection: "EPSG:3857"
        })
    })

// 地図変数 (map 変数) の定義。地理院地図を表示するように指定している。
    var map = new ol.Map({
        target: document.getElementById('map_canvas'),
        layers: [cyberJ],
        view: view,
        renderer: ['canvas', 'dom'],
        controls: ol.control.defaults().extend([new ol.control.ScaleLine()]),
        interactions: ol.interaction.defaults()
    });

// 地図をクリックした際に,座標を書き出す。小数点以下の桁数は initPrecision で指定。メルカトル座標 (EPSG:3857) を WGS84 (EPSG:4326) に変換している。
    map.on('click', function(evt) {
      var coordinate = evt.coordinate;
      var stringifyFunc = ol.coordinate.createStringXY(initPrecision);
      var outstr = stringifyFunc(ol.proj.transform(coordinate, "EPSG:3857", "EPSG:4326"));
      document.getElementById('outStr').innerHTML = outstr;
    });

// zoom slider の追加
    map.addControl(new ol.control.ZoomSlider());

// 中心の指定。view に対して指定。transform を忘れないこと。
    view.setCenter(ol.proj.transform([center_lon, center_lat], "EPSG:4326", "EPSG:3857"));

// zoom の指定。view に対して指定する。
    view.setZoom(initZoom);

} // function init_map()
// *******************************************************************
 ここで青色で書かれた「var initPrecision = 8;」は,数値を文字化する際の小数点以下の桁数であり,ここでは8桁にしている。
 赤色の部分がマウスがクリックされた際のイベント処理を定義している。 変数 map に対するイベント処理は,「map.on(type, listener, opt_this)」という形で記載される。 それぞれの引数について述べよう。
 (1) type:イベントの種類を表す。例:click,dblclick, rightclick, など…
      イベントの種類は,mousedown, mouseup, mouseover, mouseout, mousemove, mouseenter, mouseleave, などがある。
      map に対してすべて使えるのかどうかは不明…
 (2) listner:ここにイベント処理の関数を書く。
      引数から座標などを読み取る…他に何が読み取れるの? pixel はいけるみたいやけど…。
 (3) opt_this:「The object to use as this in listener」と書かれているが,なんの事やら…?

 今回は,クリックしたら,関数で処理をしなさい,と設定してある。 関数は,1行目で引数から座標データを取り出している。2行目で座標から X, Y 形式の文字列を作る関数を与えている。 3行目で座標の投影法を変換して,それを文字列に変換している。4行目でそれを「outStr」という id を持つ領域に出力している。 4行目で「.innerHTML」というのがあるが,これは web 要素の中身を取り出したり書き換えたりする時に使う。 「<input>」などの場合は,ユーザーが入力する領域があるので,.innerHTML ではなく,.value を用いないと行けない。

 これらの追加だけで,とりあえずマウスがクリックされた時の処理が記述できる(はず…)。

 「その1」のサンプルを具体的な web ページとして用意したので,具体的な表示を見てみて欲しい。(ちなみにサンプルページはアクセスログを取るルーチンを組み込んでいます)

その2:地図の不透明度を変えるに続く

0 件のコメント: