2014年7月13日日曜日

GNSS/GPS 経路の表示に OpenLayers 2 を使う (その5:KML ファイルで経路を表示)

これはGNSS/GPS 経路の表示に OpenLayers 2 を使う(その4:不透明度を変えて2つの地図を重ねて表示)からの続きである。
GNSS/GPS 経路の表示に OpenLayers 2 を使う(その0:はじめに)に目次がある。
ここでは OpenLayers 2.13.1 を使っている。
前回(その4:不透明度を変えて2つの地図を重ねて表示)では 2種類の地図を表示させ,一方の地図の不透明度を変更させて,見え具合をユーザーが変更できるようにした。

今回は,KML ファイルを読み込ませて,GNSS/GPS ロガーの経路データを任意の地図の上に表示させる。 ここでの話は 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: KML file</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 type="text/javascript">//<![CDATA[
var param = { div: 'map_canvas', lon: 136.181193333333, lat: 34.2329783333333, zoom: 15, url: 'work/map_data1.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;
// -------------------------------------------------------------------
// 初期化
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);

        // kml ファイルの読込み
        var kmlLayer = 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(kmlLayer);

        // 中心座標を設定
        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());
} // 初期化

// -------------------------------------------------------------------
</script>
</head>

<body onload="init_map()">
<div id="map_canvas"></div>

</body>
</html>

 基本的な構造はこれまでと同じである。 今回も今回に特徴的な部分を色付きにしてみた。 それぞれについて説明しよう。

 最初の赤字の部分で,読み込むべき KML ファイルの URL を相対 URL で与えている。
実際の KML ファイルの読み込みは,青字の部分で行っている。 実はこの部分は地理院地図のサンプルそのままなので,細かいパラメータに関してはよくわかっていない…。 しかし,これで簡単に経路を表示できる。

以下に KML ファイルの具体例を書こう。
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>   
<description>
  <![CDATA[<p>大杉谷20140615</p><p><a href="http://hippo.matsup.mydns.jp/motorcycle/">Powered by matsup</a></p>]]>
</description>
<Style id="Line_1">
  <LineStyle>
    <color>ffff0000</color>
    <width>3</width>
  </LineStyle>
</Style>
<Folder>
  <name>Tracks</name>
  <Placemark>
    <name>Track 1</name>
      <description><![CDATA[Original tracking filename : LOG00489.nma<br>From: 2014/06/15 07:22:32 (34.2331033333333,136.181595)<br>  To: 2014/06/15 16:50:40 (34.233195,136.181676666667)]]></description>
      <styleUrl>#Line_1</styleUrl>
      <LineString>
       <extrude>0</extrude>
        <tessellate>1</tessellate>
        <altitudeMode>clampToGround</altitudeMode>
        <coordinates>
         136.181595,34.2331033333333,320.7
          136.181633333333,34.233065,329.8
          136.181591666667,34.23311,310.7
          136.18165,34.23311,311.2
          136.181568333333,34.2330966666667,309.3
          136.181206666667,34.2327066666667,310.8
          136.180971666667,34.2327233333333,311.9
        </coordinates>
      </LineString>
  </Placemark>
</Folder>  
</Document>
</kml>  
KML ファイルは web のソースファイルと同じように,「<XX>」と「</XX>」で挟まれた XML の構造体で書かれている。 KML ファイル全体は「<kml>」と「</kml>」で挟まれている。 その中にさらに「<Document>〜</Document>」で挟まれたメインパートがある。 私が扱うものでは,「<kml>〜</kml>」の中の全部が「<Document>〜</Document>」となっている。

「<Document>〜</Document>」の中に「<description>〜</description>」, 「<Style>〜</Style>」,「<Folder>〜</Folder>」という要素が含まれている。 「<description>〜</description>」はこのファイル全体に関する記述であり,様々なことが記述できるように「<![CDATA[」と「]]>」で挟まれている。 「<Style>〜</Style>」の中にさらに「<LineStyle>〜</LineStyle>」が含まれている。 その中で経路を記載するラインの幅や色を定義している。 「<Folder>〜</Folder>」の中に「<Placemark>〜</Placemark>」があり,その中で具体的な経路が記述されている。 ラインのスタイルは「<styleUrl>〜</stleUrl>」で「Line_1」を使うと指定してある。 ここで,スタイルの指定は URL で行わないといけないため,「Line_1」の前に「#」がつけてある。 具体的な点は「<coordinates>〜</coordinates>」で挟まれ,1行に1点で経度,緯度,高度が記載されている。 高度に関しては,「<altitudeMode>clampToGround</altitudeMode>」としてあるので,意味がないかも…。

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

その6:KML ファイルで経路とマーカーを表示に続く

4 件のコメント:

高橋祥士 さんのコメント...
このコメントは投稿者によって削除されました。
Rider Matsup さんのコメント...

高橋様,

さすがにこれだけの情報だと原因を判断するのは困難ですが,
これまでの私の経験だと,

(1) kml ファイルは,外部から読める場所にないといけない。
  例えばパスワードで保護されたサイトにあると,経路は表示されません。

(2) OpenLayers のバージョンが新しい過ぎるとうまくいかない。
  ご覧のページは OpenLayers 2 用なので,新しい OpenLayers 3 以降では
  うまく動かない可能性があります。同じ OL3 の中でも OpenLayers 3.7 以降は
  kml ファイルの使い方が変わったので,うまく動かないことがあります。
  OpenLayers 3.7 の場合の kml ファイルを使った例は,
  http://matsup.blogspot.jp/2014/09/openlayers-3-kml_12.html にあるので,
  もしバージョン違いならこちらもご覧ください。

(3) 上記以外なら,JavaScript か kml ファイルの問題だと思います。
  サンプルの http://hippo.matsup.mydns.jp/OLayerMap/ex5_kml.html と,
  そのkml ファイル(http://hippo.matsup.mydns.jp/OLayerMap/work/map_data1.kml)
  を移植してみてください。もしうまくいけば,ご自身の kml ファイルを使うとか,
  逆に JavaScript の方を入れ替えるなどして,どこに原因があるのかを調べることが
  できると思います。

今のところ,この程度しか推定できませんが,問題が解決することを祈っています。

高橋祥士 さんのコメント...

Rider Matsup さん
早速のコメントありがとうございました。
手抜きで、サーバを立てずにローカルファイルで試験していたんですが、kml ファイルは url で指定しなければいけないんですね。
気がついてコメントを削除したんですが、遅かったようです。
お手数をお掛けしました。

Rider Matsup さんのコメント...

高橋様,
 ご指針で気づかれたのですね。問題が解決してよかったです。
kml ファイルがパスワードで保護した場所にあるなどで読めない,というのはよくありますが,知らないと気づきにくいと思います。他の方がこのコメントを見て少しでも役に立てば,と思います。
これからもよろしくお願いします。