2011-03-10 87 views
58

我試圖找到利用這裏描述的技術的兩個點(對我已經緯度經度&)之間的距離在Calculate distance between two latitude-longitude points? (Haversine formula)toRad()JavaScript函數拋出錯誤

的代碼如下 的Javascript:

var R = 6371; // Radius of the earth in km 
var dLat = (lat2-lat1).toRad(); // Javascript functions in radians 
var dLon = (lon2-lon1).toRad(); 
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
     Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
     Math.sin(dLon/2) * Math.sin(dLon/2); 
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
var d = R * c; // Distance in km 

但是,當我嘗試實現它時,出現一個錯誤,說明Uncaught TypeError: Object 20 has no Method 'toRad'

我需要一個特殊的庫或東西來獲得.toRad()的工作?因爲它似乎是 搞砸了第二線。

+2

請參閱[我的答案](http://stackoverflow.com/a/21623256/1090562)與Haversine距離的優化版本。平均而言,它的運行速度比起始解決方案快兩倍。 – 2014-02-07 08:56:05

回答

24

或者對於我來說這沒有工作

/** Converts numeric degrees to radians */ 
if (typeof(Number.prototype.toRad) === "undefined") { 
    Number.prototype.toRad = function() { 
    return this * Math.PI/180; 
    } 
} 

this casetoRad()必須首先被定義爲。這可能是因爲我需要在jQuery中調用toRad()。林不是100%肯定,所以我這樣做:

function CalcDistanceBetween(lat1, lon1, lat2, lon2) { 
    //Radius of the earth in: 1.609344 miles, 6371 km | var R = (6371/1.609344); 
    var R = 3958.7558657440545; // Radius of earth in Miles 
    var dLat = toRad(lat2-lat1); 
    var dLon = toRad(lon2-lon1); 
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
      Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * 
      Math.sin(dLon/2) * Math.sin(dLon/2); 
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    var d = R * c; 
    return d; 
} 

function toRad(Value) { 
    /** Converts numeric degrees to radians */ 
    return Value * Math.PI/180; 
} 
4

爲什麼不簡化上述方程和相同的幾個計算?

Math.sin(dLat/2) * Math.sin(dLat/2) = (1.0-Math.cos(dLat))/2.0

Math.sin(dLon/2) * Math.sin(dLon/2) = (1.0-Math.cos(dLon))/2.0

+0

延遲添加:因爲觸發標識是抽象的; cos版本在小距離上變得數值不佳。另外,優化編譯器可能會列出常用術語。差的微優化。 – ChrisV 2016-08-14 13:18:32

0

我改變了一些事情:

if (!Number.prototype.toRad || (typeof(Number.prototype.toRad) === undefined)) { 

和,我注意到有沒有檢查的arguments。您應該確保參數已定義,並且可能在那裏執行parseInt(arg, 10)/parseFloat

20

我需要爲我的項目計算點之間的很多距離,所以我繼續嘗試優化代碼,我在這裏找到了。平均而言,在不同的瀏覽器中,我的新實現的運行速度幾乎快於此處提及的3倍

function distance(lat1, lon1, lat2, lon2) { 
    var R = 6371; // Radius of the earth in km 
    var dLat = (lat2 - lat1) * Math.PI/180; // deg2rad below 
    var dLon = (lon2 - lon1) * Math.PI/180; 
    var a = 
    0.5 - Math.cos(dLat)/2 + 
    Math.cos(lat1 * Math.PI/180) * Math.cos(lat2 * Math.PI/180) * 
    (1 - Math.cos(dLon))/2; 

    return R * 2 * Math.asin(Math.sqrt(a)); 
} 

你可以用我的jsPerf(這是大大提高了感謝Bart)玩,看到results here

+0

您的代碼適用於我的用例。謝謝! – 2015-11-18 00:45:40

1

我有同樣的問題..看着卡斯帕的回答,我只是做了一個快速修復:Ctrl+H(查找和替換), 取代的.toRad() 所有實例* Math.PI/180。這對我有效。

雖然沒有關於瀏覽器性能速度的想法,但是..我的用例只在用戶點擊地圖時才需要。