Home ]
Archives ]
Flickr ] (RSS)
Twitter ] (RSS)
Dopplr ] (RSS)
Friendfeed ] (RSS)
Bio ]
Contact ]

::Del.icio.us (all/rss)::



::Search::

Syndicate:

RSS   0.91  1.0  2.0
Atom 1.0

:: Free geocoding thanks to Google ::

Friday, April 15, 2005

I wrote a Perl script to query Google Maps with an address and get back a latitude and longitude. My coworker Jesse helped with the regex's, because I'm a dilettante.

Usage: ./go.pl "address"

#!/usr/bin/perl

use strict;

my $str = $ARGV[0];
$str = &escape($str);
my $var = `GET 'http://maps.google.com/maps?q=$str'`;
$var=~s/.*(lat=\"-?\d+\.\d+\" lng=\"-?\d+\.\d+").*/$1/gs;
print $var;
print "\n";

sub escape {
my($toencode) = @_;
$toencode=~s/([^a-zA-Z0-9_\-. ])/uc sprintf("%%%02x",ord($1))/eg;
$toencode =~ tr/ /+/; # spaces become pluses
return $toencode;
}

Posted by morland @ 04:04 PM

:: Comments ::


cool idea for a script, but when i run it on activestate perl on windows 2000 i get the following error


An Error Occurred

An Error Occurred
400 URL must be absolute

example usage
geocode.pl "new york"

Posted by: steeev on May 12, 2005 02:38 PM


Hmm... I'm not sure what's going on there. I tried it with RedHat Linux and OS X, and it seems to run ok. It looks like you're not generating the URL properly - try hard-coding it as a test, e.g. http://maps.google.com/maps?q=10001 .

Posted by: morland on May 12, 2005 10:31 PM


Morland

What a great script, I've modifyed it to geocode from a Csv file.

Plus the Geocodes are from one of the biggest geocoding
company (NAVTEQ and Tele Atlas).

Thanks

Posted by: Jonathan on May 13, 2005 11:26 AM


replace the line
my $var = `GET 'http://maps.google.com/maps?q=$str'`;
with
my $var = `GET "http://maps.google.com/maps?q=$str"`;
to solve the problem "400 URL must be absolute" under windows OS.

Posted by: John on June 30, 2005 07:30 PM


I've been trying to get this to work with the Google API and JavaScript, and I can't seem to figure it out.

Is it possible to call this script via an html form?

Also, how are you guys calling your script? Is it through some type of command line, or what?

Posted by: Matthew on August 7, 2005 12:26 AM


I'm not sure how well it plays with the new Gmaps API.

Yes, I'm calling it from a linux command line.

Posted by: morland on August 10, 2005 05:50 PM


Here is a script to turn this wonderful code into a soap service:
#!perl -w
use SOAP::Transport::HTTP;
SOAP::Transport::HTTP::CGI
-> dispatch_to('Demo')
-> handle;


package Demo;

sub bye {
my ($class, $str) = @_;


$str=~s/([^a-zA-Z0-9_\-. ])/uc sprintf("%%%02x",ord($1))/eg;
$str =~ tr/ /+/; # spaces become pluses

my $var = `GET "http://maps.google.com/maps?q=$str"`;
$var=~s/.*(lat=\"-?\d+\.\d+\" lng=\"-?\d+\.\d+").*/$1/gs;

if ($var eq qq(lat="23.875000" lng="57.630033")){
$var = "Place not recognized";
}

return $var;
}

And the script below consumes the service and spits out a simple web page when passed a place name with a get:

#!perl -w
use SOAP::Lite;
use CGI qw(:standard escapeHTML);

#my $soap = SOAP::Lite
# -> uri('http://localhost/geocoder')
# -> proxy('http://localhost/GM/hibye.pl');

$in = param('place');


print header(),start_html(param('place'));
print SOAP::Lite
-> uri('http://www.localhost/geocoder')
-> proxy('http://localhost/scripts/hibye.pl')
-> bye($in)
-> result;
print end_html();

Posted by: joe miller on October 25, 2005 02:12 PM


Mike, just totally ran into this at random. never knew I would need geocoding + that I would find a solution here. thank you!

Posted by: Peter on December 20, 2005 08:28 PM


i believe you omitted the final " in your kungfu, master.

Posted by: rektide on February 3, 2006 09:30 AM


erp, omitted the escape on your final ",
brak.
please dont hurt me, master.

Posted by: rektide on February 3, 2006 09:31 AM


just for a laugh, here is my nasty php version:

Posted by: steelninja on February 10, 2006 04:21 AM


hmmm...didn't work that time :D...how about this:

function getHTTP($link,$refer,$to_file)
{
$ch=curl_init();
$fp=@fopen($to_file, "w");
if(!$fp)
return false;
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
curl_setopt($ch, CURLOPT_URL, $link);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_REFERER, $refer);
curl_exec($ch);
if(curl_errno($ch)){
fclose($fp);
if(file_exists($to_file))
unlink($to_file);
return false;
}
else{
curl_close($ch);
fclose($fp);
return true;
}
}

// Main Program
function getLatLong($postcode)
{
$main_link="http://maps.google.co.uk/maps?hl=en&q=".urlencode($postcode)."&btnG=Search&output=html";
$tmp_file="/tmp/temp_index";
if(!getHTTP($main_link,"http://maps.google.co.uk/",$tmp_file))
return "!";
else{
$ret_val="!";
$array_lines=file($tmp_file);
for($i=0; $i if(ereg(".setCenter\\(new GLatLng\\(([+-]?[0-9]*\.?[0-9]+), ([+-]?[0-9]*\.?[0-9]+)\\)", $array_lines{$i}, $regs)){
$ret_val=$regs{1}.":".$regs{2};
}
unlink($tmp_file);
}
return $ret_val;
}

echo getLatLong("N7 0BJ");

Posted by: on February 10, 2006 04:24 AM


Hi Just came accross this site by chance whilst searching. The PHP scropt is just great - I am just working out how to use it properly.

Anyone encountered the problemof having too many points and needing to have them load as the map is moved.

Posted by: Chris on February 22, 2006 06:31 PM


for($i=0; $i if(ereg(".setCenter\\(new GLatLng\\(([+-]?[0-9]*\.?[0-9]+), ([+-]?[0-9]*\.?[0-9]+)\\)", $array_lines{$i}, $regs)){
$ret_val=$regs{1}.":".$regs{2};

My computer is telling me that there is an error in this line, but I cannot see it - Any ideas?

Posted by: Chris on February 22, 2006 07:49 PM


Have you guys seen Yahoo's geocoding api? Its really nice, same source datasets and it works for up to 50,000 addresses per IP per day.

Here's a service that uses the Yahoo Gecoder geocode a tab delimited address file:

http://www.batchgeocode.com/

Posted by: pkh on February 25, 2006 02:14 AM


Hi,

'Fixed' the Php version, I'm no regex man either so I did it my way, could become unreliable in Google change the code but works for now.

// Main Program

.... as before...

function getLatLong($postcode)
{
$main_link="http://maps.google.co.uk/maps?hl=en&q=".urlencode($postcode)."&btnG=Search&output=html";
$tmp_file="/tmp/temp_index";
if(!getHTTP($main_link,"http://maps.google.co.uk/",$tmp_file)) return "!";
else{
$ret_val="!";
$array_lines=file($tmp_file);
foreach ($array_lines as $a){
if ($x = strpos($a,"new GLatLng(")){
$a = substr($a,$x+12);
$a = substr($a,0,strpos($a,")"));
list($lat,$long) = explode(",",$a);
break;
}
}
unlink($tmp_file);
}
return array($lat,$long);
}

list($lat,$long) = getLatLong("N7 0BJ");

Posted by: Steve on April 10, 2006 01:34 PM


Hello,

Is it legal to use this script to retreive UK postcodes for a commercial application. I cant find a single script that isnt flawed by the UK postcode laws.

Cheers

Posted by: bastian on September 4, 2006 06:12 AM


I can't say I know... this was a lunchtime project a year and a half ago.

Posted by: morland on September 8, 2006 01:27 PM



- Post a comment -






















« On the beat | Main | William Barrett Graves »