如何在pgRouting中使用其他表的点作为起终点生成路径
解决方案
前置确认
首先确认你的基础数据符合以下要求:
- 网络拓扑表(假设命名为
road_network)已通过pgr_createTopology完成拓扑构建,包含source、target拓扑节点ID字段,以及geom道路线几何字段 - 拓扑生成的节点表(默认命名为
road_network_vertices_pgr)包含节点IDid、节点几何the_geom字段 - 外部点表(假设命名为
poi,存储客户、门店坐标)包含geom点几何字段
方案1:匹配到最近拓扑节点(低精度、高性能场景)
source/target本质是拓扑网络的节点ID,外部点不能直接传入,需要先关联到离它最近的拓扑节点,拿到对应节点ID即可作为路由参数使用。
单个点查询最近节点ID的语句示例:
SELECT v.id AS node_id FROM road_network_vertices_pgr v JOIN poi p ON ST_DWithin(v.the_geom, p.geom, 500) -- 500为搜索半径,单位与坐标系一致,用于提升查询性能 WHERE p.poi_id = '待查询的POI ID' ORDER BY ST_Distance(v.the_geom, p.geom) ASC LIMIT 1;
查询返回的node_id可直接作为pgRouting路由函数的source或target参数。
方案2:匹配到道路边投影点(高精度场景)
如果不能接受用已有节点作为起终点,需要更精准的路径结果,可以将外部点投影到最近的道路边上,用虚拟节点作为起终点:
- 先查询最近道路边和投影位置
SELECT e.id AS edge_id, ST_LineLocatePoint(e.geom, p.geom) AS location -- 返回0-1的数值,代表点在边从source到target方向的位置占比 FROM road_network e JOIN poi p ON ST_DWithin(e.geom, p.geom, 500) WHERE p.poi_id = '待查询的POI ID' ORDER BY ST_Distance(e.geom, p.geom) ASC LIMIT 1;
- 将查询得到的
edge_id和location传入pgRouting的pgr_withPoints系列函数即可,这类函数原生支持虚拟点作为起终点,不需要修改原有拓扑结构。
批量处理优化
如果需要频繁查询外部点之间的路径,可以预计算所有外部点对应的匹配节点/边信息,存入POI表的新增字段,避免每次路由都重复计算最近邻:
-- 给POI表新增最近节点ID字段 ALTER TABLE poi ADD COLUMN nearest_node_id INTEGER; -- 批量更新所有POI的最近节点ID UPDATE poi p SET nearest_node_id = ( SELECT v.id FROM road_network_vertices_pgr v WHERE ST_DWithin(v.the_geom, p.geom, 500) ORDER BY ST_Distance(v.the_geom, p.geom) ASC LIMIT 1 );
后续路由直接使用nearest_node_id作为起终点参数即可。
注意事项
- 如果使用WGS84坐标系(SRID=4326),
ST_DWithin的单位为度,1度约等于111公里,需要根据实际需求换算搜索半径,或投影到平面坐标系后再计算 - 搜索半径需要根据你的数据密度调整,避免遗漏最近的节点或边
内容的提问来源于stack exchange,提问作者afflicitor
相关产品推荐
相关产品推荐

