Google Map API を使って始点終点の経路情報と地図画像を得る

概要

  • Google Directions APIを使って経路情報を得る。
  • Static Maps APIを使って経路情報付き画像を得る。
  • 事前にカレントディレクトリに保存用ディレクトリ「map」を作成しておく必要がある。
  • 使用例
    >gmap.pl 東京 ビックサイト
    >gmap.pl 東京 サンフランシスコ

ソース

  • gmap.pl
    #!/usr/bin/perl
    # gmap.pl
    # 始点終点の経路情報と地図画像を得る。
    # 使用法: gmap.pl <始点> <終点>
    
    use strict;
    use warnings;
    use utf8;
    use Encode;
    use LWP::UserAgent;
    use HTTP::Request;
    use JSON;
    use YAML::Syck;
    
    my $GoogleMapDirectionsAPI = 'http://maps.google.com/maps/api/directions/json?mode=walking&language=ja&sensor=false';
    my $GoogleMapStaticAPI = 'http://maps.google.com/maps/api/staticmap?size=640x640&language=ja&sensor=false';
    my $MapPath = './map/';
    
    $YAML::Syck::ImplicitUnicode = 1;
    
    binmode( STDIN,  ":encoding(CP932)" );
    binmode( STDOUT, ":encoding(CP932)" );
    binmode( STDERR, ":encoding(CP932)" );
    
    my $usStart = decode( 'CP932', shift );		# unicode string
    my $usGoal  = decode( 'CP932', shift );		# unicode string
    if ( !defined( $usStart ) || $usStart eq "" || !defined( $usGoal ) || $usGoal eq "" ){
    	die( "使用法: $0 <始点> <終点>\n" );
    }
    
    my $esStart = encodeURIComponent( $usStart );			# encoded string
    my $esGoal  = encodeURIComponent( $usGoal );			# encoded string
    my $usFName = $usStart . '_' . $usGoal;					# unicode string
    my $bsFName = encode( 'CP932', $MapPath . $usFName );	# byte string
    
    #printf( "start:\t%s\t%s\ngoal:\t%s\t%s\n", $usStart, $esStart, $usGoal, $esGoal );
    
    my $ua = LWP::UserAgent->new( keep_alive => 2 );
    
    my $res = $ua->get( $GoogleMapDirectionsAPI . '&origin=' . $esStart . '&destination=' . $esGoal );
    if ( $res->is_success ){
    	#print $res->content, "\n";
    	# http://www.donzoko.net/cgi-bin/tdiary/20100406.html#p01
    	my $json = JSON->new->utf8;
    	my $usRoute = $json->decode( $res->content );
    	#print Dump( $usRoute );
    	if ( $usRoute->{'status'} eq 'OK' ){
    		my $usLegs = $usRoute->{'routes'}[0]{'legs'}[0];
    		#delete $usLegs->{'steps'};
    		open( my $fout, ">:utf8", $bsFName . '.yaml' ) or die( "$usFName: $!\n" );
    		print $fout Dump( $usLegs );
    		close( $fout );
    
    		my $start_lat  = $usLegs->{'start_location'}{'lat'};
    		my $start_lng  = $usLegs->{'start_location'}{'lng'};
    		my $end_lat    = $usLegs->{'end_location'}{'lat'};
    		my $end_lng    = $usLegs->{'end_location'}{'lng'};
    		my $center_lng = ( $start_lng + $end_lng ) / 2;
    		if ( $start_lng * $end_lng < 0 && abs( $start_lng ) + abs( $end_lng ) > 180 ){
    			if ( $center_lng >= 0 ){
    				$center_lng -= 180;
    			} else {
    				$center_lng += 180;
    			}
    		}
    		my $mapURI = $GoogleMapStaticAPI
    			. '&center=' . (( $start_lat + $end_lat ) / 2 ) . ',' . $center_lng
    			. '&markers=label:S|' . $start_lat . ',' . $start_lng
    			. '&markers=label:G|' . $end_lat   . ',' . $end_lng
    			. '&path=enc:' . $usRoute->{'routes'}[0]{'overview_polyline'}{'points'};
    		$ua->request( HTTP::Request->new( GET => $mapURI ), $bsFName . '.png' );
    	} else {
    		die( "Error: $usRoute->{'status'}\n" );
    	}
    } else {
    	die( "Error: $res->status_line\n" );
    }
    
    sub encodeURIComponent {
        my $str = encode( 'utf-8', shift );
        $str =~ s/([^0-9A-Za-z!'()*\-._~])/sprintf("%%%02X", ord($1))/eg;
        return $str;
    }
    
    # EOF

リンク