Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries. Thanks for all your past and future contributions.

Calculating distance between two map points - Haversine functions in JavaScript

Article
Created: Maveric (31 Dec 2010)
Last edited: hamishwillee (05 Dec 2011)

Overview

With this JavaScript code and modified by your own needs, you should be able to calculate the distance mathematically between two points on a map, using the Haversine formula. The code is an excerpt, so there may be variables that are not needed defined.

Source file

`// Define variables  var your_longitudes = new Array();  var your_latitudes = new Array();  var R = 6371; // Earth's mean radius in km used by calculateDistance()  var dLat = 0;  var dLon = 0;  var d = 0;  var ylatFirst = "";  var ylatSecond = "";  var ylonFirst =  "";  var ylonSecond = "";  var lat1 = "";  var lat2 = "";  var lon1 = "";  var lon2 = "";  var i = 0;  var z = 0;  ... /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */// extend Number object with methods for converting degrees/radians/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */          Number.prototype.toRad = function() {  // convert degrees to radians	 return this * Math.PI / 180;	 }          Number.prototype.toDeg = function() {  // convert radians to degrees (signed)	 return this * 180 / Math.PI; 	 }         /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */	 // Use Haversine formula to calculate distance (in km) between two points specified by	 // latitude/longitude (in numeric degrees)	 //	 // from: Haversine formula - R. W. Sinnott, "Virtues of the Haversine",	 //       Sky and Telescope, vol 68, no 2, 1984	 //       http://www.census.gov/cgi-bin/geo/gisfaq?Q5.1	 //         /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */           function calculateDistance ()          { 		  dLat = (ylatSecond-ylatFirst).toRad();		  dLon = (ylonSecond-ylonFirst).toRad();       		  ylatFirst_floated = parseFloat(ylatFirst).toRad();		  ylatSecond_floated = parseFloat(ylatSecond).toRad();       		  var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(ylatFirst_floated) * Math.cos(lat2) *                   Math.sin(dLon/2) * Math.sin(dLon/2);		  var c = 2 * Math.asin(Math.sqrt(a));	    	  d = R * c;  // d equals to the distance between the two points in kilometers.          }       ... 	calculateDistance(ylatFirst.parseDeg(), ylonFirst.parseDeg(), ylatSecond.parseDeg(), ylonSecond.parseDeg());    alert('Distance between your points is : '+d+' km.'); 	...        /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */    // extend String object with method for parsing degrees or lat/long values to numeric degrees	//	// this is very flexible on formats, allowing signed decimal degrees, or deg-min-sec suffixed by	// compass direction (NSEW). A variety of separators are accepted (eg 3º 37' 09"W) or fixed-width	// format without separators (eg 0033709W). Seconds and minutes may be omitted. (Minimal validation	// is done).	//    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */ 	String.prototype.parseDeg = function()         {	  if (!isNaN(this)) return Number(this);                    // signed decimal degrees without NSEW	  var degLL = this.replace(/^-/,'').replace(/[NSEW]/i,'');  // strip off any sign or compass dir'n	  var dms = degLL.split(/[^0-9.]+/);                        // split out separate d/m/s	  for (var i in dms) if (dms[i]=='') dms.splice(i,1);       // remove empty elements (see note below)	  switch (dms.length) {                                     // convert to decimal degrees... 	  case 3:                                             // interpret 3-part result as d/m/s          var deg = dms[0]/1 + dms[1]/60 + dms[2]/3600; break;          case 2:                                                         // interpret 2-part result as d/m          var deg = dms[0]/1 + dms[1]/60; break;          case 1:                                                         // decimal or non-separated dddmmss 	  if (/[NS]/i.test(this)) degLL = '0' + degLL;                  // - normalise N/S to 3-digit degrees            var deg = dms[0].slice(0,3)/1 + dms[0].slice(3,5)/60 + dms[0].slice(5)/3600; break;  	    default: return NaN;		  }		  if (/^-/.test(this) || /[WS]/i.test(this)) deg = -deg;            // take '-', west and south as -ve		  return deg;	}	// note: whitespace at start/end will split() into empty elements (except in IE)`