OpenLayers 3 を使ってみよう(その0:はじめに:地理院地図を表示)に目次がある。
ここでは OpenLayers 3.7.0 を使っている。
前回(その9:KML データで経路を描画する)では, KML データとして与えた経路を地図上に描画する方法を記述した。
今回は KML ファイルで地図上にマーカーを描画し,さらにそのマーカーをクリックすると,マーカーの情報が吹き出しに表示されるようにしてみよう。
KML ファイルにマーカー情報を記載するのは,GNSS/GPS 経路の表示に OpenLayers 2 を使う(その5:KML ファイルで経路を表示)の KML の例を見てみて欲しい。 吹出しをつけるには,overlay を用いている。マウスで地図をクリックすると,地図上の点にある物体の feature を読み出し,そこから該当するマーカーの情報を吹出しに表示させている。 また,マウスがマーカーの上にくると,マウスの表示がポインター(手のマーク)に変わるようにしている。
KML ファイルについての説明はOpenLayers 3 を使ってみよう(番外2:KML ファイルのフォーマットについて)に書いているので,そちらを見てみて欲しい。
まず,いつものように以下に 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; }
.ol-popup { display: none; position: absolute; background-color: white;
-moz-box-shadow: 0 1px 4px rgba(0,0,0,0.2);
-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
padding: 5px; border-radius: 10px; border: 1px solid #cccccc; bottom: 24px; left: -51px; }
.ol-popup:after, .ol-popup:before { top: 100%; border: solid transparent; content: " ";
height: 0; width: 0; position: absolute; pointer-events: none; }
.ol-popup:after { border-top-color: white; border-width: 10px; left: 48px; margin-left: -10px; }
.ol-popup:before { border-top-color: #cccccc; border-width: 11px; left: 48px; margin-left: -11px; }
.ol-popup-closer { text-decoration: none; position: absolute; top: 2px; right: 8px; }
.ol-popup-closer:after { content: " ✖ "; }
</style>
<title>OpenLayers 3 Example: KML Layer Popup</title>
<script src="ol3ex10.js" type="text/javascript"></script>
<script src="../jquery.min.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 id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
</div>
<div style="font-size:85%"> 不透明度:<a title="decrease opacity" href="javascript: directSetOpacity(0.1);">0.1</a>
<a title="decrease opacity" href="javascript: directSetOpacity(0.5);">0.5</a>
<a title="decrease opacity" href="javascript: directSetOpacity(1.0); ">1.0</a>
<b> 不透明度・0.2ずつ変更:
<a title="decrease opacity" href="javascript: changeOpacity(-0.2);"><<</a>
<span id="opacity_control">0.5</span>
<a title="increase opacity" href="javascript: changeOpacity(0.2);">>></a></b>
</div>
</body>
</html>
今回の web ページ上の変更点は,主に style の中に吹出し(popup)用の設定を加えたのと,
web ページの <body> 部に吹出し(popup)用の「場所」を用意している。
ここで popup-closer というのがあるが,これは吹出しを閉じるための「☓」印である。
吹出しの右上に表示され,クリックすると吹出しが閉じられる。
また,JavaScript の中で使いたいので jQuery (jquery.min.js) を読み込ませている点である。
ここでは jQuery はサーバーにダウンロードしてきたものを読み込ませている。
それ以外の設定は特に変更はしていない。次に JavaScript を載せよう。ここでも変更箇所の色を変え,説明は web ページのソースと同じくこの下に書いておく。
// -------------------------------------------------------------------
var cyberJ = null; // 地理院地図用の変数
var center_lon = 136.181193333; // 中心の経度(大杉谷,宮川第三発電所)
var center_lat = 34.2329783333; // 中心の緯度(大杉谷,宮川第三発電所)
var kml_url = "work/map_data1.kml";
var kml_url2 = "work/wp_data1.kml";
var initZoom = 15; // ズームの初期値
var MinZoom = 6; // ズームの最小値(最も広い範囲)
var MaxZoom = 21; // ズームの最大値(最も狭い範囲)
var initPrecision = 8; // 座標表示の小数点以下の桁数の初期値
var initOpacity = 1.0; // 不透明度の初期値
var gMaxOpacity = 1.0; // 不透明度の最大値
var gMinOpacity = 0.0; // 不透明度の最小値
*******************************************************************
function init_map() {
// 以下の DOM の定義は,init_map() の中に入れないとだめだった。
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
// 表示用の view 変数の定義
var view = new ol.View({maxZoom: MaxZoom, minZoom:MinZoom});
// cyberJ の opacity をいじるために,cyberJ という変数に入れている。
cyberJ = new ol.layer.Tile({
opacity: initOpacity,
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"
})
});
// 経路の KML データ
// v3.11.0 以降の場合は new ol.format.KML() を new ol.format.KML({ showPointNames: false }) とする。
var kml_vector = new ol.layer.Vector({
source: new ol.source.Vector({ url: kml_url, format: new ol.format.KML() })
});
// マーカーの KML データ
// v3.11.0 以降の場合は new ol.format.KML() を new ol.format.KML({ showPointNames: false }) とする。
var wp_vector = new ol.layer.Vector({
source: new ol.source.Vector({ url: kml_url2, format: new ol.format.KML() })
});
// -------------------------------------------------------------------
// 地図をクリックした際に,停留点の情報を表示するための overlay 変数(popup 用)
var overlay = new ol.Overlay({
element: container
});
// 地図変数 (map 変数) の定義。地理院地図を表示するように指定している
var map = new ol.Map({
target: document.getElementById('map_canvas'),
layers: [cyberJ, kml_vector, wp_vector],
view: view,
overlays: [overlay],
renderer: ['canvas', 'dom'],
controls: ol.control.defaults().extend([new ol.control.ScaleLine()]),
interactions: ol.interaction.defaults()
});
function displayFeatureInfo(pixel, coordinate) {
var features = [];
map.forEachFeatureAtPixel(pixel, function(feature, wp_layer) {
features.push(feature);
});
if (features.length > 0) {
var info = [];
// for (i = 0; i < features.length; ++i) {
// info.push('<div id="wp_desc" style="font-size:12px; width:235px">'+features[i].get('name')+features[i].get('description')+'</div>');
// }
info.push('<div id="wp_desc" style="font-size:12px; width:215px">'+features[0].get('name')+features[0].get('description')+'</div>');
overlay.setPosition(coordinate);
content.innerHTML = info[0];
// content.innerHTML = info.join('<br>') || '(unknown)';
container.style.display = 'block';
} else {
content.innerHTML = '';
container.style.display = 'none';
}
};
map.on('click', function(evt) {
displayFeatureInfo(evt.pixel, evt.coordinate);
});
// マーカー上でアイコンの表示を変更するイベントハンドラー, jQuery が必要
$(map.getViewport()).on('mousemove', function(e) {
var pixel = map.getEventPixel(e.originalEvent);
var hit = map.forEachFeatureAtPixel(pixel, function(feature, layer) { return true; });
if (hit) { map.getTarget().style.cursor = 'pointer'; }
else { map.getTarget().style.cursor = ''; }
});
// popup を閉じるためのイベントハンドラー
closer.onclick = function() {
container.style.display = 'none';
closer.blur();
return false;
};
// 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);
// span opacity_control (地理院地図の不透明度) に初期値(実数)を入れる。
document.getElementById('opacity_control').innerHTML = initOpacity.toFixed(1);
} // 初期化
// *******************************************************************
// 地理院地図 (var cyberJ) の opacity(この場合は不透明度) を変える
function changeOpacity(opacity) {
var newOpacity = (parseFloat(document.getElementById('opacity_control').innerHTML) + opacity).toFixed(1); // 新しい opacity の値を求める
newOpacity = Math.min(gMaxOpacity, Math.max(gMinOpacity, newOpacity)); // 最大値と最小値の範囲を超えないように
cyberJ.setOpacity(newOpacity); // 地理院地図の opacity の変更
document.getElementById('opacity_control').innerHTML = newOpacity.toFixed(1); // opacity の数字の表示書き換え
}
function directSetOpacity(opacity) {
cyberJ.setOpacity(opacity);
document.getElementById('opacity_control').innerHTML = opacity.toFixed(1);
}
// *******************************************************************
今回は JavaScript の部分はまあまあ書き直されているので順に説明しよう。まず,最初の変数定義の辺りで,マーカー用の KML ファイルのファイル名を定義している。 経路用の KML ファイルの中にマーカーの情報を入れてもいいのだが,経路とマーカーを別々に消去したりできるように別ファイルとしておいた。 これに伴い,init_map() 関数中の KML 用の vector layer の定義も増えている。
次に init_map() 関数の最初の辺りにある変数定義であるが,これらは pop-up 用の web 領域の DOM を変数に入れている。 これらはこの中で後で使われる。 注意点として,init_map() 関数の外で定義すると,これらの変数が定義されてない,とされる点があげられる。
KML 用の vector layer の定義の後に overlay という変数を定義している。 これは地図上に重ねて表示する一種の layer のようなものである。 ここでは popup 用として,popup の表示領域を element として含んでいる。
map の定義では,上に書いたマーカー用の vector layer を layers に追加し, overlay 変数を overlays として登録している。 ここで,overlays は複数形で定義されているため,layer は [,] に入れて配列の形にしてある。
次にあるオレンジ色の displayFeatureInfo(),緑色の map.on, 水色の $(map.getViewport()).on, 紫色の closer.onclick が吹出し(popup)のイベント処理を表す。 順序通りではないが,先に map.on,closer.onclick について述べると, map.on は,地図をクリックした際のイベント処理を表し, すぐ上で定義されている displayFeatureInfo() を実行するように指示している。 その際,マウスがクリックされた画面上のポジションの pixel 値(evt.pixel)と,地図座標上の値(evt.coordinate)を引数として渡している。 $(map.getViewport()).on はマウスが動いた時,マウスがマーカーの上にあれば,マウスの画像をポインターに変更するものである。 サンプルを参考にしたので jQuery を使わないといけない。そのために web ページで jquery.min.js を読み込ませている。 closer.onclick は,吹出しの close ボタンが押された時のイベント処理である。 これによって吹出しは画面上から消えて見えなくなる。
最後にdisplayFeatureInfo() だが,これはマウスがクリックされた際の処理の具体的な記述である。 関数の中では,処理用に features という配列変数を用意してある。 そして,引数として与えられたマウスがクリックされた画面上の pixel 値から, そこに描画されている物体の feature を features 配列変数に順に代入(features.push...)している。 一つの点に複数の物体が描画されている事があるので,feature を持つすべての物体の feature が順に features に追加される。
もし,その画面上の点に1個以上の feature を持つ物体が描画されていれば, その中に記載されている項目のうちから「name」と「description」という項目を取り出して, 吹出し(popup)の内容(content)として代入して popup を表示させている。 これらの項目(name,description)は KML ファイルを念頭においており, その中の <name>,<description> の内容を記載することにしている。
この popup 処理では,複数ある可能性がある features の中の最初の要素のみ(features[0])の内容を書き出している。 オレンジ色の displayFeatureInfo() の中にある黒いコメントアウトされた行には, マウスクリックされた点にある全ての feature を吹出しに書き出す for 文が書かれているが, 実際にサンプルで見た際に,少し煩雑になるのでやめておいた。
これで GNSS/GPS で得られたツーリングの際のルート情報を,写真とともに表示することができるようになった。 後は,経路とマーカーの KML vector layer を別々に非表示・表示を切り替えられれば,OpenLayers 2 で作ったものと同じような事ができそうである。
「その10」のサンプルを具体的な web ページとして用意したので,具体的な表示を見てみて欲しい。(ちなみにサンプルページはアクセスログを取るルーチンを組み込んでいます)
その11:KML から描画した経路とマーカーの表示/非表示の個別切替に続く
0 件のコメント:
コメントを投稿