Bulduğum çözümü açıklayacağım (belki de en iyisi değil).
Gönderi resmine göre, Diyelim ki A noktasındayız ve B Noktasına gideceğiz . Yukarıda açıkladığım gibi, bu noktalar tepe noktası değildir (kaynak / osm2po aracıyla oluşturulan tablodaki hedefler).
Bu nedenle, yürüme / sürüş yönünü bilmemiz gerekiyor. En yakın tepe noktasından A noktasına (yeşil nokta) turuncu yoldan gidersek, A Noktası ile yeşil nokta (en yakın tepe noktası) arasındaki farkı özetlememiz gerekir . Ancak Calle Almirante Bonifaz caddesinden geçmek zorunda kalırsak, ofseti bu kenarın uzunluğuna eklemeliyiz (yeşil noktadan Calle Almirante Bonifaz ve Calle San Juan arasındaki kesişmeye ).
En kısa yolu elde etmek için aşağıdaki sorguyu çalıştırıyorum (burada açıklanan pgRouting uzantısına ihtiyacınız var pgRouting - kurulum ve gereksinimler burada kurulum ve gereksinimler ):
SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);
Bu, tüm rotayı temsil eden bir kenar kümesi ile sonuçlanır. Örneğin, bu sorgu için olası bir çıktı şunlar olabilir:
Burada gid alanı ( osm2po oluşturulan tablodaki id ) kenar tanımlayıcısını temsil eder. Başlangıçta ve sonda ofsetleri kontrol etmeliyiz (A / B Puanları).
Başlangıç ofsetini kontrol edersek, yukarıdaki sorguda elde edilen kenar kümesinin ilk kenarının A Noktasına en yakın yolla aynı olup olmadığını kontrol etmeliyiz . Eğer eşleşirlerse, ofseti özetleyeceğiz. Eşleşmezlerse, ofseti ekleyeceğiz. Bir noktaya en yakın bağlantıyı elde etmek için aşağıdaki sorguyu çalıştırın:
SELECT * FROM find_node_by_nearest_link_within_distance(point, 0.1, 'xx_2po_4pgr') as id;
Bu işlevi en yakın kenarı döndürecek şekilde uyarlamanız gerekir. Öncelikle link_point türünü değiştirmeniz gerekir (en yakın_link alanını ekleyin ):
CREATE TYPE link_point AS
(id integer,
name character varying,
nearest_link integer);
ALTER TYPE link_point
OWNER TO postgres;
Ayrıca find_node_by_nearest_link_within_distance öğesini de değiştirmeniz gerekir . Sadece son satırı ekleyin (Ben sadece fonksiyondan bir özü gösterir):
-- 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;
Ardından nokta ( A Noktası / B Noktası ) ile en yakın kenar (ofset) arasındaki mesafenin ne olduğunu bilmeniz gerekir . Bu amaçla bu sorguyu çalıştırın:
SELECT ST_Line_Locate_Point(geom , point)as offset;
Burada geom , osm2po tarafından oluşturulan tabloda the_geom alanıdır.
Bu noktada, ekleme veya özetleme ofsetine sahip oluruz.
Son olarak, yukarıdaki sorguda elde edilen değere uygulamak ve geometri türü ile çalışmak, size değer elde metreye normalleştirmek zorunda kalacak (gerçek ayarlamak için kenar legth bilmesi gerekir. Sadece çarpın 111.000 uzunluk elde tarafından sorgu):
select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";
Bitiş ofsetini kontrol edersek, yukarıdaki sorguda elde edilen yol kümesinin son yolunun bitiş noktasına ( B Noktası ) en yakın yolla aynı olup olmadığını kontrol etmeliyiz ve eskisi gibi.
İngilizcemi affedin.