GanosBase には、GPS 軌跡を道路網上の最も近い道路にスナップするマップマッチングエンジンが含まれています。このガイドでは、拡張機能のインストール、道路網データのロード、ワークスペースの構築、そして最初のマップマッチングクエリの実行まで、一連のワークフローを説明します。
前提条件
開始する前に、以下をご確認ください:
GanosBase が利用可能な実行中の PolarDB for Oracle インスタンス
データベースのスーパーユーザー権限、またはスキーマレベルの CREATE 権限
主な用語
| 用語 | 定義 |
|---|---|
| 道路網 | 道路網の構造と特性を包括的かつ組織的にデジタル表現したものです。道路の位置、種類、分類、接続、幾何学的形状、交通規制などが含まれます。 |
| ノード | 道路網において道路が交差または終端するポイントです。ノードはエッジ間の接続点です。 |
| エッジ | 道路網内の 2 つのノードを接続する抽象的な概念です。無向グラフでは、エッジに方向はありません。有向グラフでは、エッジは進行方向を表します。エッジは、長さや通行可能性などの属性情報を持ち、道路網の構造的な骨格を形成します。 |
| セグメント | 物理的な属性と地理的な位置情報を持つ道路の一部です。セグメントは、ある交差点から次の交差点まで、または車線数や制限速度などの均一な特性を持つ区間をカバーする連続した道路区間です。セグメントは、ナビゲーション、交通分析、道路維持管理計画における基本単位です。 |
拡張機能のインストール
次のコマンドを実行して、ganos_mapmatching 拡張機能と、それが必要とする ganos_fdw 拡張機能をインストールします:
CREATE EXTENSION ganos_mapmatching CASCADE;
CREATE EXTENSION ganos_fdw CASCADE;ganos_mapmatching をインストールすると、ganos_geometry、ganos_spatialref、ganos_trajectory の 3 つの追加拡張機能が自動的にインストールされます。
「ERROR: invalid extension name: "ganos_trajectory"」が表示された場合は、Alibaba Cloud サポートに連絡するか、お問い合わせください。権限の問題を回避するために、拡張機能を public スキーマにインストールします:
CREATE EXTENSION ganos_mapmatching WITH SCHEMA PUBLIC CASCADE;
CREATE EXTENSION ganos_fdw WITH SCHEMA PUBLIC CASCADE;仕組み
マップマッチングには 3 つの入力が必要です:
道路網 — それぞれが一意の ID、開始ノード、終了ノード、およびジオメトリを持つ道路セグメントのセットです。
ワークスペース — 道路網から構築されたインメモリのトポロジーネットワークグラフで、マッチングクエリに使用されます。
軌跡 — 生の GPS ポイントを表す LineString ジオメトリです。
st_createworkspace 関数は、道路網データからワークスペースを構築します。次に、st_mapmatching 関数が軌跡をそのワークスペース内の最も近い道路にマッチングさせ、スナップされた LineString を返します。
st_createworkspace に必須のカラム:
| カラム | 型 | 説明 |
|---|---|---|
fid | bigint | 一意のセグメント ID |
source | bigint | 開始ノード ID |
target | bigint | 終了ノード ID |
| geometry カラム | geometry(LineString) | セグメントジオメトリ (WGS84、SRID 4326) |
cost カラムはマップマッチングアルゴリズムでは使用されません。将来の使用のためにテーブルに含めることはできますが、マッチング結果には影響しません。
例 1:独自の道路網に対する軌跡のマッチング
ステップ 1:道路網データの作成とロード
必須のスキーマを持つテーブルを作成します。各行は、2 つのノード間の有向接続である 1 つの道路セグメントを表します:
CREATE TABLE network (
fid bigint, -- セグメント ID (一意の識別子)
source bigint, -- 開始ノード ID
target bigint, -- 終了ノード ID
cost double precision, -- エッジの重み (予約済み、マップマッチングでは未使用)
geom public.geometry(LineString,4326) -- セグメントジオメトリ (WGS84)
);道路セグメントデータを挿入します:
INSERT INTO network(fid, source, target, cost, geom) VALUES
(1, 1, 2, 1, st_geomfromtext('LINESTRING(2 1,2 0)')),
(2, 2, 1, 1, st_geomfromtext('LINESTRING(2 0,2 1)')),
(3, 3, 1, 1, st_geomfromtext('LINESTRING(3 1,2 1)')),
(4, 4, 3, 1, st_geomfromtext('LINESTRING(4 1,3 1)')),
(5, 1, 5, 1, st_geomfromtext('LINESTRING(2 1,2 2)')),
(6, 5, 1, 1, st_geomfromtext('LINESTRING(2 2,2 1)')),
(7, 3, 6, 1, st_geomfromtext('LINESTRING(3 1,3 2)')),
(8, 7, 8, 1, st_geomfromtext('LINESTRING(0 2,1 2)')),
(9, 8, 7, 1, st_geomfromtext('LINESTRING(1 2,0 2)')),
(10, 5, 8, 3, st_geomfromtext('LINESTRING(2 2,1 2)')),
(11, 8, 5, 3, st_geomfromtext('LINESTRING(1 2,2 2)')),
(12, 6, 5, 1, st_geomfromtext('LINESTRING(3 2,2 2)')),
(13, 5, 6, 1, st_geomfromtext('LINESTRING(2 2,3 2)')),
(14, 6, 9, 1, st_geomfromtext('LINESTRING(3 2,4 2)')),
(15, 9, 6, 1, st_geomfromtext('LINESTRING(4 2,3 2)')),
(16, 10, 5, 1, st_geomfromtext('LINESTRING(2 3,2 2)')),
(17, 5, 10, 1, st_geomfromtext('LINESTRING(2 2,2 3)')),
(18, 6, 11, 1, st_geomfromtext('LINESTRING(3 2,3 3)')),
(19, 10, 11, 1, st_geomfromtext('LINESTRING(2 3,3 3)')),
(20, 11, 12, 1, st_geomfromtext('LINESTRING(3 3,4 3)')),
(21, 13, 10, 1, st_geomfromtext('LINESTRING(2 4,2 3)')),
(22, 10, 13, 1, st_geomfromtext('LINESTRING(2 3,2 4)')),
(23, 9, 12, 1, st_geomfromtext('LINESTRING(4 2,4 3)')),
(24, 12, 9, 1, st_geomfromtext('LINESTRING(4 3,4 2)')),
(25, 9, 4, 1, st_geomfromtext('LINESTRING(4 2,4 1)')),
(26, 4, 9, 1, st_geomfromtext('LINESTRING(4 1,4 2)')),
(27, 14, 15, 1, st_geomfromtext('LINESTRING(0.5 3.5,2 3.5)')),
(28, 15, 14, 1, st_geomfromtext('LINESTRING(2 3.5,0.5 3.5)')),
(29, 16, 17, 1, st_geomfromtext('LINESTRING(3.5 4,3.5 2.3)')),
(30, 17, 16, 1, st_geomfromtext('LINESTRING(3.5 2.3,3.5 4)'));道路網は次のようになります:

ステップ 2:マップマッチングワークスペースの構築
道路網から mm_ws_test1 という名前のワークスペースを構築します。st_createworkspace に渡す SELECT 文には、fid、source、target、およびジオメトリカラムを含める必要があります:
SELECT st_createworkspace('mm_ws_test1', 'select fid, source, target, geom from network');これにより、マッチングに使用されるトポロジーネットワークグラフが生成されます:

ステップ 3:軌跡データの作成
テーブルを作成し、マッチングさせたい GPS 軌跡を挿入します。軌跡は WGS84 (SRID 4326) の LineString です:
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)'));生の軌跡は次のようになります:

ステップ 4:マップマッチングの実行
軌跡を道路網にマッチングさせます:
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)出力は、道路網にスナップされた LineString です。結果の各座標は、ワークスペース内の道路セグメントに対応します。マッチングされたパスを以下に示します:

例 2:OpenStreetMap (OSM) データを使用した軌跡のマッチング
カスタムデータセットの代わりに OpenStreetMap (OSM) からの実世界の道路網データがある場合は、このアプローチを使用します。
ステップ 1:Object Storage Service (OSS) からの OSM データのインポート
OSM データは Object Storage Service (OSS) からインポートする必要があります。マカオ (中国) のサンプル OSM ファイルをダウンロードして OSS バケットにアップロードし、次のコマンドを実行します:
-- OSM ファイルを外部テーブルとして登録します。
-- プレースホルダーを、ご利用の OSS の AccessKey ID、AccessKey Secret、エンドポイント、バケット、ディレクトリに置き換えてください。
SELECT st_regforeigntables(
'OSS://{accesskeyid}:{accesskeysecret}@{endpoint}/{bucket}/{directory}/macau-latest.osm.pbf',
'osmserver',
'OSMNT'
);
-- データアクセス用の OSS エンドポイントを設定します。
SELECT st_setcplconfig('OSS_ENDPOINT', '{endpoint}');OSM ファイルからノードデータ (交差点) をローカルテーブルに抽出します:
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;ステップ 2:道路網トポロジーの構築
各道路セグメントを、source および target カラムを更新することで、その開始ノードと終了ノードにリンクします:
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;結果として得られるマカオ (中国) の道路網は次のようになります:

ステップ 3:マップマッチングワークスペースの構築
SELECT st_createworkspace(
'mm_ws_test2',
'select fid, source, target, linestring from macau_network_ways'
);ステップ 4:マップマッチングの実行
GPS 軌跡をマカオ (中国) の道路網にマッチングさせます。この例では、実世界のトレースのマッチング精度を向上させるために追加のパラメーターを使用します:
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)出力座標は、ワークスペース内の実際の道路ジオメトリにスナップされます:

st_mapmatching のパラメーター
すべての例で stmatch アルゴリズムを使用します。JSON オプション文字列でマッチングの動作を制御します:
| パラメーター | 型 | 説明 | 値の例 |
|---|---|---|---|
algorithm | string | マッチングアルゴリズム。現在サポートされているのは stmatch のみです。 | "stmatch" |
k | integer | 各 GPS ポイントに対して考慮される候補道路セグメントの数。値を大きくすると、密な道路網での精度が向上しますが、計算時間が増加します。 | 4 |
r | float | データの座標単位での検索半径。各 GPS ポイントの候補となるのは、この半径内の道路セグメントのみです。ノイズが多い、または疎なトレースの場合は、この値を大きくします。 | 0.25 |
e | float | GPS 測定誤差の許容範囲。アルゴリズムが外れ値ポイントをどの程度厳密にフィルタリングするかを制御します。 | 0.5 |
tolerance | float | 生の GPS ポイントとマッチングされた位置との間で許容される最大偏差。このしきい値を超えるポイントはスキップされる場合があります。実世界のトレースで使用します。 | 0.5 |
vmax | float | マッチングされた道路セグメント間の遷移を検証するために使用される最大速度。実世界のトレースで使用します。 | 1.0 |
factor | float | マッチングスコアにおいて、空間距離と遷移確率のバランスをとるための重み付け係数。実世界のトレースで使用します。 | 0.5 |
チューニングのヒント:
ノイズの多い GPS トレース:
r(検索半径) とe(誤差許容範囲) を大きくして、アルゴリズムがより多くの候補を検討し、より大きな測定誤差を許容できるようにします。密な道路網:
kを大きくして、GPS ポイントごとにより多くの候補セグメントを評価します。これにより精度は向上しますが、計算時間が増加します。実世界のトレース:例 2 に示すように、
tolerance、vmax、factorを追加して、実際の GPS データに典型的な変動に対応します。クリーンな合成トレース:データが正確な座標から生成されている場合は、例 1 に示すように、
rとeに小さい値を使用します。