Rotaya ofset nasıl eklenir?


13

Düzenlendi:

örneklem

Soruma itiraz etmek istiyorum. "A Noktası" nda olduğunuzu ve "B Noktası" na gitmek istediğinizi varsayalım. Bu noktalar "at_2po_4pgr" tablosunda olmazdı, çünkü kaynak / hedef düğümleri değil. Sonra, en yakın düğümü A ve B noktalarını (yeşil noktalar) arayacağım. Bundan sonra, yeşil noktalar kimlikleri kullanarak bir shortest_path çağrısı yapabilir ve "turuncu" yolu elde ediyorum. Ancak gerçek yol maliyetini (mesafeyi) elde etmek için ilk durumda "offsetA" yı soyutlamak ve ikinci durumda de "offset B" yi eklemek zorunda kalırım. Kırmızı noktalar ile yeşil noktalar arasındaki mesafeyi hesaplamak için aşağıdaki sorguyu çalıştırıyorum:

SELECT * FROM st_distance( ST_GeomFromText('POINT(-3.6963314 42.3498066)',4326), ST_GeomFromText('POINT(-3.6954276 42.3479634)',4326)).

Ofseti ne zaman ekleyeceğinizi veya özetleyeceğinizi nasıl bilebilirim?

İngilizcem için üzgünüm!


1
Gis.stackexchange'e hoş geldiniz. Bu, her iş parçacığının tam olarak bir soru ve cevaplarını içermesi gereken bir Soru-Cevap sitesidir. Lütfen 3. soru için ayrı bir konu açın. # 2 cevap verilir gis.stackexchange.com/questions/33471/…
underdark

1
Aynı problemim var. herhangi bir çözüm buldun mu? Çok teşekkürler
Robert

1
Lütfen çözümünüzü cevap bölümüne gönderin. Sonra iptal edilebilir.
underdark

Yanıtlar:


2

En yakın tepe noktasına güvenebileceğinizi düşünmüyorum. Kaynak ve hedefin, aynı tepe noktasına yakın bir yerde bulunduğunu hayal edin.

Üç tanesini tercih ettin! farklı durumlar:

  1. tepe noktası en yakın noktadır.
  2. kenarın bir form düğümü sağdakidir
  3. kenar çizgisinin kendisi daha yakındır. (dikey)

Üzgünüm ama bu doğru cevap değil. pgr_trsp - Kısıtlamayı Kısalt En Kısa Yol (TRSP) @amball cevabı için şov olarak dengelendi.
Juan Carlos Oropeza

7

Böyle bir işlevi burada bulabilirsiniz: https://github.com/pgRouting/pgrouting-contrib/blob/master/wrapper/routing_core_smart.sql#L69

Genellikle daha iyi bir sonuç veren ağdaki en yakın bağlantıyı arar . Kayan Yıldız kullanıyorsanız, bu bağlantıdan / bağlantısına yönlendirmeye başlayabilirsiniz. A * veya Dijkstra için bağlantının başlangıç ​​veya bitiş noktasını seçersiniz veya bağlantıyı ikiye bölerek "sanal" bir düğüm oluşturursunuz.


1

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:

olası çıktı

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.


1

Pgroutlemede, pgr_trsp - Kısıtlamayı Kısaltın (TRSP) tam olarak aradığınızı yapar.

Kaynak ve hedef düğümleri belirtmek yerine, kaynak ve hedef kenarları ve başlangıç ​​noktanızın ve hedefinizin bulunduğu kenar boyunca kesir belirtebilirsiniz.

(En yakın kenarı bildiğinizi varsayarak, bu kesri nokta geometrinizden almak için ST_Line_Locate_Point kullanabilirsiniz.)

Bkz. Http://docs.pgrouting.org/2.0/en/src/trsp/doc/index.html#trsp

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.