私が見つけた解決策を説明します(おそらく最高ではありません)。
投稿画像によると、ポイントAにいて、ポイントBに移動するとします。上で説明したように、このポイントは頂点ではありません(osm2poツールで生成されたテーブルのソース/ターゲット)。
このため、ウォーキング/ドライブの方向を知る必要があります。最も近い頂点からオレンジパスを介してポイントA(緑のポイント)に移動する場合、ポイントAと緑のポイント(最も近い頂点)の間のオフセットを減算する必要があります。ただし、Calle Almirante Bonifaz通りを通過する必要がある場合は、このエッジの長さにオフセットを追加する必要があります(緑色の点からCalle Almirante BonifazとCalle San Juanの交差点まで)。
次のクエリを実行して最短パスを取得します(ここで説明するpgRouting拡張機能が必要ですpgRouting-インストールと要件はここにありますinstallation&requirements):
SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);
これにより、完全なルートを表すエッジのセットが作成されます。たとえば、このクエリの1つの可能な出力は次のとおりです。
フィールドgid(osm2poで生成されたテーブルのid)は、エッジ識別子を表します。さて、開始時と終了時のオフセットを確認する必要があります(ポイントA / B)。
開始オフセットを確認する場合、上記のクエリで取得したエッジセットの最初のエッジがポイントAへの最も近いパスと同じかどうかを確認する必要があります。それらが一致する場合、オフセットを減算します。それらが一致しない場合、オフセットを追加します。ポイントへの最も近いリンクを取得するには、次のクエリを実行します。
SELECT * FROM find_node_by_nearest_link_within_distance(point, 0.1, 'xx_2po_4pgr') as id;
最も近いエッジを返すように、この関数を適応させる必要があります。最初に、link_pointタイプを変更する必要があります(nearest_linkフィールドを追加します)。
CREATE TYPE link_point AS
(id integer,
name character varying,
nearest_link integer);
ALTER TYPE link_point
OWNER TO postgres;
find_node_by_nearest_link_within_distanceも変更する必要があります。最後の行を追加するだけです(関数からの抜粋のみを示します)。
-- Searching for a nearest link
FOR row in EXECUTE 'select id from find_nearest_link_within_distance('''||point||''', '||distance||', '''||tbl||''') as id'
LOOP
END LOOP;
IF row.id is null THEN
res.id = -1;
RETURN res;
END IF;
link:=row.id;
res.nearest_link:=link;
次に、ポイント(ポイントA /ポイントB)と最も近いエッジ(オフセット)の間の距離を知る必要があります。この目的のために、このクエリを実行します。
SELECT ST_Line_Locate_Point(geom , point)as offset;
どこGEOMはあるthe_geomの osm2po生成されたテーブル内のフィールド。
この時点で、追加または減算するオフセットがあります。
最後に、あなたはジオメトリタイプで作業している場合、あなたがメートルに得られた値を正規化する必要があります(上記のクエリで得られた値を適用するためにエッジlegthを知っておく必要があり、実際の調整でしょう。ただ、乗算111000で得られた長さクエリ):
select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";
終了オフセットを確認する場合は、上記のクエリで取得した一連のパスの最後のパスが終了点(Point B)に最も近いパスと同じであるかどうかを確認する必要があります。前と同じ方法。
失礼します。