2014年7月14日月曜日

GNSS/GPS 経路の表示に OpenLayers 2 を使う(その8:マーカーと経路を別々の KML ファイルで表示)

これはGNSS/GPS 経路の表示に OpenLayers 2 を使う(その7:マーカーを text ファイル,経路を KML で表示)からの続きである。
GNSS/GPS 経路の表示に OpenLayers 2 を使う(その0:はじめに)に目次がある。
ここでは OpenLayers 2.13.1 を使っている。
前回(その7:マーカーを text ファイル,経路を KML で表示)では テキストファイルにマーカー情報を記載して,経路とマーカーを地図上に記載する方法を記述した。

今回は経路とマーカーを別々の 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">
<title>OpenLayers Example: Markers</title>
<link rel="stylesheet" href="../../cj_map/popup.css" type="text/css">
<script src="http://maps.google.co.jp/maps/api/js?sensor=false&language=ja"></script>
<!--<script src="../../OpenLayers-2.13.1/lib/OpenLayers.js"></script>-->
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">//<![CDATA[
var param = { div: 'map_canvas', lon: 136.181193333333, lat: 34.2329783333333, zoom: 15, url: 'work/map_data1.kml', url2:'work/wp_data.kml' };
//]]></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 std_map = null;
var markers = null;

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

        // 地理院地図(標準地図)を表示
        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
        });
        map.addLayer(std_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());

        // kml 経路ファイルの読込み
        var kmlwayLayer = new OpenLayers.Layer.Vector('GPS経路データ', {
          projection: proj_4326,
          strategies: [new OpenLayers.Strategy.Fixed()],
          protocol: new OpenLayers.Protocol.HTTP({
            url: param.url,
            format: new OpenLayers.Format.KML({extractStyles: true, extractAttributes: true, maxDepth: 2})
          })
        });
        map.addLayer(kmlwayLayer);

        // kml ファイルの読込み
        var kmlLayer = new OpenLayers.Layer.Vector('GPSマーカーデータ', {
          projection: proj_4326,
          strategies: [new OpenLayers.Strategy.Fixed()],
          protocol: new OpenLayers.Protocol.HTTP({
            url: param.url2,
            format: new OpenLayers.Format.KML({extractStyles: true, extractAttributes: true, maxDepth: 2})
          })
        });
        map.addLayer(kmlLayer);

        // kml 内のマーカーをクリックした際の処理
        kmlLayer.events.on({
          featureselected: onFeatureSelect,
          featureunselected: onFeatureUnselect
        });
        selectControl = new OpenLayers.Control.SelectFeature(kmlLayer);
        map.addControl(selectControl);
        selectControl.activate();

        // 中心マーカーの表示
        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;
}
// -------------------------------------------------------------------
// kml 内のマーカーのコメントのpop up 処理
function onFeatureSelect(event) {
  var feature = event.feature;
  var content = '<h2>' + feature.attributes.name + '</h2>';
  if (feature.attributes.description) {
    content = content + feature.attributes.description;
  }

  var popup = new OpenLayers.Popup.FramedCloud('chicken',
    feature.geometry.getBounds().getCenterLonLat(),
    new OpenLayers.Size(200,200),
    content, null, true, onPopupClose
  );
  feature.popup = popup;
  map.addPopup(popup);
}

function onFeatureUnselect(event) {
  var popup = event.feature.popup;
  
  if (popup) {
    map.removePopup(popup);
    popup.destroy();
    delete popup;
  }
}

function onPopupClose(event) {
  selectControl.unselectAll();
}
// -------------------------------------------------------------------
</script>
</head>

<body onload="init_map()">
<div id="map_canvas" style="width: 100%; height: 95%; position:absolute; top:35px; left:0px"></div>

<div><b>
    <input style="color:blue" onclick="removeCrosshairs();" type=button value="Center消去"> 
    <input style="color:red" onclick="funcCrosshairs();" type=button value="Center表示"> 
</b></div>

</body>
</html>
  今回は中央の十字線も記載しているので,少し長めになっている。 特徴的な部分としては,青字の部分緑字の部分赤字の部分である。 青字の部分は経路の KML ファイルを読み込ませて表示させている。 マーカー用と区別するために,変数名を kmlwayLayer としてみた。 一方緑字の部分でマーカー用の KML ファイルを読み込ませているが,変数名は「kmlLayer」としておいた。 赤字の部分ではマーカーのクリック処理を記載している。 当然ターゲットとなる変数はマーカー用の変数「kmlLayer」である。

KML ファイルは,「その5:KML ファイルで経路を表示」で使った経路用の KML と,以下に示すマーカー用の KML ファイルを使う。 以下のマーカー用の KML ファイルは,基本的には「その6:KML ファイルで経路とマーカーを表示」で使った KML ファイルから,経路情報を消しただけである。
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<description>
<![CDATA[<p>大杉谷20140615</p>]]>
</description>
<Style id="StartIcon">
<IconStyle>
<scale>1</scale>
<Icon><href>http://maps.gstatic.com/intl/ja_jp/mapfiles/ms/micons/hiker.png</href></Icon>
<hotSpot x="0.5" y="0.0" xunits="fraction" yunits="fraction"/>
</IconStyle>
</Style>
<Style id="EndIcon">
<IconStyle>
<scale>1</scale>
<Icon><href>http://maps.gstatic.com/intl/ja_jp/mapfiles/ms/micons/red-pushpin.png</href></Icon>
<hotSpot x="0.5" y="0.0" xunits="fraction" yunits="fraction"/>
</IconStyle>
</Style>
<Style id="PhotoIcon">
<IconStyle>
<scale>1</scale>
<Icon><href>http://maps.gstatic.com/intl/ja_jp/mapfiles/ms/micons/camera.png</href></Icon>
<hotSpot x="0.5" y="0.0" xunits="fraction" yunits="fraction"/>
</IconStyle>
</Style>
<Folder>
<name>Icons_on_the_Map</name>
<Placemark>
<name><![CDATA[<div id="wp_name">出発点</div><div id="wp_address">三重県多気郡大台町大杉</div>]]></name>
<description><![CDATA[<div id="wp_time_info">2014/06/15 07:22:32</div>]]></description>
<styleUrl>#StartIcon</styleUrl><Point><coordinates>136.181595,34.2331033333333,320.7</coordinates></Point>
</Placemark>
<Placemark>
<name><![CDATA[<div id="wp_name">Photo Point</div><div id="wp_address">三重県多気郡大台町大杉</div>]]></name>
<description><![CDATA[<div id="wp_time_info">2014/06/15 07:27:23</div><div id="wp_photo_info"><a href="./P1110149.html" target="_blank"><img src="./image/P1110149_\
thumb.png"></a> <a href="./P1110150.html" target="_blank"><img src="../../motorcycle/Oosugidani_20140615/./image/P1110150_thumb.png"></a> </div>]]></description\
>
<styleUrl>#PhotoIcon</styleUrl><Point><coordinates>136.180895,34.2326366666667,313.1</coordinates></Point>
</Placemark>
<Placemark>
<name><![CDATA[<div id="wp_name">Photo Point</div><div id="wp_address">三重県多気郡大台町大杉</div>]]></name>
<description><![CDATA[<div id="wp_time_info">2014/06/15 07:29:28</div><div id="wp_photo_info"><a href="./P1110153.html" target="_blank"><img src="./image/P1110153_\
thumb.png"></a> </div>]]></description>
<styleUrl>#PhotoIcon</styleUrl><Point><coordinates>136.180318333333,34.2320783333333,322.3</coordinates></Point>
</Placemark>
<Placemark>
<name><![CDATA[<div id="wp_name">終点</div><div id="wp_address">三重県多気郡大台町大杉</div>]]></name>
<description><![CDATA[<div id="wp_time_info">2014/06/15 16:50:40</div>]]></description>
<styleUrl>#EndIcon</styleUrl><Point><coordinates>136.181676666667,34.233195,292.6</coordinates></Point>
</Placemark>
</Folder>
</Document>
</kml>
KML ファイルに関しては前回や前々回で書いているので,ここでは特には書かないでおこう。

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

その9:今回の一連のものをまとめたものに続く。

0 件のコメント: