Name

Geocode — Nimmt eine Adresse als Zeichenkette (oder eine bereits standardisierte Adresse) entgegen und gibt die möglichen Punktlagen zurück. Die Ausgabe beinhaltet eine Punktgeometrie in NAD 83 Länge/Breite, eine standardisierte Adresse und eine Rangfolge (Rating) für jede Punktlage. Umso niedriger die Rangfolge ist, um so wahrscheinlicher ist die Übereinstimmung. Die Ergebnisse werden mit aufsteigender Rangfolge sortiert - dar niedrigste Rang zuerst. Optional kann die maximale Anzahl der Ergebnisse angegeben werden (Standardeinstellung ist 10) und der Bereich mit restrict_region beschränkt werden (Standardeinstellung ist NULL)

Synopsis

setof record geocode( varchar address, integer max_results=10, geometry restrict_region=NULL, norm_addy OUT addy, geometry OUT geomout, integer OUT rating);

setof record geocode( norm_addy in_addy, integer max_results=10, geometry restrict_region=NULL, norm_addy OUT addy, geometry OUT geomout, integer OUT rating);

Beschreibung

Nimmt eine Adresse als Zeichenkette (oder eine bereits standardisierte Adresse) entgegen und gibt die möglichen Punktlagen zurück. Die Ausgabe beinhaltet eine Punktgeometrie in NAD 83 Länge/Breite, eine standardisierte Adresse normalized_address (addy) und eine Rangfolge (Rating) für jede Punktlage. Umso niedriger die Rangfolge ist, um so wahrscheinlicher ist die Übereinstimmung. Die Ergebnisse werden nach dem Rating aufsteigend sortiert - das niedrigste Rating zuerst. Verwendet Tiger Daten (Kanten, Maschen, Adressen), Fuzzy String Matching (soundex, levenshtein) von PostgreSQL und PostGIS Funktionen zur Interpolation entlang von Linien, um die Adressen entlang der Kanten von TIGER zu interpolieren. Umso höher das Rating, umso unwahrscheinlicher ist es, dass die Geokodierung richtig liegt. Der geokodierte Punkt wird dort, wo sich die Adresse befindet, standardmäßig um 10 Meter von der Mittellinie auf die Seite (L/R) versetzt. Optional kann die maximale Anzahl der Ergebnisse angegeben werden (Standardeinstellung ist 10) und der Bereich mit restrict_region beschränkt werden (Standardeinstellung ist NULL)

Erweiterung: 2.0.0 Unterstützung von strukturierten Daten von TIGER 2010. Weiters wurde die Logik überarbeitet, um die Rechengeschwindigkeit und die Genauigkeit der Geokodierung zu erhöhen, und den Versatz von der Mittellinie auf die Straßenseite zu ermöglichen. Der neue Parameter max_results kann verwendet werden, um die Anzahl der besten Ergebnisse zu beschränken oder um nur das beste Ergebnis zu erhalten.

Beispiele: Grundlagen

Die Zeitangaben für die unteren Beispiele beziehen sich auf einen 3.0 GHZ Prozessor mit Windows 7, 2GB RAM, PostgreSQL 9.1rc1/PostGIS 2.0 und den geladenen TIGER-Daten der Staaten MA, MN, CA und RI.

Genaue Übereinstimmungen haben eine kürzere Rechenzeit (61ms)

SELECT g.rating, ST_X(g.geomout) As lon, ST_Y(g.geomout) As lat,
    (addy).address As stno, (addy).streetname As street,
    (addy).streettypeabbrev As styp, (addy).location As city, (addy).stateabbrev As st,(addy).zip
    FROM geocode('75 State Street, Boston MA 02109', 1) As g;
 rating |        lon        |      lat       | stno | street | styp |  city  | st |  zip
--------+-------------------+----------------+------+--------+------+--------+----+-------
      0 | -71.0557505845646 | 42.35897920691 |   75 | State  | St   | Boston | MA | 02109

Sogar wenn der Zip-Code nicht übergeben wird, kann ihn der Geokodierer erraten (dauerte ca. 122-150ms)

SELECT g.rating, ST_AsText(ST_SnapToGrid(g.geomout,0.00001)) As wktlonlat,
    (addy).address As stno, (addy).streetname As street,
    (addy).streettypeabbrev As styp, (addy).location As city, (addy).stateabbrev As st,(addy).zip
    FROM geocode('226 Hanover Street, Boston, MA',1) As g;
 rating |         wktlonlat         | stno | street  | styp |  city  | st |  zip
--------+---------------------------+------+---------+------+--------+----+-------
      1 | POINT(-71.05528 42.36316) |  226 | Hanover | St   | Boston | MA | 02113

Kann Rechtschreibfehler behandeln und liefert mehre mögliche Lösungen mit Einstufungen, hat allerdings eine längere Laufzeit (500ms).

SELECT g.rating, ST_AsText(ST_SnapToGrid(g.geomout,0.00001)) As wktlonlat,
    (addy).address As stno, (addy).streetname As street,
    (addy).streettypeabbrev As styp, (addy).location As city, (addy).stateabbrev As st,(addy).zip
    FROM geocode('31 - 37 Stewart Street, Boston, MA 02116',1) As g;
 rating |         wktlonlat         | stno | street | styp |  city  | st |  zip
--------+---------------------------+------+--------+------+--------+----+-------
     70 | POINT(-71.06466 42.35114) |   31 | Stuart | St   | Boston | MA | 02116
    

Verwendet um die Adresskodierung in enier Stapelverarbeitung auszuführen. Am einfachsten ist es max_results=1 zu setzen. Berechnet nur die Fälle, die noch nicht geokodiert wurden (keine Einstufung haben).

CREATE TABLE addresses_to_geocode(addid serial PRIMARY KEY, address text,
        lon numeric, lat numeric, new_address text, rating integer);

INSERT INTO addresses_to_geocode(address)
VALUES ('529 Main Street, Boston MA, 02129'),
 ('77 Massachusetts Avenue, Cambridge, MA 02139'),
 ('25 Wizard of Oz, Walaford, KS 99912323'),
 ('26 Capen Street, Medford, MA'),
 ('124 Mount Auburn St, Cambridge, Massachusetts 02138'),
 ('950 Main Street, Worcester, MA 01610');

-- aktualisiert nur die ersten 3 Adressen (323-704 ms - Zwischenspeicherung (Caching) und gemeinsamer Arbeitsspeicher (Shared Memory) haben Auswirkungen, sodass die erste Geokodierung immer langsamer abläuft --
-- bei einer großen Anzahl von Adressen sollten nicht alle auf einmal aktualisiert werden,
-- da die gesamte Geokodierung in einem Schritt ausgeführt werden muss
-- Bei diesem Beispiel erfolt ein erneuter JOIN über einen LEFT JOIN
-- und die Einstufung (rating) wird auf -1 gesetzt, wenn es keine Übereinstimmung gibt;
-- damit wird sichergestellt, dass eine falsche Adresse nicht erneut geokodiert wird
UPDATE addresses_to_geocode
  SET  (rating, new_address, lon, lat)
    = ( COALESCE(g.rating,-1), pprint_addy(g.addy),
       ST_X(g.geomout)::numeric(8,5), ST_Y(g.geomout)::numeric(8,5) )
FROM (SELECT addid, address
    FROM addresses_to_geocode
    WHERE rating IS NULL ORDER BY addid LIMIT 3) As a
    LEFT JOIN LATERAL geocode(a.address,1) As g ON true
WHERE a.addid = addresses_to_geocode.addid;

result
-----
Query returned successfully: 3 rows affected, 480 ms execution time.

SELECT * FROM addresses_to_geocode WHERE rating is not null;

 addid |                   address                    |    lon    |   lat    |                new_address                | rating
-------+----------------------------------------------+-----------+----------+-------------------------------------------+--------
     1 | 529 Main Street, Boston MA, 02129            | -71.07177 | 42.38357 | 529 Main St, Boston, MA 02129             |      0
     2 | 77 Massachusetts Avenue, Cambridge, MA 02139 | -71.09396 | 42.35961 | 77 Massachusetts Ave, Cambridge, MA 02139 |      0
     3 | 25 Wizard of Oz, Walaford, KS 99912323       | -97.92913 | 38.12717 | Willowbrook, KS 67502                     |    108
(3 rows)

Beispiele: Verwendung eines Geometrie-Filters

SELECT g.rating, ST_AsText(ST_SnapToGrid(g.geomout,0.00001)) As wktlonlat,
    (addy).address As stno, (addy).streetname As street,
    (addy).streettypeabbrev As styp,
    (addy).location As city, (addy).stateabbrev As st,(addy).zip
  FROM geocode('100 Federal Street, MA',
        3,
        (SELECT ST_Union(the_geom)
            FROM place WHERE statefp = '25' AND name = 'Lynn')::geometry
        ) As g;

 rating |         wktlonlat         | stno | street  | styp | city | st |  zip
--------+---------------------------+------+---------+------+------+----+-------
      7 | POINT(-70.96796 42.4659)  |  100 | Federal | St   | Lynn | MA | 01905
     16 | POINT(-70.96786 42.46853) | NULL | Federal | St   | Lynn | MA | 01905
(2 rows)

Time: 622.939 ms
          

Siehe auch

Normalize_Address, Pprint_Addy, ST_AsText, ST_SnapToGrid, ST_X, ST_Y