web-dev-qa-db-fra.com

Erreur de lancement de la fonction Javascript toRad ()

J'essaie de trouver la distance entre deux points (pour lesquels j'ai des latitudes et des longitudes) en utilisant la technique décrite ici à Calculer la distance entre deux points de latitude-longitude? (Formule Haversine)

Les codes sont comme ci-dessous 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

Mais quand j'essaye de l'implémenter, une erreur apparaît en disant Uncaught TypeError: Object 20 has no Method 'toRad'.

Ai-je besoin d'une bibliothèque spéciale ou de quelque chose pour faire fonctionner .toRad ()? parce que ça semble bousiller sur la deuxième ligne.

60
ptamzz

Il vous manque une déclaration de fonction.

Dans dans ce castoRad() doit d'abord être défini comme:

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

selon le segment de code tout au en bas de la page

111
Caspar Kleijne

Ou dans mon cas, cela n'a pas fonctionné. C'est peut-être parce que j'avais besoin d'appeler toRad () dans jquery. Je ne suis pas sûr à 100%, j'ai donc fait ceci:

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;
}
25
Christopher Gray

J'avais besoin de calculer beaucoup de distances entre les points pour mon projet, alors j'ai continué et j'ai essayé d'optimiser le code, j'ai trouvé ici. En moyenne, dans différents navigateurs, ma nouvelle implémentation fonctionne presque 3 fois plus vite que celle mentionnée ici.

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));
}

Vous pouvez jouer avec mon jsPerf (qui a été considérablement amélioré grâce à Bart) et voir les résultats ici .

23
Salvador Dali

Pourquoi ne pas simplifier l'équation ci-dessus et même quelques calculs?

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

4
jostmey

J'avais le même problème .. en regardant la réponse de Casper, je viens de faire une solution rapide: Ctrl+H (Rechercher et remplacer), remplacé toutes les instances de .toRad() par * Math.PI / 180. Cela a fonctionné pour moi.

Aucune idée sur les vitesses de performance du navigateur, etc., cependant. Mon cas d'utilisation n'a besoin de cela que lorsque l'utilisateur clique sur une carte.

1
Nikhil VJ

J'ai changé deux ou trois choses:

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

et, j'ai remarqué qu'il n'y avait aucune vérification pour le arguments. Vous devez vous assurer que les arguments sont définis ET probablement faire une parseInt(arg, 10)/parseFloat là-bas.

0
Cody