2015年9月17日木曜日

19 - pgRouting 10 - 10. OpenLayers 3 ベースのルート検索インターフェース(Workshop)

19-10 10. OpenLayers 3 ベースのルート検索インターフェース
19-10-1 10.1. OpenLayers 3 入門
この章には、OpenLayers 3 の概要が書かれています。

19-10-2 10.2. 最小限の地図の作成
私の場合は NetBeans で環境が整っているので、これで地図を作成します。
詳しい説明はホームページを参照してください。
1 NetBeans を起動します。









2 「新規ファイル」ボタンをクリック。

3 「新規ファイル」ダイアログで「カテゴリ」を「HTML5」ファイルタイプ」を「HTMLファイル」を選択して「次>」ボタンをクリック。






4 「new HTML ファイル」ダイアログで「ファイル名」を「19-10_ol3-1.html」と入力して「終了」ボタンをクリック。






「index.html」
<html>
 <head>
  <title>TODO supply a title</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 </head>
 <body>
  <div>TODO write content</div>
  <div><a href="./13-3_ol3-1.html">13-3_ol3-1.html</a></div>
  <div><a href="./14-7_ol3-1.html">14-7_ol3-1.html</a></div>
  <div><a href="./15-3_ol3-1.html">15-3_ol3-1.html</a></div>
  <div><a href="./16-3_ol3-1.html">16-3_ol3-1.html</a></div>
  <div><a href="./16-4_ol3-1.html">16-4_ol3-1.html</a></div>
  <div><a href="./19-10_ol3-1.html">19-10_ol3-1.html</a></div>
 </body>
</html>

「19-10_ol3-1.html」
<!DOCTYPE html>
<html>
 <head>
  <title>ol3 pgRouting client</title>
  <meta charset="utf-8">
  <!-- <link href="ol3/ol.css" rel="stylesheet"> 
  デフォルトの OpenLayers CSS ファイルを読み込み -->
  <link rel="stylesheet" href="js/libs/v3.7.0/css/ol.css" type="text/css">
  <!-- 地図の DOM 要素にサイズを割り当てるため、 CSS ルールを記述 -->
  <style>
  #map {
    width: 100%;
    height: 400px;
  }
  </style>
 </head>
 <body>
  <!--地図のために div 要素を追加 -->
  <div id="map"></div>
  <!-- <script src="ol3/ol.js"></script> 
  OpenLayers 3 のライブラリコードを読み込み -->
  <script src="js/libs/v3.7.0/build/ol.js"></script>
  <script type="text/javascript">
   var map = new ol.Map({
    target: 'map',
    layers: [
     new ol.layer.Tile({
     /** ol.layer.Tile 
      * For layer sources that provide pre-rendered, tiled 
      * images in grids that are organized by zoom levels for 
      * specific resolutions. 
      * リレンダリング(事前描画)を提供するレイヤソースのための、
      * 特定の解像度でのズームレベルによって編成されているグリッ
      * ドのタイルイメージ。(ol3 API)
      */
      source: new ol.source.OSM()
      /** ol.source.OSM 
       * Layer source for the OpenStreetMap tile server.
       * OpenStreetMap タイルサーバのレイヤソース。(ol3 API)
       */
     })
    ],
    view: new ol.View({
     center: [-13657275.569447909, 5699392.057118396],
     zoom: 10
    }),
    controls: ol.control.defaults({
    /** controls
     * Controls initially added to the map. 
     * If not specified, ol.control.defaults() is used.
     * 初期設定で、マップに追加されたコントロール。
     * 明示されていなければ、ol.control.defaults() が使用され
     * ます。(ol3 API)
     */
    /** ol.control.defaults()
     * デフォルトでは、マップに含まコントロールのセット。
     * 特に設定しない限り、これは、以下の各コントロールの
     * インスタンスを含むコレクションを返します。(API Doc より)
     * ol.control.Zoom, ol.control.Rotate,
     * ol.control.Attribution
     */
     attributionOptions: {
      collapsible: false // 折りたたみ
     }
    })
   });
  </script>
 </body>
</html>

19-10-3 10.3. WMS GET パラメータ
以下のコードを地図の作成の後に追加。(この後のコードも順次後ろに追加)GeoServer に送信される WMS GET パラメータを保持。
---
   var params = {
    LAYERS: 'pgrouting:pgrouting',
    FORMAT: 'image/png'
   };

  </script>
 </body>
</html>

19-10-4 10.4. “出発地” と “目的地” の選択
地図上でのクリックにより、ユーザが出発地と目的地を追加。
// The "start" and "destination" features.
// 「出発地」と「目的地」フィーチャ。
var startPoint = new ol.Feature();
/** ol.Feature 
 * A vector object for geographic features with a 
 * geometry and other attribute properties, similar to 
 * the features vector file formats like GeoJSON.
 * GeoJSONのようなフィーチャベクタファイルフォーマットと同様
 * の、ジオメトリおよびその他の属性プロパティを持つ地理的
 * フィーチャのベクタオブジェクト。(ol3 API)
 */
var destPoint = new ol.Feature();
// The vector layer used to display the "start" and 
// "destination" features.
// 「出発地」と「目的地」のフィーチャを表示するために使用される
// ベクタレイヤ。
var vectorLayer = new ol.layer.Vector({
/** ol.layer.Vector
 * Vector data that is rendered client-side.
 * クライアント側で描画されたベクタデータ。(ol3 API)
 */
 source: new ol.source.Vector({
 /** ol.source.Vector
  * Provides a source of features for vector layers.
  * ベクタレイヤのフィーチャのソースを用意します。(ol3 API)
  */
  features: [startPoint, destPoint]
 })
});
map.addLayer(vectorLayer);


上の部分コードは、 2 つのベクタフィーチャを作成。1 つは “出発地” 、もう 1 つは “目的地”。
これらのフィーチャは、空 - ジオメトリを含まない - 状態。
下の部分のコードは、さらにベクタレイヤを作成し、 “出発地” と “目的地” のフィーチャを追加。さらに、 map の addLayer メソッドにより、地図にベクタレイヤを追加。

以下のコードを追加:
// A transform function to convert coordinates from 
// EPSG:3857 to EPSG:4326.
// EPSG:3857 から EPSG:4326 へ座標を変換するための transform 
// 関数。
var transform = ol.proj.getTransform('EPSG:3857', 'EPSG:4326');
/** ol.proj.getTransform(source, destination)
 * Given the projection-like objects, searches for a
 * transformation function to convert a coordinates 
 * array from the source projection to the destination 
 * projection.
 * projection 系オブジェクトを与えられると、変換関数のための
 * 検索は、ソース投影から宛先の投影にの座標の配列に変換します。
 * (ol3 API)
 */
// Register a map click listener.
// マップのクリックリスナを登録。
map.on('click', function(event) {
/** on(type, listener, opt_this)
 * Listen for a certain type of event.
 * あるタイプのイベントをリッスンします。(ol3 API)
 */
 if (startPoint.getGeometry() == null) {
 /** getGeometry()
  * Get the feature's default geometry. A feature may 
  * have any number of named geometries. The "default" 
  * geometry (the one that is rendered by default) is 
  * set when calling ol.Feature#setGeometry.
  * フィーチャのデフォルトのジオメトリを取得します。フィーチャ
  * は、任意の数の指定の図形を有することができます。 「デフォル
  * ト」のジオメトリ(デフォルトでレンダリングされるもの)が 
  * ol.Feature#setGeometry を呼び出すときに設定されます。
  * (ol3 API)
  */
  // First click.
  startPoint.setGeometry(new ol.geom.Point(event.coordinate));
  /** setGeometry(geometry)
   * Set the default geometry for the feature. This will 
   * update the property with the name returned by 
   * ol.Feature#getGeometryName.
   * フィーチャのデフォルトのジオメトリを設定します。これは
   * ol.Feature#getGeometryName によって返された名前で
   * プロパティを更新します。(ol3 API)
   */
  /** ol.geom.Point 
   * Point geometry.
   * 点のジオメトリ。(ol3 API)
   */
 } else if (destPoint.getGeometry() == null) {
  // Second click.
  destPoint.setGeometry(new ol.geom.Point(event.coordinate));
  // Transform the coordinates from the map projection 
  // (EPSG:3857) to the server projection (EPSG:4326).
  // マップ投影(EPSG:3857)からサーバ投影(EPSG:4326)へ座標を
  // 変換。 
  var startCoord = transform(startPoint.getGeometry().getCoordinates());
  /** transform(source, destination)
   * Transform each coordinate of the geometry from 
   * one coordinate reference system to another. The 
   * geometry is modified in place. For example, a 
   * line will be transformed to a line and a circle 
   * to a circle. If you do not want the geometry 
   * modified in place, first clone() it and then use 
   * this function on the clone.
   * ジオメトリの各座標をある座標参照系から別のものへ変換し
   * ます。ジオメトリは、所定の位置に修正されます。例えば、
   * ラインはライン、円は円に変換されます。ジオメトリを所定
   * の位置に修正したくない場合は、最初にそれを clone() し、
   * それからこの関数をクローンで使用します。(ol3 API)
   */
  /** getCoordinates()
   * Return the coordinate of the point.
   * 点の座標を返します。(ol3 API)
   */
  var destCoord = transform(destPoint.getGeometry().getCoordinates());
  var viewparams = [
   'x1:' + startCoord[0], 'y1:' + startCoord[1],
   'x2:' + destCoord[0], 'y2:' + destCoord[1]
  ];
  params.viewparams = viewparams.join(';');
  /** Array.join
   * 配列の全ての要素を繋いで文字列にします。
   * (MDN [https://developer.mozilla.org/ja/docs/Web/
   * JavaScript/Reference/Global_Objects/Array/join])
   */
  result = new ol.layer.Image({
  /** ol.layer.Image
   * Server-rendered images that are available for arbitrary 
   * extents and resolutions. 
    * 任意の範囲と解像度で利用可能な server-rendered イメージ。
   * (ol3 API)
   */
   source: new ol.source.ImageWMS({
   /** ol.source.ImageWMS
    * Source for WMS servers providing single, untiled 
    * images.
    * 単一、アンタイル(タイル状でない)イメージを提供する WMS 
    * のためのソース。(ol3 API)
    */
    url: 'http://localhost:8080/geoserver/pgrouting/wms',
    params: params
   })
  });
  map.addLayer(result);
 }
});


上記のコードは、地図の click イベントのためのリスナー関数を登録。OpenLayers 3 は地図上でのクリックイベントの検知の度に、この関数を呼び出す。

リスナー関数に渡されるイベントオブジェクトは、 クリックの地理的な位置を表す coordinate プロパティを含む。coordinate は “出発地” と “目的地” フィーチャの ポイント ジオメトリを作成するのに使用。

一度、出発地と目的地のポイントが(2度のクリックにより)確定すると、2つの座標値のペアは、地図の投影法(EPSG:3857)からサーバの投影法(EPSG:4326)に transform 関数を使用して変換。

viewparams プロパティは WMS GET パラメータオブジェクトに設定。このプロパティの値は特別な意味を持つ: GeoServer はこのレイヤのための SQL クエリを実行する前に、この値を代用。

例えば、もし:

SELECT * FROM ways WHERE maxspeed_forward BETWEEN %min% AND %max%

の場合、 viewparams は viewparams=min:20;max:120 となり、 PostGIS に送信される SQL クエリは:

SELECT * FROM ways WHERE maxspeed_forward BETWEEN 20 AND 120

となる。最後に、param オブジェクトが渡された、新しい OpenLayers WMS レイヤが作成されて、地図に追加。

19-10-5 10.5. 結果のクリア
以下のコードを HTML ページの地図の div の後に追加:
---
<div id="map"></div>
<!-- 追加 -->
<button id="clear">clear</button>
---

上記により、ルート検索ポイントをクリアし、新しいルート検索クエリを開始することを可能にするボタンが作成。

次に、以下のコードを JavaScript コードに追加:
var clearButton = document.getElementById('clear');
clearButton.addEventListener('click', function(event) {
/** EventTarget.addEventListener
 * addEventListener は、 1 つのイベントターゲットにイベント 
 * リスナーを1 つ登録します。イベントターゲットは、ドキュメント
 * 上の単一のノード、ドキュメント自身、ウィンドウ、あるいは、
 * XMLHttpRequest です。
 *(MDN[https://developer.mozilla.org/ja/docs/Web/API/
 * EventTarget.addEventListener])
 */
 // Reset the "start" and "destination" features.
 // “出発地” と “目的地” のフィーチャをリセット
 startPoint.setGeometry(null);
 destPoint.setGeometry(null);
 // Remove the result layer.
 // 結果レイヤを削除
 map.removeLayer(result);
});


このボタンがクリックされた際は、 addEventListener に渡されたこの関数が実行。この関数は “出発地” と “目的地” のフィーチャをリセットし、ルート検索結果レイヤを地図から削除。


ルート検索ができる範囲よりも広く表示されています。

0 件のコメント: