本文帮助您快速理解Ganos MapMatching引擎的基本用法,包括扩展创建、创建路网数据、构建拓扑网络图、执行轨迹匹配等部分。
基本概念
路网(Road Network):指描述道路交通网络结构和特性的数字化信息集合,包括了道路的位置、类型、等级、连接关系、几何形状、交通规则等多方面的信息。
节点(Node):在路网数据中,节点通常代表道路的交叉点或端点,是道路网络中连接各边的点。
边(Edge):在路网数据的上下文中,边是路网中连接两个节点的抽象概念。边主要用来表示两个地点之间的连接关系,而不涉及具体的道路物理特征。在无向图中,边没有方向;在有向图中,边则可以表示行驶方向。边通常会携带一些属性信息,比如长度、是否可通行等,但其核心作用是构建路网的结构框架。
路段(Segment):路段是道路的一部分,具有实际的物理属性和地理位置信息,它是路网中连续的一段道路,可能从一个路口开始到下一个路口结束,或者是道路中具有相同特征(如车道数、限速等)的一段。路段数据比边更为详细,通常包含路面材质、宽度、坡度、车道配置、交通标志信息、路权(如是否允许转弯、直行等)等。路段是实现导航、交通分析、道路维护规划等应用的基础单位。
案例参考
创建插件
使用MapMatching函数需要您在数据库中创建ganos_mapmatching
插件。
CREATE EXTENSION ganos_mapmatching CASCADE;
CREATE EXTENSION ganos_fdw CASCADE;
创建
ganos_mapmatching
插件时,将同步安装ganos_geometry
、ganos_spatialref
和ganos_trajectory
插件,如遇到类似ERROR: invalid extension name: "ganos_trajectory"
报错,请联系我们处理。为避免权限问题,建议您将扩展安装在public模式下。
CREATE EXTENSION ganos_mapmatching WITH SCHEMA PUBLIC CASCADE; CREATE EXTENSION ganos_fdw WITH SCHEMA PUBLIC CASCADE;
示例一:利用自有路网数据实现道路匹配。
导入路网数据。
CREATE TABLE network (fid bigint, -- 路段的唯一标识 source bigint, -- 路段的开始节点标识 target bigint, -- 路段的结束节点标识 cost double precision, -- 道路权重值(目前未使用) geom public.geometry(LineString,4326) --路段的几何对象 ); INSERT INTO network(fid, source, target, cost, geom) VALUES(1, 1, 2,1, st_geomfromtext('LINESTRING(2 1,2 0)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(2, 2, 1,1, st_geomfromtext('LINESTRING(2 0,2 1)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(3, 3, 1,1, st_geomfromtext('LINESTRING(3 1,2 1)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(4, 4, 3,1, st_geomfromtext('LINESTRING(4 1,3 1)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(5, 1, 5,1, st_geomfromtext('LINESTRING(2 1,2 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(6, 5, 1,1, st_geomfromtext('LINESTRING(2 2,2 1)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(7, 3, 6,1, st_geomfromtext('LINESTRING(3 1,3 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(8, 7, 8,1, st_geomfromtext('LINESTRING(0 2,1 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(9, 8, 7,1, st_geomfromtext('LINESTRING(1 2,0 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(10,5, 8,3, st_geomfromtext('LINESTRING(2 2,1 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(11,8, 5,3, st_geomfromtext('LINESTRING(1 2,2 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(12,6, 5,1, st_geomfromtext('LINESTRING(3 2,2 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(13,5, 6,1, st_geomfromtext('LINESTRING(2 2,3 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(14,6, 9,1, st_geomfromtext('LINESTRING(3 2,4 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(15,9, 6,1, st_geomfromtext('LINESTRING(4 2,3 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(16,10,5,1, st_geomfromtext('LINESTRING(2 3,2 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(17,5, 10,1, st_geomfromtext('LINESTRING(2 2,2 3)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(18,6, 11,1, st_geomfromtext('LINESTRING(3 2,3 3)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(19,10,11,1, st_geomfromtext('LINESTRING(2 3,3 3)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(20,11,12,1, st_geomfromtext('LINESTRING(3 3,4 3)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(21,13,10,1, st_geomfromtext('LINESTRING(2 4,2 3)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(22,10,13,1, st_geomfromtext('LINESTRING(2 3,2 4)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(23,9, 12,1, st_geomfromtext('LINESTRING(4 2,4 3)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(24,12,9,1, st_geomfromtext('LINESTRING(4 3,4 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(25,9, 4,1, st_geomfromtext('LINESTRING(4 2,4 1)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(26,4, 9,1, st_geomfromtext('LINESTRING(4 1,4 2)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(27,14,15,1, st_geomfromtext('LINESTRING(0.5 3.5,2 3.5)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(28,15,14,1, st_geomfromtext('LINESTRING(2 3.5,0.5 3.5)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(29,16,17,1, st_geomfromtext('LINESTRING(3.5 4,3.5 2.3)')); INSERT INTO network(fid, source, target, cost, geom) VALUES(30,17,16,1, st_geomfromtext('LINESTRING(3.5 2.3,3.5 4)'));
构建地图匹配工作空间。
SELECT st_createworkspace('mm_ws_test1', 'select fid, source, target, geom from network');
工作空间中生成的路网结构如下:
创建待匹配的轨迹线数据。
CREATE TABLE traj(id int, geom geometry(linestring, 4326)); INSERT INTO traj(id, geom) VALUES(1,st_geomfromtext('LINESTRING(4.15 1.6,3.47 0.92,2.4 0.92,2.14 1.53,2.14 2.57,2.49 2.98)'));
执行道路匹配。
SELECT st_astext(st_mapmatching('mm_ws_test1', geom, '{"algorithm":"stmatch","k":4,"r":0.25,"e":0.5}'::text)) AS geom FROM traj;
返回结果如下:
geom ---------------------------------------------- LINESTRING(4 1.6,4 1,3 1,2 1,2 2,2 3,2.49 3) (1 row)
示例二:利用OSM数据实现道路匹配。
导入OSM数据。
-- 导入OSS上的OSM路网数据,目前只支持导入OSS上的源文件 -- accesskeyid,accesskeysecret为OSS的访问密钥 -- directory指文件夹,如果在根目录下可不填 SELECT st_regforeigntables('OSS://{accesskeyid}:{accesskeysecret}@{endpoint}/{bucket}/{directory}/macau-latest.osm.pbf' , 'osmserver', 'OSMNT'); SELECT st_setcplconfig('OSS_ENDPOINT', '{endpoint}'); -- 提取路网节点数据 CREATE TABLE macau_network_nodes ( id BIGSERIAL, fid BIGINT, eout INTEGER, lon DOUBLE PRECISION , lat DOUBLE PRECISION, cnt INTEGER, chk INTEGER, ein INTEGER, name text, tags text, point GEOMETRY(point, 4326) ); INSERT INTO macau_network_nodes(fid, lon, lat, name, tags, point) SELECT osm_id::bigint, ST_X(geom), ST_Y(geom), name, to_json(other_tags)::jsonb, geom FROM points; -- 提取路网边数据 CREATE TABLE macau_network_ways ( gid BIGSERIAL, fid BIGINT, length DOUBLE PRECISION, length_m DOUBLE PRECISION, p TEXT, source BIGINT, target BIGINT, source_osm BIGINT, target_osm BIGINT, cost DOUBLE PRECISION, reverse_cost DOUBLE PRECISION DEFAULT -1, cost_s DOUBLE PRECISION, reverse_cost_s DOUBLE PRECISION DEFAULT -1, rule TEXT, one_way INT, oneway TEXT, x1 DOUBLE PRECISION, y1 DOUBLE PRECISION, x2 DOUBLE PRECISION, y2 DOUBLE PRECISION, maxspeed_forward DOUBLE PRECISION, maxspeed_backward DOUBLE PRECISION DEFAULT -1, priority DOUBLE PRECISION DEFAULT 1, name TEXT, tags JSONB, linestring GEOMETRY(LINESTRING, 4326) ); INSERT INTO macau_network_ways(fid, source_osm, target_osm, name, tags, linestring) SELECT osm_id::bigint, source_osm, target_osm, name, to_json(other_tags)::jsonb, geom FROM lines;
构造路网数据。
-- 更新路网起止节点ID UPDATE macau_network_ways SET source = macau_network_nodes.id FROM macau_network_nodes WHERE macau_network_ways.source_osm = macau_network_nodes.fid; UPDATE macau_network_ways SET target = macau_network_nodes.id FROM macau_network_nodes WHERE macau_network_ways.target_osm = macau_network_nodes.fid;
构建地图匹配工作空间。
SELECT st_createworkspace('mm_ws_test2', 'select fid, source, target, linestring from macau_network_ways');
执行道路匹配。
SELECT st_astext(st_mapmatching('mm_ws_test2', 'LINESTRING(113.5492 22.1881,113.5493 22.1881,113.5504 22.1885,113.5505 22.1886,113.5502 22.189,113.5501 22.1891,113.5491 22.1887,113.5489 22.1887)', '{"algorithm":"stmatch","k":4,"r":0.25,"e":0.5,"tolerance":0.5,"vmax":1.0,"factor":0.5}'::text));
返回结果如下:
LINESTRING(113.5492633 22.1880942,113.5493491 22.1881266,113.5504129 22.1885289,113.5505378 22.1885762,113.5502504 22.1892274,113.5505378 22.1885762,113.5502504 22.1892274,113.5501282 22.1891812,113.5490843 22.1887864,113.5489761 22.1887455)