2014年7月9日水曜日

GNSS/GPS 経路の表示に OpenLayers 2 を使う (その3:中央にセンターマークを表示)

これはGNSS/GPS 経路の表示に OpenLayers 2 を使う(その2:OpenLayers 2 を使って地理院地図を表示)からの続きである。
GNSS/GPS 経路の表示に OpenLayers 2 を使う(その0:はじめに)に目次がある。
ここでは OpenLayers 2.13.1 を使っている。
前回(その2:OpenLayers 2 を使って地理院地図を表示)は OpenLayers を使って地理院地図を表示させたが,今回は地図の中央にセンターマークを表示させてみる。 ここでの記載は地理院地図のページのソースや, y2blog OpenLayersでレイヤーをオーバレイ表示する方法などのサイトを参考にさせてもらっている。
 以下に 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">
<title>OpenLayers Example: Center Marker</title>
<script src="../OpenLayers-2.13.1/lib/OpenLayers.js"></script>
<script type="text/javascript">//<![CDATA[
var param = { div: 'map_canvas', lon: 136.181193333333, lat: 34.2329783333333, zoom: 15};
//]]></script>
<script type="text/javascript">
// -------------------------------------------------------------------
var proj_3857 = new OpenLayers.Projection('EPSG:3857');
var proj_4326 =  new OpenLayers.Projection('EPSG:4326'); // WGS84

var map = null;

var crosshairsCursorCtrl = null; // 中心マーカー用 crosshairs の変数
var centercross = 1; // 表示する
// -------------------------------------------------------------------
// 初期化
function init_map() {
        // 地図表示の変数定義
        map = new OpenLayers.Map({
          div: param.div, projection: proj_3857, displayProjection: proj_4326
        });

        // 地理院地図(標準地図)を半透明にして baselay として表示
        var std_map = new OpenLayers.Layer.XYZ('標準地図', 'http://cyberjapandata.gsi.go.jp/xyz/std/${z}/${x}/${y}.png', {
          attribution: '<a href="http://portal.cyberjapan.jp/help/termsofuse.html" target="_blank">国土地理院</a>',
          maxZoomLevel: 17, isBaseLayer: false
        });
        var pale_map = new OpenLayers.Layer.XYZ('淡色地図', 'http://cyberjapandata.gsi.go.jp/xyz/pale/${z}/${x}/${y}.png', {
          attribution: '<a href="http://portal.cyberjapan.jp/help/termsofuse.html" target="_blank">国土地理院</a>',
          maxZoomLevel: 17
        });
        map.addLayers([std_map, pale_map]);

        // 中心座標を設定
        if (!map.getCenter()) {
          map.setCenter(new OpenLayers.LonLat(param.lon, param.lat).transform(proj_4326, proj_3857), param.zoom);
        }

        // Layer 切替スイッチ表示
        map.addControl(new OpenLayers.Control.LayerSwitcher());

        // スケールの表示
        map.addControl(new OpenLayers.Control.ScaleLine());

        // 中心マーカーの表示
        funcCrosshairs(); // centercross ==1 なら表示される
} // 初期化

// -------------------------------------------------------------------
// 中心マーカー:crosshairs cursor のクラス設定
OpenLayers.Control.CrosshairsCursor = OpenLayers.Class( OpenLayers.Control, {
  element : null,
  iconImageUrl: null,
  iconSize: new OpenLayers.Size(32,32),
  xyPos: new OpenLayers.Pixel(320,240),

  initialize: function(element) {
    OpenLayers.Control.prototype.initialize.apply(this, arguments);
    this.element = OpenLayers.Util.getElement(element);
  },

  draw: function() {
    OpenLayers.Control.prototype.draw.apply(this, arguments);
    var xy = this.xyPos.clone();
    var centerXYPos = new OpenLayers.Pixel( xy.x - (this.iconSize.w / 2),
    xy.y - (this.iconSize.h / 2));
    this.buttons = new Array();

    var uniqID = OpenLayers.Util.createUniqueID("OpenLayers.Control.Crosshairs_");
    this.div = OpenLayers.Util.createAlphaImageDiv(
      uniqID, centerXYPos, this.iconSize, this.iconImageUrl, "absolute");
    return this.div;
  },
  CLASS_NAME: "OpenLayers.Control.CrosshairsCursor"
});
// -------------------------------------------------------------------
/* 中央の十字を書く関数(初期起動時と、ウインドウサイズが変更されると呼び出す。)*/
function funcCrosshairs(){
  if(map){//初期起動時のエラー回避処理
    if (centercross) { //チェックが入っている場合
      removeCrosshairs(); // いったん十字コントロール削除
      createCrosshairs(); // 十字コントロールの作成
    } else{
      return false;
    }
  }
}

/* 中央の十字の表示・非表示を切り替える関数(チェックボックスで呼び出し)*/
function funcCrosshairs2() {
  if (!document.getElementById('centercross').checked) { //チェックが入っていない場合
    removeCrosshairs(); // 十字コントロール削除
  } else{
    createCrosshairs(); // 十字コントロールの作成
  }
}

/* 十字コントロールの作成 */
function createCrosshairs() {
  crosshairsCursorCtrl = new OpenLayers.Control.CrosshairsCursor({
    iconImageUrl:  "../cj_map/crosshairs.png", iconSize: new OpenLayers.Size(32, 32), xyPos: new OpenLayers.Pixel( map.getCurrentSize().w/2, map.getCurrentSize().h/2 )
  });
  map.addControl( crosshairsCursorCtrl );
}

/* 十字コントロール削除 */
function removeCrosshairs(){
  if (crosshairsCursorCtrl) {
    map.removeControl(crosshairsCursorCtrl);
  }
  crosshairsCursorCtrl = null;
}
// -------------------------------------------------------------------
</script>
</head>

<body onload="init_map()">
<div id="map_canvas" style="width: 100%; height: 95%; position:absolute; top:35px; left:0px"></div>
<div>
<input style="color:blue" onclick="removeCrosshairs();" type=button value="Center消去"> 
<input style="color:red" onclick="funcCrosshairs();" type=button value="Center表示"> 
</div>
</body>
</html>

 基本的な構造は前回と同じである。 違っている部分を色付きにしてみた。 それぞれについて少しだけ(わかっている範囲で)説明しよう。

 最初の青字の部分は,変数の定義である。 これは関数の中で定義すると関数の中でしか使えないので,それを避けるために関数の外で定義しているものである。 「crosshairsCursorCtrl」というのが,十字形のセンターマーク用の変数である。 「centercross」という変数は十字を表示するかしないかを示す変数である。

 次の青字の部分は,地図上にスケール(長さの目安)を表示するものであり, OpenLayers に標準で用意されているものである。

 次に赤字の部分だが,ここは新しい crosshairs cursor というクラスを定義している。 具体的には,どのような引数を持つかや,初期化の関数,描画の関数に関する記述など,がある。 変数,特に「iconSize」と「xyPos」は初期値であり,通常は引数として渡されたものに置換えられる。 それ以上のこと,特に「uniqID」などはよくわかっていないので,おまじないだと思ってそのまま残している。 この赤字の部分の必然性がまだよくわかっていないのだが, とりあえず画像を地図の上に「動かないように」表示するために新しいクラスを作っているのだと解釈している。

 それに続く緑字の部分は実際に十字を描画したり消したりする関数が定義されている。 「funcCorsshairs」は centercross 変数が1かどうかを判断して,1なら十字を描画する関数である。 何故かわからないが,一度十字を消してから新たに描き直している。
「funcCrosshairs2」は表示・非表示を切り替えるトグルスイッチのような関数である。
 「createCrosshairs」と「removeCrosshairs」はそれぞれ十字の描画と消去を行う部分である。 「createCrosshairs」の方は,「crosshairsCursorCtrl」という名前の OpenLayers.Control.CrosshairsCursor クラス変数を定義している。 そこでは十字の画像ファイル名や,アイコン(図)のサイズ,表示場所を記載している。 最後に「map.addControl(corsshairsCursorCtrl)」とすることで,実際に十字が地図上に描画される。 当然ながら,この web ソースファイル以外に十字の画像ファイルを適当な場所に置いておかないとうまく表示されない。

 web ページの「」の中の記載も多少変更点がある。 一つは,地図の上の方にボタンを配置したいので,地図の表示を少し縦方向に縮めている。 地図表示領域の高さを95%に減らし,少し下げた位置に表示されるように定義している。 また,十字の消去と再表示のボタンを配置し,それぞれ JavaScript の removeCrosshairs と funcCrosshairs 関数を実行するように定義している。

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

その4:不透明度を変えて2つの地図を重ねて表示に続く

0 件のコメント: