ฉันจะอธิบายวิธีแก้ปัญหาที่พบ (อาจไม่ดีที่สุด)
ตามที่โพสต์ภาพสมมติว่าเราอยู่ในจุด Aและเราจะไปที่จุด B ดังที่ฉันได้อธิบายข้างต้นจุดนี้ไม่ได้จุดสุดยอด (แหล่งที่มา / เป้าหมายในตารางที่สร้างขึ้นด้วยเครื่องมือ osm2po)
ด้วยเหตุนี้เราจำเป็นต้องรู้ทิศทางการเดิน / ขับรถ หากเราไปจากจุดสุดยอดที่ใกล้ที่สุดไปยังจุด A (จุดสีเขียว) ผ่านเส้นทางสีส้มเราจะต้องลดการชดเชยระหว่างจุด Aและจุดสีเขียว (จุดสุดที่ใกล้ที่สุด) แต่ถ้าเราต้องผ่านถนนCalle Almirante Bonifazเราควรเพิ่มออฟเซ็ตตามความยาวของขอบนี้ (จากจุดสีเขียวไปจนถึงจุดตัดระหว่างCalle Almirante BonifazและCalle San Juan )
ฉันเรียกใช้แบบสอบถามต่อไปนี้เพื่อรับเส้นทางที่สั้นที่สุด (คุณต้องการส่วนขยาย pgRouting อธิบายที่นี่pgRouting - การติดตั้งและข้อกำหนดที่นี่การติดตั้งและข้อกำหนด ):
SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);
ซึ่งส่งผลให้ชุดของขอบที่แสดงถึงเส้นทางที่สมบูรณ์ ตัวอย่างเช่นหนึ่งผลลัพธ์ที่เป็นไปได้สำหรับแบบสอบถามนี้อาจเป็น:
ตำแหน่งที่gid ของฟิลด์( idในตารางที่สร้างจาก osm2po) แสดงถึงตัวระบุขอบ เราต้องตรวจสอบค่าชดเชยในตอนเริ่มต้นและตอนท้าย (คะแนน 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
ณ จุดนี้เราจะมีออฟเซ็ตเพื่อเพิ่มหรือย่อส่วน
ในที่สุดคุณจะต้องทราบความกว้างขอบเพื่อใช้ค่าที่ได้จากแบบสอบถามด้านบนและปรับค่าจริง (ถ้าคุณทำงานกับชนิดรูปทรงเรขาคณิตคุณจะต้องทำให้มาตรฐานเป็นเมตรที่ได้รับเพียงคูณ111000ด้วยความยาวที่ได้รับ แบบสอบถาม):
select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";
หากเราจะตรวจสอบจุดสิ้นสุดของจุดสิ้นสุดเราจะต้องตรวจสอบว่าเส้นทางสุดท้ายของชุดเส้นทางที่ได้จากแบบสอบถามด้านบนนั้นเหมือนกับเส้นทางที่ใกล้ที่สุดไปยังจุดสิ้นสุด ( จุด B ) และเราจะเพิ่ม / ย่อยที่ แบบเดียวกับก่อน
ขอโทษภาษาอังกฤษของฉัน