#!/usr/bin/perl -l use strict; use warnings; use LWP::Simple; use URI::Escape; my %geocache; # so we don't look up a simple city+state if we already have it $| = 1; # flush on print so we can tail my $COORDS = 0; my $CITY = 4; my $STATE = 5; my $LOC_LABEL = 6; my $LOC_ADDR_JUNK = 7; my $LOC_ADDR_LAST = 8; my $LOC_CSZ = 9; my $key = $ENV{GOOGLE_KEY}; die 'Set $ENV{GOOGLE_KEY} with your Google API Key.' unless $key; # take care of hte header line my $header = <>; chomp $header; print "$header|Coords From"; while (<>) { chomp; my @data = split /\|/, $_, -1;; my $coords_from; # try the full info of the Location first if ($data[$COORDS] eq "0,0") { $data[$COORDS] = get_coords("$data[$LOC_LABEL] $data[$LOC_ADDR_JUNK] $data[$LOC_ADDR_LAST] $data[$LOC_CSZ]"); $coords_from = 'fulladdr'; } # next try the full Location address w/ City, State, Zip if ($data[$COORDS] eq "0,0") { $data[$COORDS] = get_coords("$data[$LOC_ADDR_JUNK] $data[$LOC_ADDR_LAST] $data[$LOC_CSZ]"); $coords_from = 'addr'; } # next try the last part of Location Addr w/ City, State, Zip if ($data[$COORDS] eq "0,0") { $data[$COORDS] = get_coords("$data[$LOC_ADDR_LAST] $data[$LOC_CSZ]"); $coords_from = 'addrlast'; } # next try the Location Label w/ City, State, Zip if ($data[$COORDS] eq "0,0") { $data[$COORDS] = get_coords("$data[$LOC_LABEL] $data[$LOC_CSZ]"); $coords_from = 'label+csz'; } # next try just the Location City, State, Zip if ($data[$COORDS] eq "0,0") { $data[$COORDS] = get_coords($data[$LOC_CSZ]); $coords_from = 'csz'; } # last ditch: program City, State if ($data[$COORDS] eq "0,0") { $data[$COORDS] = get_coords("$data[$CITY], $data[$STATE]"); $coords_from = 'cs'; } print join '|', @data, $coords_from } sub get_coords { my $where = shift; $where =~ s/\s+/ /g; return "0,0" if $where =~ /^\s*$/; if (exists $geocache{$where}) { return $geocache{$where}; } sleep 1; my $url = 'http://maps.google.com/maps/geo?key='. $key .'&output=csv&gl=us&q=' . uri_escape($where); my @rows = split /\n/, get($url); if (1 < scalar @rows) { warn "$where == $_" for @rows; } my @data = split /\,/, $rows[0]; $geocache{$where} = "$data[2],$data[3]"; return $geocache{$where}; }