ラベル pgRouting の投稿を表示しています。 すべての投稿を表示
ラベル pgRouting の投稿を表示しています。 すべての投稿を表示

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 に渡されたこの関数が実行。この関数は “出発地” と “目的地” のフィーチャをリセットし、ルート検索結果レイヤを地図から削除。


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

19 - pgRouting 9 - 9. GeoServer による WMS サーバ(Workshop)

19-9 9. GeoServer による WMS サーバ
私の場合は、GeoServer の準備ができているのでホームページの手順で進めていきます。

19-9-1 9.1. 管理者ページへの接続
1 ブラウザのアドレスバーに http://localhost:8080/geoserver と入力して Enter キーを押し、ログインします。

19-9-2 9.2. レイヤの作成
1 左側の欄の「データ」の「ワークスペース」をクリックします。






2 「新規ワークスペース追加」をクリックします。






3 「新しいワークスペース」で次のように入力します。

Name: pgrouting
ネームスペースURI: http://pgrouting.org
19092a-deb8.png

4 「送信」ボタンをクリックします。




Store の追加
1 左側の欄の「データ」の「ストア」をクリックします。








2 「ストア新規追加」をクリックします。






3 「PostGIS」をクリックします。












4 ワークスペース の初期設定は変えずに、「ストア基本情報」の データソース名 と 解説 を入力します。

ワークスペース: pgrouting (変更なし)
データソース名: pgrouting
解説: pgrouting (説明、任意です)
有効化: チェックする(変更なし)






5 PostGIS データベースの「パラメーターの接続」を指定します。
host: localhost (変更なし)
port: 5432 (変更なし)
database: pgrouting-workshop
schema: public (変更なし)
user: user (ways テーブルに接続できるユーザ)
password: ●●●●●●● (user がテーブルに接続するときのパスワード)

設定値の残りの箇所については、そのまま

6 「保存」ボタンをクリックします。
追加されたレイヤ一覧が表示されます。






7 「SQL ビューを新規作成...」リンクをクリックします。



8 「SQL ビューの新規作成」の「名称を表示」と「SQL ステートメント」を次のように入力します。

名称を表示: pgrouting
SQL ステートメント:
SELECT ST_MakeLine(route.geom) FROM (
 SELECT geom FROM pgr_fromAtoB('ways', %x1%, %y1%, %x2%, %y2%
) ORDER BY seq) AS route


9 「SQLからパラメータを推測」をクリックすると、上記の SQL から抽出されたパラメータが表示されます。


各パラメータを以下のように設定します:

デフォルト値: 0
正規表現を検証: ^-?[\d.]+$


10 「属性」の「再読み込み」リンクをクリックすると、一つの属性が現れます (st_makeline と記載されています)
各パラメータを以下のように設定します:

種類: LineString
SRID: 4326


11 「保存」ボタンをクリックします。
12 「レイヤ編集」のページに遷移するので、次のように入力します。

「座標参照系(CRS)」を入力します。
元ファイルSRS: EPSG:4326(変更なし)
指定中のSRS: EPSG:3857 (「検索中」ボタンをクリックして「3857」を検索して表示された「3857 WGS 84 / Pseudo-Mercator」をクリック)

SRSのハンドリング: 投影法をネイティブから変換




「範囲矩形」を入力します。
ネイティブの範囲矩形: (「データを元に算出」をクリック -以下の値が入力されました)
最小X: -111,319.49079327357
最小Y: -111,325.14286638597
最大X: 0
最大Y: -0.0000000007081155
緯度経度範囲矩形: (「ネイティブの範囲を元に算出」をクリック -以下の値が入力されました)
最小X: -1
最小Y: -1.0000000000000142
最大X: 0
最大Y: 0


「保存」ボタンをクリックします。

19 - pgRouting 8 - 8. pl/pgsql のラッパーを記述する(Workshop)

19-8 8. pl/pgsql のラッパーを記述する
19-8-1 8.1. ネットワークのジオメトリと共にルートを返す
経路のラインのジオメトリと共にルートを返すにはラッパー関数を記述する必要はありません。

ダイクストラ法による最短経路探索

user@deb8-vmw:~$ su - postgres
パスワード:
postgres@deb8-vmw:~$ psql pgrouting-workshop
psql (9.4.3)
"help" でヘルプを表示します.

pgrouting-workshop=# SELECT seq, id1 AS node, id2 AS edge, cost FROM pgr_dijkstra('
pgrouting-workshop'# SELECT gid AS id,
pgrouting-workshop'# source::integer,
pgrouting-workshop'# target::integer,
pgrouting-workshop'# length::double precision AS cost
pgrouting-workshop'# FROM ways',
pgrouting-workshop(# 30, 60, false, false);
 seq | node  |  edge  |        cost         
-----+-------+--------+---------------------
   0 |    30 |  53981 | 0.00179787381215754
   1 |    29 |  54683 | 0.00414306299059075
   2 |  2929 |  54682 | 0.00415625981313575
---
  84 | 52876 | 108239 |  0.0663451932790427
  85 | 51208 |  78537 |  0.0296600224657156
  86 |    60 |     -1 |                   0
(87 行)

(END):q


ジオメトリを含んだ結果

pgrouting-workshop=# SELECT seq, id1 AS node, id2 AS edge, cost, b.the_geom FROM pgr_dijkstra('
SELECT gid AS id,
source::integer,
target::integer,
length::double precision AS cost
FROM ways',
30, 60, false, false) a LEFT JOIN ways b ON (aid2 = b,gid);
 seq | node  |  edge  |        cost         |           the_geom
-----+-------+--------+---------------------+------------------------
   0 |    30 |  53981 | 0.00179787381215754 | 0102000020E6100000020000002D7F19E7
CAAD5EC0B34DE08C50B74640748A9F10CBAD5EC0D10A671250B74640
---
  86 |    60 |     -1 |                   0 | 
(87 行)

(END):q


19-8-2 8.2. 結果を可視化する
ターミナルのスクリーン上で行や列、数字を眺める代わりに、地図上にルートを可視化します。

CREATE TABLE <table name> AS SELECT ... を使って 結果をテーブルに保存して その結果を QGIS で見る方法(QGIS を Synaptic マネージャでインストールしておきます。)

pgrouting-workshop=# CREATE TABLE route AS SELECT seq, id1 AS node, id2 AS edge, cost, b.the_geom FROM pgr_dijkstra('
SELECT gid AS id,
source::integer,
target::integer,
length::double precision AS cost
FROM ways',
30, 60, false, false) a LEFT JOIN ways b ON (aid2 = b,gid);

QGIS で表示できませんでした。(次のように表示されました。)











この章(19-8 8. pl/pgsql のラッパーを記述する)が終わったら、pgrouting-workshop データベースの所有者を user にして、操作します。

19-8-3 8.3. 入力パラメータとジオメトリの出力を単純化
最短経路探索の Dijkstra 関数を呼ぶときに単純化 (そして標準の値をセット)した関数(ダイクストラ法のラッパー)です。
(内容はホームページを参照してください。)

19-8-4 8.4. 緯度/経度 のポイントの間のルートで順番にならんだジオメトリと方位を返す
入力パラメータとして 緯度/経度 のポイントを扱い、 QGIS または Mapserver や Geoserver のような WMS サービスで表示ができるルートを返す関数です。
(内容はホームページを参照してください。)

データベースにこのファンクションをインストールします:

psql -U user -d pgrouting-workshop -f ~/Desktop/pgrouting-workshop/data/fromAtoB.sql

user@deb8-vmw:~$ su - postgres
パスワード:
postgres@deb8-vmw:~$ cd /home/user/public_html/pgrouting-workshop/data/
postgres@deb8-vmw:/home/user/public_html/pgrouting-workshop/data$ ls
SHP          sampledata.osm         sampledata_routing.sql
fromAtoB.sql  sampledata_notopo.sql
postgres@deb8-vmw:/home/user/public_html/pgrouting-workshop/data$ psql -d pgrouting-workshop -f fromAtoB.sql
CREATE FUNCTION

19-8-5 QGIS で route テーブルを表示
もう一度、QGIS で route テーブルを表示してみます。
「19-8-2 8.2. 結果を可視化する」で
pgrouting-workshop データベースの所有者を user にして操作してみます。

user@deb8-vmw:~$ su - postgres
パスワード:
postgres@deb8-vmw:~$ psql pgrouting-workshop
psql (9.4.3)
"help" でヘルプを表示します.

pgrouting-workshop=# \d
                     リレーションの一覧
 スキーマ |           名前           |     型     |  所有者  
----------+--------------------------+------------+----------
 public   | classes                  | テーブル   | postgres
 public   | geography_columns        | ビュー     | postgres
 public   | geometry_columns         | ビュー     | postgres
 public   | nodes                    | テーブル   | postgres
 public   | raster_columns           | ビュー     | postgres
 public   | raster_overviews         | ビュー     | postgres
 public   | relation_ways            | テーブル   | postgres
 public   | relations                | テーブル   | postgres
 public   | route                    | テーブル   | postgres
 public   | spatial_ref_sys          | テーブル   | postgres
 public   | types                    | テーブル   | postgres
 public   | way_tag                  | テーブル   | postgres
 public   | ways                     | テーブル   | postgres
 public   | ways_vertices_pgr        | テーブル   | postgres
 public   | ways_vertices_pgr_id_seq | シーケンス | postgres
(15 行)

pgrouting-workshop=# ALTER TABLE classes OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER VIEW geography_columns OWNER TO user;
ALTER VIEW
pgrouting-workshop=# ALTER VIEW geometry_columns OWNER TO user;
ALTER VIEW
pgrouting-workshop=# ALTER TABLE nodes OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER VIEW raster_columns OWNER TO user;
ALTER VIEW
pgrouting-workshop=# ALTER VIEW raster_overviews OWNER TO user;
ALTER VIEW
pgrouting-workshop=# ALTER TABLE relation_ways OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE relations OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE route OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE spatial_ref_sys OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE types OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE way_tag OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE ways OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE ways_vertices_pgr OWNER TO user;
ALTER TABLE
pgrouting-workshop=# ALTER SEQUENCE ways_vertices_pgr_id_seq OWNER TO user;
ALTER SEQUENCE

pgrouting-workshop=# \d
                    リレーションの一覧
 スキーマ |           名前           |     型     | 所有者 
----------+--------------------------+------------+--------
 public   | classes                  | テーブル   | user
 public   | geography_columns        | ビュー     | user
 public   | geometry_columns         | ビュー     | user
 public   | nodes                    | テーブル   | user
 public   | raster_columns           | ビュー     | user
 public   | raster_overviews         | ビュー     | user
 public   | relation_ways            | テーブル   | user
 public   | relations                | テーブル   | user
 public   | route                    | テーブル   | user
 public   | spatial_ref_sys          | テーブル   | user
 public   | types                    | テーブル   | user
 public   | way_tag                  | テーブル   | user
 public   | ways                     | テーブル   | user
 public   | ways_vertices_pgr        | テーブル   | user
 public   | ways_vertices_pgr_id_seq | シーケンス | user
(15 行)

(stdin):q


1 QGIS を起動します。


2 「ブラウザ」の「PostGIS」を右クリックして、「新しい接続」ます。










3 「新規 PostGIS 接続を作成」で次のように入力します。
名称: pgrouting(任意)
サービス: (空 そのまま)
ホスト: localhost
ポート: 5432(そのまま)
データベース: pgrouting-workshop
SSL モード: 禁止(そのまま)
ユーザ名: user(postgres の user)
パスワード: (postgres の user のパスワード)



4 「接続テスト」ボタンをクリックします。成功すれば次のように表示されるので、「OK」ボタンをクリックします。



「新規 PostGIS 接続を作成」ダイアログの「OK」ボタンをクリックします。

5 「ブラウザ」ペインの「PostGIS -> pgrouting -> public -> route」をクリックして展開し、「route」をダブルクリックします。






● PostGIS レイヤを追加して QGIS の SQL where clause を使う方法:
1 「レイヤ」ペインの「route」を右クリックし、「削除」をクリックします。


2 「レイヤとグループの削除」ダイアログで「OK」ボタンをクリックします。





3 「ブラウザ」の「ways」をダブルクリックし、表示します。







4 「レイヤ」ペインの「ways」を右クリックし、「プロパティ」をクリックします。











5 「レイヤプロパティ - ways|一般情報」ダイアログで、一番下にある「クエリビルダ」ボタンをクリックします。








6 「クエリビルダ」ダイアログの「プロバイダ特有フィルタ式」に次のクエリを入力して「テスト」ボタンをクリックします。

"gid" IN ( SELECT id2 AS gid FROM pgr_dijkstra('
 SELECT gid AS id,
  source::integer,
  target::integer,
  length::double precision AS cost
 FROM ways',
30, 60, false, false) a LEFT JOIN ways b ON (a.id2 = b.gid)
)



7 「クエリ結果」が表示されたら「OK」ボタンをクリックします。






「クエリビルダ」ダイアログの「OK」ボタンをクリックします。
「レイヤプロパティ - ways|一般情報」ダイアログの「OK」ボタンをクリックします。




8 「ブラウザ」ペインの「ways」をダブルクリックし、表示します。背景レイヤにするため、「レイヤ」ペインの直前に追加した「ways」をドラッグして下に移動します。「route」が目立たないときは、この「ways」を右クリックし、「プロパティ」をクリックして「レイヤプロパティ - ways|スタイル」ダイアログで、「色」を変更してください。
1

19 - pgRouting 7 - 7. より高度なルート検索クエリ(Workshop)

19-7 7. より高度なルート検索クエリ
前章「19-6 6. osm2pgrouting インポートツール」でデータを準備していないので、「ノート:」にあるように、データベースダンプファイルを読み込みます。

user@deb8-vmw:~$ su - postgres
パスワード:
postgres@deb8-vmw:~$ dropdb pgrouting-workshop
postgres@deb8-vmw:~$ createdb pgrouting-workshop
postgres@deb8-vmw:~$ cd /home/user/public_html/pgrouting-workshop/data/
postgres@deb8-vmw:/home/user/public_html/pgrouting-workshop/data$ psql -d pgrouting-workshop -f sampledata_routing.sql
SET
SET
SET
SET
SET
SET
psql:sampledata_routing.sql:12: ERROR:  現在オープンしているデータベースを削除できません
psql:sampledata_routing.sql:17: ERROR:  ロケール名"en_US.UTF-8"は無効です
データベース "pgrouting-workshop" にユーザ"postgres"として接続しました。
SET
SET
SET
SET
SET
SET
psql:sampledata_routing.sql:33: ERROR:  スキーマ"public"はすでに存在します
COMMENT
CREATE EXTENSION
COMMENT
CREATE EXTENSION
COMMENT
CREATE EXTENSION
COMMENT
SET
SET
SET
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE SEQUENCE
ALTER SEQUENCE
ALTER TABLE
COPY 36
COPY 492902
COPY 53108
COPY 40
COPY 0
COPY 4
COPY 198192
COPY 92435
COPY 67076
 setval
--------
  67076
(1 行)

ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
REVOKE
REVOKE
GRANT
GRANT

19-7-1 7.1. 重み付けされたコスト
pgrouting-workshop データベースを確認します。

postgres@deb8-vmw:/home/user/public_html/pgrouting-workshop/data$ cd
postgres@deb8-vmw:~$ psql pgrouting-workshop
psql (9.4.3)
"help" でヘルプを表示します.

pgrouting-workshop=# \d
                     リレーションの一覧
 スキーマ |           名前           |     型     |  所有者  
----------+--------------------------+------------+----------
 public   | classes                  | テーブル   | postgres
 public   | geography_columns        | ビュー     | postgres
 public   | geometry_columns         | ビュー     | postgres
 public   | nodes                    | テーブル   | postgres
 public   | raster_columns           | ビュー     | postgres
 public   | raster_overviews         | ビュー     | postgres
 public   | relation_ways            | テーブル   | postgres
 public   | relations                | テーブル   | postgres
 public   | spatial_ref_sys          | テーブル   | postgres
 public   | types                    | テーブル   | postgres
 public   | way_tag                  | テーブル   | postgres
 public   | ways                     | テーブル   | postgres
 public   | ways_vertices_pgr        | テーブル   | postgres
 public   | ways_vertices_pgr_id_seq | シーケンス | postgres
(14 行)

(stdin):q


次の SQL を実行して types と classes の内容を確認します。

pgrouting-workshop=# SELECT * FROM types ORDER BY id;
 id |   name    
----+-----------
  1 | highway
  2 | cycleway
  3 | tracktype
  4 | junction
(4 行)


pgrouting-workshop=# SELECT * FROM classes ORDER BY id;
 id  | type_id |       name        | cost | priority | default_maxspeed 
-----+---------+-------------------+------+----------+------------------
 100 |       1 | road              |      |        1 |               50
 101 |       1 | motorway          |      |        1 |               50
 102 |       1 | motorway_link     |      |        1 |               50
 103 |       1 | motorway_junction |      |        1 |               50
 104 |       1 | trunk             |      |        1 |               50
 105 |       1 | trunk_link        |      |        1 |               50
 106 |       1 | primary           |      |        1 |               50
 107 |       1 | primary_link      |      |        1 |               50
 108 |       1 | secondary         |      |        1 |               50
 109 |       1 | tertiary          |      |        1 |               50
 110 |       1 | residential       |      |        1 |               50
 111 |       1 | living_street     |      |        1 |               50
 112 |       1 | service           |      |        1 |               50
 113 |       1 | track             |      |        1 |               50
 114 |       1 | pedestrian        |      |        1 |               50
 115 |       1 | services          |      |        1 |               50
 116 |       1 | bus_guideway      |      |        1 |               50
 117 |       1 | path              |      |        1 |               50
 118 |       1 | cycleway          |      |        1 |               50
 119 |       1 | footway           |      |        1 |               50
 120 |       1 | bridleway         |      |        1 |               50
 121 |       1 | byway             |      |        1 |               50
 122 |       1 | steps             |      |        1 |               50
 123 |       1 | unclassified      |      |        1 |               50
 124 |       1 | secondary_link    |      |        1 |               50
 125 |       1 | tertiary_link     |      |        1 |               50
 201 |       2 | lane              |      |        1 |               50
 202 |       2 | track             |      |        1 |               50
 203 |       2 | opposite_lane     |      |        1 |               50
 204 |       2 | opposite          |      |        1 |               50
 301 |       3 | grade1            |      |        1 |               50
 302 |       3 | grade2            |      |        1 |               50
 303 |       3 | grade3            |      |        1 |               50
 304 |       3 | grade4            |      |        1 |               50
 305 |       3 | grade5            |      |        1 |               50
 401 |       4 | roundabout        |      |        1 |               50
(36 行)

(END):q


classes テーブルの cost の値を任意に与えます。

pgrouting-workshop=# UPDATE classes SET cost=1 ;
UPDATE 36
pgrouting-workshop=# UPDATE classes SET cost=2.0 WHERE name IN ('pedestrian','steps','footway');
UPDATE 3
pgrouting-workshop=# UPDATE classes SET cost=1.5 WHERE name IN ('cicleway','living_street','path');
UPDATE 2
pgrouting-workshop=# UPDATE classes SET cost=0.8 WHERE name IN ('secondary','tertiary');
UPDATE 2
pgrouting-workshop=# UPDATE classes SET cost=0.6 WHERE name IN ('primary','primary_link');
UPDATE 2
pgrouting-workshop=# UPDATE classes SET cost=0.4 WHERE name IN ('trunk','trunk_link');
UPDATE 2
pgrouting-workshop=# UPDATE classes SET cost=0.3 WHERE name IN ('motorway','motorway_junction','motorway_link');
UPDATE 3

ways テーブルの class_id フィールドと最終的には types テーブルの id フィールドにインデックスを作成します。

pgrouting-workshop=# CREATE INDEX ways_class_idx ON ways (class_id);
CREATE INDEX
pgrouting-workshop=# CREATE INDEX classes_idx ON classes (id);
CREATE INDEX

19-7-2 7.2. 制限されたアクセス
この章には、任意の道路のアクセスを制限する方法が書かれています。

19 - pgRouting 6 - 6. osm2pgrouting インポートツール(Workshop)

19-6 6. osm2pgrouting インポートツール
osm2pgrouting インポートツールを使用しないので、この章はとばします。
「8. pl/pgsql のラッパーを記述する」で手順通りに操作して、結果を確認するには osm2pgrouting を使用してください。

19 - pgRouting 5 - 5. pgRouting のアルゴリズム(Workshop)

19-5 5. pgRouting のアルゴリズム
19-5-1 5.1. ダイクストラ法による最短経路探索
前提条件
reverse cost を使えるようにするには追加の cost 列を追加する必要があります。私達は reverse cost を length としてセットすることができます。

user@deb8-vmw:~$ su - postgres
パスワード:
postgres@deb8-vmw:~$ psql pgrouting-workshop
psql (9.4.3)
"help" でヘルプを表示します.

pgrouting-workshop=# ALTER TABLE ways ADD COLUMN reverse_cost double precision;
ALTER TABLE
pgrouting-workshop=# UPDATE ways SET reverse_cost = length;
UPDATE 92435

説明やパラメータについてはホームページを参照してください。

クエリの例

pgrouting-workshop=# SELECT seq, id1 AS node, id2 AS edge, cost FROM pgr_dijkstra('
pgrouting-workshop'# SELECT gid AS id,
pgrouting-workshop'# source::integer,
pgrouting-workshop'# target::integer,
pgrouting-workshop'# length::double precision AS cost
pgrouting-workshop'# FROM ways',
pgrouting-workshop(# 30, 60, false, false);
 seq | node  |  edge  |        cost         
-----+-------+--------+---------------------
   0 |    30 |  63270 |  0.0826068346706699
   1 | 34780 |  43876 |  0.0387878379553639
   2 | 34779 |  74414 |   0.116939114260876
---
 321 | 45425 |  64167 |  0.0191919170925815
 322 | 45389 |  64077 |  0.0212719045648489
 323 |    60 |     -1 |                   0
(324 行)

(END):q


結果がホームページと違っていました。

19-5-2 5.2. A* アルゴリズムによる最短経路探索
前提条件
A-Star はあなたのネットワークのテーブルに事前に latitude/longitude 列 (x1, y1 と x2, y2) を追加してそれらの値を計算しておく必要があります。

pgrouting-workshop=# ALTER TABLE ways ADD COLUMN x1 double precision;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE ways ADD COLUMN y1 double precision;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE ways ADD COLUMN x2 double precision;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE ways ADD COLUMN y2 double precision;
ALTER TABLE
pgrouting-workshop=# UPDATE ways SET x1 = ST_x(ST_PointN(the_geom, 1));
UPDATE 92435
pgrouting-workshop=# UPDATE ways SET y1 = ST_x(ST_PointN(the_geom, 1));
UPDATE 92435
pgrouting-workshop=# UPDATE ways SET x2 = ST_x(ST_PointN(the_geom, ST_NumPoints(the_geom)));
UPDATE 92435
pgrouting-workshop=# UPDATE ways SET y2 = ST_y(ST_PointN(the_geom, ST_NumPoints(the_geom)));
UPDATE 92435

説明やパラメータについてはホームページを参照してください。

クエリの例

pgrouting-workshop=# SELECT seq, id1 AS node, id2 AS edge, cost FROM pgr_astar('
SELECT gid AS id,
source::integer,
target::integer,
length::double precision AS cost,
x1, y1, x2, y2 FROM ways',
30, 60, false, false);
 seq | node  |  edge  |        cost         
-----+-------+--------+---------------------
   0 |    30 |  63270 |  0.0826068346706699
   1 | 34780 |  43876 |  0.0387878379553639
   2 | 34779 |  74414 |   0.116939114260876
---
 307 | 45408 |  64119 |  0.0215188911800576
 308 |    61 |  64165 |  0.0907426692530298
 309 |    60 |     -1 |                   0
(310 行)

(END):q


19-5-3 5.3. kDijkstra による複数の最短経路探索
説明やパラメータについてはホームページを参照してください。

pgr_kdijkstraCost のクエリの例

pgrouting-workshop=# SELECT seq, id1 AS source, id2 AS edge, cost FROM pgr_kdijkstraCost('  
SELECT gid AS id,
source::integer,
target::integer,
length::double precision AS cost
FROM ways',
10, array[60,70,80], false, false);
 seq | source | edge |       cost       
-----+--------+------+------------------
   0 |     10 |   60 | 12.7760976802851
   1 |     10 |   70 | 10.7254161085963
   2 |     10 |   80 | 1.35366721454691
(3 行)


pgr_kdijkstraPath のクエリの例

pgrouting-workshop=# SELECT seq, id1 AS path, id2 AS edge, cost FROM pgr_kdijkstraPath('
SELECT gid AS id,
source::integer,
target::integer,
length::double precision AS cost
FROM ways',
10, array[60,70,80], false, false);
 seq | path | edge  |        cost         
-----+------+-------+---------------------
   0 |   60 |    10 |  0.0130619186690278
   1 |   60 |  9274 |  0.0394297727975931
   2 |   60 | 56902 |  0.0247002816010054
---
 292 |   80 | 49455 |   0.223475992065702
 293 |   80 |    81 |  0.0570772918753206
 294 |   80 |    80 |                   0
(295 行)

(END):q

19 - pgRouting 4 - 4. ネットワーク・トポロジーを作成する(Workshop)

19-4-1 4.1. ネットワークデータを読み込む
ワークショップのサンプルデータを pgrouting-workshop データベースにインポートします。
はじめに、データベースを作成します。
名前が pgrouting-workshop でないと sampledata_notopo.sql がインポートできません。
また、所有者(オーナ)がスーパーユーザ出ないとエラーが発生します。ユーザにスーパーユーザの権限があれば OK です。
今回は postgres で操作します。
sampledata_notopo.sql をインポートすると postgis と pgrouting の拡張機能が追加されるようです。

user@deb8-vmw:~/ダウンロード$ cd
user@deb8-vmw:~$ su - postgres
パスワード:
postgres@deb8-vmw:~$ createdb pgrouting-workshop
postgres@deb8-vmw:~$ exit
user@deb8-vmw:~$ cd public_html/pgrouting-workshop/
user@deb8-vmw:~/public_html/pgrouting-workshop$ ls
data.tar.gz  docs  web
user@deb8-vmw:~/public_html/pgrouting-workshop$ tar -xvzf data.tar.gz
data/SHP/sampledata.prj
data/SHP/sampledata.qpj
data/SHP/sampledata.shp
data/sampledata_notopo.sql
data/sampledata.osm
data/SHP/
data/SHP/sampledata.dbf
data/fromAtoB.sql
data/sampledata_routing.sql
data/SHP/sampledata.shx
data/
data/SHP/sampledata.cpg
user@deb8-vmw:~/public_html/pgrouting-workshop$ su - postgres
パスワード:
postgres@deb8-vmw:~$ cd /home/user/public_html/pgrouting-workshop/data/
postgres@deb8-vmw:/home/user/public_html/pgrouting-workshop/data$ psql -d pgrouting-workshop -f sampledata_notopo.sql
SET
SET
SET
SET
SET
SET
psql:sampledata_notopo.sql:12: ERROR:  現在オープンしているデータベースを削除できません
psql:sampledata_notopo.sql:17: ERROR:  ロケール名"en_US.UTF-8"は無効です
データベース "pgrouting-workshop" にユーザ"postgres"として接続しました。
SET
SET
SET
SET
SET
SET
psql:sampledata_notopo.sql:33: ERROR:  スキーマ"public"はすでに存在します
COMMENT
CREATE EXTENSION
COMMENT
CREATE EXTENSION
COMMENT
CREATE EXTENSION
COMMENT
SET
SET
SET
CREATE TABLE
COPY 0
COPY 92435
CREATE INDEX
CREATE INDEX
REVOKE
REVOKE
GRANT
GRANT
postgres@deb8-vmw:/home/user/public_html/pgrouting-workshop/data$ cd

作成されたテーブルを見てみます。

postgres@deb8-vmw:~$ psql pgrouting-workshop
psql (9.4.3)
"help" でヘルプを表示します.

pgrouting-workshop=# \d
                 リレーションの一覧
 スキーマ |       名前        |    型    |  所有者  
----------+-------------------+----------+----------
 public   | geography_columns | ビュー   | postgres
 public   | geometry_columns  | ビュー   | postgres
 public   | raster_columns    | ビュー   | postgres
 public   | raster_overviews  | ビュー   | postgres
 public   | spatial_ref_sys   | テーブル | postgres
 public   | ways              | テーブル | postgres
(6 行)


道路ネットワークデータが含まれているテーブル ways の属性を見てみます。

pgrouting-workshop=# \d ways
             テーブル "public.ways"
    列    |            型             |  修飾語  
----------+---------------------------+----------
 gid      | integer                   | 
 class_id | integer                   | not null
 length   | double precision          | 
 name     | text                      | 
 osm_id   | bigint                    | 
 the_geom | geometry(LineString,4326) | 
インデックス:
    "ways_gid_idx" UNIQUE, btree (gid)
    "geom_idx" gist (the_geom)


19-4-2 4.2. トポロジーを計算する
データが正確なネットワーク・トポロジーを提供できるように、pgr_createTopology 関数を実行します。
最初に source と target の列を追加し、次に pgr_createTopology 関数を実行します。

pgrouting-workshop=# ALTER TABLE ways ADD COLUMN "source" integer;
ALTER TABLE
pgrouting-workshop=# ALTER TABLE ways ADD COLUMN "target" integer;
ALTER TABLE
pgrouting-workshop=# SELECT pgr_createTopology('ways', 0.00001, 'the_geom', 'gid');
NOTICE:  PROCESSING:
NOTICE:  pgr_createTopology('ways',1e-05,'the_geom','gid','source','target','true')
NOTICE:  Performing checks, pelase wait .....
NOTICE:  Creating Topology, Please wait...
NOTICE:  1000 edges processed
---
NOTICE:  92000 edges processed
NOTICE:  -------------> TOPOLOGY CREATED FOR  92435 edges
NOTICE:  Rows with NULL geometry or NULL id: 0
NOTICE:  Vertices table for table public.ways is: public.ways_vertices_pgr
NOTICE:  ----------------------------------------------
 pgr_createtopology
--------------------
 OK
(1 行)

19-4-3 4.3. インデックスを追加
ネットワークのテーブルが、source、target 列にインデックスを持つことを確認します。
次のコマンドを実行して、インデックスを追加します。私の場合は、次のように表示されました。

pgrouting-workshop=# CREATE INDEX ways_source_idx ON ways("source");
ERROR:  リレーション"ways_source_idx"はすでに存在します
pgrouting-workshop=# CREATE INDEX ways_target_idx ON ways("target");
ERROR:  リレーション"ways_target_idx"はすでに存在します

データベースは次のようになります。

pgrouting-workshop=# \d
                     リレーションの一覧
 スキーマ |           名前           |     型     |  所有者  
----------+--------------------------+------------+----------
 public   | geography_columns        | ビュー     | postgres
 public   | geometry_columns         | ビュー     | postgres
 public   | raster_columns           | ビュー     | postgres
 public   | raster_overviews         | ビュー     | postgres
 public   | spatial_ref_sys          | テーブル   | postgres
 public   | ways                     | テーブル   | postgres
 public   | ways_vertices_pgr        | テーブル   | postgres
 public   | ways_vertices_pgr_id_seq | シーケンス | postgres
(8 行)


テーブル ways の属性は、

pgrouting-workshop=# \d ways
             テーブル "public.ways"
    列    |            型             |  修飾語  
----------+---------------------------+----------
 gid      | integer                   | 
 class_id | integer                   | not null
 length   | double precision          | 
 name     | text                      | 
 osm_id   | bigint                    | 
 the_geom | geometry(LineString,4326) | 
 source   | integer                   | 
 target   | integer                   | 
インデックス:
    "ways_gid_idx" UNIQUE, btree (gid)
    "geom_idx" gist (the_geom)
    "ways_source_idx" btree (source)
    "ways_target_idx" btree (target)


詳細な説明は、ホームページを参照してください。

19 - pgRouting 3 - 3. インストール及び必要なもの(Workshop)

19-3 3. インストール及び必要なもの
ワークショップに必要なもの

linux オペレーションシステム
エディタ(Gedit)
Geoserver
インターネット接続

は、準備出来ています。

19-3-1 3.1. pgRouting
1 postgresql-9.4-pgrouting
Synaptic パッケージマネージャで

postgresql-9.4-pgrouting 2.0.0-3

をインストールします。

2 workshop package

OSGeo-Live Workshop installation
http://trac.osgeo.org/osgeo/wiki/Live_GIS_Workshop_Install

の「FOSS4G-EU (Como)」の「Software」の「Download workshop package」をクリックして、「pgrouting-workshop_2.0.6-ppa1_all.deb」をダウンロードします。

スーパーユーザで次のコマンドを実行してインストールします。

dpkg -i pgrouting-workshop_2.0.6-ppa1_all.deb

user@deb8-vmw:~$ cd ダウンロード
user@deb8-vmw:~/ダウンロード$ ls
---
pgrouting-workshop_2.0.6-ppa1_all.deb
---
user@deb8-vmw:~/ダウンロード$ su
パスワード:
root@deb8-vmw:/home/user/ダウンロード# dpkg -i pgrouting-workshop_2.0.6-ppa1_all.deb

19-3-2 3.2. ワークショップ
ワークショップのパッケージの確認をします。

root@deb8-vmw:/home/user/ダウンロード# ls /usr/share/pgrouting/workshop/
data.tar.gz  docs  web

ユーザのホームディレクトリにファイルをコピーして、ユーザの webserver のフォルダにシンボリックリンクを貼ります。

root@deb8-vmw:/home/user/ダウンロード# exit
exit
user@deb8-vmw:~/ダウンロード$ cd
user@deb8-vmw:~$ cp -R /usr/share/pgrouting/workshop/ pgrouting-workshop
user@deb8-vmw:~$ ln -s pgrouting-workshop public_html/pgrouting-workshop

Web のディレクトリ: http://localhost/~user/pgrouting-workshop/web/
オンラインマニュアル: http://localhost/~user/pgrouting-workshop/docs/html

ですが、表示できませんでした。

user@deb8-vmw:~$ ls public_html/pgrouting-workshop/
ls: public_html/pgrouting-workshop/ にアクセスできません: シンボリックリンクの階層が多すぎます

ということなので、pgrouting-workshop フォルダを public_html に移動しました。

user@deb8-vmw:~$ cd public_html/
user@deb8-vmw:~/public_html$ rm pgrouting-workshop
user@deb8-vmw:~/public_html$ mv ../pgrouting-workshop/ ./
user@deb8-vmw:~/public_html$ ls
---
pgrouting-workshop
---


19-3-3 3.3. データベースに pgRouting の機能を追加する
pgRouting の機能を拡張として簡単にインストールできます。(すでに 19-3-1 3.1 pgRouting でインストールしました。)
データベースを作成するには、次のようにコマンドを実行します。(今回は手順を確認するだけで、作成しなくても OK です。)

user@deb8-vmw:~$ su - postgres
パスワード:
postgres@deb8-vmw:~$ createdb routing
postgres@deb8-vmw:~$ psql -d routing -c "CREATE EXTENSION postgis;"
CREATE EXTENSION
postgres@deb8-vmw:~$ psql -d routing -c "CREATE EXTENSION pgrouting;"
CREATE EXTENSION


19-3-4 3.4. データ
osm2pgrouting を使用しませんが、「8. pl/pgsql のラッパーを記述する」で手順通りに操作して、結果を確認するには osm2pgrouting を使用してください。

19 - pgRouting 2 - 2. 使用するFOSS4Gツールについて(Workshop)

19-2 2. 使用するFOSS4Gツールについて
「2. 使用するFOSS4Gツールについて」には、このワークショップで使用する FOSS4G ツールについて記載されています。
「2.1. pgRouting」には、提供される機能について記載されています。
「2.2. OpenStreetMap」には、ワークショップで使用する地図 OpenStreetMap について説明があります。
「2.3. osm2pgrouting」osm2pgrouting は OpenStreetMap データを pgRouting データベースにインポートするのを容易にするコマンドラインツールですが、PostGIS にシャイプファイルのデータをインポートする方法(shp2pgsql)もできます。

Shapefiles-OpenStreetMap Wiki
http://wiki.openstreetmap.org/wiki/Shapefiles

に、シェイプファイルのデータの取得方法が記載されています。
「2.4. OpenLayers 3」には、簡単な OpenLayers 3 の説明があります。

19 - pgRouting 1 - 1. 序章(Workshop)

19-0 pgRouting について
pgRouting のホームページ

pgRouting Project - Open Source Librsry
http://pgrouting.org/

に、次のようにあります。


pgRouting Project

pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
pgRoutingは、地理空間ルーティング機能を提供するために PostGIS/ PostgreSQL の地理空間データベースを拡張します。

Advantages of the database routing approach are:
データベースルーティングアプローチの利点は以下のとおりです。

● Data and attributes can be modified by many clients, like QGIS and uDig through JDBC, ODBC, or directly using Pl/pgSQL. The clients can either be PCs or mobile devices.
データと属性は、JDBC、ODBC 経由で、または直接 PL/pgSQL を使用することで、 QGIS と uDig のような多くのクライアントによって変更されます。クライアントは、PC やモバイルデバイスのいずれかとすることができます。

● Data changes can be reflected instantaneously through the routing engine. There is no need for precalculation.
データの変更は、ルーティングエンジンを経由して瞬時に反映させることができます。事前計算を必要としません。

● The “cost” parameter can be dynamically calculated through SQL and its value can come from multiple fields or tables.
「コスト(cost)」パラメータは、SQLを経由して動的に計算することができ、その値は、複数のフィールドやテーブルから入手することができます。


ライセンスは、「pgRouting is Open Source」に次のようにあります。


pgRouting is available under the GPLv2 license and is supported by a growing community of individuals, businesses and organizations.
pgRouting は GPLv2 ライセンスの下で利用可能で、個人、企業や組織の成長するコミュニティによってサポートされています。


19-1 1. 序章
pgRouting ワークショップマニュアル - Workshop-FOSS4G routing with pgRouting
http://workshop.pgrouting.org/ja/index.html

に従ってワークショップを作業していきます。
英語版は次の場所にあります。

pgRouting Workshop Manual - Workshop-FOSS4G routing with pgRouting
http://workshop.pgrouting.org/

1. 序章
「1.序章」の「要約」にこのワークショップの進め方にについて記載されていますので、よく読んでおきました。

2011年4月27日水曜日

16 pgRouting in Debian6 10 - ルーティングをブラウザで表示6

9.5. What’s next ?

を説明していきます。
訳しながらみていきたいと思います。

*****
拡張の可能性:

* 始点/終点ポイントを取得するジオコーディングサービスの使用
* way ポイントのサポート
* 始点と終点ポイントのための素晴らしいアイコン
* ドライブ方向(ロードマップ):我々はすでにセグメントの長さを持っている
*****

9.6. Full source code

実際にルーティングを表示したマップのコードです。

routing_geoext_page.html.gz



長いルートの表示には時間がかかりました。
広域表示のときは、高速道路や幹線道路を経由するように cost の値を調整する必要があります。

16 pgRouting in Debian6 10 - ルーティングをブラウザで表示5

9.4. Trigger the web service call
ウェッブサービス呼び出しトリガー

で、コードを説明しています。
訳しながらみていきたいと思います。

*****
次のときにWebサービスを呼び出す必要があります:

* 2つのポイントが描かれている
* ポイントの一つが移動している
* ルーティング方式が変更されている

新しいフィーチャが追加されたときに、ベクトルレイヤは(featureadded と呼ばれる)イベントを発生します。すなわち、このイベントを待ち受け、pgrouting 関数(この関数はすぐに表示されます)を呼び出すことができます。:

draw_layer.events.on({
featureadded: function() {
pgrouting(store, draw_layer, method.getValue());
}
});

注意
イベントに関するいくつかの説明を続ける前に:OpenLayers のイベント(ExtJSや他のフレームワークの同じ apply)は、何かが起こったときに呼び出される関数を許可するシステムです。例えば、レイヤがマップに追加されるときや、マウスがフィーチャと重なるときです。複数の関数は、同じイベントに接続することができます。

ポイントの移動のとき発生するイベントがない、幸いに、点が移動したときに呼びだすための DragFeature コントロールに関数を与えることができます。:

drag_points.onComplete = function() {
pgrouting(store, draw_layer, method.getValue());
};

method combo のために、(ユーザが値を変更したときイベントが発生する)選択引数によって待ち受けオプションをコンストラクタに追加することができます:

var method = new Ext.form.ComboBox({
renderTo: "method",
triggerAction: "all",
editable: false,
forceSelection: true,
store: [
["SPD", "Shortest Path Dijkstra"],
["SPA", "Shortest Path A*"],
["SPS", "Shortest Path Shooting*"]
],
listeners: {
select: function() {
pgrouting(store, draw_layer, method.getValue());
}
});

pgrouting 関数を提供するとき:

// global projection objects (uses the proj4js lib)
var epsg_4326 = new OpenLayers.Projection("EPSG:4326"),
epsg_900913 = new OpenLayers.Projection("EPSG:900913");

function pgrouting(store, layer, method) {
if (layer.features.length == 2) {
// erase the previous route
store.removeAll();

// transform the two geometries from EPSG:900913 to EPSG:4326
var startpoint = layer.features[0].geometry.clone();
startpoint.transform(epsg_900913, epsg_4326);
var finalpoint = layer.features[1].geometry.clone();
finalpoint.transform(epsg_900913, epsg_4326);

// load to route
store.load({
params: {
startpoint: startpoint.x + " " + startpoint.y,
finalpoint: finalpoint.x + " " + finalpoint.y,
method: method
}
});
}
}

pgrouting 関数は、ストアの引数を介してWebサービスを呼び出します。

最初に、2つのポイントが引数で渡された場合、関数がチェックします。その次に、store.removeAll()はレイヤ(ストアとベクトルレイヤが結びついていることを思い出してください)​​から前の結果を消去するために呼び出されます。 2つの点の座標が次に OpenLayers.Projection インスタンスを使用して投影されます。

最後に、store.load()は pgrouting.php 引数を表す params で呼び出されます(それらがHTTP GET 呼び出しへ渡されます)。
*****
続く ...

16 pgRouting in Debian6 10 - ルーティングをブラウザで表示4

9.3. Call and receive data from web service
ウェッブサービスからデータを呼び出し受け取る

で、コードを説明しています。
訳しながらみていきたいと思います。

*****
ウェッブサービスからルートを取得する基本的なワークフローは、

1.点の座標を EPSG:900913 から EPSG:4326 へ変換する
(今回の東京都のマップの場合は、 EPSG:2456 から EPSG:4326 へ変換)
2.ウェッブサービスを正確な引数(メソッド名と2つの点の座標)で呼び出す
3.ウェッブサービスの応答を解析する: GeoJSON を OpenLayers.Feature.Vector へ変換する
4.すべての座標を EPSG:4326 から EPSG:900913 へ変換する
(今回の東京都のマップの場合は、 EPSG:4326 から EPSG:2456 へ変換)
5.この結果をベクトルレイヤへ追加する

最初の項目は、新しいものです。すなわち、地図は EPSG:900913(東京都のマップは EPSG:2456) 投影(OSM レイヤを使用するため)を使用して、Webサービスは EPSG:4326 座標を期待しています。そのため、データを送信する前に再投影する必要があります。これは大したことではありません。それには、Proj4js の JavaScript ライブラリを使用するだけです。

(2番目の項目は、次の章で説明されている Web サービスを呼び出します。)

pgrouting.php のルーティング Web サービスは、GeoJSON へ FeatureCollection オブジェクトを返します。FeatureCollection は、単にフィーチャの配列です。すなわち、各ルートセグメントに対して1つのフィーチャです。 OpenLayers と GeoExtは、この形式を処理するために必要なすべてのものを持っているので、これは非常に便利です。作業を効率的にするため、GeoExt.data.FeatureStore を使用します:

var store = new GeoExt.data.FeatureStore({
layer: route_layer,
fields: [
{name: "length"}
],
proxy: new GeoExt.data.ProtocolProxy({
protocol: new OpenLayers.Protocol.HTTP({
url: './php/pgrouting.php',
format: new OpenLayers.Format.GeoJSON({
internalProjection: epsg_900913,
externalProjection: epsg_4326
})
})
})
});

ストアは、単に情報を記憶するためのコンテナです:データを送り出し、取り出すことができます。

すべてのオプションを説明します:

layer:引数はベクトルレイヤです。すなわち、レイヤを指定することにより、FeatureStore は自動的にこのレイヤに受信されたデータを描画します。これは、上記のリストの最後の項目(ベクトルレイヤにこの結果を追加)に必要なものです。

fields:ジオメトリと一緒に返されるすべての属性を示します。すなわち、ここに設定することで pgrouting.php はセグメントの長さを返します。この情報は、このワークショップで使用されていないことに注意してください。

proxy:プロキシの項目はデータが取得される場所を指定します。すなわち、今回は HTTP サーバからの場合、になっています。プロキシ型は GeoExt.data.ProtocolProxy です。すなわち、このクラスは ExtJS の世界(ストア)と OpenLayers の世界(プロトコルオブジェクト)を接続します。

protocol:この OpenLayers コンポーネントは、URL(PHPスクリプト)にHTTP 要求を作成し、応答(フォーマットオプション)を解析することができます。 internalProjection と externalProjection オプションを追加することにより、形式によって座標の再投影が実行されます。

私たちは今、Webサービスによって返されたデータを処理するために必要なすべてのものを持っています。次の章では、サービスを呼び出すタイミングと方法を説明します:
*****
続く ...

16 pgRouting in Debian6 10 - ルーティングをブラウザで表示3

9.2. Select the start and final destination

で、コードを説明しています。
訳しながらみていきたいと思います。

*****
ユーザーが始点および終点宛を描画し移動できるようにします。これは、Googleマップや他のものと引けを取らない動作です。ユーザーが検索ボックス(アドレス検索)を介して、またはマップをクリックして、ポイントを選択します。システムはサーバーを検索し、地図上に経路を表示します。ユーザーは後で始点または終点ポイントを移動し、ルートを更新することができます。

このワークショップでは、地図を介した入力(ポイントやドラッグ&ドロップの描画)を実装しますが、地図製作や他のジオコーディングサービスのような Web サービスを使用することによって、検索ボックスの機能を実装することが可能です。

これを行うには、ポイントを描画するためのツール(OpenLayers.Control.DrawFeatures コントロールを使用します)とポイントを移動するためのツール(OpenLayers.Control.DragFeatures はこの作業に最適です)が必要になります。この名前は、これらのコントロールが OpenLayers から来ているを示しています。

これらの2つのコントロールは、ポイントを描画して操作する場所が必要になります。同様に、OpenLayers.Layer.Vector.Layers が必要になります。 OpenLayersでは、ベクトルレイヤは、フィーチャ(形状と属性)がプログラム的に描画することができる場所(対照的に、OSM レイヤはラスタレイヤです。)です。
(注釈:今回の東京都の地図では、OSM レイヤは WMS レイヤです。)

ベクトルレイヤが機能が低い(?)ので、Webサービスから返された経路を描画する2番目の方法を使用します。レイヤの初期化は:

// create the layer where the route will be drawn
var route_layer = new OpenLayers.Layer.Vector("route", {
styleMap: new OpenLayers.StyleMap(new OpenLayers.Style({
strokeColor: "#ff9933",
strokeWidth: 3
}))
});

"route" は、レイヤ名で、任意の文字列を使用することができます。 styleMap は、レイヤーに任意の線の色と幅(ピクセル単位)の少しの視覚スタイルを提供します。

2番目のレイヤの初期化は簡単で

// create the layer where the start and final points will be drawn 
// 始点と終点を描くレイヤの作成
var points_layer = new OpenLayers.Layer.Vector("points");

OpenLayers.Map object に2つのレイヤを追加:

// add the layers to the map
map.addLayers([points_layer, route_layer]);

ポイントを描画するコントロールを見てみましょう:このコンポーネントは特殊な動作をするので、OpenLayers.Control.DrawFeatures コントロールに基づいて新しいクラスを作成するのはより簡単です。この新しいコントロールは、(DrawPoints という名前)で分けられた JavaScript のファイル(web/DrawPoints.js)に保存されます:

DrawPoints = OpenLayers.Class(OpenLayers.Control.DrawFeature, {

// this control is active by default
autoActivate: true,

initialize: function(layer, options) {
// only point can be drawn
var handler = OpenLayers.Handler.Point;
OpenLayers.Control.DrawFeature.prototype.initialize.apply(
this, [layer, handler, options]
);
},

drawFeature: function(geometry) {
OpenLayers.Control.DrawFeature.prototype.drawFeature.apply(
this, arguments
);
if (this.layer.features.length == 1) {
// we just draw the startpoint
// note: if we want to apply a special style to the
// start point we should do this here
} else if (this.layer.features.length == 2) {
// we just draw the finalpoint
// note: if we want to apply a special style to the
// final point we should do this here

// we have all what we need; we can deactivate ourself.
this.deactivate();
}
}
});

初期化関数(クラスコンストラクタです)では、このコントロールがポイントを描くことができるように設定します(ハンドラ変数は OpenLayers.Handler.Point)。

特別な動作は drawFeature 関数で実装されています:始点と終点だけが必要なので、vector layer にあるフィーチャがいくつか数えることによって、2つのポイントが描かれたときコントロールは自動的に非アクティブになります。コントロールの非アクティブ化は、this.deactivate() です。

コントロールはつぎのように作成します:

// create the control to draw the points (see the DrawPoints.js file)
var draw_points = new DrawPoints(points_layer);

points_layer はより早く作成されるベクトルレイヤです。

DragFeature コントロールは:

// create the control to move the points
var drag_points = new OpenLayers.Control.DragFeature(points_layer, {
autoActivate: true
});

もう一度、points_layer はベクトルレイヤで、autoActivate: true は、OpenLayers にこのコントロールを自動的にアクティブ化したいことをつげます。

// add the controls to the map
map.addControls([draw_points, drag_points]);

マップにコントロールを追加します。
*****
続く ...