参考記事
基本的に上記の記事と同じ手順でイケます!!
※pgr_createTopologyが使えれば
PostgreSQLへのデータ投入の流れ
ダウンロード
国土数値情報ダウンロードサービス「道路データ」から東京付近のメッシュ「5339」を使いました。
ダウンロード形式はshape形式を選択しました。(QGISで読み込みやすいかとお思ったから)
PostgreSQLへデータ投入
shapeデータをQGISで開いて、DBツールでPostgreSQLに投入しました。
- テーブル名称: "N13-24_5339"
- 地物のid:id (QGISによる自動生成)
- ジオメトリカラム:geom
- PostgreSQL : バージョン 18
pgRoutingで利用可能なデータセットへの加工
配布されているデータは
- 道路の線分形状(MULTILINESTRING形式のGeometry型)
- 道路の属性情報 (N13_001 ~ N13_0008)
QGISからPostgreSQLへ投入時に付与されたデータ
- id : 各行(道路形状)に一意な整数値
PgRoutingを使う際に不足の情報
- 道路の始点ノードのID
- 道路の終点ノードのID
- 道路を通行する際のコスト
- 道路を逆に通行する際のコスト
pgr_createTopologyが無い!
道路から交差点のデータ(トポロジー)を作る必要があります。
PgRoutingのpgr_createTopologyを使うのが一般的ですが、私の環境では見当たらずPostGISを駆使して書きました。
自作SQLによるノードIDの抽出とPgRouting用テーブルの作成
無いものは仕方が無いので、自分で作りました。
処理のフローとテーブルの変化を記載します。
例では、1の道路の終点が2と3の道路と接している交差点であり、交差点は1つのノードIDを付与する必要があります。
SQLによる実装
/**
* PgRouting用交差点テーブルを自力で作る
**/
CREATE TABLE tb_node AS
WITH t1 AS
(
SELECT
id
, ST_StartPoint( ST_GeometryN( geom , 1 ) ) AS from_node_point
, ST_EndPoint( ST_GeometryN( geom , 1 ) ) AS to_node_point
FROM "N13-24_5339"
)
, t2 AS (
SELECT
from_node_point AS node_point
FROM t1
UNION ALL
SELECT
to_node_point AS node_point
FROM t1
)
, t3 AS (
SELECT
node_point
, row_number()OVER(PARTITION BY node_point) AS pcount
FROM t2
) , t4 AS (
SELECT
row_number()over() AS node_id , node_point
FROM t3
WHERE pcount = 1
)
SELECT
t1.id
, t4_source.node_id AS source
, t4_target.node_id AS target
, ST_length( geom::geography) AS cost
, ST_length( geom::geography) AS reverse_cost
FROM t1
JOIN t4 AS t4_source ON(t1.from_node_point = t4_source.node_point)
JOIN t4 AS t4_target ON(t1.to_node_point = t4_target.node_point)
JOIN "N13-24_5339" ON (t1.id = "N13-24_5339".id );
到達圏解析
作成したテーブルを用いて到達圏解析を実施します。
コストには道路の長さがメートル単位で入力されているので、到達距離をpgr_drivingDistance関数のコストとして指定します。(下記の例では500m)
SELECT a.*,b.geom
FROM pgr_drivingDistance
('select id,source,target,cost,reverse_cost from tb_node',
******, --スタート地点のノードID
500, --コストは距離をメートル単位で入力
false)as a
left join "N13-24_5339" as b
on a.edge = b.id
)
実行結果の可視化
300m , 500m , 1000m で色を変えて表現してみました


