ServBayでpgRoutingを利用した地理空間ルーティング解析
pgRouting
は、PostgreSQLおよびPostGISデータベース向けの強力な拡張モジュールであり、地理空間データのための多様なルーティングおよびネットワーク解析機能を提供します。pgRouting
を活用することで、道路ネットワーク上での最短経路探索、巡回セールスマン問題(TSP)の解決、サービスエリア分析などの複雑なクエリを簡単に実行できます。これらの機能は、地図アプリケーションの構築、物流計画、交通分析など幅広い場面で大いに役立ちます。
本記事では、ローカルWeb開発環境であるServBayにおいて、PostgreSQLデータベースでpgRouting
を手軽に有効化し、基本設定からルーティング解析までを詳しく紹介します。
概要
ServBayは、macOS上の開発者に向けて、便利なオールインワンのローカル開発環境を提供します。Webサーバ、データベース、各プログラミング言語などが事前に統合されています。ServBayにバンドルされているPostgreSQLパッケージには、すでにpgRouting
とPostGIS
の拡張モジュールが含まれています。そのため、これらを手動でダウンロードやビルドする必要はなく、必要なデータベースで有効化するだけですぐに利用することができます。
前提条件
pgRouting
を利用する前に、以下の条件を満たしているかご確認ください。
- ServBayがインストールされ、起動していること: まだインストールしていない場合は、ServBay公式サイトより最新版をダウンロード・インストールしてください。
- ServBay内でPostgreSQLパッケージがインストール・起動中であること: ServBayアプリの画面でPostgreSQLパッケージがインストール済みかつ「稼働中」であることを確認してください。
- SQLおよびPostgreSQLの基本操作に習熟していること: 本記事は、PostgreSQLとSQLクエリの基礎知識があることを前提としています。
- PostGISの基礎知識があること:
pgRouting
はPostGIS
拡張を利用して地理空間データ型や関数を扱います。データベースでPostGIS
が有効化されていることを確認ください。ServBayに付属するPostgreSQLパッケージは通常PostGISも含まれています。
pgRouting拡張機能のインストールと有効化
ServBayによりpgRouting
の拡張ファイルは事前に準備されていますので、利用したい特定のデータベース内で有効化するだけでOKです。
PostgreSQLデータベースに接続する:
PostgreSQLへの接続は
psql
コマンドラインツール、pgAdminやDBeaver等のGUIツール、または各種プログラミング言語のクライアントライブラリ等、様々な方法が利用可能です。ServBayが提供する
psql
コマンドラインツール経由が一般的かつわかりやすいでしょう。ServBayアプリ内の「ターミナル」ボタンを使えば、必要な環境変数が設定済みのターミナルをすぐ開けます。またはServBayのbinディレクトリをシステムのPATHに追加しておきます。ターミナルにて、次のコマンドで対象データベース(例:
servbay_geo_db
という名前、ユーザーはデフォルトのservbay
)に接続します。bashpsql -U servbay -d servbay_geo_db
1データベース名やユーザー名・パスワードが異なる場合は適宜変更してください。
PostGIS拡張の確認と有効化(未有効の場合):
pgRouting
はPostGIS
に依存しています。先にPostGIS
を有効化しておきましょう。psql
プロンプトで下記を入力します。sqlCREATE EXTENSION IF NOT EXISTS postgis;
1このコマンドは、
PostGIS
拡張を新規作成、または既存なら何もしません。pgRouting拡張の作成:
同じデータベース接続内で、以下のSQLを実行して
pgRouting
を有効化します。sqlCREATE EXTENSION pgrouting;
1成功すると
CREATE EXTENSION
のような出力が表示されます。インストールの検証:
インストール済み拡張一覧を表示し、
pgRouting
が有効化されたか確認できます。sql\dx
1実行結果に
postgis
およびpgrouting
が表示されます。
pgRoutingの設定:道路ネットワークデータとトポロジー作成
pgRouting
のアルゴリズムは、道路ネットワークを表すテーブルを基に動作します。通常、各道路(線分)ごとに、始点ノードID、終点ノードID、コスト(距離や時間等)情報が格納されています。効率良くルーティング計算を行うには、これら道路線分データから“トポロジー”構造(ノード間のつながり情報)を構築する必要があります。
道路ネットワークデータテーブルの作成
下記は、道路ネットワークデータを保存するためのテーブルways
作成の基本例です。このテーブルには道路のID、始点・終点ノードID、順方向・逆方向のコスト値(cost
, reverse_cost
)、およびPostGISのGEOMETRY
型で格納する道路形状情報が含まれます。
-- 道路ネットワークデータ格納用テーブル作成
CREATE TABLE ways (
id SERIAL PRIMARY KEY, -- 道路区間の一意な識別子
source INTEGER, -- 始点ノードID
target INTEGER, -- 終点ノードID
cost DOUBLE PRECISION, -- 順方向のコスト(例:距離や所要時間等)
reverse_cost DOUBLE PRECISION, -- 逆方向のコスト
geom GEOMETRY(LineString, 4326) -- 線形状のジオメトリ、SRID 4326(WGS 84緯度経度座標系)
);
2
3
4
5
6
7
8
9
補足:
SERIAL PRIMARY KEY
: 自動で一意なIDを生成source
,target
: 各道路区間の始点・終点ノードID(トポロジー作成時に自動的に付与または紐付け)cost
,reverse_cost
: この道路区間を通過するための重み(例:一方通行ならreverse_cost
をNULLか非常に大きな数に設定)geom
:PostGIS
のGEOMETRY
型で道路の空間情報を格納。LineString
型、SRIDは一般的な4326
を使用
サンプルデータの挿入
ways
テーブルに試験用のサンプル道路区間データを挿入してみましょう。
-- サンプル道路区間データの挿入
INSERT INTO ways (source, target, cost, reverse_cost, geom) VALUES
(1, 2, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4074, 39.9042), ST_MakePoint(116.4084, 39.9052)), 4326)),
(2, 3, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4084, 39.9052), ST_MakePoint(116.4094, 39.9062)), 4326)),
(3, 4, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4094, 39.9062), ST_MakePoint(116.4104, 39.9072)), 4326));
2
3
4
5
補足:
ST_MakePoint(x, y)
: 指定した経度・緯度のPostGISポイントを作成ST_MakeLine(point1, point2)
: 2点でライン型オブジェクトを作成ST_SetSRID(geometry, srid)
: 空間参照IDを設定- この例では、北京市内をモデルとした3区間の道路データを作成
トポロジーの作成
道路ネットワークテーブルの準備ができたら、pgr_createTopology
関数でネットワークのトポロジーを生成します。これは、各道路区間の形状からノード(交差点等)を自動認識し、source
・target
カラムを補完し、さらにノード一覧テーブル(通常[テーブル名]_vertices_pgr
)を新規作成する処理です。
-- 道路ネットワークのトポロジー作成
-- パラメーター:
-- 'ways': トポロジーを作成するテーブル名
-- 0.00001: 許容誤差(距離)値。同一ノードとして扱うための閾値
-- 'geom': 幾何情報を格納したカラム名
-- 'id': 道路区間IDのカラム名
SELECT pgr_createTopology('ways', 0.00001, 'geom', 'id');
2
3
4
5
6
7
補足:
pgr_createTopology
: ノード・エッジモデルのネットワーク構築に必須のコア関数- 許容誤差(tolerance)は、どの距離までを同一交差点とみなすかを指定。用途やデータ精度により要調整
この処理を実行後、ways
テーブルのsource
・target
カラムが埋められ、新たなways_vertices_pgr
テーブル(全ノード情報)も生成されます。
pgRoutingを用いたルーティング解析
トポロジーが作成できたら、さまざまなpgRoutingのアルゴリズム関数を用いてルーティング解析が可能になります。以下、よく使われる代表的なアルゴリズム例を紹介します。
最短経路分析(Dijkstraアルゴリズム)
2つのノード間の最短経路検索はルーティングの最も基本的な用途です。pgRouting
はDijkstraアルゴリズムを実装しています。
-- ノード1からノード4までの最短経路を検索
-- パラメーター:
-- 'SELECT id, source, target, cost FROM ways': グラフを構築するクエリ(id, source, target, cost列を含む必要あり)
-- 1: 開始ノードID
-- 4: 目的地ノードID
-- directed := true: 有向グラフかどうかを指定(costとreverse_costが異なる場合)
SELECT seq, id1 AS node, id2 AS edge, cost, geom
FROM pgr_dijkstra(
'SELECT id, source, target, cost FROM ways',
1, -- 開始ノードID
4, -- 目的ノードID
directed := true -- 逆方向も考慮する場合はfalseや省略可
)
JOIN ways ON edge = ways.id; -- 結果を元のwaysテーブルに結合しGeometry等を取得
2
3
4
5
6
7
8
9
10
11
12
13
14
補足:
pgr_dijkstra
: Dijkstra法による最短経路計算の実行- 1パラメータ目のSQLクエリには、経路ネットワークのエッジ情報(id, source, target, cost)は必須。逆走も許可するなら
reverse_cost
追加&directedをfalseに設定 - 2,3パラメータは開始・目的ノードのID
JOIN
活用でコストやGeometry情報も取得できるのでビジュアライズ用途にも便利
巡回セールスマン問題(TSP)
TSPアルゴリズムは、指定した一連のノード(地点)を最短または最小コストで巡回するルートを探索します。
-- ノード1, 2, 3, 4をすべて巡回し、ノード1から開始するTSPを解く
-- パラメーター:
-- 'SELECT id, x::float8 AS x, y::float8 AS y FROM ways_vertices_pgr': 訪問ノードと座標情報
-- start_id := 1: 出発ノードID
SELECT seq, node, edge, cost
FROM pgr_tsp(
'SELECT id, ST_X(the_geom)::float8 AS x, ST_Y(the_geom)::float8 AS y FROM ways_vertices_pgr WHERE id IN (1, 2, 3, 4)', -- 対象ノードと座標
start_id := 1 -- 開始ノードID
);
2
3
4
5
6
7
8
9
補足:
pgr_tsp
: TSPの最適経路探索を実行- 1パラメータ目のクエリは、最低限id, x, y(座標)を持つノード情報が必要(通常
ways_vertices_pgr
から取得) start_id
で開始ノードを指定可
サービスエリア分析(Driving Distance / Time)
サービスエリア分析では、指定した始点から特定コスト(距離・時間など)の範囲内で到達可能なネットワーク区間またはエリアを特定します。
-- ノード1を出発点とし、コストが2以内で到達可能な全区間を検索
-- パラメーター:
-- 'SELECT id, source, target, cost FROM ways': ネットワーク定義のクエリ
-- 1: 始点ノードID
-- 2: 最大許容コスト
-- directed := true: 有向グラフかどうか
SELECT seq, id1 AS node, id2 AS edge, cost, geom
FROM pgr_drivingDistance(
'SELECT id, source, target, cost FROM ways',
1, -- 始点ノードID
2, -- 最大コスト
directed := true
)
JOIN ways ON edge = ways.id; -- 結果を結合しGeometry等を取得
2
3
4
5
6
7
8
9
10
11
12
13
14
補足:
pgr_drivingDistance
: サービスエリア解析アルゴリズム- 1パラメータ目のSQLクエリでネットワーク定義
- 2パラメータ目は始点ノードID
- 3パラメータ目は最大許容コスト
- 必要に応じGeometryをビジュアル化
ルート解析結果の可視化
pgRouting
の計算結果を可視化することで、ルート情報を直感的に理解・表現できます。デスクトップGISツールやWebマップライブラリ等で容易に表示可能です。
デスクトップGIS(QGISなど)の利用
QGISはオープンソースかつ無料のデスクトップGISアプリで、PostgreSQL/PostGISデータベースへ直接接続し、空間データやpgRouting
の結果を簡単に描画できます。
- QGISを起動
- **[レイヤ] > [データソースマネージャ]**を選択
- 左側メニューから**[PostGIS]**を選択
- **[新規作成]**ボタンで新しいDB接続を追加
- ServBayのPostgreSQL接続情報を入力(例:ホスト:
localhost
, ポート:5432
, データベース:servbay_geo_db
, ユーザー:servbay
, パスワード: PostgreSQLパスワード)。接続のテストで確認可能 - 接続成功後、データベースを展開すると
ways
やways_vertices_pgr
、解析用ビューテーブルなどが確認・追加できます - 表やビュー(最短経路など)を選択し、**[追加]**ボタンでQGIS上に読み込んで可視化
Webアプリケーションでの可視化(LeafletやOpenLayers)
Webアプリの場合、バックエンドサービス(PHP, Node.js, Python等)でpgRouting
クエリを実行し、GeoJSON形式等でフロントエンドへ返却する構成が一般的です。フロントエンドはLeafletやOpenLayers等のマップライブラリで地理空間データを表示します。
以下、Leafletで静的なポリラインを追加するHTML例です。動的なルーティング結果表示には、
- バックエンドで
pgRouting
クエリを実行 - 結果のジオメトリ情報をGeoJSON等に変換
- APIを介してフロントエンドへ提供
- JavaScriptでLeafletの
L.geoJSON
等によりGeoJSONデータを描画
という流れとなります。
<!DOCTYPE html>
<html>
<head>
<title>ServBay pgRouting Web 可視化例</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<style>
#map { height: 600px; width: 100%; } /* マップコンテナのサイズ設定 */
</style>
</head>
<body>
<h1>ServBay pgRouting結果の可視化</h1>
<div id="map"></div>
<script>
// マップの初期化(中心座標とズーム)
var map = L.map('map').setView([39.906, 116.409], 14); // サンプルデータ中央付近
// OpenStreetMapベースマップの追加
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// サンプル:pgRoutingクエリ結果をGeoJSON化したデータ
// 実際にはgeojsonDataはAJAX等でバックエンドから取得
var geojsonData = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": 1,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4074, 39.9042],
[116.4084, 39.9052]
]
}
},
{
"type": "Feature",
"properties": {
"id": 2,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4084, 39.9052],
[116.4094, 39.9062]
]
}
},
{
"type": "Feature",
"properties": {
"id": 3,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4094, 39.9062],
[116.4104, 39.9072]
]
}
}
]
};
// L.geoJSONでGeoJSONデータを地図へ追加
L.geoJSON(geojsonData, {
style: function (feature) {
return {color: "#ff0000", weight: 4}; // ルートを赤色で太線表示
}
}).addTo(map);
// 追加した全要素を画面内におさめる
if (L.geoJSON(geojsonData).getBounds().isValid()) {
map.fitBounds(L.geoJSON(geojsonData).getBounds());
}
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
このHTMLファイルをServBayのWebルート(例:/Applications/ServBay/www/pgrouting-demo/index.html
)へ保存し、http://pgrouting-demo.servbay.demo
として参照すればサンプルルートの地図表示が確認できます。なお、上記は静的例であり、動的データ利用にはAPI経由でGeoJSON等を取得ください。
注意点
- データ品質の重要性:
pgRouting
の解析結果はインプットとなる道路ネットワークデータの品質に大きく依存します。正確かつ完全なデータ、正しいトポロジー構造の確保が重要です。 - パフォーマンス: 大規模ネットワークの場合、ルーティング計算コストが高くなることも。インデックス利用やネットワークの簡略化、効率的なアルゴリズムの選択も重要です。
- メモリ使用量: 大規模ネットワークでは大量のメモリを消費することがあります。適切なサーバリソースを確保してください。
よくある質問(FAQ)
Q: CREATE EXTENSION pgrouting;
で拡張が存在しないというエラーになる場合は?
A: まず、ServBayのPostgreSQLパッケージが正しくインストールおよび起動しているか確認してください。次に、接続先データベースやバージョンがpgRouting
サポート対象であるか、またServBayに同拡張モジュールが含まれているかをチェックしましょう(通常は含まれています)。それでも解決しない場合、ServBayやPostgreSQLのログファイルを参照して詳細なエラー内容を確認、また必ず十分な権限(例:servbay
ユーザー)での接続であることを確認してください。
Q: pgr_createTopology
関数のtolerance(許容誤差)はどのように設定すべきですか?
A: toleranceは、ご自身の空間データ精度に依存します。2頂点が同一ノードとみなす最小距離を指定します。高精度なGPSデータ等の場合は非常に小さい値(例:0.000001以下)を、やや粗いデータや複数データソースを扱う場合はもう少し大きめの値を選ぶとよいでしょう。設定値が大きいと、本来無関係の道路が誤って接続されるので注意が必要です。
Q: 一方通行や転回禁止といった交通規則の扱い方法は?
A: ways
テーブルのcost
とreverse_cost
カラムを活用します。一方通行道路は、逆方向のreverse_cost
をNULLまたは非常に大きな数値(通行不可)に設定してください。転回禁止等の複雑な交通規則は、より高度なネットワークモデルの利用や、ルーティング結果の後処理で対応可能です。pgRouting
にはこうした複雑な状況に対応するための拡張機能も用意されています。
まとめ
ServBayを活用すれば、ローカル開発環境上でpgRouting
対応のPostgreSQLデータベース構築がスムーズに行えます。SQLコマンドで拡張を有効化し、道路ネットワークデータを用意・トポロジー作成したら、pgRouting
の強力な地理空間ルーティングアルゴリズムを用いて即座に解析が行えます。デスクトップGISやWebマップライブラリ等と組み合わせれば、多様な業務・サービスでルート計算結果を手軽に可視化できます。ServBayにより煩雑な環境構築を最小限に抑え、開発者はアプリケーションのロジックや企画に専念できます。