Какой пакет NPM я должен использовать для поиска ближайшего города. - PullRequest
2 голосов
/ 27 ноября 2011

Я использую Node.js и MongoDB.Допустим, у меня есть несколько предопределенных городов (например, Сиэтл, Майами, Нью-Йорк) с Lat & Lon.и пользователь нажимает на мой веб-сайт, и я знаю его IP-адрес, и узнаю его адрес.Затем я хочу узнать, какой город, который я определил, ближе всего к пользователю.

Я знаю, что могу сделать это, используя геопространственную функцию Монго.но было бы довольно «дорого» использовать БД для вычисления этого для каждого веб-запроса.

Существует ли пакет NPM Node.js, который может выполнять гео-функцию, как я описал выше?

Ответы [ 2 ]

5 голосов
/ 28 ноября 2011

С какими «заранее определенными» городами вы работаете?Если это небольшое число, вы можете просто сохранить список в памяти и выполнить линейное сканирование.Кроме того, вы, вероятно, должны просто дать геопространственному запросу mongo попытку получить представление о том, насколько точно это дорого, прежде чем предполагать, что это неразумно - если вы укажете местоположение города и, это будет довольно быстро. Если вы имеете делос большим количеством пунктов, все еще не хочу полагаться на моно-индексирование монго, и нужно что-то действительно специализированное, возможно, R-Tree стоило бы экспериментировать с.Вот реализация r-дерева для JavaScript.https://github.com/imbcmdth/RTree

3 голосов
/ 28 ноября 2011

Если у вас уже есть местоположение пользователя и местоположение каждого города, должно быть достаточно быстро вычислить расстояние до ближайшего.Проверьте этот сайт: http://www.movable -type.co.uk / scripts / latlong.html Я использовал первый алгоритм несколько раз.

  function getDistance(lat1,lat2,lon1,lon2){
    var R = 6371; // km
    var c = Math.PI / 180;
    var dLat = (lat2-lat1) * c;
    var dLon = (lon2-lon1) * c;
    var lat1 = lat1 * c;
    var lat2 = lat2 * c;

    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    var d = R * c;
    return d;
   }
var closest, dist = Number.MAX_VALUE;
for(var i = 0, l=cities.length;i<l;++i){
  if(getDistance(cities[i].longitude, cities[i].latitude, user.longitude, user.latitude) < max){
  closest = cities[i];
 }
}

  alert(closest.name + ' is the winner :)');

Возможно, вы захотите добавитьнекоторая обработка исключений здесь:)

...