このサイトから多くの助けを受け取った後、私は最終的に私が望んでいた仕事をする関数のセットを作成しました. ありがとうございます。しかし、最後の問題が 1 つあります。それは、メモリの効率的な使用です。問題は次の
とおりです。postgreSQL 9.3 では、postGIS 2.1 と pgRouting 2.0 を使用して、pgrouting 関数 pgr_trsp を使用して 2 点間のルートを計算し、ジオメトリ (Linestring) 値を返す関数を作成しました。コードは次のとおりです。
CREATE OR REPLACE FUNCTION fm_pgr2geom(edge1 integer, pos1 double precision, edge2 integer, pos2 double precision)
RETURNS geometry AS
$BODY$
--We have to do a routing query. And declare a cursor for it
DECLARE resc CURSOR FOR
SELECT * FROM pgr_trsp (
'SELECT * FROM th_2po_4pgr',
$1, $2, $3, $4, false, true);
doline geometry[];
temp_point geometry;
geom geometry;
temp_rec RECORD;
n integer;
BEGIN
--Append all the edges
FOR temp_rec IN SELECT * FROM pgr_trsp (
'SELECT * FROM th_2po_4pgr',
$1, $2, $3, $4, false, true) LOOP
doline := array_append(
doline, (SELECT map.geom_way FROM th_2po_4pgr map WHERE map.id = temp_rec.id2));
END LOOP;
--Remove 1st and last edge
n := array_length (doline, 1);
doline := doline [2:n-1];
--Find startpoint and append to doline
doline := array_prepend(
ST_LineInterpolatePoint((SELECT map.geom_way FROM th_2po_4pgr map WHERE map.id = $1),$2),doline);
--Append the endpoint
doline := array_append(
doline,ST_LineInterpolatePoint((SELECT map.geom_way FROM th_2po_4pgr map WHERE map.id = $3),$4));
geom := ST_MakeLine(doline);
RETURN geom;
EXCEPTION
WHEN SQLSTATE 'XX000' THEN RETURN NULL;
WHEN SQLSTATE '38001' THEN RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION fm_pgr2geom(integer, double precision, integer, double precision)
OWNER TO postgres;
この関数は別の関数で使用され、ジオメトリ結果で大きなテーブル (800k+) をバッチ更新します。ここに参照用があります:
CREATE OR REPLACE FUNCTION fm_seqrouting()
RETURNS integer AS
$BODY$
--Declarations
DECLARE
r record;
i integer;
BEGIN
--CODE to calculate routes and update table
i := 0;
FOR r IN
SELECT veh_id
,dt
,map_edge_id AS map_id1
,map_edge_pos AS map_pos1
,lead(map_edge_id) OVER w AS map_id2
,lead(map_edge_pos) OVER w AS map_pos2
FROM taxilocs
WINDOW w AS (ORDER BY veh_id, dt)
LOOP
UPDATE taxilocs
SET geom_route = fm_pgr2geom (r.map_id1,r.map_pos1,r.map_id2,r.map_pos2)
WHERE r.veh_id = taxilocs.veh_id AND r.dt=taxilocs.dt;
i := i + 1;
END LOOP;
RETURN i;
END;
$BODY$
LANGUAGE plpgsql;
例外は、前述のテーブルから一部のデータが欠落している場合や、ルーティング パスが見つからない場合を処理するため、絶対に必要です。ただし、更新クエリが数分後にクラッシュするという問題を引き起こしているようです。数分の実行後に受け取るメッセージは次のとおりです。
エラー: メモリ不足
SQL 状態: 53200
詳細: サイズ 640000 の要求で失敗しました。
問題は、この関数を効果的に使用または再コーディングして、必要なテーブルを更新するにはどうすればよいかということです。何か案は?
前もって感謝します!