27

I want to show specific information depending on where i am.

I have five cities with different information, and i want to show that city(information) that i'm closest to.

How to i do that the simplest way, using javascript.

Ex.

If i store the cities lat, long in an array

var cities = [
  ['new york', '111111', '222222', 'blablabla']
  ['boston', '111111', '222222', 'blablabla']
  ['seattle', '111111', '222222', 'blablabla']
  ['london', '111111', '222222', 'blablabla']
]

And with my current location(lat, long) i want the city that i'm closet to.

3 Answers3

57

Here is a basic code example using HTML5 geolocation to get the user's position. It then calls NearestCity() and calculates the distance (km) from the location to each city. I passed on using the Haversine formulae and instead used the simpler Pythagoras formulae and an equirectangular projection to adjust for the curvature in longitude lines.

// Get User's Coordinate from their Browser
window.onload = function() {
  // HTML5/W3C Geolocation
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(UserLocation);
  }
  // Default to Washington, DC
  else
    NearestCity(38.8951, -77.0367);
}

// Callback function for asynchronous call to HTML5 geolocation
function UserLocation(position) {
  NearestCity(position.coords.latitude, position.coords.longitude);
}


// Convert Degress to Radians
function Deg2Rad(deg) {
  return deg * Math.PI / 180;
}

function PythagorasEquirectangular(lat1, lon1, lat2, lon2) {
  lat1 = Deg2Rad(lat1);
  lat2 = Deg2Rad(lat2);
  lon1 = Deg2Rad(lon1);
  lon2 = Deg2Rad(lon2);
  var R = 6371; // km
  var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
  var y = (lat2 - lat1);
  var d = Math.sqrt(x * x + y * y) * R;
  return d;
}

var lat = 20; // user's latitude
var lon = 40; // user's longitude

var cities = [
  ["city1", 10, 50, "blah"],
  ["city2", 40, 60, "blah"],
  ["city3", 25, 10, "blah"],
  ["city4", 5, 80, "blah"]
];

function NearestCity(latitude, longitude) {
  var minDif = 99999;
  var closest;

  for (index = 0; index < cities.length; ++index) {
    var dif = PythagorasEquirectangular(latitude, longitude, cities[index][1], cities[index][2]);
    if (dif < minDif) {
      closest = index;
      minDif = dif;
    }
  }

  // echo the nearest city
  alert(cities[closest]);
}
john-raymon
  • 306
  • 1
  • 7
  • 20
Andrew - OpenGeoCode
  • 2,299
  • 18
  • 15
  • Beware, there is a typo in the following line: var dif = PythagorasEquirectangular( lat, lon, cities[ index ][ 1 ], cities[ index ][ 2 ] ); Should be var dif = PythagorasEquirectangular( latitude, longitude, cities[ index ][ 1 ], cities[ index ][ 2 ] ); – Kennet Apr 29 '16 at 13:07
  • @Kennet - thanks for letting me know about the typo. I fixed it in the answer. – Andrew - OpenGeoCode Apr 29 '16 at 21:26
  • This. is. Awesome. Thanks @Andrew-OpenGeoCode – AndrewLeonardi Aug 20 '16 at 18:25
  • This is great. I'd like to modify it to list possibly the closest three locations. – user3120861 Jul 29 '19 at 16:55
  • can anyone please explain me how this code is working, in detail? – Akhil S Jan 23 '21 at 14:21
  • var minDif = 99999; hi, please explain what is the value and what its purpose of it – SDK Jun 01 '21 at 03:00
  • @SDK the purpose of minDif would be to start with a very high value so that the first iteration will be lower. Otherwise, we'd need an edge case for the first part of the loop, since we still need the distance from the first item – Justin Jul 12 '23 at 04:39
  • Worth noting if you only care about the closest city, you could avoid multiplying by R as well as some other steps. Probably could avoid converting deg to rad. – Justin Jul 12 '23 at 04:40
21

With HTML5, you can pull the location of the user and then compares this example using a Haversine function (function below taken from here):

function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(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; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI/180)
}
Community
  • 1
  • 1
Pesulap
  • 884
  • 8
  • 19
1

You can calculate the distance by latitude with your location and the cities locations. And find the shortest and draw. To calculate you can read more in http://www.movable-type.co.uk/scripts/latlong.html

LogPi
  • 706
  • 6
  • 11