Question

When using Geo::Coder:Google, a mapping from an address to lat/lon works vice versa.

But the output is not suitable for an immediate access concerning concrete fields especially when converting lat/lon to an address.

According to my debug log:

loc by lat 48.308472 / lon 14.284578 --- \ {#012 address_components [#012 [0] {#012 long_name "Nibelungenbrücke",#012 short_name "B129",#012 types [#012 [0] "route"#012 ]#012 },#012 [1] {#012 long_name "Landstraße",#012 short_name "Landstraße",#012 types [#012 [0] "neighborhood",#012 [1] "political"#012 ]#012 },#012 [2] {#012 long_name "Innenstadt",#012 short_name "Innenstadt",#012 types [#012 [0] "sublocality",#012 [1] "political"#012 ]#012 },#012 [3] {#012 long_name "Linz",#012 short_name "Linz",#012 types [#012 [0] "locality",#012 [1] "political"#012 ]#012 },#012 [4] {#012 long_name "Linz",#012 short_name "Linz",#012 types [#012 [0] "administrative_area_level_2",#012 [1] "political"#012 ]#012 },#012 [5] {#012 long_name "Upper Austria",#012 short_name "OÖ",#012 types [#012 [0] "administrative_area_level_1",#012 [1] "political"#012 ]#012 },#012 [6] {#012 long_name "Austria",#012 short_name "AT",#012 types [#012 [0] "country",#012 [1] "political"#012 ]#012 },#012 [7] {#012 long_name 4020,#012 short_name 4020,#012 types [#012 [0] "postal_code"#012 ]#012 }#012 ],#012 formatted_address "Nibelungenbrücke, 4020 Linz, Austria",#012 geometry {#012 bounds {#012 n

Using substring subs would drive me nuts. Currently, the code:

    sub map_latlon_to_loc($$){ my $lat = shift; my $lon = shift;
          $location = $geocoder_google->reverse_geocode(latlng => $lat.','.$lon);
          dbg("loc by lat ".$lat." / lon ".$lon." --- " . p $location);
    }

Which concrete way / method / sub is suitable to access attributes within $location?

btw p refers to a Printer module

Have nothing seen on CPAN, which would do the trick. It should not work only for US. My implementation has to cope with any country.

Was it helpful?

Solution

You don't say what you're using to display the data returned by Google (what are dbg and p?) but it's certainly not a string: it's a complex hash containing nested hashes and arrays. Using Data::Dump to display it reveals the contents and makes them simple to access and manipulate.

This program uses a fixed-up version of your own subroutine to fetch information for the Royal Observatory in Greenwich. It then prints the long_name value of each line in the address_components array. It also dumps the entire data structure using Data::Dump so that you can see what is being returned.

If you prefer, the Data::Dumper may also be used. It is a core module for Perl 5 and so won't need installing, but the layout of the text it produces is inferior to that of Data::Dump.

use strict;
use warnings;

use Geo::Coder::Google;
use Data::Dump;

my $geocoder = Geo::Coder::Google->new(apiver => 3);

my $location = map_latlon_to_loc(51.4768777, 0);

my $address = $location->{address_components};
print $_->{long_name}, "\n" for @$address;
print "\n\n";
dd $location;

sub map_latlon_to_loc {
  my ($lat, $lng) = @_;
  $geocoder->reverse_geocode(latlng => "$lat,$lng");
}

output

Blackheath Avenue
Greater London
United Kingdom
SE10 8XJ
London


{
  address_components => [
    {
      long_name => "Blackheath Avenue",
      short_name => "Blackheath Ave",
      types => ["route"],
    },
    {
      long_name => "Greater London",
      short_name => "Gt Lon",
      types => ["administrative_area_level_2", "political"],
    },
    {
      long_name => "United Kingdom",
      short_name => "GB",
      types => ["country", "political"],
    },
    {
      long_name => "SE10 8XJ",
      short_name => "SE10 8XJ",
      types => ["postal_code"],
    },
    { long_name => "London", short_name => "London", types => ["postal_town"] },
  ],
  formatted_address => "Blackheath Avenue, London SE10 8XJ, UK",
  geometry => {
    bounds        => {
                       northeast => { lat => 51.4770228, lng => 0.0005404 },
                       southwest => { lat => 51.4762273, lng => -0.0001147 },
                     },
    location      => { lat => 51.4766277, lng => 0.0002212 },
    location_type => "APPROXIMATE",
    viewport      => {
                       northeast => { lat => 51.4779740302915, lng => 0.00156183029150203 },
                       southwest => { lat => 51.4752760697085, lng => -0.00113613029150203 },
                     },
  },
  types => ["route"],
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top