Вычислить расстояние между несколькими точками, используя jQuery и Формулу Хаверсина? [Дубликат]

Когда нужно встроить:

1. Когда кто-то хочет избежать накладных расходов на вещи, возникающие при вызове функции как передача параметров, передача управления, возврат управления и т. д.

2. Функция должна быть небольшой, часто вызываемой и сделать встроенную, действительно выгодной, поскольку в соответствии с правилом 80-20 попытайтесь сделать эту функцию встроенной, что оказывает значительное влияние на производительность программы.

Как известно, inline - это просто запрос к компилятору, подобный регистру, и он будет стоить вам при размере кода объекта.

25
задан Creights 28 January 2013 в 13:26
поделиться

7 ответов

Почему бы не попробовать прямое решение? Вместо расширения прототипа Number просто определите toRad как регулярную функцию:

function toRad(x) {
   return x * Math.PI / 180;
}

, а затем вызовите toRad всюду:

var dLat = toRad(lat2-lat1); 

Расширение прототипа Number не всегда работает как и ожидалось. Например, вызов 123.toRad () не работает. Я думаю, что если вы делаете var x1 = lat2 - lat1; x1.toRad();, работает лучше, чем (lat2-lat1).toRad()

38
ответ дан talkol 28 August 2018 в 00:26
поделиться

, когда я помещаю это ниже функции

Вам нужно только поставить ее выше точки, где вы вызываете test(). Там, где объявлена ​​функция test, не имеет значения.

1
ответ дан Bergi 28 August 2018 в 00:26
поделиться

Другой вариант уменьшения избыточности и совместимость с объектами Google LatLng:

  function haversine_distance(coords1, coords2) {

     function toRad(x) {
         return x * Math.PI / 180;
    }

  var dLat = toRad(coords2.latitude - coords1.latitude);
  var dLon = toRad(coords2.longitude - coords1.longitude)

  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
          Math.cos(toRad(coords1.latitude)) * 
          Math.cos(toRad(coords2.latitude)) *
          Math.sin(dLon / 2) * Math.sin(dLon / 2);

  return 12742 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}
1
ответ дан candidJ 28 August 2018 в 00:26
поделиться

Вам нужно расширить прототип Number, прежде чем вызывать эти расширения в функции.

Поэтому просто убедитесь, что

Number.prototype.toRad = function() {
  return this * Math.PI / 180;
}

называется до вашего функция вызывается.

1
ответ дан DanSingerman 28 August 2018 в 00:26
поделиться

Рефинансированная версия JavaScript / NodeJS для ES6:

/**
 * Calculates the haversine distance between point A, and B.
 * @param {number[]} latlngA [lat, lng] point A
 * @param {number[]} latlngB [lat, lng] point B
 * @param {boolean} isMiles If we are using miles, else km.
 */
function haversineDistance(latlngA, latlngB, isMiles) {
  const toRad = x => (x * Math.PI) / 180;
  const R = 6371; // km

  const dLat = toRad(latlngB[1] - latlngA[1]);
  const dLatSin = Math.sin(dLat / 2);
  const dLon = toRad(latlngB[0] - latlngA[0]);
  const dLonSin = Math.sin(dLon / 2);

  const a = (dLatSin * dLatSin) +
            (Math.cos(toRad(latlngA[1])) * Math.cos(toRad(latlngB[1])) * dLonSin * dLonSin);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  let distance = R * c;

  if (isMiles) distance /= 1.60934;

  return distance;
}
8
ответ дан Harry Mumford-Turner 28 August 2018 в 00:26
поделиться

Вот отредактированная функция, основанная на 3 других ответах!

Обратите внимание, что аргументы в коордорах - [долгота, широта].

function haversineDistance(coords1, coords2, isMiles) {
  function toRad(x) {
    return x * Math.PI / 180;
  }

  var lon1 = coords1[0];
  var lat1 = coords1[1];

  var lon2 = coords2[0];
  var lat2 = coords2[1];

  var R = 6371; // km

  var x1 = lat2 - lat1;
  var dLat = toRad(x1);
  var x2 = lon2 - lon1;
  var dLon = toRad(x2)
  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;

  if(isMiles) d /= 1.60934;

  return d;
}
19
ответ дан Nathan Lippi 28 August 2018 в 00:26
поделиться

Это java-реализация решения Talkol выше. Его или ее решение работало очень хорошо для нас. Я не пытаюсь ответить на вопрос, так как исходный вопрос был для javascript. Я просто разделяю нашу реализацию java данного javascript-решения, если другие считают его полезным.

// this was a pojo class we used internally...
public class GisPostalCode {

    private String country;
    private String postalCode;
    private double latitude;
    private double longitude;

    // getters/setters, etc.
}


public static double distanceBetweenCoordinatesInMiles2(GisPostalCode c1, GisPostalCode c2) {

    double lat2 = c2.getLatitude();
    double lon2 = c2.getLongitude();
    double lat1 = c1.getLatitude();
    double lon1 = c1.getLongitude();

    double R = 6371; // km
    double x1 = lat2 - lat1;
    double dLat = x1 * Math.PI / 180;
    double x2 = lon2 - lon1;
    double dLon = x2 * Math.PI / 180;

    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(lat1*Math.PI/180) * Math.cos(lat2*Math.PI/180) *
        Math.sin(dLon/2) * Math.sin(dLon/2);

    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double d = R * c;

    // convert to miles
    return d / 1.60934;
}
0
ответ дан Perry Tew 28 August 2018 в 00:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: