Domanda

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.

È stato utile?

Soluzione

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"],
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top