PostGIS: Weisen Sie die ID des Punkts in Layer A dem nächstgelegenen Punkt in Layer B zu

15

Dies hätte ein offensichtlicher Vorläufer (den ich nicht gestellt habe) meiner anderen Frage sein sollen: Wie erstelle ich Spinnendiagramme (Hub-Linien) in PostGIS?

Wenn ich die Beziehung zwischen einem Punkt in Schicht A (Geschäfte) und einem Punkt in Schicht B (Kunden) nicht kenne, möchte ich allgemein sagen, dass "Kunde 1 vom nächstgelegenen Geschäft bedient wird". Mir ist zwar klar, dass diese Tatsache möglicherweise nicht zutrifft, aber es kann ein anständiger Ersatz sein.

Was ist die effizienteste Methode, um mit PostGIS jedem Punkt in Schicht B (Kunden) die ID des nächstgelegenen Punkts in Schicht A (Filialen) zuzuweisen. Die Ausgabe, die ich suche, ist etwas wie unten.

Customer | Store
    1    |   A
    2    |   A
    3    |   B
    4    |   C
RyanKDalton-OffTheGridMaps
quelle

Antworten:

6

gleichfalls:

Wählen Sie A.ID als CUST_ID aus (wählen Sie B.ID aus B order by st_distance (A.geom, B.geom) limit 1) als STORE_ID aus A aus

eprand
quelle
Dies war der beste Weg, um die Aufgabe zu erfüllen. In meinem Hinweis unten finden Sie den tatsächlichen Code, den ich verwendet habe.
RyanKDalton-OffTheGridMaps
8

Wenn Sie viel mehr Kunden als Geschäfte haben, ist es möglicherweise effizienter, eine Ebene mit Voronoi-Polygonen für die Geschäfte zu erstellen und dann eine räumliche Verknüpfung von Kunden mit den Geschäftspolygonen durchzuführen.

Kirk Kuykendall
quelle
1
Ich mag diesen Ansatz!
underdark
Welcher Ansatz wäre am einfachsten, um voronoi polys zu erstellen? Gibt es andere Optionen, die hier vermerkt sind: bostongis.com/… bostongis.com/…
RyanKDalton-OffTheGridMaps
Ich denke, das Delaunay-Triangulations- und Dirichlet-Paket im zweiten Tutorial wäre angemessen, nicht sicher, ob es das einfachste ist.
Kirk Kuykendall
5

Von http://www.bostongis.com/?content_name=postgis_nearest_neighbor :

Wenn Sie für alle Datensätze in einer Tabelle den nächsten Nachbarn ermitteln müssen, für jeden jedoch nur den ersten nächsten Nachbarn, können Sie die für PostgreSQL typische DISTINCT ON-Syntax verwenden. Welches würde ungefähr so ​​aussehen:

SELECT DISTINCT ON(g1.gid)  g1.gid As gref_gid, 
       g1.description As gref_description, 
       g2.gid As gnn_gid, 
       g2.description As gnn_description  
FROM sometable As g1, sometable As g2   
WHERE g1.gid <> g2.gid 
      AND ST_DWithin(g1.the_geom, g2.the_geom, 300)   
ORDER BY g1.gid, ST_Distance(g1.the_geom,g2.the_geom) 

Damit werden Mindestabstände von bis zu 300 Einheiten erreicht. Sie müssen also zuerst Ihre Daten überprüfen und herausfinden, wie groß Ihre Mindestentfernungen werden.

Underdunkel
quelle
3

Vielen Dank für alle Beiträge. Letztendlich habe ich mich für eine Kombination aus eprands und underdarks Vorschlägen entschieden. Der endgültige Code, den ich verwendet habe, war:

CREATE TABLE closest_point as
SELECT DISTINCT ON (A.GID) A.GID AS CUST_ID, 
      (SELECT B.GID FROM "STORES" as B 
       ORDER BY ST_Distance(A.the_geom, B.the_geom) limit 1) as STORE_ID, 
       A.the_geom 
FROM "CUSTOMERS" as A, "STORES" as B;

Ich habe dann ein Voronoi-Diagramm auf der Ebene "Stores" erstellt, um zu bestätigen, dass die Ergebnisse korrekt funktionieren, was natürlich auch der Fall war. Vielen Dank für die großartige Arbeit!

RyanKDalton-OffTheGridMaps
quelle