Here's a simple PERL geocoder for Google.<br><br>-- $Id: google_geocode.sql 171 2007-01-26 02:35:09Z mark $ --<br><br>DROP TABLE google_api_key;<br><br>CREATE TABLE google_api_key (<br>    key text primary key<br>);<br>
<br>INSERT INTO google_api_key values ('your key here');<br><br>CREATE OR REPLACE FUNCTION geocode(text) returns geometry as $$<br>declare<br>    mykey text;<br>begin<br>    select key into mykey from google_api_key;
<br>    return GeomFromEWKT(geocode_impl($1, mykey));<br>end;<br>$$ language plpgsql;<br><br>CREATE OR REPLACE FUNCTION geocode_impl(text, text) returns text as '<br>   use LWP::Simple;<br>   $csv = get("<a href="http://maps.google.com/maps/geo?output=csv&q=">
http://maps.google.com/maps/geo?output=csv&q=</a>".$_[0]."&key=".$_[1]);<br>   @tokens = split(/,/, $csv);<br>   if ($tokens[0] == "200") {<br>       return "SRID=4326;POINT(" . $tokens[3] . " " . $tokens[2] . ")";
<br>   } else {<br>       return "";<br>   }<br>' LANGUAGE plperlu IMMUTABLE;<br><br>google uses tmerc, so you can call a function like this to get correct SRID for point and use transform<br><br>create or replace function getUTMZoneEPSG(geometry) returns int as $$
<br>declare<br>    i int := 32600;<br>    j numeric;<br>begin<br>    j := abs((-180 - X($1)) / 6);<br>    if j < 0.5 then<br>        j := 1;<br>    end if;<br>    i := i + round(j);<br>    if Y($1) < 0 then<br>        i := i + 30;
<br>    end if;<br>    return i;<br>end;<br>$$ language plpgsql;<br><br><br>