| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package WWW::MapBlast; | 
| 2 |  |  |  |  |  |  | our $VERSION = 0.02; | 
| 3 |  |  |  |  |  |  | our $DATE = "Mon Jun 25 18:13:00 2001 BST"; | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 1 |  |  | 1 |  | 6293 | use LWP::UserAgent; | 
|  | 1 |  |  |  |  | 51186 |  | 
|  | 1 |  |  |  |  | 35 |  | 
| 6 | 1 |  |  | 1 |  | 12 | use HTTP::Request; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 24 |  | 
| 7 | 1 |  |  | 1 |  | 1005 | use HTML::TokeParser; | 
|  | 1 |  |  |  |  | 12787 |  | 
|  | 1 |  |  |  |  | 30 |  | 
| 8 | 1 |  |  | 1 |  | 8 | use strict; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 23 |  | 
| 9 | 1 |  |  | 1 |  | 4 | use warnings; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 1467 |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | =head1 NAME | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | WWW::MapBlast - latitude & longitude from postal codes. | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | use WWW::MapBlast; | 
| 18 |  |  |  |  |  |  | my ($lat, $lon) = WWW::MapBlast::latlon('United Kingdom','BN3 3AG'); | 
| 19 |  |  |  |  |  |  | __END__; | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | Simply accesses L and | 
| 24 |  |  |  |  |  |  | retrieves latitude and longitude information. | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | Only minimal error checking, so have a look through the source before you use. | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | =cut | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | our %countriesList = ( | 
| 31 |  |  |  |  |  |  | "United States"=>"USA","AFG"=>"Afghanistan","Albania"=>"ALB","Algeria"=>"DZA", | 
| 32 |  |  |  |  |  |  | "American Samoa"=>"ASM","Andorra"=>"AND","Angola"=>"AGO","Anguilla"=>"AIA", | 
| 33 |  |  |  |  |  |  | "Antigua and Barbuda"=>"ATG","Argentina"=>"ARG","Armenia"=>"ARM","Aruba"=>"ABW", | 
| 34 |  |  |  |  |  |  | "Australia"=>"AUS","Austria"=>"AUT","Azerbaijan"=>"AZE","Bahamas"=>"BHS", | 
| 35 |  |  |  |  |  |  | "Bahrain"=>"BHR","Bangladesh"=>"BGD","Barbados"=>"BRB","Belarus"=>"BLR", | 
| 36 |  |  |  |  |  |  | "Belgium"=>"BEL","Belize"=>"BLZ","Benin"=>"BEN","Bermuda"=>"BMU", | 
| 37 |  |  |  |  |  |  | "Bhutan"=>"BTN","Bolivia"=>"BOL","Bosnia and Herzegovina"=>"BIH","Botswana"=>"BWA", | 
| 38 |  |  |  |  |  |  | "Brazil"=>"BRA","British Virgin Islands"=>"VGB","Brunei Darussalam"=>"BRN", | 
| 39 |  |  |  |  |  |  | "Bulgaria"=>"BGR","Burkina Faso"=>"BFA","Burundi"=>"BDI","Cambodia"=>"KHM", | 
| 40 |  |  |  |  |  |  | "Cameroon"=>"CMR","Canada"=>"CAN","Cape Verde"=>"CPV","Cayman Islands"=>"CYM", | 
| 41 |  |  |  |  |  |  | "Central African Republic"=>"CAF","Chad"=>"TCD", | 
| 42 |  |  |  |  |  |  | "Chile"=>"CHL","China"=>"CHN","Colombia"=>"COL","Comoros"=>"COM", | 
| 43 |  |  |  |  |  |  | "Congo"=>"COG","Cook Islands"=>"COK","Costa Rica"=>"CRI","Croatia"=>"HRV", | 
| 44 |  |  |  |  |  |  | "Cuba"=>"CUB","Cyprus"=>"CYP","Czech Republic"=>"CZE","Denmark"=>"DNK", | 
| 45 |  |  |  |  |  |  | "Djibouti"=>"DJI","Dominica"=>"DMA","Dominican Republic"=>"DOM","Ecuador"=>"ECU", | 
| 46 |  |  |  |  |  |  | "Egypt"=>"EGY","El Salvador"=>"SLV","Equatorial Guinea"=>"GNQ","Eritrea"=>"ERI", | 
| 47 |  |  |  |  |  |  | "Estonia"=>"EST","Ethiopia"=>"ETH","Falkland Islands"=>"FLK","Faroe Islands"=>"FRO", | 
| 48 |  |  |  |  |  |  | "Fiji"=>"FJI","Finland"=>"FIN","France"=>"FRA","French Guiana"=>"GUF", | 
| 49 |  |  |  |  |  |  | "French Polynesia"=>"PYF","Gabon"=>"GAB","Gambia"=>"GMB","Georgia"=>"GEO", | 
| 50 |  |  |  |  |  |  | "Germany"=>"DEU","Ghana"=>"GHA","Gibraltar"=>"GIB","Greece"=>"GRC", | 
| 51 |  |  |  |  |  |  | "Greenland"=>"GRL","Grenada"=>"GRD","Guadeloupe"=>"GLP","Guatemala"=>"GTM", | 
| 52 |  |  |  |  |  |  | "Guinea"=>"GIN","Guinea Bissau"=>"GNB","Guyana"=>"GUY","Haiti"=>"HTI", | 
| 53 |  |  |  |  |  |  | "Honduras"=>"HND","Hong Kong"=>"HKG","Hungary"=>"HUN","Iceland"=>"ISL", | 
| 54 |  |  |  |  |  |  | "India"=>"IND","Indonesia"=>"IDN","Iran"=>"IRN","Iraq"=>"IRQ", | 
| 55 |  |  |  |  |  |  | "Ireland"=>"IRL","Israel"=>"ISR","Italy"=>"ITA","Ivory Coast"=>"CIV", | 
| 56 |  |  |  |  |  |  | "Jamaica"=>"JAM","Japan"=>"JPN","Jordan"=>"JOR","Kazakhstan"=>"KAZ", | 
| 57 |  |  |  |  |  |  | "Kenya"=>"KEN","Kiribati"=>"KIR","Kuwait"=>"KWT","Kyrgyzstan"=>"KGZ", | 
| 58 |  |  |  |  |  |  | "Laos"=>"LAO","Latvia"=>"LVA","Lebanon"=>"LBN","Lesotho"=>"LSO", | 
| 59 |  |  |  |  |  |  | "Liberia"=>"LBR","Libya"=>"LBY",",Liechtenstein"=>"LIE","Lithuania"=>"LTU", | 
| 60 |  |  |  |  |  |  | "Luxembourg"=>"LUX","Macau"=>"MAC","Macedonia"=>"MKD","Madagascar"=>"MDG", | 
| 61 |  |  |  |  |  |  | "Malawi"=>"MWI","Malaysia"=>"MYS","Maldives"=>"MDV","Mali"=>"MLI", | 
| 62 |  |  |  |  |  |  | "Malta"=>"MLT","Marshall Islands"=>"MHL","Martinique"=>"MTQ","Mauritania"=>"MRT", | 
| 63 |  |  |  |  |  |  | "Mauritius"=>"MUS","Mexico"=>"MEX","Micronesia"=>"FSM","Moldova"=>"MDA", | 
| 64 |  |  |  |  |  |  | "Monaco"=>"MCO","Mongolia"=>"MNG","Montserrat"=>"MSR","Morocco"=>"MAR", | 
| 65 |  |  |  |  |  |  | "Mozambique"=>"MOZ","Myanmar"=>"MMR","Namibia"=>"NAM","Nepal"=>"NPL", | 
| 66 |  |  |  |  |  |  | "Netherlands"=>"NLD","Netherlands Antilles"=>"ANT","New Caledonia"=>"NCL","New Zealand"=>"NZL", | 
| 67 |  |  |  |  |  |  | "Nicaragua"=>"NIC","Niger"=>"NER","Nigeria"=>"NGA","Norfolk Island"=>"NFK", | 
| 68 |  |  |  |  |  |  | "North Korea"=>"PRK","Northern Mariana Islands"=>"MNP","Norway"=>"NOR","Oman"=>"OMN", | 
| 69 |  |  |  |  |  |  | "Pakistan"=>"PAK","Palau"=>"PLW","Panama"=>"PAN","Papua New Guinea"=>"PNG", | 
| 70 |  |  |  |  |  |  | "Paraguay"=>"PRY","Peru"=>"PER","Philippines"=>"PHL","Poland"=>"POL", | 
| 71 |  |  |  |  |  |  | "Portugal"=>"PRT","Puerto Rico"=>"PRI","Qatar"=>"QAT","Reunion"=>"REU", | 
| 72 |  |  |  |  |  |  | "Romania"=>"ROM","Russia"=>"RUS","Rwanda"=>"RWA","Saint Helena"=>"SHN", | 
| 73 |  |  |  |  |  |  | "Saint Kitts and Nevis"=>"KNA","Saint Lucia"=>"LCA","Saint Pierre and Miquelon"=>"SPM","Saint Vincent/Grenadines"=>"VCT","Samoa"=>"WSM","San Marino"=>"SMR", | 
| 74 |  |  |  |  |  |  | "Saotome and Principe"=>"STP","Saudi Arabia"=>"SAU","Senegal"=>"SEN","Seychelles"=>"SYC", | 
| 75 |  |  |  |  |  |  | "Sierra Leone"=>"SLE","Singapore"=>"SGP","Slovak Republic"=>"SVK","Slovenia"=>"SVN", | 
| 76 |  |  |  |  |  |  | "Solomon Islands"=>"SLB","Somalia"=>"SOM","South Africa"=>"ZAF","South Korea"=>"KOR", | 
| 77 |  |  |  |  |  |  | "Spain"=>"ESP","Sri Lanka"=>"LKA","Sudan"=>"SDN","Suriname"=>"SUR", | 
| 78 |  |  |  |  |  |  | "Swaziland"=>"SWZ","Sweden"=>"SWE","Switzerland"=>"CHE","Syria"=>"SYR", | 
| 79 |  |  |  |  |  |  | "Taiwan"=>"TWN","Tajikistan"=>"TJK","Tanzania"=>"TZA","Thailand"=>"THA", | 
| 80 |  |  |  |  |  |  | "Togo"=>"TGO","Tokelau"=>"TKL","Tonga"=>"TON","Trinidad and Tobago"=>"TTO", | 
| 81 |  |  |  |  |  |  | "Tunisia"=>"TUN","Turkey"=>"TUR","Turkmenistan"=>"TKM","Turks and Caicos Islands"=>"TCA", | 
| 82 |  |  |  |  |  |  | "Uganda"=>"UGA","Ukraine"=>"UKR","United Arab Emirates"=>"ARE","United Kingdom"=>"GBR", | 
| 83 |  |  |  |  |  |  | "United States"=>"USA","US Virgin Islands"=>"VIR","Uruguay"=>"URY","Uzbekistan"=>"UZB", | 
| 84 |  |  |  |  |  |  | "Vanuatu"=>"VUT","Vatican"=>"VAT","Venezuela"=>"VEN","Vietnam"=>"VNM", | 
| 85 |  |  |  |  |  |  | "Western Sahara"=>"ESH","Yemen"=>"YEM","Yugoslavia"=>"YUG","Zambia"=>"ZMB", | 
| 86 |  |  |  |  |  |  | "Zimbabwe"=>"ZWE" | 
| 87 |  |  |  |  |  |  | ); | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  | =head1 Commentary | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | Set $CHAT if you wish to see what's going on during net access. | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | =cut | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | our $CHAT; | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | =head1 Subroutine latlon (country, postcode) | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | Accepts a country name and a postal code, returns the relative latitude and longitude as defined by MapBlast.com | 
| 101 |  |  |  |  |  |  |  | 
| 102 |  |  |  |  |  |  | The argument C must match a key of the module's C<%countriesList> hash, so it may be an idea to check your input against those keys before calling. | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | Will try to connect four times, and return C on failure. | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | B that latitude and longitude is not (C,C) ! | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | =cut | 
| 109 |  |  |  |  |  |  |  | 
| 110 | 0 |  |  | 0 | 0 |  | sub latlon { my ($country, $postcode) = (shift,shift); | 
| 111 | 0 |  |  |  |  |  | for (0..3){ | 
| 112 | 0 | 0 |  |  |  |  | warn "Trying $_...\n" if $CHAT; | 
| 113 | 0 |  |  |  |  |  | my $doc = get_document($country,$postcode); | 
| 114 | 0 |  |  |  |  |  | @_ = extract_latlon($doc); | 
| 115 | 0 | 0 |  |  |  |  | last if defined $_[0]; | 
| 116 |  |  |  |  |  |  | } | 
| 117 | 0 |  |  |  |  |  | return @_; | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | # | 
| 122 |  |  |  |  |  |  | # SUB get_document | 
| 123 |  |  |  |  |  |  | # Accepts a country name, and a postcode | 
| 124 |  |  |  |  |  |  | # Returns: | 
| 125 |  |  |  |  |  |  | # | 
| 126 | 0 |  |  | 0 | 0 |  | sub get_document { my ($country,$postcode) = (shift,shift); | 
| 127 | 0 | 0 | 0 |  |  |  | die "get_document requires a \$country,\$postcode arrity" if not defined $country or not defined $postcode; | 
| 128 | 0 | 0 | 0 |  |  |  | warn "No code for country <$country>." and return undef if not exists $countriesList{$country}; | 
| 129 | 0 |  |  |  |  |  | $postcode =~ s/\s//g; | 
| 130 |  |  |  |  |  |  |  | 
| 131 | 0 |  |  |  |  |  | my $ua = LWP::UserAgent->new;											# Create a new UserAgent | 
| 132 | 0 |  |  |  |  |  | $ua->agent('Mozilla/25.'.(localtime)." (PERL __PACKAGE__ $VERSION");	# Give it a type name | 
| 133 | 0 | 0 |  |  |  |  | warn "Attempting to access ...\n" if $CHAT; | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 0 |  |  |  |  |  | my $url = | 
| 136 |  |  |  |  |  |  | 'http://www.mapblast.com/myblast/map.mb?' | 
| 137 |  |  |  |  |  |  | . 'CMD=GEO&req_action=crmap&AD4='. $countriesList{$country} | 
| 138 |  |  |  |  |  |  | . '&AD3='.$postcode | 
| 139 |  |  |  |  |  |  | . '&x=0&y=0'; | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | # Format URL request | 
| 142 | 0 | 0 | 0 |  |  |  | my $req = new HTTP::Request ('GET',$url) or die "...could not GET.\n" and return undef; | 
| 143 | 0 |  |  |  |  |  | my $res = $ua->request($req);						# $res is the object UA returned | 
| 144 | 0 | 0 |  |  |  |  | if (not $res->is_success()) {						# If successful | 
| 145 | 0 | 0 |  |  |  |  | warn"...failed.\n" if $CHAT; | 
| 146 |  |  |  |  |  |  | return undef | 
| 147 | 0 |  |  |  |  |  | } | 
| 148 | 0 | 0 |  |  |  |  | warn "...ok.\n" if $CHAT; | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 0 |  |  |  |  |  | return $res->content; | 
| 151 |  |  |  |  |  |  | } | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | # | 
| 155 |  |  |  |  |  |  | # extract_latlon | 
| 156 |  |  |  |  |  |  | # Accepts an HTML result page from a MapBlast.com search | 
| 157 |  |  |  |  |  |  | # Extracts the latitude/longitude from a link within the page | 
| 158 |  |  |  |  |  |  | # - such as http://www.mapblast.com/myblast/driveSilo.mb?&IC_2=51.592423:-0.171996:8:&CT_2=51.592423:-0.171995:20000&AD4_2=GBR&apmenu_2=&apcode_2=&GAD1_2=&GAD2_2=Leslie+Road&GAD3_2=London%2c+N2+8BH&GMI_2=&MA=1&phone_2=" | 
| 159 |  |  |  |  |  |  | # Retunrs lat/lon, and the address as three scalars | 
| 160 |  |  |  |  |  |  | # | 
| 161 | 0 |  |  | 0 | 0 |  | sub extract_latlon { my $doc = shift; | 
| 162 | 0 |  |  |  |  |  | my $token; | 
| 163 | 0 |  |  |  |  |  | my $address = ' '; | 
| 164 | 0 | 0 |  |  |  |  | my $p = HTML::TokeParser->new(\$doc) or die "Couldn't create TokePraser: $!"; | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | # Get the address | 
| 167 | 0 |  |  |  |  |  | while ($token = $p->get_token){ | 
| 168 | 0 | 0 | 0 |  |  |  | if (@$token[1] eq 'input' | 
|  | 0 |  | 0 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
| 169 |  |  |  |  |  |  | and defined @$token[2] | 
| 170 | 0 |  |  |  |  |  | and exists %{@$token[2]}->{name} | 
| 171 | 0 |  |  |  |  |  | and exists %{@$token[2]}->{value} | 
| 172 | 0 |  |  |  |  |  | and %{@$token[2]}->{name} =~ /^GAD\d$/ | 
| 173 |  |  |  |  |  |  | and %{@$token[2]}->{value} !~ m/^\s*$/ | 
| 174 |  |  |  |  |  |  | ){ | 
| 175 | 0 |  |  |  |  |  | $_ = %{@$token[2]}->{value}; | 
|  | 0 |  |  |  |  |  |  | 
| 176 | 0 | 0 | 0 |  |  |  | if (defined $address and $address !~ m/$_/i){ | 
| 177 | 0 |  |  |  |  |  | $address .=  "$_,"; | 
| 178 |  |  |  |  |  |  | } | 
| 179 |  |  |  |  |  |  | } | 
| 180 |  |  |  |  |  |  | } | 
| 181 | 0 | 0 |  |  |  |  | $address = substr( $address, 1, length($address)-2 ) if defined $address; | 
| 182 | 0 |  |  |  |  |  | $address =~ s/,+(\w)/, $1/g;	# MapBlast returns ugly lists | 
| 183 | 0 | 0 | 0 |  |  |  | return "Address not found" if not defined $address and $doc=~/Address not found/i; | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | # Get the co-ords | 
| 186 | 0 | 0 |  |  |  |  | $p = HTML::TokeParser->new(\$doc) or die "Couldn't create TokePraser: $!"; | 
| 187 | 0 |  | 0 |  |  |  | while ($token = $p->get_token | 
|  |  |  | 0 |  |  |  |  | 
| 188 |  |  |  |  |  |  | and not (@$token[1] eq 'img' and %{@$token[2]}->{src} eq '/myblast/images/topnav/mapsiloon.gif') | 
| 189 |  |  |  |  |  |  | ){} | 
| 190 | 0 |  | 0 |  |  |  | while ($token = $p->get_token and @$token[1] ne 'a'){} | 
| 191 | 0 | 0 |  |  |  |  | if (defined @$token[2]){ | 
| 192 | 0 |  |  |  |  |  | %{@$token[2]}->{href} =~ m/IC_2=([\d:.-]+)&/; | 
|  | 0 |  |  |  |  |  |  | 
| 193 | 0 | 0 |  |  |  |  | if (defined $1){ | 
| 194 | 0 |  |  |  |  |  | my ($lat,$lon,$rubbish) = split(/:/,$1,3); | 
| 195 | 0 |  |  |  |  |  | return ($lat,$lon,$address); | 
| 196 |  |  |  |  |  |  | } | 
| 197 |  |  |  |  |  |  | } | 
| 198 | 0 |  |  |  |  |  | warn "Unexpected format from MapBlast.com.\n"; | 
| 199 | 0 |  |  |  |  |  | return undef; | 
| 200 |  |  |  |  |  |  | } | 
| 201 |  |  |  |  |  |  |  | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | =head1 LATITUDE AND LONGITUDE | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | After L: | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | =over 4 | 
| 208 |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  | Zero degrees latitude is the equator, with the North pole at 90 degrees latitude and the South pole at -90 degrees latitude. | 
| 210 |  |  |  |  |  |  | one degree is approximately 69 miles. Greenwich, England is at 51.466 degrees north of the equator. | 
| 211 |  |  |  |  |  |  |  | 
| 212 |  |  |  |  |  |  | Zero degrees longitude goes through Greenwich, England. | 
| 213 |  |  |  |  |  |  | Again, Each 69 miles from this meridian represents approximately 1 degree of longitude. | 
| 214 |  |  |  |  |  |  | East/West is plus/minus respectively. | 
| 215 |  |  |  |  |  |  |  | 
| 216 |  |  |  |  |  |  | =back | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | =head1 PREREQUISITES | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | LWP::UserAgent; | 
| 221 |  |  |  |  |  |  | HTTP::Request; | 
| 222 |  |  |  |  |  |  | HTML::TokeParser; | 
| 223 |  |  |  |  |  |  | strict; | 
| 224 |  |  |  |  |  |  | warnings. | 
| 225 |  |  |  |  |  |  |  | 
| 226 |  |  |  |  |  |  | =head1 EXPORTS | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  | None by default. | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | =head1 REVISIONS | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | =item 0.02 | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  | Now returns street addresses in addition to latitude and longitude. | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | L, L, L. | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | =head1 AUTHOR | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | Lee Goddard L. | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | =head1 COPYRIGHT | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | Copyright (C) Lee Goddard, 2001 - All Rights Reserved. | 
| 247 |  |  |  |  |  |  |  | 
| 248 |  |  |  |  |  |  | This library is free software and may be used only under the same terms as Perl itself. | 
| 249 |  |  |  |  |  |  |  | 
| 250 |  |  |  |  |  |  | =cut | 
| 251 |  |  |  |  |  |  |  | 
| 252 |  |  |  |  |  |  | 1; | 
| 253 |  |  |  |  |  |  | __END__ |