PostGIS를 사용하여 모든 포인트를 연결하는 가장 작은 네트워크를 계산하는 방법은 무엇입니까?


13

두 개의 테이블을 생성하는 postgis 스크립트 세트가 있습니다. 하나는 점 세트 중 하나이고 두 번째는 그 주위를 둘러싸는 도로 세트입니다. 모든 데이터는 동일한 투영에 있으며 두 출력은 postgres 2.1이있는 postgres 9.2 테이블에 저장됩니다

도로 네트워크의 그라우팅 토폴로지가 생성되었으며 포인트 테이블에 가장 가까운 도로 구간이 포함 된 열이 있습니다.

그런 다음 최소 스패닝 트리와 같은 것을 사용하여 모든 지점을 연결하는 가장 작은 네트워크를 나타내는 도로 네트워크의 하위 집합을 생성하고 싶습니다. 도로 네트워크는 방향이 정해져 있지 않으며 비용은 단순히 경로 길이입니다.

v.net 모듈 제품군을 사용하여 QGIS / Grass에서이 작업을 수행 할 수 있지만 이상적으로이 최종 단계를 SQL로 유지하고 싶습니다.

나는 새로운 apspWarshall postgis 기능을 살펴 보았지만 전체 네트워크가 아닌 포인트를 연결하는 데 에너지를 집중시키는 방법에 대해 상실했습니다.

이것은 이것을 해결하기 위해 프레임 워크를 만들려고 모은 짧은 스크립트이지만 가장자리의 하위 집합으로 시작하기 위해 함수를 집중시킬 수있는 곳을 볼 수는 없습니다.

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

단일 경로 최단 경로 문제에서 함수는 시작과 끝을 요구하지만 모든 점에서 문제는 아닙니다. 마찬가지로 Grass에서도 v.net.spanningtree 및 v.net.steiner는 결합 된 네트워크로 작동 할 점과 선 집합을 기대합니다.

PostGIS 에서이 작업을 수행하는 방법에 대한 제안이 있습니까?


나는 질문을 이해하지만 확실하지 않지만 docs.pgrouting.org/2.0/en/src/tsp/doc/index.html#pgr-tsp 여행 영업 담당자 알고리즘이 도움이됩니까?
simplexio

1
감사. 정말 두려워하지 않습니다. 출장 세일즈맨은 a에서 b 로의 여행 등을 선형으로 가정합니다. 내가 원하는 것은 모든 지점을 효율적으로 연결하여 모든 지점을 효율적으로 연결하는 최소한의 네트워크로, 어떤 지점이든 잃어 버릴 경로가 없다는 지식의 다른 지점으로 여행을 시작할 수 있습니다. 다른 플랫폼에서는 보통 최소 스패닝 트리 기능인 Steiner Tree ( en.wikipedia.org/wiki/Steiner_tree_problem ) 또는 이와 유사한 기능을 사용하여 수행됩니다 . 원하는 경우 TSP는 물류 회사에 적합하지만 사용할 도로를 계획하고 싶습니다.
Adrian

답변:


2

이 답변은 완전하거나 테스트되지 않았지만 다음과 같이 시도하십시오.

질문 / 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;

나는 이것이 매우 효율적이지 않다고 생각한다.


정말 감사합니다-감사합니다. 이것은 내가 생각하지 못했던 탐구 할 새로운 각도를 내게주었습니다. 이 코드는 포인트 테이블에서 가장 가까운 연결되지 않은 이웃을 찾습니다. 내가 추가 한 복잡한 점은 내 경우의 점이 선 문자열 네트워크를 통해 연결되어 있지만 ST_Distance 쿼리를 pgRouting 도로 거리로 바꿀 수 있는지 궁금합니다. 라우팅되지 않은 포인트 쿼리보다 상당히 느릴 것입니다.
Adrian

2

@Adrian, 나는 그라우팅 결과에 익숙하지 않지만 문서는 매우 상세합니다. 내 대답은 2 단계 함수를 기반으로하며 SQL에서는 매우 비효율적이지만 결과를 생성합니다. 이 [권장되지 않은] 솔루션은 최상의 시작 지점을 최적화하지는 않지만 전체 경로 네트워크를 모든 정류장을 연결하는 가장자리로만 줄인 다음 모든 정류장으로 효율적으로 라우팅합니다.

1 단계 (모든 정류장을 연결하는 도로 네트워크 하위 집합의 하위 선택) 다중 목적지 (K Dijkstr 경로) 라우팅 기능을 사용하여 (비용 <> -1 인 경우) 실제로 모든 경로를 연결하는 경로 모음을 반환합니다. 중지합니다.

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

내가 가진 문제는 실제로 질문에 설명되지 않았으므로 중지 테이블에서 배열을 조립하는 구문입니다. 그러나 SQL 구문이 해당 배열을 어셈블 할 수 있고 최소 id 중지가 나머지 대상 중지에 대한 모든 K 경로의 시작점이되어야한다고 가정 해 봅시다.

2 단계 (모든 정류장을 연결하는 위의 하위 도로 네트워크 경로를 기반으로 최소 경로의 최종 선택) 이것은 본질적으로 시작한 것이지만 도로 네트워크를 id1 (경로)의 초기 결과와 동일하게 결합 하는 것이 좋습니다 최종 Field-Warshal 라우팅에서 도로의 하위 세트 만 사용되도록합니다 .

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

요약하면, 내부 k_dijkstra_path 라우팅 쿼리는 전체 도로 네트워크를 모든 정류장을 연결하는 경로로만 줄인 다음 외부 fField_Warshal 라우팅은 해당 에지 ID 만 사용하여 경로 최적화 쿼리를 해결합니다.


감사합니다-이것은 매우 도움이되고 첫 번째 새 리드입니다. 지금보고 있습니다. 최소 중지 ID와 배열을 생성하는 방법을 찾으려고합니다. 필요한 ID 테이블이 있지만 'SELECT min (id) FROM node_table'및 'SELECT ARRAY [id] FROM node_table'은 코드에 삽입하면 구문 오류가 발생하지만 독립 코드로 작동합니다 (잘 모르겠습니다. ) 확인
아드리안
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.