36

Haversine Distance Formula を使用しようとしています (ここにあります: http://www.movable-type.co.uk/scripts/latlong.html ) が、動作させることができません。次のコードを参照してください。

    function test() { 
    var lat2 = 42.741; 
    var lon2 = -71.3161; 
    var lat1 = 42.806911; 
    var lon1 = -71.290611; 

    var R = 6371; // km 
    //has a problem with the .toRad() method below.
    var dLat = (lat2-lat1).toRad();  
    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; 

    alert(d); 
}

エラーは次のとおりです。

Uncaught TypeError: Object -0.06591099999999983 has no method 'toRad' 

次のことを行う必要があるため、私はそれを理解している:

Number.prototype.toRad = function() {
return this * Math.PI / 180;
}

しかし、これを関数の下に置くと、同じエラーメッセージが返されます。ヘルパーメソッドを使用するにはどうすればよいですか? または、これを機能させるためにこれをコーディングする別の方法はありますか? ありがとう!

4

9 に答える 9

54

このコードは機能しています:

Number.prototype.toRad = function() {
   return this * Math.PI / 180;
}

var lat2 = 42.741; 
var lon2 = -71.3161; 
var lat1 = 42.806911; 
var lon1 = -71.290611; 

var R = 6371; // km 
//has a problem with the .toRad() method below.
var x1 = lat2-lat1;
var dLat = x1.toRad();  
var x2 = lon2-lon1;
var dLon = x2.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; 

alert(d);

x1 と x2 をどのように定義したかに注目してください。で遊んでください: https://tinker.io/3f794

于 2013-01-28T11:51:52.843 に答える
28

これは、他の3つの回答に基づいてリファクタリングされた関数です!

coords 引数は [経度、緯度] であることに注意してください。

function haversineDistance(coords1, coords2, isMiles) {
  function toRad(x) {
    return x * Math.PI / 180;
  }

  var lon1 = coords1[0];
  var lat1 = coords1[1];

  var lon2 = coords2[0];
  var lat2 = coords2[1];

  var R = 6371; // km

  var x1 = lat2 - lat1;
  var dLat = toRad(x1);
  var x2 = lon2 - lon1;
  var dLon = toRad(x2)
  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;

  if(isMiles) d /= 1.60934;

  return d;
}
于 2015-05-19T03:57:42.837 に答える
13

簡単な解決策を試してみませんか?Number プロトタイプを拡張する代わりに、toRad を通常の関数として定義するだけです。

function toRad(x) {
   return x * Math.PI / 180;
}

そして、toRadどこでも呼び出します:

var dLat = toRad(lat2-lat1); 

Number プロトタイプの拡張は、常に期待どおりに機能するとは限りません。たとえば、123.toRad() の呼び出しは機能しません。私はあなたがvar x1 = lat2 - lat1; x1.toRad();するよりもうまくいくと思います(lat2-lat1).toRad()

于 2013-01-28T11:38:04.987 に答える
1

関数でこれらの拡張機能を呼び出す前に、Numberプロトタイプを拡張する必要があります。

だから

Number.prototype.toRad = function() {
  return this * Math.PI / 180;
}

関数が呼び出される前に呼び出されます。

于 2013-01-28T11:42:30.110 に答える
1

これを関数の下に置くと

を呼び出すポイントの上に配置するだけですtest()。関数自体がどこtestで宣言されているかは問題ではありません。

于 2013-01-28T11:46:55.343 に答える
0

冗長性を減らし、Google LatLng オブジェクトとも互換性のある別のバリ​​アント:

  function haversine_distance(coords1, coords2) {

     function toRad(x) {
         return x * Math.PI / 180;
    }

  var dLat = toRad(coords2.latitude - coords1.latitude);
  var dLon = toRad(coords2.longitude - coords1.longitude)

  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
          Math.cos(toRad(coords1.latitude)) * 
          Math.cos(toRad(coords2.latitude)) *
          Math.sin(dLon / 2) * Math.sin(dLon / 2);

  return 12742 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}
于 2016-07-24T06:22:15.690 に答える
-1

これは、上記の talkol のソリューションの Java 実装です。彼または彼女のソリューションは、私たちにとって非常にうまく機能しました。元の質問はjavascriptに関するものだったので、私は質問に答えようとしていません。他の人が役に立つと思った場合に備えて、指定された JavaScript ソリューションの Java 実装を共有しているだけです。

// this was a pojo class we used internally...
public class GisPostalCode {

    private String country;
    private String postalCode;
    private double latitude;
    private double longitude;

    // getters/setters, etc.
}


public static double distanceBetweenCoordinatesInMiles2(GisPostalCode c1, GisPostalCode c2) {

    double lat2 = c2.getLatitude();
    double lon2 = c2.getLongitude();
    double lat1 = c1.getLatitude();
    double lon1 = c1.getLongitude();

    double R = 6371; // km
    double x1 = lat2 - lat1;
    double dLat = x1 * Math.PI / 180;
    double x2 = lon2 - lon1;
    double dLon = x2 * Math.PI / 180;

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

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

    // convert to miles
    return d / 1.60934;
}
于 2013-12-17T14:27:29.327 に答える