PostGIS kullanarak tüm noktaları birleştiren en küçük ağ nasıl hesaplanır?


13

Noktalardan biri ve ikincisi onları çevreleyen yollar kümesi - iki tablo üreten postgis komut dosyaları bir dizi var. Tüm veriler aynı projeksiyondadır ve her iki çıkış da postgis 2.1 ile postgres 9.2 tablolarında saklanır

Yol ağının pgrouting topolojisi oluşturuldu ve noktalar tablosunda en yakın yol segmentini içeren bir sütun var.

O zaman tüm noktaları minimum yayılan ağaç gibi bir şey kullanarak bağlayan en küçük ağı temsil eden yol ağının bir alt kümesi oluşturmak istiyorum. Karayolu ağı yönlendirilmemiştir ve maliyetler sadece rota uzunluğudur.

Bunu vG modüllerini kullanarak QGIS / Grass'ta yapabilirim ama ideal olarak bu son adımı SQL'de de tutmak istiyorum.

Yeni apspWarshall postgis işlevine baktım, ancak enerjisini tüm ağı değil, noktaları birleştirmeye odaklamanın nasıl teşvik edileceği konusunda bir kayıptayım.

Bu, bunu çözmek için bir çerçeve oluşturmak amacıyla bir araya getirdiğim kısa komut dosyasıdır, ancak kenarların bir alt kümesiyle başlamak için işlevi odaklamanın mümkün olduğu yeri göremiyorum.

SELECT seq, id1 AS node, id2 AS edge, cost, the_geom
FROM   pgr_apspWarshall('SELECT gid AS id, 
                                source, 
                                target, 
                                st_length(the_geom) AS cost 
                         FROM   road_network
                        ',
                        false, false
                       ) AS tree
JOIN   road_network As roads
ON     tree.id2 = roads.gid

Tek yol en kısa yol problemlerinde fonksiyon başlangıç ​​ve bitiş ister ancak görünüşte tüm nokta problemlerinde değil. Aynı şekilde Grass v.net.spanningtree ve v.net.steiner birlikte çalışmak için birleşik bir ağ olarak bir dizi nokta ve çizgi bekliyoruz.

PostGIS'te bunun nasıl yapılacağı konusunda bir önerisi olan var mı?


soruyu anladığımdan emin değilim ama docs.pgrouting.org/2.0/en/src/tsp/doc/index.html#pgr-tsp Satış Personeli Seyahat algoritması size yardımcı oluyor mu?
simplexio

1
Teşekkürler. Gerçekten korkmuyorum. Gezgin satıcı, doğrusal bir şekilde a'dan b'ye ve c'ye kadar bir yolculuk yapar. Ne istediğim her noktayı verimli bir şekilde birbirine bağlayan minimum ağdır, böylece herhangi bir nokta kaybolmak için gereksiz yollar olmadığı bilgisinde başka bir noktaya bir yolculuğa başlayabilir. Diğer platformlarda bu genellikle Minimum Yayılan Ağaç işlevi, Steiner Ağacı ( en.wikipedia.org/wiki/Steiner_tree_problem ) veya benzeri ile yapılır. İsterseniz, TSP lojistik şirketi için harikadır, ancak kullanacakları yolları planlamak istiyorum.
Adrian

Yanıtlar:


2

Bu cevap tam değil veya test edilmedi, ancak böyle bir şey deneyin:

sorulara göre / 39210 :

with index_query as (
SELECT
        ,ST_Distance(i.geom, i.b_geom) AS dist
        ,ST_MakeLine(i.geom, i.b_geom) as geom
FROM(
SELECT
        ,a.geom
        ,b.geom AS b_geom
        ,rank() OVER (PARTITION BY a.id ORDER BY ST_Distance(a.centroid_geom, b.the_geom)) AS pos
FROM points a, points b 
WHERE a.id <> b.id) i
WHERE pos = 1
) select ST_Union(geom) from index_query;

bunun çok verimli olmadığını düşünüyorum.


Bunu gerçekten takdir ediyorum - teşekkür ederim. Bu bana hiç düşünmediğim yeni açıları verdi. Bu kod bir nokta tablosundan en yakın bağlantısız komşuları bulacaktır. Eklediğim karmaşıklık benim durumumda noktaları linestrings bir ağ boyunca bağlı olmasıdır ama yönlendirilmemiş bir nokta sorgusu önemli ölçüde daha yavaş olsa da ben ST_Distance sorgusu bir pgRouting yol mesafesi ile değiştirebilir miyim merak ediyorum.
Adrian

2

@Adrian, sayfalama sonuçlarına gerçekten aşina değilim, ancak belgeler çok ayrıntılı. Cevabım, SQL'de çok yetersiz olan ancak [muhtemelen] sonuçları üreten iki aşamalı bir işleve dayanmaktadır. Bu [test edilmemiş] çözüm, en iyi başlangıç ​​noktası olan optimizasyonu YAPMAZ, ancak tüm rota ağını yalnızca tüm durakları birbirine bağlayan kenarlara indirgeyecek, daha sonra tüm duraklara verimli bir şekilde yönlendirecektir.

Adım 1 (tüm durakları birbirine bağlayan bir yol ağı alt kümesinin alt seçimi) Bu, (maliyeti <> -1 olduğunda) tüm durur.

SELECT id1 as path, st_astext(st_linemerge(st_union(b.the_geom))) as the_geom
FROM pgr_kdijkstraPath(
SELECT id, source, target, cost FROM edge_table’,
min(all_your_stop_ids), [array_of_all_your_stop_ids], false, false
) a,
edge_table b
WHERE a.id3=b.id
GROUP by id1
ORDER by id1

Burada sorun, gerçekten soruda açıklanmadığı gibi stop tablonuzdan bir dizi montajı için sözdizimidir. Ancak, SQL sözdiziminin bu diziyi bir araya getirebileceğini ve minimum id durağının kalan hedef duraklara giden tüm K yolları için başlangıç ​​noktası olması gerektiğini varsayalım.

Adım 2 (tüm durakları birbirine bağlayan yukarıdaki alt küme yol ağı yollarına dayanan minimum yolların son seçimi) Bu aslında başladığınız şeydir, ancak yol ağınızı id1 (yol) üzerindeki ilk sonuca eşit olarak eklemenizi öneririm. böylece son Field-Warshal yolunda sadece yolların alt kümesi kullanılır :

SELECT seq, id1 AS node, id2 AS edge, cost, the_geom
FROM   pgr_apspWarshall('SELECT R.gid AS id, 
                                R.source, 
                                R.target, 
                                st_length(R.the_geom) AS cost 
             FROM   road_network AS R JOIN
                   (SELECT id1 as path
                     FROM pgr_kdijkstraPath(
                            ’SELECT id, source, target, cost FROM edge_table’,
                            min(all_your_stop_ids), 
                            [array_of_all_your_stop_ids], false, false
                           ) a,
                     edge_table b
                    WHERE a.id3=b.id
                    GROUP by id1
                    ORDER by id1
                        ',
                        false, false
                  ) AS  Just_K_Paths
         on R.id1 = just_K_paths.id1',       /* this join reduces R down to K paths */
         false, false
        ) AS tree
  JOIN   road_network As roads
  ON     tree.id2 = roads.gid

Yani, özet olarak ... iç k_dijkstra_path yönlendirme sorgusu, toplam yol ağını yalnızca tüm duraklarınızı bağlayan yollara indirir, ardından dış fField_Warshal yönlendirme, yol optimizasyonu sorgusunu çözmek için yalnızca bu kenar kimliklerini kullanır .... belki.


Teşekkür ederim - bu çok yararlı ve ilk yeni ipucum. Şimdi bakıyorum. Ben sadece minimum stop id ve dizi oluşturmak için nasıl çalışıyorum. Gerekli kimlikleri içeren bir tablo var ama 'SELECT min (id) FROM node_table' ve 'SELECT ARRAY [id] FROM node_table' kodunuza eklendiğinde sözdizimi hataları üretiyor ancak serbest kod olarak çalışıyorum (benim zayıf anlayışım emin)
Adrian
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.