Google Mapから画像を取得する

Google Mapから次のようなURLで地図画像を取得できる。位置は緯度経度ではなく2次元のメッシュ座標で指定する必要がある。

http://mt.google.com/mt?x=58200&y=25808&zoom=1

http://mt.google.com/mt?x=58200&y=25808&zoom=1&file=zzz.png
メッシュ座標は、緯度、経度、および、表示倍率から求めることができ、計算方法はhttp://mapki.com/wiki/Lat/Lon_To_Tileが詳しい。PHPJavaのソースがあるのでPerlに移植するのは容易であるが、とりあえずは同サイトにリンクされているTile Boundary Calculatorから取得することにしよう。負荷をかけてしまうので頻繁に使う場合はほかの方法にするべし。

#!/usr/bin/perl
use strict;
use warnings;

use LWP::UserAgent;
use IO::File;

my @p = get_tile_code(35.672351, 139.705664, 1);
get_map_image($p[0], $p[1], 1, 'zzz.png');

sub get_tile_code {
  my ($lat, $long, $zoom) = @_;

  my $ua = LWP::UserAgent->new;
  my $resp =
    $ua->post('http://www.makemeamap.com/cgi-bin/mercator4.pl?transact=', { lat => $lat, long => $long });

  die 'received bad response: '.$resp->status_line
    if !$resp->is_success;
  die 'failed to parse response'
    if !($resp->content =~ /x=(\d+)&y=(\d+)&zoom=$zoom"/);

  return ($1, $2);
}

sub get_map_image {
  my ($x, $y, $zoom, $file) = @_;

  my $ua = LWP::UserAgent->new;
  my $resp = $ua->get(sprintf('http://mt.google.com/mt?x=%d&y=%d&zoom=%d', $x, $y, $zoom));

  die 'received bad response: '.$resp->status_line
    if !$resp->is_success;

  make_file($file, $resp->content, $resp->content_length);
}

sub make_file {
  my ($file, $data, $size) = @_;

  my $out = IO::File->new($file, 'w');
  $out->binmode();
  $out->write($data, $size);
  $out->close();
}