../_images/logo_pgrouting.png ../_images/OSGeo_community.png

pgRouting Quickstart

pgrouting是一个扩展,它将路由和其他网络分析功能添加到 PostGIS / PostgreSQL 数据库。

此快速入门介绍了如何在PostgreSQL数据库中启用PGRouting,如何使用OSM2PGRouting加载数据,以及如何使用示例测试数据运行基本的最短路径查询。

在数据库中启用PGRouting

在这个例子中,我们将创建一个名为 city_routing 并在数据库中启用PGRouting。

  • 打开一个 System Tools ‣ LXTerminal window和open-up-psql:(psql是与postgresql打包的命令行工具)
psql

在psql提示下键入:

CREATE DATABASE city_routing;
\connect city_routing;
CREATE EXTENSION postgis;
CREATE EXTENSION pgrouting;

如果您运行的是PostgreSQL 9.6+,那么可以跳过Postgis行并执行 CREATE EXTENSION pgrouting CASCADE;

您可以通过运行以下命令来验证安装:

SELECT  * FROM pgr_version();
 version |  tag   |   hash    | branch | boost
---------+--------+-----------+--------+--------
 2.3.2   | v2.3.2 | 1f2af3c52 | master | 1.58.0
(1 row)

您的版本应该是2.1.0或更高版本,以便在此快速入门中使用示例。

使用OSM2PGRouting加载OSM数据

osm2pgrouting是用于将.osm文件加载到pgrouting兼容格式的命令行工具。下面是如何使用OSM2PGRouting版本2.1.0+。

打开一个新的终端窗口以验证您安装的osm2pgrouting版本。应为2.1或更高。

osm2pgrouting --version

输出显示:

This is osm2pgrouting Version 2.2

现在从OSM文件加载数据:

cd
bzcat data/osm/feature_city.osm.bz2 > /tmp/feature_city.osm
osm2pgrouting -f /tmp/feature_city.osm -h localhost -U user -d city_routing -p 5432 -W user --conf=/usr/share/osm2pgrouting/mapconfig_for_cars.xml
rm /tmp/feature_city.osm

输出应该类似于:

Export Ways ...
    Processing 45383 ways:
[*************************************************| ] (99%)    Ways Processed: 45383        Split Ways generated: 10483 Vertices inserted 9165 Inserted 10483 split ways
Creating Foreign Keys ...
Foreign keys for osm_way_classes table created
Foreign keys for relations_ways table created
Foreign keys for Ways table created
#########################
size of streets: 45383
#########################

正在运行PGRouting

  • 打开一个 System Tools ‣ LXTerminal 窗口并连接到 city_routing 数据库:
psql -U postgres city_routing
  • 类型 \d 将列出所有可用的表:
                    List of relations
 Schema |           Name           |   Type   |  Owner
--------+--------------------------+----------+----------
 public | geography_columns        | view     | postgres
 public | geometry_columns         | view     | postgres
 public | osm_nodes                | table    | postgres
 public | osm_nodes_node_id_seq    | sequence | postgres
 public | osm_relations            | table    | postgres
 public | osm_way_classes          | table    | postgres
 public | osm_way_types            | table    | postgres
 public | raster_columns           | view     | postgres
 public | raster_overviews         | view     | postgres
 public | relations_ways           | table    | postgres
 public | spatial_ref_sys          | table    | postgres
 public | ways                     | table    | postgres
 public | ways_gid_seq             | sequence | postgres
 public | ways_vertices_pgr        | table    | postgres
 public | ways_vertices_pgr_id_seq | sequence | postgres
(15 rows)
  • 运行Dijkstra最短路径函数,假设无向行程:
SELECT seq, node, edge, cost
        FROM pgr_dijkstra('
                SELECT gid as id, source, target,
                        length as cost FROM ways',
                100, 600, false
        );
 seq | node | edge  |         cost
-----+------+-------+-----------------------
   1 |  100 |   148 |  0.000106201177015572
   2 | 3603 |  4118 |  0.000171096610136435
   3 | 8284 |  9429 |  0.000101401380664492
 ... |  ... |   ... |                 ...
  37 | 3461 |  3964 |   0.00121559903339768
  38 | 1761 |  2013 |   0.00307553090376563
  39 | 5981 |  6801 |  0.000158813884783759
  40 |  600 |    -1 |                     0
(40 rows)

pgr_dijkstra还支持节点和边缘的bigints,osm2pgrouting也加载osm_id,因此您可以选择使用osm_id,而不是为节点自动生成源和目标。要查找节点的相应osm_id,我们将使用以下查询:

SELECT id, osm_id
        FROM ways_vertices_pgr where id IN( 100, 600);

输出:

 id  |   osm_id
-----+------------
 100 | 1896068597
 600 |   31369798
(2 rows)

为此,您可以将查询更改为以下内容:

SELECT seq, node, edge, cost
FROM pgr_dijkstra('
        SELECT gid as id, source_osm AS source, target_osm AS target,
                length as cost FROM ways',
        1896068597, 31369798, false
);

注意:SQL语句必须始终具有字段名 id, source, target, and cost . 因为我们在使用字段 source_osmtarget_osm ,我们需要对它们进行别名,以便将生成的pgr_djkstra查询列命名为source和target。

输出为:

 seq |    node    | edge  |         cost
-----+------------+-------+-----------------------
   1 | 1896068597 |   148 |  0.000106201177015572
   2 |  471372588 |  4118 |  0.000171096610136435
   3 |  471372583 |  9429 |  0.000101401380664492
   :
   :
  ...|  ...       |   ... |                 ...
  37 | 1370351630 |  3964 |   0.00121559903339768
  38 |   30812815 |  2013 |   0.00307553090376563
  39 | 3214028631 |  6801 |  0.000158813884783759
  40 |   31369798 |    -1 |                     0
(40 rows)

由于我们仍然使用自动生成的边缘ID,因此我们的边缘编号与前面的查询相同,但节点是OSM节点ID。

使用osm_id而不是自动生成的id的好处是,如果不同的数据库共享一组共同的osm id,那么结果将在不同的数据库之间保持一致。并不是所有的pgmrouting函数都被更改为使用bigints,所以osm_id不能与所有函数一起使用。

  • 要输出路线几何图形,请将结果与道路几何图形链接:
SELECT seq, edge, rpad(b.the_geom::text,60,' ') AS "the_geom (truncated)"
        FROM pgr_dijkstra('
                SELECT gid as id, source, target,
                        length as cost FROM ways',
                100, 600, false
        ) a INNER JOIN ways b ON (a.edge = b.gid) ORDER BY seq;
 seq | edge  |                     the_geom (truncated)
-----+-------+--------------------------------------------------------------
   1 |   148 | 0102000020E61000000200000035BEE5A03A641C40BC98C1734A5E4940F4
   2 |  4118 | 0102000020E610000002000000F4CE577F3A641C402B5CA0EE4D5E494058
   3 |  9429 | 0102000020E61000000200000058BCA2A53C641C40C3503D88535E4940F5
 ... |   ... |                                                          ...
  36 |  6538 | 0102000020E6100000020000002999F7938C6F1C409DD843FB585D49405C
  37 |  3964 | 0102000020E6100000020000005CAE7E6C926F1C40E55C2FF2575D494088
  38 |  2013 | 0102000020E6100000020000008849B89047701C406DF7BC2C375D4940E8
  39 |  6801 | 0102000020E610000002000000E82E89B322721C40A85890C1E55C494059
(39 rows)
  • 您可以使用图形工具查看路线。
    OpenJumpQGIS DBManager扩展。

要使用qgis的dbmanager扩展,请打开qgis,然后转到 Database -> DB Manager -> DB Manager . 选择SQL窗口图标,剪切并粘贴上面的pgrouting查询。

  • 在考虑方向的情况下运行Dijkstra最短路径函数。

在前面的例子中,我们假设街道在两个方向上的成本相等。如果您在任一车道上有一条路或不同的速度限制,则在一条道路的一个方向上行驶的成本可能与在另一条道路上行驶的成本不同。对于这些情况,您需要在查询的“反向成本”中添加一个附加列。`

SELECT seq, node, edge, cost
        FROM pgr_dijkstra('
                SELECT gid as id, source, target,
                        cost_s As cost, reverse_cost_s AS reverse_cost FROM ways',
                100, 600, true
        );
  • \q 命令离开postgresql shell。

接下来呢?