Postgres / Postgis-Cursor

8

Ich habe ein Straßennetz mit StreetName- und Min / Max-Adressbereichen für jedes Segment (dh StreetName = 'Main St', Min = 100, Max = 199). Ich habe auch einzelne Adresspunkte mit ähnlichen Informationen (zB StreetName = 'Main St', HouseNumber = 115).

Ich möchte jedem Adresspunkt, der einen passenden Straßennamen hat und in den Min / Max-Bereich des Straßensegments fällt, die Feature-ID (GID) von Straßensegmenten zuweisen. In ArcGIS würde ich wahrscheinlich einen Suchcursor für die Straßen schreiben, der durch jedes Straßensegment zyklisch aussehen würde, die Werte für gid, name, min und max abrufen und dann eine Abfrageanweisung ausführen, um alle Adresspunkte mit HouseNumbers zu finden, die unter die fallen Berechnen Sie bei gegebenem Segmentbereich (dh wählen Sie AddressPoints mit StreetName = 'Main St' und min> = 100 und max <= 199) die GID des Straßensegments in ein Feld für die ausgewählten Punkte in der Ebene Address Point. Fahren Sie dann fort zum nächsten Straßensegment und wiederholen.

  1. Wie würde ich einen ähnlichen Cursor in postgres / postgis oder schreiben?
  2. Gibt es eine effizientere Möglichkeit, dies zu tun?
RyanKDalton
quelle

Antworten:

8

Soweit ich Ihre Frage verstehe, sind keine Cursor erforderlich. Dies ist eine sehr häufige und einfache Aufgabe, die mit einfachem SQL zu tun hat. Wenn wir Ihre beiden Tabellen als Straßensegmente und Adresspunkte mit Feldern wie diesen bezeichnen:

Roadsegments
gid
the_geom
min_address
max_address

Adresspunkte
Hausname
Hausnummer

Anschließend können Sie zunächst die Spalte für die Straßen-ID in der Adresspunkttabelle wie folgt erstellen:

ALTER TABLE adresspoints ADD COLUMN roadid integer;

Dann können Sie dieses Feld folgendermaßen aktualisieren:

UPDATE adresspoints SET roadid = roadsegmants.gid FROM 
roadsegments WHERE roadsegments.streetname=adresspoints.streetnames
AND addresspoints.housenumber >= roadsegments.min_address
AND addresspoints.housenumber <= roadsegments.max_address;

Wenn es sich um sehr große Tabellen handelt, ist es möglicherweise effizienter, eine Adresspunkttabelle wie folgt neu zu erstellen:

CREATE TABLE new_addresspoints as
SELECT a.*, b.gid as roadid  
FROM addresspoints a inner join roadsegments b
on a.streetname=b.streetnames
AND a.housenumber >= b.min_address
AND a.housenumber <= b.max_addres;

Damit die Dinge schnell laufen, sollten Sie auch in den Tabellen und in min_address, max_address und Housenumber Indizes für den Straßennamen einfügen.

HTH
Nicklas

Nicklas Avén
quelle