Google Mapsに「ぼうけん」(ドラクエ?)モードが追加されてる

本日(2012年4月1日)にGoogle マップ – 地図検索を見たら、画面の右上に「ぼうけん」なるアイコンが出現していました。

試にそのアイコンをクリックすると、昔流行った「ドラゴンクエスト」のマップに近いイメージの地図が表示されました。

しかもこれは、自分も昔ハマった「ドラゴンクエストⅢ」の地図に似てる。
「ドラゴンクエストⅢ」は「アリアハン」(地図上ではオーストラリアの位置)から冒険を初めて、世界中を旅するRPGゲーム。

30代の男性なら、このゲームにハマった人も多いはず。
4月1日はエープリルフールなので、Googleからのちょっとした「お遊び」なのかもしれませんが、とても懐かしい気分になれました。
ちなみに、日本の地図を拡大するとこんな感じ。

まさにドラクエの世界の「ジパング」。ゲームではヤマタノオロチに戦いを挑み、オーブをゲットしたものでした。

しかも地図を拡大してくと、懐かしのキャラが地図上に現れます。

これは長野県に「立俣山」の位置にいる、「グリズリー」かな?

ちなみに4月2日に日付が変わっても、「ぼうけん」のアイコンは残っていました。
※4月2日 0時4分時点
最初は4月1日だけの「お遊び」かと思ってましたが、このままこのサービスを継続するつもりなのでしょうか?

Google Japan Blog: ファミコン版 Google マップ 8 ビットができました。にGoogleからのコメントが出ています。
さすがにファミコンのソフトを出すというのは無いかと思いますが、「ぼうけん」モードは実在しているので、この先面白い展開を期待したいです。

zipnavi 地図から郵便番号検索をリリースしました

郵便番号検索 -zipnavi-にて、地図から郵便番号検索機能をリリースしました。
この機能は近所や公共施設など、地図上の場所は分かるけど、住所と郵便番号が分からない、といった場合などに使ってもらえる想定で作りました。
これで「住所」、「都道府県、市区町村、町域」、「地図」の3つの視点から郵便番号の検索する事が可能になりました。

新たにリリースした地図から郵便検索の画面イメージは以下の様な感じです。
地図検索ページ

初期状態は日本全体なので、駅名など検索したいエリア付近の情報を入力して地図を絞り込みます。そして地図上をクリックすると、吹き出しが表示されて、そこに住所と「郵便番号検索」ボタンが表示されます。
地図上の地点をクリック時

「郵便番号検索」ボタンをクリックすると、zipnaviの検索エンジンにより郵便番号検索が行なわれ、結果が噴出し内に表示されます。
郵便番号検索

郵便番号検索 -zipnavi- 地図から検索にて実際に動作を確認できます。

ちなみに仕組みを簡単に説明すると以下の通りです。

1.GoogleMAPS APIを使用して、地図上から緯度経度を取得する。
2.GoogleMAPS APIの逆ジオコーディングを使用して、緯度経度から住所を取得する。
3.zipnaviの検索エンジンを使用して、住所から郵便番号を検索する。

上記を実現する為の方法として、1、2は、メンバーの「もじゃもじゃ」さんが既に開拓済みだった為、そちらの記事を参考にさせてもらい、それに若干のアレンジを加えました。
flashcast:フリーで働くITエンジニア集団のブログ: iPhone OS 3.0のSafariでGPS機能を使ったWeb Applicationを作る!(iPhoneでテスト編)

あと、GoogleMAP上にAdsenseの広告も表示させましたが、これもflashcast:フリーで働くITエンジニア集団のブログ: Strayed Childの地図に広告を載せてみた!の記事を参考にさせてもらいました。

ただ、開発中のテストで気付いたのですが、上記2の方法で取得できる住所情報にはちょっとクセがあります。
A.地図上の道路を指定すると、「日本国道1号線」。海上を指定すると、「日本」といった情報が表示される。
国道海上
B.地図上の陸地を指定しているのに、住所ではなく、郵便番号が表示される。
郵便番号

Aの様な場合、googleのAPIでは正確な住所が表示されないようです。

Bはちょっとナゾです。
コレは何?
ネットで調べてもよく分かりません。
ただ表示された郵便番号をよ~く見ると・・・
これはたぶん事業所の郵便番号の様に思われます。

上記の様なケースを考慮し、Aの場合は噴出しに警告メッセージを表示しました。
またBの場合は、新たに郵便番号検索するまでもないので、GoogleMAPS APIで取得できた郵便番号をそのまま表示させました。

GoogleMAPS APIの仕様では上記の様な記述はありませんでしたが、色々とテストをしていく中で、上記の様な判断条件でほぼ処理出来る事が分かりました。
ただ、一部の地域で上記A、Bいも該当しない例外がありますが、その際はzipnaviの検索エンジンがエラーと判断するので、間違った郵便番号が検索される事はありません。
具体的には以下の様な地域です。
茨城県かすみがうら市
※「茨城県かすみがうら市」だけでは、郵便番号を特定できません。この様な場合も、googleのAPIでは正確な住所が表示されないようです。

3については取得した住所をAjaxを使用して、zipnaviの検索エンジンに渡し、その検索結果(郵便番号)を地図上に表示しています。
なお、今回の機能追加に合わせて、サイトのデザインもリニューアルしました。
新しくなったzipnaviを今後ともよろしくお願いします!

2地点の緯度経度から距離を求める(Goole MAPS API ~距離の計算式編~)

my-hobby : 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~結果報告編~)の結果で、Google Maps API リファレンス – Google Maps API – Google Code(google方式)の精度が、3平方の定理を使用した方式(ろっきー方式)よりも精度が良い事が分かりました。
そこでgoogle方式の計算式を調べていたところ、偶然、javascriptのコードを緯度経度から2点の距離を求める – masakiplusの日記で見つけました。

今回は、これをVB.netに変換し、2点間の距離を算出しました。
以下のプログラムです。
[vbnet]
Imports System.Math
Public Function Getdistance(ByVal longitudeFrom As Double, ByVal latitudeFrom As Double, ByVal longitudeTo As Double, ByVal latitudeTo As Double)As Double
Dim from_x As Double ‘A地点の経度(ラジアン)
Dim from_y As Double ‘A地点の緯度(ラジアン)
Dim to_x As Double ‘B地点の経度(ラジアン)
Dim to_y As Double ‘B地点の緯度(ラジアン)
Dim deg As Double
Dim distance As Double ‘2地点の距離

from_x = longitudeFrom* Math.PI / 180
from_y = latitudeFrom * Math.PI / 180
to_x = longitudeTo * Math.PI / 180
to_y = latitudeTo * Math.PI / 180

deg = Sin(from_y) * Sin(to_y) + Cos(from_y) * Cos(to_y) * Cos(to_x – from_x)
distance = 6378140 * (Atan(-deg / Sqrt(-deg * deg + 1)) + Math.PI / 2) / 1000 ‘2地点の距離(Km)
Return distance

End Function
[/vbnet]

このプログラムを使用して、計算を行った結果と、google方式の結果を比較したところ、以下の様な結果となりました。

図1-計算結果
図1-計算結果

※赤がgoogle方式、黒がインターネット上で見つけた計算式です。
google方式、インターネット上で見つけた方式の順に上書き描画しています。

なんと黒色の点しか存在しません。

詳細に調べる為、結果を数値レベルで比較したところ、最も誤差の大きいところでも0.013Km程度でした。(0.00008%の誤差)
また、上記のケースは東経0~180度、北緯0~90度の範囲ですが、念の為に世界全体で比較した場合も同様の結果となりました。(図2を参照)

図2-計算結果(世界全体)
図2-計算結果(世界全体)

プログラムで小数点以下を扱う以上、この程度の誤差は出てしまうので、ほぼこの計算式で間違いないと言えます。

なおGoogle MAPS APIの公式な情報として、この計算式が発表されているわけでは無いので、本当の計算式は不明ですが、非常によく似た結果になった事は事実です。
今回は計5回に分けて記事を書きましたが、その結果以下の結論を得る事が出来ました。

・三平方の定理を使用した2地点の距離の計算式(ろっきー方式)よりは、Google MAPS APIが提供している機能(google方式)の方が精度が良い。
・図1、図2の様なテストケースにおいて、Google MAPS APIが提供している2地点の距離を求める計算結果は、上記の計算式を使用して計算した結果と非常によく似ている。

前者は悔しいですが、ある意味予想通りの結果でした。
ただ後者の事実が得られた事は予想外の収穫でした。

この計算式があれば、インターネットが利用できない環境(Google MAPS APIが利用できない環境)でも、Google MAPS APIを利用した場合と同等の結果(2地点の距離)を求めることが出来るようになります。

ちなみに余談ですが、計算式のヒントとして紹介したサイトから、更にそのサイトが参考にしたサイト(Seis Pesos)は、googleマップを使った技術がすごいです。
上記の計算式も、元々はこのサイトで掲載されていた様です。(今は無かったです)
今後googleマップを使ったアプリを作る機会があったら参考にしたいと思います。(今回のもう一つの収穫でした)

2地点の緯度経度から距離を求める(Google MAPS APIとの比較~結果報告編~)

my-hobby : 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~テスト結果GoogleAPI編~)で、3平方の定理を使用した方式(ここでは「ろっきー方式」とさせていただいてます)と、Google MAPS APIが提供している距離の算出(google方式)の結果の差を報告しました。
※ろっきー方式の計算式はバックナンバーを参照して下さい。

今回はいよいよどちらの精度がよいのかを検証してみたいと思います。
測量計算(距離と方位角の計算)より取得した結果を「正しい結果」として、それを画面上に描画した結果は以下の通りとなりました。

図1-3者の結果比較-
図1-3者の結果比較-

※青がろっきー方式、赤がgoogle方式、緑が正しい結果です。
※なお、上記のサイトで計算すると、緯度、もしくは経度0の時、正しい結果が得られなかったので、0度を0度0分0.001秒として計算しています。(多分バグだと思います)
※計算上、0度から0度0分0.001秒までの長さはわずか3cmである為、今回の計算結果には影響を与えない範囲と考えられます。

なお描画は、ろっきー方式、google方式、正しい結果の順に上書き描画しています。
「ろっきー方式」、「google方式」それぞれの計算結果が正しい場合は、緑の点に上書きされるので、上書きされなかった(残ってしまった)点が多いほど、精度が悪いという事になります。

上記の図1を見ると、赤の点(Google方式)がほとんど無く、青の点(ろっきー方式)が多い事が分かります。
その結果、ろっきー方式よりもgoogle方式の方が精度が高い事が判明しました。

ではgoogle方式はどの様な計算式で、距離を割り出しているのか?エンジニアの自分としては気になって仕方がありません。
やはり、3平方の定理を使用したろっきー方式より精度が良いという事であれば、地球を球体とみなして計算をしているに違いありません。
しかし、自分だけの力でこの計算式を割り出すのは到底無理なので、ダメもとでいろいろ検索してたら、ろっきー方式と違う計算式を見つけ出しました。

この計算式を使って、再度my-hobby : 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~概念編~)で紹介した方法で描画して、google方式との差を比較したいと思います。
今回の目的は達成しましたが、番外編として比較結果を次回報告したいと思います。

2地点の緯度経度から距離を求める(Google MAPS APIとの比較~テスト結果GoogleAPI編~)

flashcast:フリーで働くITエンジニア集団のブログ: 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~テスト結果自作計算編~)の続編です。
Google Maps API リファレンス – Google Maps API – Google Codeで紹介されている2地点の距離の結果を、flashcast:フリーで働くITエンジニア集団のブログ: 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~概念編~)で紹介した方法で図形化すると、以下の様な図が出来上がりました。

図1-google方式の結果-
図1-google方式の結果-

・・・なんか、前回紹介した「ろっきー」方式と似ているような、でもちょっと違うような・・・
改めてろっきー方式と、google方式の違いを一つの図で表示させて、両者を見比べてみたいと思います。

図2-両者の比較結果-
図2-両者の比較結果-

青がろっきー方式、赤がgoogle方式で描画しています。
ろっきー方式、google方式の順に上書き描画していますので、赤い点しかない部分はろっきー方式とgoogle方式の計算結果が同じという事になります。

図2を見ると、緑で囲った部分の差が大きいようです。
そこで、緑で囲った部分を含む東経0~180度、北緯0~90度の範囲(図2のオレンジで囲った部分)だけをクローズアップして見てみたいと思います。
ただ、10度刻みだと間隔が大きすぎるので、5度刻みにして描画してみました。
クローズアップして描画した結果は以下の通りになりました。

図3-クローズアップ-
図3-クローズアップ-

図3を見ると、青で囲った箇所は結果がほぼ一致していますが、赤で囲った箇所はかなりの差が出ているようです。
とりあえず現時点で分かった事としては、以下の通りです。
・ろっきー方式とgoogle方式は計算結果に違いがある。
・計算結果の違いは、B地点の緯度経度によって、大きかったり小さかったりする。
※B地点とは、背景の黄色い罫線が交差している点を指しています。
この事から、ろっきー方式と、google方式とでは、計算式が異なると言う事が確実となりました。

では今回のシリーズの本題である「ろっきー方式とgoogle方式とではどちらが精度が良いのか?」を検証してみたいと思います。
そこで、正しい結果を取得するべく、過去にも何度かお世話になっている測量計算(距離と方位角の計算)よりクローズアップ部分のみの結果を取得して、この図に描画してみる事にしました。
※このサイトで得られた結果を正解として、ろっきー方式と、google方式を比較してみたいと思います。

描画してみた結果は、次回報告したいと思います。

●バックナンバー
第1回:flashcast:フリーで働くITエンジニア集団のブログ: 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~概念編~)
第2回:flashcast:フリーで働くITエンジニア集団のブログ: 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~テスト結果自作計算編~)

2地点の緯度経度から距離を求める(Google MAPS APIとの比較~テスト結果自作計算編~)

my-hobby : 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~概念編~)の続編です。
googleAPIが提供している距離計算「google方式」と、3平方の定理を使用した距離計算(ここでは「ろっきー方式」とさせていただきます)の精度の差を比較すべく、先ずはろっきー方式のテスト結果を報告します。

早速計算結果を描画してみたところ、以下の様な図が出来上がりました。

図1-ろっきー方式の結果-
図1-ろっきー方式の結果-

・・・う~ん。。。一見おかしな図形ですが、とりあえずこれはこれで良しとします。
ちなみにこの図形は、google方式との比較をする為のもので、この図形自体には何の意味もありませんのでご注意下さい。。。

では次にいよいよ「google方式」の検証です。
同じ3平方の定理(ろっきー方式)を使用していれば、同じ様な図形を描くはずですが、この方式は誤差が大きい為、別の方法を採用している可能性があります。

「google方式」はどの様な図形を描くのでしょうか?
ちなみに、googleの2地点の距離を求める方法については、もじゃもじゃさんの記事flashcast:フリーで働くITエンジニア集団のブログ: iPhone OS 3.0のSafariでGPS機能を使ったWeb Applicationを作る!(iPhoneでテスト編)を参考にしました。

結果は次回報告したいと思います。

2地点の緯度経度から距離を求める(Google MAPS APIとの比較~概念編~)

my-hobby : 2地点の緯度経度から距離を求める(global化 2/2)でglobal化が完了して一段落しましたが、メンバーのもじゃもじゃさんから、以下の様な話が出ました。
「GoogleMAPS APIにも、2地点の緯度経度から距離を求めるAPIがあるんだけど、ろっきーが紹介している方法とどちらの方が精度がいいのか知りたい」

googleの精度(以降「google方式」とします)に勝つつもりは無いですけど、ろっきーが紹介した方法(以降「ろっきー方式」とします)とどれだけ精度に差があるのか気になるところなので、せっかくだからこの疑問に対して自分なりの答えを出してみたいと思います。
ではどの様にして両者を比較すればよいのか?

比較と言うからには、やっぱり2地点のそれぞれの緯度経度から、「ろっきー方式」と、「google方式」を使用して、どの様な距離が算出されるかを比較すればよいという事になります。
ではテスト対象となる、2地点の緯度経度はどの様に決めるべきか?
ただ、単に1ケースだけでは、全体的な計算結果の差を把握する事は出来ません。
やはり全世界を網羅し、かつ簡単な(解り易い)テストケースであるのが、現時点では望ましいと言えます。

とりあえず最も単純な方法として、以下の様な方法を考えました。(1~4を順番に行なう)
1.東経0度、北緯0度の位置にポイントを打ち、これをA地点とします。
2.東経0~180度、西経0~180度、北緯0~90度、南緯0~90度の範囲(地球全体)で、それぞれ10度毎に線を引き、線が交差した部分にポイントを打ち、これをB地点とします。

図1-A地点とB地点の配置イメージ-
図1-A地点とB地点の配置イメージ-

※世界中にB地点として、703個のポイントが打たれます。
703=横(経度10度間隔)×縦(緯度10度間隔)=37×19=(360÷10+1)+(180÷10+1)=(360÷10+1(経度0度上のポイント))+(180÷10+1(緯度0度上のポイント))

3.A地点と、703箇所のB地点それぞれに対して、「ろっきー方式」「google方式」で距離を求める。
4.両者で算出された距離を比較する。

この結果をそれぞれ比較すれば、両者の計算結果にどれだけの違いが出てくるかが解ります。
ただ、それぞれの計算結果(数値)を比較しても個々の差がどれくらいあるかは解りますが、全体的な差のイメージが湧きません。

そこで、計算結果の距離をビジュアル的に表現してみたいと思います。
では、距離をどの様にして表現するのか?
とりあえず今回は以下の様な方法を考えてみました。

A、Bの2地点に対して距離を求めた場合、通常の2次元の世界であれば、A地点からB地点までを直線で引いた長さが距離となります。

しかし、3次元である円い地球を、図1の様に2次元上で表現している為、A地点とB地点を直線で結んだ長さが実際の距離にはなりません。
例えば単純に2次元上でA地点(0,0)、B地点(150,30)の2点に対して3平方の定理を使用して、斜辺の長さを求めると、152.97となります。
これに1度あたりの距離111Kmを掛けると、16979.73Kmとなります。
これを実際の地球に想定して、東経0度、北緯0度と、東経150度、北緯30度としての2地点の距離を「ろっきー」方式で求めると、15427.82Kmとなります。
上記の計算方法についてはmy-hobby : GoogleAPI~2つの住所から距離を求める~を参照して下さい。

図2-2地点の実際の距離-
図2-2地点の実際の距離-

上記の計算結果で得られたこの結果(図2)の距離を点として画面上に描画して、これを703のポイントに対して全て行ないます。
そうすると、A地点(東経0度、北緯0度)からB地点(703個のポイント)のそれぞれに対しての距離が点として描画される為、距離を基準とした「703個の点の集合からなる図形」が出来上がります。
これを「Google方式」、「ろっきー」方式のそれぞれに対して行い、先ずはビジュアル的に両者の計算結果を確認してみようという作戦です!

結果がどうなるか分かりませんが、興味がある方はこの「研究」にお付き合い下さい。
※研究なので失敗する事もあります。。。
なおこのテストの為に、専用のアプリをVB.netで開発してしまいました!

では先ず手始めに、「ろっきー」方式から試してみたいと思います。
さてどの様な図形が浮かび上がるのか?
結果は次回報告したいと思います。

GoogleAPI~郵便番号から地図を表示してみる~

せっかく郵便番号検索が出来たので、郵便番号に該当する付近の地図をGoogleMAPS APIを使用して表示したいと思います。
以前紹介したmy-hobby : 知ってると便利googleマップの使い方で表示させる方法もありますが、この方法だと地図の表示のさせ方(特に噴出し部分)のカスタマイズが、現状調べた限りでは出来ない事が分かりました。

そこでよりカスタマイズが可能なJavaScriptを使用して、地図を表示させたいと思います。
先ずは簡単な地図を表示させる為のサンプルソースを以下のサイトより取得しました。
地図の基本 – Google Maps API – Google Code
【Google マップの「Hello, World」】タブにあるリンク先のページGoogle マップ JavaScript API 使用例: 簡単な地図より取得したのが以下のソースです。

[javascript]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google マップ JavaScript API 使用例: 簡単な地図</title>
<script src="http://maps.google.co.jp/maps?hl=ja&amp;amp;file=api&amp;amp;v=2&amp;amp;key=(各自取得したAPIキーを設定)"
type="text/javascript"></script>
<script type="text/javascript">

function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(35.664694, 139.700016), 13);
}
}

</script>
</head>

<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width: 500px; height: 300px"></div>
</body>
</html>
[/javascript]

このソースから読み取れるのが、以下の記述の「GLatLng(35.664694, 139.700016)」で緯度と経度を設定して、その位置の地図を表示しているという事です。
map.setCenter(new GLatLng(35.664694, 139.700016), 13);
※APIの詳細な仕様については、Google Maps API リファレンス – Google Maps API – Google CodeGMap2で確認できます。

ただ、今回は郵便番号から地図を表示させたいので、上記のソースのままでは使用できません。
APIの仕様を色々探していたら、住所から緯度経度を検索し、そこから地図を表示させるAPI(クラス)GClientGeocoderを発見しました。

早速このクラスを元に、サンプルソースを作成してみました。

[javascript]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS" /><meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=(各自取得したAPIキーを設定); type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" >
//<![CDATA[
var map;
var geocoder;
function load() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map"));
map.addControl(new GMapTypeControl());
map.addControl(new GLargeMapControl());
geocoder = new GClientGeocoder();
geocoder.getLatLng(document.mapform.address.value, showMap);
}
}

function showMap(latlng){
if (latlng){
//緯度経度が検索された場合
map.setCenter(latlng, 15);
var marker = new GMarker(latlng);
map.addOverlay(marker);
marker.openInfoWindowHtml(document.mapform.address.value);
}else{
//緯度経度が検索できなかった場合、全国の地図を表示する。
map.setCenter(new GLatLng(37.055177, 139.174805), 5);
}
}
//]]>
</script>
</head>

<body onload="load()" onunload="GUnload()">
<form name="mapform" id="mapform">
<div id="map" style="width: 700px; height: 500px"></div>
<input type="hidden" id="address" name="address" value="東京都港区芝公園4丁目2-8">
</form>
</body>
</html>[/javascript]

上記スクリプトをブラウザで表示させると以下の様な感じになります。

※東京タワーの住所を設定しています。
サンプルソースを作成するに当たり、以下のサイトを参考にしました。
住所から緯度と経度を取得(GClientGeocoderクラス, getLatLngメソッド) – ジオコーディング – Google Maps入門

結局、住所から地図を表示する方法は見つかりましたが、郵便番号から緯度経度を検索するAPI(クラス)は見つかりませんでした。
そこでダメもとで住所の代わりに郵便番号(〒105-0011)を引数にして設定してみると、
なんと郵便番号でも地図が正しく表示されました。


※東京タワーの郵便番号を設定していますが、若干位置がずれています。
これは、〒105-0011は「東京都港区芝公園」全体を指している為、東京タワーの位置にピンポイントでマーカーが当たらなかった為と思われます。
住所は位置を特定できますが、郵便番号は範囲の為、この程度の誤差は仕方が無いでしょう。

実はこのクラスって、住所以外の情報でも緯度経度を検索できるのでは?と思い、試しに「東京タワー」という文字をセットしてみたところ、、、
地図が正しく表示されました。

API仕様では住所と明言されていますが、実際に試した結果キーワード検索と同じ様な機能になっているようです。
もしこれが公式な情報になれば、地図表示の自由度(汎用性)がより高くなりますね。

ちなみに、APIの仕様がバージョンアップされているようです。
http://code.google.com/intl/ja/apis/maps/documentation/v3/
今回は旧バージョンで記事を書きましたが、新バージョンで今回の記事に関する変更があれば、また紹介したいと思います。

GoogleAPI~住所から緯度経度を取得する(その2)~

前回は、Google MAPSのWeb APIを使用して、緯度経度を含んだ情報をXML形式で取得する方法を紹介しました。
前回の情報はmy-hobby : GoogleAPI~住所から緯度経度を取得する(その1)~で確認できます。

今回はGoogleAPIを使用して取得したXMLの仕様を確認し、そこから緯度経度を取得してみたいと思います。

緯度経度を取得するに当たり、サービス – Google Maps API – Google Codeを参考にしました。
なおリンク先の説明はJSONになってますが、実際に動作テストした結果、リンク先に記載されている内容と合致していたので、今回はこれを基にプログラムを作成しました。

その内容から見るべきXPATHは以下の2つと考えました。
1.kml/Response/Status/code
リターンコードを示しています。
「200」が正常終了。それ以外は今回の処理では異常終了とみなす事にします。
リターンコードの種類についてはGoogle Maps API リファレンス – Google Maps API – Google Codeに記載されています。

2.kml/Response/Placemark/Point/coordinates
リクエストされた住所の 緯度、経度、高度 をカンマ区切りで示しています。
※高度は常に0が返されます。

上記内容を踏まえてWindowsフォームより入力した住所に対して、GoogleAPIを使用して緯度と経度を求めます。
■入力フォーム

■ソースコード

[vbnet]
Imports System.Xml
Imports System.Web
Public Class Form1

Private Sub btn_Search_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Search.Click

Dim xNode As XmlNodeList
Dim Enc_Address As String
Dim APIKey As String = "(各自で取得したAPIキー)"
Dim RequestUrl As String
Dim GeoCode() As String

If txt_Address.Text = "" Then
Exit Sub
End If

Enc_Address = HttpUtility.UrlEncode(txt_Address.Text)
RequestUrl = "http://maps.google.com/maps/geo?&amp;q=" &amp; Enc_Address &amp; "&amp;output=xml&amp;key=" &amp; APIKey

Dim xDoc As XmlDocument = New XmlDocument
xDoc.Load(RequestUrl)

Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xDoc.NameTable)
nsmgr.AddNamespace("gmap", "http://earth.google.com/kml/2.0")
xNode = xDoc.SelectNodes("/gmap:kml/gmap:Response/gmap:Status/gmap:code", nsmgr)

If xNode.Item(0).InnerText &lt;&gt; "200" Then
Exit Sub
End If

xNode = xDoc.SelectNodes("/gmap:kml/gmap:Response/gmap:Placemark/gmap:Point/gmap:coordinates", nsmgr)

GeoCode = Split(xNode.Item(0).InnerText, ",")
txt_Keido.Text = GeoCode(0)
txt_Ido.Text = GeoCode(1)

End Sub
End Class[/vbnet]

■実行結果

ちなみにGoogleAPIの仕様上は、施設名などでも緯度経度の検索は可能ですが、複数ヒットした場合、このプログラムでは考慮されていません。
複数ヒットの場合は、最初のデータが使用されます。

※施設名(東京タワー)で検索した場合

次回は2つの住所から、2点間のおおよその距離を求める方法にチャレンジしてみたいと思います。

GoogleAPI~住所から緯度経度を取得する(その1)~

郵便番号構想を始めてから、住所に関する事にどっぷりと浸かっています。
郵便番号以外にも、住所から何か検索できるものは無いか・・・
住所を使って他にも出来る事は無いか・・・

ふと2つの住所を使って、2点間の距離を求める事が出来たら面白いのではないか?
なんて事を考えて見ました。
ただ住所だけでは2点間の距離を求めることは出来ないので、住所からある情報を検索してそこから2点間の距離を求める方法を考えました。

それは緯度と経度です。
ただ、住所から緯度と経度を検索する事なんで出来るのでしょうか?

出来ます。
それはGoogle MAPSです。
Web APIとしてGoogle MAPSがWeb APIを公開していました。

ただし、GoogleのWeb APIを使うためには、Google APIキー(ライセンスキーの様なもの)が必要という事なので、
先ずはGoogle APIキーの取得を行ないます。

Google APIキーは以下のサイトより入手できます。
Google Maps API – Google Code

より詳細な取得方法はGeekなぺーじ : Google MAPS API keyを取得するが参考になると思います。
※このページではJavaScriptによる緯度経度の取得方法も記載されています。
今回の記事を作成するにあたっても、参考にさせていただきました。

JavaScriptで実装する場合は、専用のオブジェクトが用意されていますが、
VB.netで実装する場合はURIにパラメータを直接指定して、
その戻り値(レスポンス)を元に緯度経度を取得する形式となります。
詳細はこちら
今回は戻り値をXML形式で取得し、そこから緯度経度を抽出する方式とします。

先ずはGoogleAPIにリクエストするURIの仕様は以下の通りです。

ジオコーディングとは、住所 (「1600 Amphitheatre Parkway, Mountain View, CA」など) を地理座標 (緯度37.423021、経度 -122.083739など) に変換する処理のことです。地理座標を使用して、マーカーを配置したり地図の位置決めを行うことができます。Google Maps API は、HTTP 要求を経由して直接アクセスするか、または GClientGeocoder オブジェクトを使用してアクセスできるジオコーディング サービスを備えています。

(中略)

HTTP 要求経由のジオコーディング
サーバー側スクリプトを使用して Maps API ジオコーダに直接アクセスするには、URI
に次のパラメータを指定して http://maps.google.com/maps/geo? に要求を送信します。
q — ジオコーディングする住所。
key — API キー。
output — 生成される出力の形式。xml、kml、csv、または json を指定できます。

※ジオコーディングする住所はURLエンコードが必要です。

【例】住所:日本東京都港区芝公園4丁目2-8とした場合
http://maps.google.com/maps/geo?&q=%93%8C%8B%9E%93s%8D%60%8B%E6%8E%C5%8C%F6%89%80%82S%92%9A%96%DA2-8&output=xml&key=(各個人で取得したAPIキー)

試しにこれをブラウザのアドレスに直接入力すると、
以下の様な結果が表示されます。

これをプログラムで読み込むには以下のコードを記述します。
■入力フォーム

■ソース

[vbnet]
Imports System.Xml
Imports System.Web

Public Class Form1
Private Sub btn_Search_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Search.Click

Dim Enc_Address As String
Dim APIKey As String = "(各個人で取得したAPIキー)"
Dim RequestUrl As String

If txt_Address.Text = "" Then
Exit Sub
End If

Enc_Address = HttpUtility.UrlEncode(txt_Address.Text)
RequestUrl = "http://maps.google.com/maps/geo?&amp;q=" &amp; Enc_Address &amp; "&amp;output=xml&amp;key=" &amp; APIKey

Dim xDoc As XmlDocument = New XmlDocument

xDoc.Load(RequestUrl)
Console.Write(xDoc.InnerXml)

End Sub
End Class[/vbnet]

■デバッグ

[xml]
&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;kml xmlns="http://earth.google.com/kml/2.0"&gt;&lt;Response&gt;&lt;name&gt;日本東京都港区芝公園4丁目2?8&lt;/name&gt;&lt;Status&gt;&lt;code&gt;200&lt;/code&gt;&lt;request&gt;geocode&lt;/request&gt;&lt;/Status&gt;&lt;Placemark id="p1"&gt;&lt;address&gt;4丁目2 8 Shiba Park, Minato, Tokyo, Japan&lt;/address&gt;&lt;AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"&gt;&lt;Country&gt;&lt;CountryNameCode&gt;JP&lt;/CountryNameCode&gt;&lt;CountryName&gt;Japan&lt;/CountryName&gt;&lt;AdministrativeArea&gt;&lt;AdministrativeAreaName&gt;Tokyo&lt;/AdministrativeAreaName&gt;&lt;Locality&gt;&lt;LocalityName&gt;Minato&lt;/LocalityName&gt;&lt;DependentLocality&gt;&lt;DependentLocalityName&gt;Shiba Park&lt;/DependentLocalityName&gt;&lt;Thoroughfare&gt;&lt;ThoroughfareName&gt;4丁目2?8&lt;/ThoroughfareName&gt;&lt;/Thoroughfare&gt;&lt;/DependentLocality&gt;&lt;/Locality&gt;&lt;/AdministrativeArea&gt;&lt;/Country&gt;&lt;/AddressDetails&gt;&lt;ExtendedData&gt;&lt;LatLonBox north="35.6617821" south="35.6554869" east="139.7485585" west="139.7422633" /&gt;&lt;/ExtendedData&gt;&lt;Point&gt;&lt;coordinates&gt;139.7454109,35.6586345,0&lt;/coordinates&gt;&lt;/Point&gt;&lt;/Placemark&gt;&lt;/Response&gt;&lt;/kml&gt;[/xml]

XmlDocumentオブジェクトを使用すると、非常に簡単に結果を取得する事が出来ます。
次回は取得したXML情報から、緯度と経度を取得する方法を紹介します。