Geo-Coder-YahooJapan

 view release on metacpan or  search on metacpan

lib/Geo/Coder/YahooJapan.pm  view on Meta::CPAN

require Exporter;

our @ISA = qw(Exporter);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use Geo::Coder::YahooJapan ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(
	
) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(
	lookup
);

our $VERSION = '0.04';

# Preloaded methods go here.

my $entry_point = 'http://api.map.yahoo.co.jp/MapsService/V1/search';

my $ua = undef;

sub lookup {
	my $address = shift;
	my $opts = shift;

	$address or return undef;

	$ua or $ua = LWP::UserAgent->new(agent => __PACKAGE__ . "/$VERSION");

	my $datum = $opts->{datum} || 'wgs84';

	defined $opts->{num} or $opts->{num} = 10;
	defined $opts->{prop} or $opts->{prop} = 'widget';
	$address =~ s/([\W])/ sprintf "%%%02X", ord($1) /ge;

	my $params = {
		prop => $opts->{prop},
		b => 1,
		n => int $opts->{num},
		ac => "",
		st => "",
		p => $address
	};
	
	my $q = join "&", ( map { "$_=" . $params->{$_} } (keys %$params) );
	my $url = "$entry_point?$q";
	my $response = $ua->get( $url );

	$response or return undef;
	my $content = $response->content;
	
	my @items = ();
	@_ = split m|<item>|, $content;
	scalar @_ == 0 and return undef;

	while ( $content =~ m|<item>(.+?)</item>|sg ) {
		my $item_content = $1;

		my $result = {};
		while ( $item_content =~ m|<(\w+)>(.+?)</\1>|g ) {
			$result->{$1} = $2;
		}
		if ( $datum !~ /^tokyo$/i ) {
			my $tokyo = Location::GeoTool->create_coord(
				$result->{latitude}, $result->{longitude}, 'tokyo', 'degree');
			my $wgs = $tokyo->datum_wgs84;
			$wgs->format_degree;
			$result->{latitude}  = $wgs->lat;
			$result->{longitude} = $wgs->long;
		}
		push @items, $result;
	}


	return {
		datum => $datum,
		latitude => $items[0]->{latitude},
		longitude => $items[0]->{longitude},
		hits => scalar @items,
		items => \@items
	};
}

1;
__END__
# Below is stub documentation for your module. You'd better edit it!

=head1 NAME

Geo::Coder::YahooJapan - a simple wrapper for Yahoo Japan Geocoder API

=head1 SYNOPSIS

  use Geo::Coder::YahooJapan;
  $r = lookup( $address_in_japanese_characters );
  my ($lat, $lng) = ( $r->{latitude}, $r->{longitude} ); # coordinate in WGS87.

  # if you want to get result in TOKYO datum, specify it in option.
  $r = lookup( $address_in_japanese_characters, { datum => 'tokyo' } );

  # if address is ambiguous and the server returns multiple items
  $r = lookup( $address_in_japanese_characters );
  # $r->{latitude} and $r->{longitude} contains coordinate of first item.
  ($lat, $lng) = ( $r->{latitude}, $r->{longitude} );

  # $r->{hits} has the number of candidates.
  if ( $r->{hits} > 1 ) {
  	# and $r->{items} contains each candidates infomation.
  	foreach ( $r->{items} ) {
		print join "\t", ( $_->{title}, $_->{latitude}, $_->{longitude} );
		print "\n";
	}
  }



( run in 1.806 second using v1.01-cache-2.11-cpan-71847e10f99 )