- ベストアンサー
距離から緯度経度を求める方法
このジャンルでお願いします。 始点(lat1, lng1)と始点から 北向きが0度として角度は分かっています。 そこから例えば角度60度、1.5mの距離の緯度経度(終点)が知りたいのですが、 どのようなプログラムになるのでしょうか?
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
単純なモデルで計算しても問題にならなさそうな条件ですね。 ・地球を1周の長さがL(≒40000000メートル)のゆがみのない球体として扱う ・緯度・経度は北緯、東経の範囲、単位は° ・始点からの方角αは、真北が0°、真東が90° ・始点からの距離はx、単位メートル 緯度方向は、1mが0.000009°に相当します(360/L)。経度方向の長さは緯度によって変わり、1mが(0.000009/cos(lat1))°となります(360/Lcos(lat1))。 終点(lat2, lng2)は lat2 = lat1 + 0.000009x・sin(α) lng2 = lng2 + 0.000009x・cos(α)/cos(lat1) と計算できます。あとは、三角関数の計算をするときにラジアンに変換するところに気をつける必要があります。 検算はしていません。
その他の回答 (7)
- やぎ じじい(@yagijijii)
- ベストアンサー率56% (63/112)
質問者さんのおっしゃる通り、北極点または南極点に近づくほど 長方形近似に誤差が生じてきて、台形補正しなければいけません。 そこで、東+0.00001度、北+0.00001度の場合の、右斜め45度で 計算してみました。 結果を見ると、結構誤差が大きいですね。 基点緯度:距離 0:1.5742953363631(m) 10:1.5623825371302(m) 20:1.5275622620182(m) 30:1.4726183799388(m) 40:1.4022827123297(m) 50:1.3233334724947(m) 60:1.2445896682403(m) 70:1.1765041298042(m) 80:1.1298536938737(m) そもそも、私がこれを作ったのは、ストリートビュー間の距離を 求めるためで、日本で使えれば良いぐらいに安易に考えました。 是非、正確な補正を行なって、完璧なものにしてください。
お礼
ご回答ありがとうございます。 なるほど、両極で50センチぐらいの差ですね。 日本限定で使っていけば大丈夫そうですかね。 参考になりました。
- _kappe_
- ベストアンサー率68% (1581/2304)
>ただ_kappe_さんの仰るcos(lat1)の値はマイナスになりませんか? >lat1というのはおそらくこの場合だと始点の35.669442の数値を入れるのですよね? 「三角関数の計算をするときにラジアンに変換するところに気をつける必要があります」と書いたとおりです。 35.669442°をラジアンに変換してからcosの計算をしてください。 >←このlng2はおそらくlng1(始点)の間違いでは? こちらはそのとおりです。失礼しました。
お礼
ご回答ありがとうございます。 なるほど、勘違いしていました。すいません。 $lng2 = $startlng + ($len * $cos)/cos(deg2rad($startlat)); // ←目的のlng このようにしたら理想とする結果が得られました。 参考になりました。
- やぎ じじい(@yagijijii)
- ベストアンサー率56% (63/112)
同じような目的で、以下の計算式を使用しています。 //基点(laty1,lngx1) //相対点(laty2,lngx2) $erad = 6378137;//地球の半径(単位m) $leny = $erad * M_PI * 2 * ($laty2 - $laty1) / 360; $lenx = $erad * M_PI * 2 * ($lngx2 - $lngx1) / 360 * cos($laty2 / 180 * M_PI); $lenval = sqrt($leny * $leny + $lenx * $lenx);//2点間の距離 これが正しいとすれば、以下のように計算できると思います。 $laty1 = 35;//基点緯度 $lngx1 = 140;//基点経度 $leny = 1.5 * sin(30 / 180 * M_PI);//緯度方向距離、北から60度なので30 $lenx = 1.5 * cos(30 / 180 * M_PI);//経度方向距離、北から60度なので30 $laty2 = $laty1 + 360 * $leny / $erad / M_PI / 2; $lngx2 = $lngx1 + 360 * $lenx / $erad / M_PI / 2 / cos($laty2 / 180 * M_PI); 結果 laty2:35.000006737365 lngx2:140.00001424578
お礼
ご回答ありがとうございます。 試してみましたが、おそらく理想とする結果が得られたと思います。 参考になりました。 1つ気になるのがあるのですが、これは緯度による補正は入れてないようなのですが、 この例の場合だとそれでも問題はないとyagijijiiさんはお考えでしょうか?
補足
すいません、このコードは緯度による補正はいれてますね。 勘違いでした。 ただ_kappe_さんと異なる点は、 / cos($laty2 / 180 * M_PI); $laty1ではなくて$laty2を入れてるところなのですが、 これはこちらの方が良いのでしょうか?
- _kappe_
- ベストアンサー率68% (1581/2304)
No.4の訂正です。sinとcosが逆でした。 lat2 = lat1 + 0.000009x・cos(α) lng2 = lng2 + 0.000009x・sin(α)/cos(lat1)
- _kappe_
- ベストアンサー率68% (1581/2304)
挙がっている例では距離1.5mとなっていますが、距離は最大でどのくらいまで計算できる必要がありますか? と言うのは、緯線と経線が厳密に直角に交わっているわけではないせいで距離が長くなると方角のずれが無視できなくなってくるからです。 東京から真東に向けて出発してひたすら真っ直ぐ進むと北アメリカではなく南アメリカにたどり着く、というのはよく知られている話です(正距方位図法の地図を見れば分かります)。 もう一つ、誤差は10センチ以下なら許容範囲と書かれていますが、これは距離が1.5mのときですか? それとも、もっと距離が伸びても誤差は10センチ以下ですか?
お礼
ご回答ありがとうございます。 距離は最大で10mぐらいまでです。 もし10mなら最大で1メートルぐらいの誤差まで許容できます。 できれば10センチぐらいまでの誤差にはしたいですが。 これならば計算は可能でしょうか?
- hashioogi
- ベストアンサー率25% (102/404)
続き PHPという言語はよく知らないのです。悪しからず。 南北方向の1m当たりの緯度の差をLaとしましょう。 東西方向の1m当たりの経度の差をLoとしましょう。 東向きを0°とした角度をαとしましょう。東北方向は+α、東南方向は-αです。 1.5m移動するとどれ位差が生じるか。緯度は1.5sin(α)、経度は1.5cos(α)です。この値を始点に加算すれば終点の経緯度が出ます。 問題はLa、Loが始点の位置によって異なることです。Laは地球を円と考えれば一定、楕円と考えればほぼ一定。Loは円と考えようが楕円と考えようが、始点の緯度によって大きく変わります。赤道付近は小さく、極に向かって大きくなっていきます。従って、始点の緯度によって補間するテーブルを使用することで可能かと思います。 テーブルは以下のページの測地基準系1980(GRS80楕円体)の赤道半径と扁平率の逆数を 参考に作成してください。 http://vldb.gsi.go.jp/sokuchi/datum/tokyodatum.html
お礼
ご回答ありがとうございます。 なるほど、スタート緯度経度によって多少の補正をすればいいわけですね。 ただ1つ疑問があるのですが PHPというかプログラムで緯度経度を指定する場合、 lat=33.4567・・・ lng=135.687・・・ といった数値を利用するのですが、 「1m当たりの緯度」や経度というのはこの数値に変換するとどのようになるのでしょうか? 例えば 40,000Kmを360で割れば1度の長さが出て さらにそれを60で割れば1分の長さが出るんですよね? 度はわかるのですが、 1分って「lat=33.4567」の場合、小数点第何位の数値のことなんでしょうか?
- hashioogi
- ベストアンサー率25% (102/404)
どの程度の精度が必要なのかによって若干違います。地球は若干南北に押された楕円ということになっています。更に緯度を計算するときに地球の中心から測っていません。以下のページの地理緯度というのがそれです。 http://ja.wikipedia.org/wiki/%E7%B7%AF%E5%BA%A6 この辺を考慮すれば正確な値になりますが、完全な円ということで計算すれば若干誤差がでるということになると思います。 用事があるので続きはまた後で…。
お礼
ご回答ありがとうございます。 そうですね、一応10センチ以下の誤差なら許容範囲なのですが、 そうだとするとPHPで記述できるような内容の式になるのでしょうか?
お礼
ご回答ありがとうございます。 変更すいません、角度は分かっていると質問に書いたのですが、 角度は始点と終点から自動的に算出できるようにしたいと思います(まあどちらでもいいかとは思いますが(^^;) という設定だとすると、例えば 始点 35.669442、139.696205 終点 35.66951、139.696393 150センチ の場合、理想とする結果は北が見ため的に上だとすると、 始点から少し右上に上がる位置に終点が来てほしいのです。 ただ_kappe_さんの仰るcos(lat1)の値はマイナスになりませんか? lat1というのはおそらくこの場合だと始点の35.669442の数値を入れるのですよね? この数値を入れると cos(35.669442) = -0.44293843695322 という結果になり、それだと lng2 = lng2(←このlng2はおそらくlng1(始点)の間違いでは?(終点は求める結果なので)) + 0.000009x・cos(α)/cos(lat1) lng2の値はスタートlng1より左に向かうことになりませんか? このcos(lat1)のlat1にはこの場合だと具体的にどのような数値を入れれば良いのでしょうか? >経度方向の長さは緯度によって変わり もしよろしければ、これを考慮してない自分が試してみたコードを見ていただけないでしょうか? $startlat = 35.669442; $startlng = 139.696205; $endlat = 35.66951; $endlng = 139.696393; $rad = atan2($endlat - $startlat, $endlng - $startlng); $cos = cos($rad); $sin = sin($rad); $cf = 2*pi()*6378150 * 100; // 円周(cm) $sec = $cf/(360*60*60); //1秒をセンチに変換 $len = (1/60/60) / $sec;// 1センチを度に変換 $len *= 150;// 150cmにする $lat2 = $startlat + $len * $sin; // ←目的のlat $lng2 = $startlng + $len * $cos; // ←目的のlng これだと理想とする結果に近いのですが、やや上(北)の方に傾いてる気がします・・・ 具体的にどこを修正すれば理想とする結果が得られるのでしょうか?
補足
すいません訂正します >角度は始点と終点 この場合の終点とは方角を決めるためだけに必要な点になります。 長さはあくまで今回の例だと150センチです。