APIの計算式の検証を行ないました。APIとの比較~概念編~)で提案した図についてもう少し詳しく説明したいと思います。この図を使って、ちょっとした実験もしてみたいと思います。この記事を見て、図に興味を持った方は是非見ていってください。図のサンプル図1●初めに、この図で検証しようと思ったきっかけ2地点の緯度経度の距離を数字で比較するよりかは、ビジュアル的な図で比較した方がぱっと見た感じ解りやすくて良いと思ったからです。●この図を一言で言うとA地点からB地点までの距離を点の集合体で表現した図です。APIとの比較~概念編~)を参考にしてください。この図は、A地点を中心に上下左右が対称である事が分かります。縦2等分、横2等分に4分割したいづれの部分も、同じ理論で描画されている事になるので、どこか1箇所を説明すれば、それが他の3箇所にも当てはまる事になります。そこで、今回は右上のエリアに絞って説明を行ないます。右上のみに絞った図を以下に示します。図2この点について全てを説明するのは大変なので、更にいくつかポイントを絞って説明していきます。1.B地点が東経0~180度、北緯90度(北極点)の場合の距離(図3参照)この図は、地球という球面を平面に見立てて距離を求めようとしているのですが、平面の場合、単純に3平方の定理を使用して、2地点の長さを求めると、その距離は2点(A地点、B地点)を対角線で結んだ長さとなります。※青色の線しかし(2地点の緯度経度)で紹介した計算式(ここでは「ろっきー方式」とさせて頂きます)を使用して解くと、必ずしも2点を対角線で結んだ長さにはなりません。※赤色の線この1の例で言うと、ろっきー方式を使用して2地点の距離を求めると、B地点の経度は異なるのですが、実は北極点の1点をさしているので、全て同じ計算結果になります。図3実際の計算結果は以下の通りです。9990この計算結果を図に反映させると、A地点を中心とした半径(距離Km)の円を描く様な図が出来上がります。2.B地点が東経180度、北緯0~90度の場合の距離(図4参照)距離の長さを赤線で示していますが、1の円形と違って、楕円を描くような感じの図になっています。北緯90度から0度に移動するにつ入れて、距離が長くなっている事になります。1の場合はB地点がいづれも北極点を指していた為、距離が同じでしたが、今度は北極点から赤道に向かってB地点が配置されている為、距離が伸びていく結果になります。図4実際の計算結果は以下の通りです。19980これでもいまいちイメージが付きづらいと思うので、ちょっと視点を変えて、地球を球体として見るとどの様になるか図にしてみました。(図5)図5図4の青枠の線と、図5の青枠の線は同じ場所を指しています。図4では分かりませんでしたが、図5の様に視点を変えてみると、A地点からの距離が伸びているのが分かると思います。この様な計算結果を今回提案したような図に描くと、図1の様な図形が出来上がります。これを踏まえると、基準となるA地点と、計測対象となるB地点の緯度経度が分かれば、地球上のどこの場所の地図でも描く事が出来るという事です。冒頭にも書きましたが、試しにこの図の概念を使って面白い実験をしてみたいと思います。JR東京駅をA地点、東京都内の各地域をB地点として、それぞれの2地点の距離を使用して東京都の形を描いてみたいと思います。B地点となる緯度経度情報については位置参照情報ダウンロードサービスより取得しました。約5200箇所のB地点の緯度経度情報を元に、それぞれの距離計算して作成した図は以下の通りです。APIと近い計算結果になった計算式で描画してみました。図6うーん・・・何となく東京都っぽい形が浮かび上がりました。※言われてみないと分かりませんが・・・B地点の緯度経度情報が均等で無い為、山岳部などは点の数が少なくなっています。逆に都心部はそれなりの形を成しています。277何かこの図の考え方は他にも応用が利きそうですが、またアイデアが浮かんだら記事にしたいと思います。この記事を読んだ方!意味不明かと思いますので、興味があればバックナンバーを参考にして下さい。Code(google方式)の精度が、3平方の定理を使用した方式(ろっきー方式)よりも精度が良い事が分かりました。masakiplusの日記で見つけました。今回は、これをVB.netに変換し、2点間の距離を算出しました。以下のプログラムです。Function[/vbnet]このプログラムを使用して、計算を行った結果と、google方式の結果を比較したところ、以下の様な結果となりました。※赤がgoogle方式、黒がインターネット上で見つけた計算式です。google方式、インターネット上で見つけた方式の順に上書き描画しています。なんと黒色の点しか存在しません。詳細に調べる為、結果を数値レベルで比較したところ、最も誤差の大きいところでも0.013Km程度でした。(0.00008%の誤差)また、上記のケースは東経0~180度、北緯0~90度の範囲ですが、念の為に世界全体で比較した場合も同様の結果となりました。(図2を参照)図2-計算結果(世界全体)プログラムで小数点以下を扱う以上、この程度の誤差は出てしまうので、ほぼこの計算式で間違いないと言えます。APIの公式な情報として、この計算式が発表されているわけでは無いので、本当の計算式は不明ですが、非常によく似た結果になった事は事実です。今回は計5回に分けて記事を書きましたが、その結果以下の結論を得る事が出来ました。APIが提供している機能(google方式)の方が精度が良い。APIが提供している2地点の距離を求める計算結果は、上記の計算式を使用して計算した結果と非常によく似ている。前者は悔しいですが、ある意味予想通りの結果でした。後者の事実が得られた事は予想外の収穫でした。APIを利用した場合と同等の結果(2地点の距離)を求めることが出来るようになります。Pesos)は、googleマップを使った技術がすごいです。上記の計算式も、元々はこのサイトで掲載されていた様です。(今は無かったです)今後googleマップを使ったアプリを作る機会があったら参考にしたいと思います。APIが提供している距離の算出(google方式)の結果の差を報告しました。※ろっきー方式の計算式はバックナンバーを参照して下さい。今回はいよいよどちらの精度がよいのかを検証してみたいと思います。測量計算(距離と方位角の計算)より取得した結果を「正しい結果」として、それを画面上に描画した結果は以下の通りとなりました。図1-3者の結果比較-※青がろっきー方式、赤がgoogle方式、緑が正しい結果です。※なお、上記のサイトで計算すると、緯度、もしくは経度0の時、正しい結果が得られなかったので、0度を0度0分0.001秒として計算しています。(多分バグだと思います)※計算上、0度から0度0分0.001秒までの長さはわずか3cmである為、今回の計算結果には影響を与えない範囲と考えられます。描画は、ろっきー方式、google方式、正しい結果の順に上書き描画しています。「ろっきー方式」、「google方式」それぞれの計算結果が正しい場合は、緑の点に上書きされるので、上書きされなかった(残ってしまった)点が多いほど、精度が悪いという事になります。上記の図1を見ると、赤の点(Google方式)がほとんど無く、青の点(ろっきー方式)が多い事が分かります。その結果、ろっきー方式よりもgoogle方式の方が精度が高い事が判明しました。google方式はどの様な計算式で、距離を割り出しているのか?エンジニアの自分としては気になって仕方がありません。3平方の定理を使用したろっきー方式より精度が良いという事であれば、地球を球体とみなして計算をしているに違いありません。自分だけの力でこの計算式を割り出すのは到底無理なので、ダメもとでいろいろ検索してたら、ろっきー方式と違う計算式を見つけ出しました。APIとの比較~概念編~)で紹介した方法で描画して、google方式との差を比較したいと思います。今回の目的は達成しましたが、番外編として比較結果を次回報告したいと思います。APIとの比較~テスト結果自作計算編~)の続編です。APIとの比較~概念編~)で紹介した方法で図形化すると、以下の様な図が出来上がりました。ろっきー方式と、google方式の違いを一つの図で表示させて、両者を見比べてみたいと思います。図2-両者の比較結果-青がろっきー方式、赤がgoogle方式で描画しています。ろっきー方式、google方式の順に上書き描画していますので、赤い点しかない部分はろっきー方式とgoogle方式の計算結果が同じという事になります。図2を見ると、緑で囲った部分の差が大きいようです。そこで、緑で囲った部分を含む東経0~180度、北緯0~90度の範囲(図2のオレンジで囲った部分)だけをクローズアップして見てみたいと思います。10度刻みだと間隔が大きすぎるので、5度刻みにして描画してみました。クローズアップして描画した結果は以下の通りになりました。図3-クローズアップ-図3を見ると、青で囲った箇所は結果がほぼ一致していますが、赤で囲った箇所はかなりの差が出ているようです。現時点で分かった事としては、以下の通りです。・ろっきー方式とgoogle方式は計算結果に違いがある。・計算結果の違いは、B地点の緯度経度によって、大きかったり小さかったりする。※B地点とは、背景の黄色い罫線が交差している点を指しています。この事から、ろっきー方式と、google方式とでは、計算式が異なると言う事が確実となりました。今回のシリーズの本題である「ろっきー方式とgoogle方式とではどちらが精度が良いのか?」を検証してみたいと思います。そこで、正しい結果を取得するべく、過去にも何度かお世話になっている測量計算(距離と方位角の計算)よりクローズアップ部分のみの結果を取得して、この図に描画してみる事にしました。※このサイトで得られた結果を正解として、ろっきー方式と、google方式を比較してみたいと思います。描画してみた結果は、次回報告したいと思います。APIとの比較~概念編~)の続編です。googleAPIが提供している距離計算「google方式」と、3平方の定理を使用した距離計算(ここでは「ろっきー方式」とさせていただきます)の精度の差を比較すべく、先ずはろっきー方式のテスト結果を報告します。計算結果を描画してみたところ、以下の様な図が出来上がりました。図1-ろっきー方式の結果-・・・う~ん。おかしな図形ですが、とりあえずこれはこれで良しとします。ちなみにこの図形は、google方式との比較をする為のもので、この図形自体には何の意味もありませんのでご注意下さい。次にいよいよ「google方式」の検証です。同じ3平方の定理(ろっきー方式)を使用していれば、同じ様な図形を描くはずですが、この方式は誤差が大きい為、別の方法を採用している可能性があります。Applicationを作る!(iPhoneでテスト編)を参考にしました。結果は次回報告したいと思います。2/2)でglobal化が完了して一段落しましたが、メンバーのもじゃもじゃさんから、以下の様な話が出ました。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地点の配置イメージ-※世界中に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となります。GoogleAPI~2つの住所から距離を求める~を参照して下さい。図2-2地点の実際の距離-上記の計算結果で得られたこの結果(図2)の距離を点として画面上に描画して、これを703のポイントに対して全て行ないます。すると、A地点(東経0度、北緯0度)からB地点(703個のポイント)のそれぞれに対しての距離が点として描画される為、距離を基準とした「703個の点の集合からなる図形」が出来上がります。これを「Google方式」、「ろっきー」方式のそれぞれに対して行い、先ずはビジュアル的に両者の計算結果を確認してみようという作戦です!結果がどうなるか分かりませんが、興味がある方はこの「研究」にお付き合い下さい。※研究なので失敗する事もあります。このテストの為に、専用のアプリをVB.netで開発してしまいました!では先ず手始めに、「ろっきー」方式から試してみたいと思います。どの様な図形が浮かび上がるのか?結果は次回報告したいと思います。-zipnavi-が完成し、住所から郵便番号が検索できるようになりました。郵便番号だけ検索できても面白くありません。そこでzipnaviでは、サイト(Webサービス)の汎用性を広げるべく、住所の構造化に取り組みたいと思います。その他」の4つの情報に分割する事を意味します。4丁目2-8一見これで何が出来るの?と思いますが、この機能は住所情報単体で使ってもあまり意味がありません。複数の住所を併せて使用する事で、色々なメリットが出てきます。1.住所情報の地域別の分布が採れる。東京都には3件、神奈川県には1件、更に東京都の中で港区芝公園には2件、港区高輪には1件、といった感じで、分布を採る事が出来ます。これを応用すれば、この地域は温泉が多い、少ないといった情報を把握する事が出来ます。ちつ】2.施設検索等で現在地から近い施設を検索できる。GPS付きの携帯電話等で、現在地の住所を取得する事が出来れば、現在地点から近い温泉施設を検索する事や、現在地から近い順に温泉施設を一覧表示するといったレコメンドも出来るようになります。それぞれ合致するものを一覧に表示していけばよい事になります。それぞれの住所に対して事前に緯度経度を取得し、2地点の距離を計算して距離の短い順に並べるという方法もありますが、仮に検索対象の施設が1000件あった場合に、1000施設全てに対してそれぞれの距離を計算する必要がある為、1回の検索でPCの負荷が掛かり過ぎるといった問題があります。それに比べて、住所の構造化を利用した方法では、単純に文字列の一致で検索するだけなので、非常に実用的な方法と言えます。※施設の件数が増加しても、レスポンスの低下を最小限に出来ます。3.住所情報を分けて入力する必要が無くなるこれは住所情報単体でも使えます。ECサイトなどで買い物をした際に、配送先の住所を入力しますが、入力欄がいくつかに分かれてて、都道府県はプルダウンになってたり、と入力が面倒くさい場合があります。プルダウンは入力ミスを防ぐという目的があるのかもしれませんが、利用者側からしてみれば一気に住所情報を入力したいです。そこで住所の構造化が利用されれば、住所の入力欄は1つにする事ができ、1つの入力情報から自動的に住所を構造化出来るので、紛らわしい入力の手間が省けます。郵便番号は入力する必要が無い(郵便番号検索で自動的に検索される)ので、まさに一石二鳥です。上げただけでも上記の様な事が可能になります。今までは「住所」という情報だけで終わってしまっていたものが、今後は「住所の構造化」によって、さまざまな利用方法が生まれてくる可能性があります。今後「住所の構造化」機能を実現する事で、今後新しいサービスを提案していければと思っています。その為には更なる住所解析の精度向上も今後必要となってくる課題です。ホントにこんな機能が出来るの?という意見もありますが、初期の開発時に将来的にこの様な機能の実現を考慮しながら開発していた為、そんな大げさな開発では無いと言うのが本音です。大きな落とし穴(バグ)が無ければ、実現できると思います。Codeで既に実現されていました。※既に先を越されてました。自分で実装すれば、サービスの内容によって自由にカスタマイズ出来るというメリットがあります。その点では今後他サイトには無いオリジナルに富んだサービスを提供できる事に繋がるので、無駄ではないと思っています。現在のzipnaviですぐにこの機能を活用する予定はありませんが、検索エンジンの汎用性が広がれば、今後新たなサービスが閃くきっかけになるかもしれませんので、とりあえず作ってみたいと思います。住所構造化を使った具体的なサービスが閃いたら、いずれ本ブログで報告したいと思います。1/2))の続きです。前回の内容を踏まえて、問題点を解決する方法を考えました。具体的に言うと以下の様な方法です。1.A地点の座標がx軸の中心となるように、地図を移動させる。2.B地点についてはA地点の緯度経度から相対的な位置関係を計算して、B地点とのx軸、y軸の経差、緯差を求める。3.x軸、y軸の距離差を使用して、2地点の距離を計算する。この方法だとA地点を経度の基点として、地図を左右に移動できるので、前回の様な問題を解決する事が出来ます。上記の方法で計算式を書くと以下の様な感じです。If‘A地点、B地点の経差、緯差を求める。If[/vbnet]※上記計算式は、2地点の距離が2極点を通過する場合は、超レアケースでかつ計算式が複雑になる為考慮していません。GoogleAPI~2つの住所から距離を求める~)でも紹介していますが、この計算式には根本的な欠陥があって、そもそも地球の円い表面を、平らな表面と仮定して計算している為、2地点の緯度差、経度差が大きくなればなるほど、その誤差は大きくなる可能性があります。具体的には、以下の様な例と考えられます。上記の様な例を元に、今回採用した方法で距離を計算するとA地点とB地点の距離は約17303Kmとなります。A地点からB地点の移動は単純に地球を半周している為、40000Km÷2=20000Kmとなるのが正しい答えのはずです。※計算結果と実際の距離には、約2700Kmもの誤差が発生しています。要は、国を跨るような距離の計算は誤差が出過ぎるという事です。正確に測ろうとすると、非常に難しい計算式になります。今回の計算式は、国をまたぐような2点間の距離の計算は考慮しませんが、同じ国の中で2地点の距離の計算には最適だと思います。GoogleAPI~2つの住所から距離を求める~を紹介しましたが、こちらの内容はあくまで日本国内に限った場合の方法でした。先日メンバーのもじゃもじゃさんから、iPhoneのGPS機能を使ったアプリを作っているので、記事で掲載した内容を使いたいという話がありました。自分の記事の内容を実際に使ってもらえるのはうれしい事なのですが、今の機能(日本国内限定)で使ってもらうのはちょっと失礼なので、思い切って全世界どこででも使えるようにしようと思います!そもそも、なぜ日本国内限定にしているかと言うと、以前の記事で紹介した計算式は東経0~180度、北緯0~90度までの範囲でしか計算できない為、日本国内限定としていました。APIが返す座標(緯度経度)は以下の様な値となっています。東経0~180度:0~180西経0~180度:0~-180北緯0~90度:0~90南緯0~90度:0~-90世界地図で表すと、以下の様な感じです。APIが返す座標(緯度経度)の結果を確認できます東経0~180度、北緯0~90度以外は座標が-(マイナス)を返すので、差を使った計算が出来ないという理由がありました。緯度・経度の差より距離を求めているので、マイナスを返す場合、単純に差を求めると、結果が意図したものと異なる場合があります。2)今回は上記内容を考慮してどの経度、緯度でも計算可能な式に変更したいと思います。計算する際に-(マイナス)が邪魔になるので、これをどの位置でも0以上になるように原点(0,0)の位置を移動させます。移動させた結果は以下の様な感じです。※x(経度)を180、y(緯度)を90足した(補正した)状態としました。これでヨシ!と思いきや、この方法には大きな落とし穴がありました。以下の図3の左のケースの様な場合に、上記の方法で2地点の距離を求めようとすると、最適な結果が得られなくなります。図2で示した座標で計算を行なうと、図3の左側の図の様な結果が2地点の距離になりますが、実は右側の図の方が距離が近いのです。2地点の距離を求めると言っても、遠い距離を返してしまっては意味がありません。地球の様に円い3次元の物体の表面を移動する場合には、単純に2地点を直線で結んだだけでは、最短距離を求める事が出来ないと言う事です。いって、3次元の世界で新たに計算式を作るのも面倒なので、2次元の世界で前回作った計算式を応用して最短距離を求める方法を考えたいと思います。この問題の解決する為、少ない知恵を絞って考えた方法を次回紹介します。前回のブログでは、2点間の距離を求める方法を紹介しました。GoogleAPI~2つの住所から距離を求める~で確認できます。今回はITとはかなりかけ離れていますが、番外編として前回のブログで紹介した計算方法の詳しい内容を紹介します。前回の内容より1度あたりの2点間の緯度差から距離を求めるには1.0061504(緯度差)×111Kmで計算する事が出来ますが、なぜ経度差から距離を求めるのは、4.2389033(経度差)×111Km×cos34.6524841(緯度)となるのでしょうか?※なぜ「cos34.6524841(緯度)」が必要なのか?※前回までのおさらい上記内容は1度あたりの距離ですが、説明を解りやすくする為にまず地球の緯線と経線の外周の距離を見てみたいと思います。極点(北極点、南極点)を通過する為、どの経度でも必ず同じ長さとなります。極点(北緯・南緯90度)では、経線の外周は0Kmとなります。●図1つまり緯線の外周の距離は、緯度によって異なるのです。北緯・南緯0度では4万Km、北緯・南緯90度では0Km。北緯30度では何kmになるのか?それは以下の様な方法で求める事が出来ます。北緯0度と北緯30度の地点に対し、地球の中心から線を引きます。すると、角Aは30度になり、線1は北緯0度の外周の半径になります。線2も地球の中心から引いた線になるので線1と同じ長さになります。・線1=線2次に北緯30度の地点から、地球の地軸に対して線を引きます。すると、線3は北緯30度の外周の半径になります。線1と線3は平行なので、角Bも30度となります。・角B:30度ここで話は変わって、cosは三角形の斜辺を1とした場合の、角Cに対する底辺の長さを示したものになるので、cos30とした場合は、底辺の長さは0.866となります。線1に対する線3の長さの比率が解ります。線1、線3の比率が解れば、北緯0度の外周から、北緯30度の外周の距離も求まります。これと同じ考えで、1度あたりの距離も同じ比率を使って求めることが出来ます。これにより、北緯30度の1度あたりの距離は111Km×0.866=96.13Kmとなります。●図6・北緯30度の1度あたりの距離:96.13Kmこれを先ほどの式に当てはめると4.2389033(経度差)×111Km×cos34.6524841(緯度)といった計算式になります。なんか数学の授業をやっている様な気がするのは自分だけでしょうか?最後まで読んで理解してくださった方、ありがとうございます。次回はまたITネタに戻します。