2014年9月8日月曜日

OpenLayers 3 を使ってみよう (その0:はじめに:地理院地図を表示)

追記の追記の追記)2017/2/1 現在,最新バージョンは 3.20.1 になっていた…。 このサイトに書いてある内容としては v3.16.0 から特に変更はないみたい。 個別には特に記載してないが,サンプルはすべて v3.20.1 にしておいた。

追記の追記)2016/5/28 現在,最新バージョンはいつのまにやら 3.16.0 になっていた…。 細かい変更点に関しては,v3.16.0 release pagecomplete list of releases を見てほしいが,私のサイトに関連して1箇所変更点があった。 詳しくは番外4:OpenLayers v3.7.0 から v3.16.0 の間に変わった点を見てほしい。

追記)2015/7/25 現在,最新バージョンは 3.7.0 になっている。 v3.7.0 release page によると, 「ol.FeatureOverlay の廃止」,「ol.View.fitExtent() と ol.View.fitGeometry() の ol.View.fit() への統一」などの変更が行われている。

ここに書いた内容は,一部を除いて,基本的に 3.7.0 の時点のものである。(2015/8 に v3.0.0 用から v3.7.0 用に記述を変更した)
 前回の投稿まで「GNSS/GPS 経路の表示に OpenLayers 2 を使う」と題して,OpenLayers 2 を使って,地図に GNSS/GPS の経路データを表示するやり方について述べた。その時の OpenLayers のバージョンは 2.13.1 だった。 しかし,最近 OpenLayers のサイトに行くと,バージョン 3.7.0 が最新版として表示されていた。 そこで,さっそく OpenLayers 3 を使って地図を表示させるのに挑戦してみた。 その事について数回に分けて書こう。

 まず OpenLayers 3 関連のリンクを書こう。
  ・OpenLayers:メインのサイト (2014/9/8 現在は OpenLayers 3 が最新版になってる)
  ・User Documents:現状での最新版の OpenLayers の使い方の文章へのリンク
  ・API Documents:変数に関する説明
  ・Development examples:現状での最新版の OpenLayers の使用例
  ・complete list of releases:v3 全バージョンの更新情報
これらは当然ながら英語である。

 数回になっているので,目次も書いておこう。
  ・その0:はじめに(このページ)
  ・その1:マウスクリックのイベント処理:マウスクリックした座標を読取る
  ・その2:地図の不透明度を変える
  ・その3:地図上に折線を引く:vector layer と MultiLineString で折れ線描画
  ・その4:マウスクリックで地図上に経路を描画する:マウスクリックで折れ線作成
  ・その5:テキストデータから折線データ読込み
  ・その6:ol.interaction.Draw を使った例:ol.layer.Vector を使ったもの
  ・その7:ol.interaction.Modify を使った修正可能バージョン
  ・その8:ol.interaction.Draw 修正可能バージョンで表示領域の大きさの調整を行う
  ・その9:KML データで経路を描画する
  ・その10:KML でマーカーを描画して吹出しをつける
  ・その11:KML から描画した経路とマーカーの表示/非表示の個別切替
  ・その12:KML+マーカーで zoom の自動調整
  ・その13:センターマークと凡例の表示・KML による経路+マーカーの場合
  ・その14:GPX による経路の表示・各点の通過時刻を知る (これ以降 v3.16.0 で記述)
  ・その15:OpenLayers v3 で Google Map を表示する
  ・その16:OpenLayers v3 で Google Map と地理院地図を重ねる
  ・その17:OpenLayers v3 で 経路の距離を測る
  ・その18:Marker アニメーション
  ・その19:その9からその18までのまとめ
  ・その20:Open Street Map を表示させる
  ・その21:Highcharts でルートの標高グラフを表示

  ・番外:OpenLayers 3 について私なりにまとめてみた:いまいちまとめになってないかも…
  ・番外2:KML ファイルのフォーマットについて
  ・番外3:OpenLayers ver. 3.0.0 と 3.7.0 の違いについて
  ・番外4:OpenLayers v3.7.0 から v3.16.0 の間に変わった点

  ・関連1:OpenLayers のバージョンが 4.0.1 になっていた

 まずは OpenLayers 3 についておおまかに述べておこう。 (番外:OpenLayers 3 について私なりにまとめてみたに別の視点でまとめた)
OpenLayers は JavaScript を使って web ページ上に地図を表示するものである。 そのために web ページが必要となる。 その web ページ上で JavaScript を使って地図を表示させたり,マウスクリックで何かの作業を行わせたりする,のが OpenLayers である。

 以下に OpenLayers を使った地図を表示するための基本形を書いておこう。
<!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 3 Example: Cyber Japan Map</title>
<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>
<script src="ol3ex1.js" type="text/javascript"></script>
</head>
<body onload="init_map()">
<div id="map_canvas">
</body>
</html>
 これは web ページのソース形式で書かれている。 1行目や,それに続く「<html>〜</html>」,「<head>〜</head>」は web ページを記述している。 ここでは web ページの基本についてはわかっているものとして話を進めたい。 わからない人はまずは html の基本についてどこかで勉強して欲しい。

 <meta .... > の形式の行は,当該の web ページの全体設定のようなものなので,ここではおまじないと考えておいて欲しい。 一点注意するところは,「content="text/html; charset=UTF-8"」と書かれている部分である。 これは,このファイルを UTF-8 という文字コードで記述してある,という意味なので,UTF-8 で書いておかないと,web ページが文字化けしてしまう。

<title> の行は言うまでもなく web ページのタイトルである。

<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>

の行は,OpenLayers 3 を使うために必要な基本となる css ファイルと JavaScript を読み込んでいる。 ここでは両方とも OpenLayers のサイトから直接読み込んでいる。 ちなみに下記にあるサンプルでは,ローカルのサーバーにダウンロードしたものを読み込んでいる。

<style type="text/css"> に続く行は,ここで使うスタイルファイルである。 これは地理院地図のサンプルコードからもらってきたものなので,上記の ol.css とダブっている部分もあるかもしれない…。
 また,最後の4行,.ol-zoom や .ol-zoom-out,.ol-zoomslider,.ol-touch に関する行は, 後で述べる zoomSlider(スライドさせてズームを変更するスイッチ)を,拡大(+)縮小(-)の間に入れるためのスタイルである。 この4行を消すと,zoomSlider は「+」「-」ボタンの下に表示される。

青字の部分は後回しにして,オレンジ色の部分は web ページの中身である。 実は中身はほとんど何もない。 <body> は,読み込まれたら JavaScript の「init_map()」という関数を実行する。 後は「id="map_canvas"」を持つ「カラの <div>」があるのみである。 この「カラの <div>」に青い字の JavaScript 部分で地図の画像を表示させていることになる。

 最後に青字の部分について述べよう。 <script src="ol3ex1.js"></script>の行は,この web ページで地図を表示する一番肝心な JavaScript を読み込んでいる。 以下にその JavaScript を書こう。説明はこの例の後に書いてある。
// ===================================================================
var center_lon = 135.100303888; // 中心の経度(須磨浦公園)
var center_lat = 34.637674639; // 中心の緯度(須磨浦公園)

var initZoom = 10; // ズームの初期値
var MinZoom  = 6;   // ズームの最小値(最も広い範囲)
var MaxZoom  = 17;  // ズームの最大値(最も狭い範囲)
// *******************************************************************
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()
    });

// 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()
// *******************************************************************

 ここで OpenLayers 3 のメインとなる JavaScript について述べよう。
OpenLayers 3 では,青字で書かれた map という変数(インスタンス)を用意する。 これが地図などの Layer(層)を表示するための必須変数である。 この map の中に地図に関する要素を記述して地図を描画している。 以下に map に含まれるオプションについて述べよう。

 (1) target : 地図を web のどこに表示するか。web page を記述する際の DOM と呼ばれるもので指定する。
     <div id="map_canvas"> のように id を使って指定すると混同によるミスが少なくなる。
     document.getElementById('map_canvas') 様に書かずに target に id の名前のみ(例: map_campus)を直接書いてもいいみたい。

 (2) layers : 表示したい層(layer)を設定する。ここでは Tile クラスの layer(名前が cyberJ)を設定している。
     地理院地図を表示する時は,上記の例の赤字で書いた「var cyberJ = ....」と同じにすればよい(おまじないみたいなものと考える)。
     [ と ] で囲んであるのは,複数の layer を設定するのが前提となっているためである。
     (複数を設定する時には,[A, B] のようにコンマで区切って複数並べればよい)
     定義した後で map.addLayer(xxx); のように追加することもできる。

 (3) view : 見え方を設定している。OpenLayers 2にはなかったものである。
     この view に対して,投影法(projection)を指定したり,ズームや中心座標を設定している。
     逆に中心座標を得るのも,この view からになる。
     上記の例「var view = ....」では投影法として "EPSG:3857" と呼ばれる球面メルカトル図法を指定している。
     ズームの最大値(どれだけ詳細な地図を表示するか)と最小値(どこまで広い範囲を表示するか)も設定している。
     これらの設定は必要なら後から追加や変更が可能となっている。
     上記の例では「view.setZoom(initZoom);」としてズームを設定し,
     「view.setCenter(ol.proj.transform([center_lon, center_lat], "EPSG:4326", "EPSG:3857"));」として中心を設定している。
     中心は,WGS84("EPSG:4326")と呼ばれる通常の経度,緯度による設定なので,それを "EPSG:3857" に変換してから設定している。

 (4) renderer : 地図の描画方法を設定しているみたいなのだが,いまいち理解できていない。

 (5) controls : ズームのスイッチや,スケール表示などの制御スイッチを設定する。
     ここでは defaults を設定している。
     これは,Zoom,Rotate,Attribution(地図データの帰属)のスイッチを含んでいる。
     Rotate はわかりにくいが,「Shift + Alt + マウスドラッグで回転させることが可能」である。
     Zoom は「Shift + マウスドラッグ」で,指定した範囲が入るように拡大してくれる。
     control は後で map.addControl(yyy); として追加可能である。
     実際,上記の例では「map.addControl(new ol.control.ZoomSlider());」として control を map に追加している。

 (6) interactions : interaction は,マウスドラッグなどに対する動作を設定している。
     もし「マウスドラッグして地図を動かす」という interaction をオフにしておくと,ドラッグで地図上の移動ができなくなる。
     ここでは defaults を指定している。defaults の内容は「defaults」のリンクを見て欲しい。
     interaction も後で追加や変更が可能である。

 他には「overlayers」と「logo」がある。 overlayers は,基本的に固定されている layer の上に描画する層(over layer ?)であり,後でも追加可能である。 logo は URL で指定した地図のロゴを表示できるみたいである(使ってないのでわからない…) 上記のみならず,Experimental(実験的)なものを含めると,さらに「pixelRatio」,「keyboardEventTarget」,「loadTilesWhileAnimating」,「loadTilesWhileInteracting」があるらしい。

 最後に一点だけ注意を述べておこう。 ここでは JavaScript 全体が「init_map()」という関数の中に入れてある。 これは,この JavaScript が web ページの header 部で読み込まれるため,web ページの body 部を読み込んだ際に「init_map()関数」を使って JavaScript を実行させないといけないことに由来する。 OpenLayers 3 のサンプルでは,「init_map()」の部分を関数の中に入れない形で JavaScript が書かれている。 それは,JavaScript を web ページの body 部で読み込ませているので,読み込まれると同時に JavaScript が実行されるためである。 web も HTML5 になっているので,書き方の流儀が変わったのかなぁ? とりあえずここでは以前から行われている方法に従って書いている。

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

その1:マウスクリックのイベント処理に続く

0 件のコメント: