2017-07-21 9 views
0

Haversine公式を使用して、2つの緯度経度ペアからの距離を計算しています。地球儀上の移動後の最終緯度経度を求める

function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) { 
    var R = 6371; // Radius of the earth in km 
    var dLat = deg2rad(lat2-lat1); 
    var dLon = deg2rad(lon2-lon1); 
    var lat1 = deg2rad(lat1); 
    var lat2 = deg2rad(lat2); 

    var a = 
     Math.sin(dLat/2) * Math.sin(dLat/2) + 
     Math.sin(dLon/2) * Math.sin(dLon/2) * 
     Math.cos(lat1) * Math.cos(lat2); 

    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    var d = R * c; 
    return d; 
} 

(LAT1、LAT2)出発点を考えると、直線と角度に移動させるのに必要な距離は、私は(LAT2とlon2のように)エンドポイントを決定する必要があります。あなたが水平移動している場合、あなたはdistance/(R * cos(lat))で経度をインクリメントすることができます

function getFinalLatLon(lat1, lon1, distance, angle) { 
    var R = 6371; // Radius of the earth in km 
    var c = distance/R; 
    // Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) = c/2 
    var a = // stuck here 

    // looking for this part of the code 

    return [lat2, lon2]; 
} 
+0

'Math.atan2'の逆数ですか?あなたは...「Math.tan」? – meowgoesthedog

+0

いいえ...そのMath.atan2 – TechyTimo

+0

つまり、 'Math.atan2'の逆数はそれ自体ですか?私はここで面白くしようとしているわけではありませんが、問題のステートメント(とタイトル)はちょっと混乱しています。 – meowgoesthedog

答えて

2

は、以下の私の試みを参照してください。いいえatanが必要です。


EDIT:あなたは一般的なケースのための式を求めていましたので、下記の幾何学的な派生を考えてみます。

  • フロントビュー:

    enter image description here

  • サイドビュー:

    enter image description here

  • 全体のセットアップ:

    enter image description here

注:

  • rは、あなたの開始位置の単位ベクトルであり、sは、エンドポイントです。

    enter image description here

  • a, b, c計算を支援する中間ベクターです。

  • (θ, φ)は(緯度、経度)座標です。
  • γを使用するに移動しようとしている方向の軸受ある。
  • δ角(距離/半径R = 6400000m)を通過します。

は、我々はa, brに垂直であるともa北朝鮮と一致する必要があります。これは与える:

enter image description here

こうして私たちは(いくつかの非常に退屈な代数経由)sを得る:

enter image description here

enter image description here

cは(簡単な三角法)によって与えられ、

ここで、

enter image description here


コード:

function deg2rad(deg) { return deg * (Math.PI/180.0) } 
function rad2deg(rad) { return rad * (180.0/Math.PI) } 

function getFinalLatLong(lat1, long1, distance, angle, radius) { 
    // calculate angles 
    var delta = distance/radius, 
     theta = deg2rad(lat1), 
     phi = deg2rad(long1), 
     gamma = deg2rad(angle); 

    // calculate sines and cosines 
    var c_theta = Math.cos(theta), s_theta = Math.sin(theta); 
    var c_phi = Math.cos(phi) , s_phi = Math.sin(phi) ; 
    var c_delta = Math.cos(delta), s_delta = Math.sin(delta); 
    var c_gamma = Math.cos(gamma), s_gamma = Math.sin(gamma); 

    // calculate end vector 
    var x = c_delta * c_theta * c_phi - s_delta * (s_theta * c_phi * c_gamma + s_phi * s_gamma); 
    var y = c_delta * c_theta * s_phi - s_delta * (s_theta * s_phi * c_gamma - c_phi * s_gamma); 
    var z = s_delta * c_theta * c_gamma + c_delta * s_theta; 

    // calculate end lat long 
    var theta2 = Math.asin(z), phi2 = Math.atan2(y, x); 

    return [rad2deg(theta2), rad2deg(phi2)]; 
} 

テストケース:

  1. 入力(lat, long) = (45, 0)angle = 0distance = radius * deg2rad(90) =>を、最終的な(緯度、長い)を用いsの座標(45, 180)(I sai D前)

  2. 入力(lat, long) = (0, 0)angle = 90distance = radius * deg2rad(90)は=>(0, 90)(予想通り - 赤道から始まり、90経度によって東移動)

  3. 入力(lat, long) = (54, 29)angle = 36、=>(54, 29)distance = radius * deg2rad(360)(予想通り - 開始どんな方向でも完全な円になる)

  4. 興味深いケース:入力(lat, long) = (30, 0)、それ以外はすべて同じです。 =>(0, 90)(?我々は(30, 90)を期待 - 北へ90度、旅行赤道から始まるない)(あなたが赤道でいないのであれば)

    この理由は、北朝鮮から90度が東ではないということです!

    enter image description here

    あなたが見ることができるように、北に90度の移動経路が東の方向にない:この図は、なぜが表示されるはずです。

+0

私が受け入れる前にこれを証明してもらいましょう...そう簡単に私の心を吹き飛ばします。 – TechyTimo

+0

@TechyTimo oopsがハングアップしました。申し訳ありませんが少しありました。 – meowgoesthedog

+1

@ meowgoesthedog度数で経度を取得するために180/Piを掛けて – MBo

0

私は同様の質問hereを発見し、私は私の場合のために働く機能を思い付くソリューションを追いました。

は、それが他の誰かの役に立てば幸い:

function getFinalLatLon(lat1, lon1, distance, angle){ 
    function deg2rad(deg) { 
     return deg * (Math.PI/180) 
    } 
    // dy = R*sin(theta) 
    var dy = distance * Math.sin(deg2rad(angle)) 
    var delta_latitude = dy/110574 
    // One degree of latitude on the Earth's surface equals (110574 meters 
    delta_latitude = parseFloat(delta_latitude.toFixed(6)); 

    // final latitude = start_latitude + delta_latitude 
    var lat2 = lat1 + delta_latitude 

    // dx = R*cos(theta) 
    var dx = distance * Math.cos(deg2rad(angle)) 
    // One degree of longitude equals 111321 meters (at the equator) 
    var delta_longitude = dx/(111321*Math.cos(deg2rad(lat1))) 
    delta_longitude = parseFloat(delta_longitude.toFixed(6)); 

    // final longitude = start_longitude + delta_longitude 
    var lon2 = lon1 + delta_longitude 

    return [lat2, lon2]; 
} 

角度は水平方向の移動のために0度です。それはあなたが望むように切り替えることができます。誰かが90度になる北を移動している場合。北西に135度など...

+0

これが動作するかどうかわかりません。あなたがノースノースを '2 *(90 - lat)'で動かすとしましょう。 'lat'でも終わるはずですが、' 180-lat'を得るのは間違いです。 – meowgoesthedog

+0

私はその固定されていると思う - 私は非常に必要なラジアンの変換度を逃していた。 – TechyTimo

+0

これは必要ですが、上記で指摘した問題は解決しません。 – meowgoesthedog

関連する問題