Wie erstelle ich Spinnendiagramme (Hublinien) in PostGIS?

8

Ich bin ziemlich neu in PostGIS, aber ich habe viel gelesen. Eine Sache, nach der ich gesucht habe, ist eine Funktion, mit der Benutzer in PostGIS ein "Spinnendiagramm" (auch "Wunschlinien" oder "Hublinien" genannt) erstellen können.

Zeichnen Sie beispielsweise Linien von einem Lebensmittelgeschäft (Punkt) zu allen geokodierten Kundenadressen (Punkt) dieses Lebensmittelgeschäfts. Stellen Sie sich natürlich vor, es gäbe Hunderte von Geschäften und Tausende von Kunden. Ich würde mir vorstellen, dass jedes Geschäft eine eindeutige ID hat, die jeder Kundenpunkt in ein Feld eingebettet hätte, damit die Software die Herkunft-Ziel-Verbindung kennt.

Gibt es eine einfache ST_-Funktion, die diese Aufgabe erfüllt, oder müssen mehrere Abfragen kombiniert werden, um die Aufgabe auszuführen?

RyanKDalton
quelle

Antworten:

9

Angenommen, Ihr Datenbankschema sieht folgendermaßen aus:

table customer:                     table shops:
customer_id | shop_id | the_geom    shop_id | the_geom
--------------------------------    ------------------
       1000 |     100 |    ...          100 |    ...
       1001 |     100 |    ...          101 |    ...
       1002 |     101 |    ...

Die folgende Anweisung sollte ein "Spinnendiagramm" für Shop 100 erstellen:

SELECT c.customer_id, c.shop_id, ST_MakeLine(c.the_geom,s.the_geom)
FROM customer as c JOIN shops as s
     ON c.shop_id = s.shop_id
WHERE shop_id = 100

Doc: http://postgis.net/docs/ST_MakeLine.html

Unterdunkel
quelle
Dieser Code hat beim ersten Mal perfekt funktioniert. Das einzige, was ich entfernt habe, war die WHERE-Anweisung, da ich Linien von allen Kunden zu allen Geschäften erstellen wollte. Ausgezeichnet!
RyanKDalton
9

Die Frage ist mehr oder weniger beantwortet. Ich möchte nur ein paar Kommentare hinzufügen, um auf die Flexibilität und Leistungsfähigkeit solcher Dinge mit räumlichem SQL hinzuweisen

Während ich die Frage lese, kann sie in zwei Fragen unterteilt werden. Eine GIS-Frage und eine SQL-Frage zum Kombinieren von Zeilen in verschiedenen Tabellen.

Der GIS-Teil kann, wie bereits erwähnt, am besten mit ST_MakeLine gelöst werden, wenn Sie zwei Punkte mit Ihrer Leitung verbinden möchten. Wenn es Linien oder Polygone gewesen wären, könnten Sie stattdessen ST_Shortestline verwenden, um eine Linie aus den Geometrien zwischen ihren nächsten Punkten zu erhalten. Das funktioniert sowohl mit Punkten als auch mit Linien und Polygonen.

Der andere Teil befasst sich mit der Verbindung des richtigen Geschäftspunkts mit dem richtigen Kundenpunkt.

Das ist eine grundlegende Datenbankfrage. Wenn Sie das verstehen, wird die Verwendung von PostGIS viel mehr Freude bereiten.

Die einfachste Situation ist ein Geschäft mit vielen Kunden. Dann brauchen Sie nur noch einen Kundentisch und Ihren Laden und es würde ungefähr so ​​aussehen:

Select ST_Makeline(customers.the_geom, yourPoint) from custmers;

Wenn Sie Ihr einziges Geschäft in einer Tabelle haben, würde es so aussehen:

Select ST_Makeline(customers.the_geom, stores.the_geom) from custmers, stores;

Wenn jedoch viele Geschäfte vorhanden sind und jeder Kunde nur ein Geschäft nutzt, erhalten Sie eine Lösung, die wie die anderen Antworten hier aussieht, zum Beispiel:

Select ST_Makeline(customers.the_geom, stores.the_geom) 
 from custmers, stores
   where customers.storeid = stores.id;

PostgreSQL behandelt diese Abfrage wie folgt:

    Select ST_Makeline(customers.the_geom, stores.the_geom) 
     from custmers inner join stores 
      on customers.storeid = stores.id;

Aber in der realen Welt werden Sie wahrscheinlich in die Situation geraten, dass die meisten Kunden viele Geschäfte nutzen. In früheren Beispielen hatten wir die Beziehung eines Geschäfts zu vielen Kunden, jetzt haben wir eine Situation von vielen zu vielen. Viele Kunden nutzen viele Geschäfte.

Dann gibt es eine schlechte Lösung, die Sie manchmal sehen. Die Leute fügen eine neue Kundenzeile für jedes Geschäft hinzu, das er verwendet. Das wird viele Probleme verursachen, wenn Sie zum Beispiel seine Adresse ändern möchten, müssen Sie dies an vielen Stellen tun. Die korrektere Datenbank besteht darin, eine "Verknüpfungstabelle" zu erstellen. Ich weiß nicht, ob das das richtige Wort auf Englisch ist, aber trotzdem. Dies ist eine Tabelle, die alle spezifischen Daten für die Kundenbeziehung zu jedem von ihm verwendeten Geschäft enthält. Dann haben Sie drei Tabellen. Eine mit Geschäften und allen Attributen, die zum Geschäft gehören, wie wenn es geöffnet ist, und der Telefonnummer, um Kontakt aufzunehmen. Dann haben Sie die Kundentabelle vielleicht mit Adresse und Telefonnummer zum Kunden. Dann haben Sie diese "Link-Tabelle", die eine ID für das Geschäft enthalten sollte, Die ID für den Kunden und möglicherweise zusätzliche Informationen wie die Häufigkeit des Besuchs des jeweiligen Geschäfts oder die Entfernung zum Geschäft oder die von Ihnen erstellte Linie (Entfernung und Linie lassen sich jedoch besser im laufenden Betrieb erstellen, wenn Sie sie benötigen). Dann würde Ihre Abfrage mit dieser neuen Tabelle ungefähr so ​​aussehen:

Select ST_Makeline(customers.the_geom, stores.the_geom) 
  from customers inner join  
     c_s_link_table on customers.id = c_s_link_table.customerid 
     inner join stores 
     on c_s_link_table.storeid = stores.id;

Dann haben Sie die volle Flexibilität. Nehmen wir zum Beispiel an, Sie fügen Ihrem Linktable hinzu, wie oft der Kunde diesen Shop im Monat besucht. Dann können Sie eine Abfrage wie folgt schreiben:

Select ST_Makeline(customers.the_geom, stores.the_geom), 
c_s_link_table.visits_per_month from
 customers inner join c_s_link_table on customers.id = c_s_link_table.customerid 
  inner join stores on c_s_link_table.storeid = stores.id;

Dann können Sie dieses Attribut, Visits_per_month, verwenden, um die Dicke Ihrer Linien auf der Karte zu definieren und zu veranschaulichen, wie viele Besuche jedes Geschäft erhält.

Nicklas Avén
quelle
4

Eine Möglichkeit, das Spinnen-Digram in PostGIS zu erstellen, ist die Verwendung der Funktion ST_MakeLine . Siehe Beispiel unten:

SELECT ST_MakeLine(a.the_geom, b.the_geom), a.id as customer_id, a.store_id 
FROM customers a, stores b WHERE a.store_id = b.id

Taudorf
quelle