0

hi i have been struggling with using the have sine formula to get the distance between the users current location and objects in an array, i have found a great answer to this question but when i try to use variables instead of actual coordinates the formula dosent work, hopefully some one will know where i am going wrong

this is the question that got me to this point, thank you Talkol for your answer

Using the Haversine Formula in Javascript

this is what I've got so far

  navigator.geolocation.getCurrentPosition (function (posa)
{
  var lat = posa.coords.latitude.toFixed(6);
  var lng = posa.coords.longitude.toFixed(6);

});

    function getCurrent() {

var lat1 = lat; 
var lon1 = lng;

var lat2 = 42.741; 
var lon2 = -71.3161; 

Number.prototype.toRad = function() {
   return this * Math.PI / 180;
}
 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);
var distance = d

$("#distance").val (distance);
}
Community
  • 1
  • 1

2 Answers2

1

I tried to get your code working without errors. I eventually used my own code. As you can see lat2&lon2 are declared globally. The two functions Haversine() and deg2rad() are declared outside load() ,with parameters,and return values.

<script type="text/javascript">
var lat2 = 42.741; 
var lon2 = -71.3161; 

function deg2rad(degrees){
radians = degrees * (Math.PI/180);
return radians;
}

function Haversine(lat1,lon1,lat2,lon2) {
  deltaLat = lat2 - lat1 ;
  deltaLon = lon2 - lon1 ;
  earthRadius =  6369087 ; // in meters 3959 in miles.
  alpha    = deltaLat/2;
  beta     = deltaLon/2;
  a        = Math.sin(deg2rad(alpha)) * Math.sin(deg2rad(alpha)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(deg2rad(beta)) * Math.sin(deg2rad(beta)) ;
  c        = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  distance =  earthRadius * c;
  return distance.toFixed(2);
}

function load(){//Called on page load
if(navigator.geolocation)
  {
  navigator.geolocation.getCurrentPosition(function(position)
   {
  var lat1 = position.coords.latitude.toFixed(6);
  var lon1 = position.coords.longitude.toFixed(6);
  var distance = Haversine(lat1,lon1,lat2,lon2)+ " meters";
  $("#distance").val (distance);

    });
}
}
</script>
david strachan
  • 7,174
  • 2
  • 23
  • 33
  • thank you for taking the time to answer by looking at what you have written i have learnt a lot about structuring my function, i will try re structuring what i got along these lines. i also saw this similar to what aim trying to do but couldn't get it to work for me http://stackoverflow.com/questions/13166261/geolocation-loop-with-for-and-javascript – lee delaney Jul 26 '13 at 14:11
  • 6371 ... isnt that km not meters? for example, in nyc radius is 6369087 meters – kuanb Oct 21 '15 at 18:53
  • 1
    @kuanb you are correct I have changed answer to suit – david strachan Oct 21 '15 at 19:16
0

You don't appear to be declaring lat or lng in scope - they're currently being assigned as local variables in the asynchronous getCurrentPosition callback function so they are currently undefined variables (rather than Number objects).

You will need to invoke getCurrent from within the callback, and pass in the lat and lng parameters. You will still also need to keep them as Number objects - your calls to .toFixed will be forcibly converting them to strings, which will also prevent .toRad from working.

Finally, you should also only add your .toRad function to Number.prototype once, not every time that getCurrent is called.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • thank you for taking the time to answer i really appreciate it, I guess i got a lot to learn yet and have been reading about different types of and asynchronous functions, maybe use something like var distance = new Function("lat1", "lat2", lon1, lon2, "return arg1 * arg2;"); – lee delaney Jul 24 '13 at 07:13
  • No, don't use `Function` - there's no need. – Alnitak Jul 24 '13 at 07:17