Geocode — Assimila um endereço como uma string (ou outro endereço normalizado) e gera um conjunto de localizações possíveis que inclui um ponto em NAD 83 long lat, um endereço normalizado para cada um e a avaliação. Quanto menor a avaliação, maior a chance de combinar. Os resultados são separados com menor avaliação em primeiro lugar. Pode passar no resultados máximos, até 10, e restrict_region (padrão NULO)
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)
;
Assimila um endereço como uma string (ou endereço já normalizado) e gera uma série de possíveis localizações que inclui um ponto em NAD 83 long lat, um normalized_address
(addy) para cada e a avaliação. Quanto menor a avaliação, maior a chance de combinar. Os resultados são separados com a menor avaliação em primeiro lugar. Usa os dados (limites, faces, addr) Tiger, uma string confusa PostgreSQL (soundex,levenshtein) linha de interpolação PostGIS para interpolar endereços ao longo dos limites do Tiger. Quanto maior a avaliação, menos o geocoder estará correto. O ponto geocodificado é padronizado para compensar 10 metros da lina central do lado (E/D) que o endereço da rua está localizado.
Melhorias: 2.0.0 para suportar o Tiger 2010, dados estruturados e lógica revisada para melhorar a velocidade, exatidão do geocoding e para compensar ponto da linha central para o lado do endereço que a rua está localizada. O novo parâmetro max_results
é útil para especificar números dos melhores resultados ou apenas retornar o melhor resultado.
Os exemplos abaixo estão em um único processador 3.0 GHZ no Windows 7 com 2GB ram executando PostgreSQL 9.1rc1/PostGIS 2.0 carregados com todos os dados de estado Tiger MA,MN,CA, RI.
Combinações exatas são mais fáceis de computar (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
Mesmo se o zip não tiver passado no geocode pode estimar (demorou cerca de 122-150 ms)
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
Sabe lidar com erros de ortografia e fornece mair de uma possibilidade de solução com avaliações e tomadas maiores (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
Utilizando para fazer um agrupamento geocode de endereços. Mais fácil para configurar max_results=1
. Processa somente aqueles que ainda não foram geocodificados (não possuem avaliação).
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'); -- only update the first 3 addresses (323-704 ms - there are caching and shared memory effects so first geocode you do is always slower) -- -- for large numbers of addresses you don't want to update all at once -- since the whole geocode must commit at once -- For this example we rejoin with LEFT JOIN -- and set to rating to -1 rating if no match -- to ensure we don't regeocode a bad address 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)
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
Normalize_Address, Pprint_Addy, ST_AsText, ST_SnapToGrid, ST_X, ST_Y