математический вопрос PHP + широта - PullRequest
0 голосов
/ 19 марта 2009

Я нашел функцию на странице PHP, которая вычисляет количество миль между двумя точками, но она неисправна. Предполагается, что он будет работать с картами Google, но разница в расстояниях в картах Google увеличивается в 1,3–1,65 раза (что более точно).

Вот функция:

$M =  69.09 * rad2deg(acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2))));

Я нахожу это немного сложным, и я не знаю много о геометрии, чтобы знать, правильно это или нет.

Может ли кто-то с немного большим ноу-хау взглянуть на это и посмотреть, что с ним не так?

Ответы [ 7 ]

5 голосов
/ 19 марта 2009

Может быть, вы сравниваете «расстояние по прямой линии» (прямая линия между двумя точками) с пройденным расстоянием?

Также, см. Этот пост для расчета расстояния между двумя точками в PHP.

2 голосов
/ 19 марта 2009

Существует как минимум три пары различных методов расчета расстояния на поверхности Земли, которые различаются по точности и требуемым вычислениям.

  1. Сферический закон косинусов [не очень точный, очень простой в расчете]
  2. Формула Хаверсин [точный, за исключением меньших расстояний, все еще относительно простой для вычисления]
  3. Формула Винсенти [с высокой точностью и может использовать несколько различных эллипсоидальных моделей земной поверхности, более сложных для вычисления]

Приведенный вами пример, по-видимому, является законом вычисления косинусов, в то время как Карты Google являются более точными, поскольку в них используется формула Винсенти. (Я считаю, что ссылка Винсенти объясняет формулу более подробно, чем ее страница в Википедии)

Редактировать: Я видел комментарий выше, что ошибка, вызванная отклонением на поверхности Земли, тривиальна и не может составить ошибку, которую вы видите. Боюсь, это правда только на очень больших расстояниях. На расстояниях в пару сотен километров или меньше ошибки могут быть совершенно нетривиальными.

2 голосов
/ 19 марта 2009

Вы ищете формулу Haversine для расчета расстояния между двумя точками, для которых у вас есть долгота и широта.

Простую реализацию этого в Javascript можно найти здесь , который должно быть легко преобразовать в PHP.

1 голос
/ 20 марта 2009

Вот более простая версия, но не точная для очень удаленных мест:

    const ONE_DEGREE = 111120;

public function distance( $point ) {
    $coef = cos( $this->getLatitude() / 180 * M_PI );
    $x = $this->getLatitude() - $point->getLatitude();
    $y = ( $this->getLongitude() - $point->getLongitude() ) * $coef;
    $result = sqrt( $x * $x + $y * $y ) * self::ONE_DEGREE;
    return $result;
}

$ point и $ this являются экземплярами класса Location с методами getLatitude () и getLongitude ().

0 голосов
/ 19 марта 2009

Похоже, что формула точна - см., Например, Википедия о "расстоянии большого круга" . Коэффициент 69.09 впереди, я полагаю, равен количеству миль в одном градусе по большому кругу (например, миль за 1 градус долготы на экваторе), поэтому ваш ответ будет в милях.

Идея Джонстжона о том, что вы, возможно, неправильно сравниваете расстояние по прямой линии с расстоянием езды, кажется мне наиболее вероятным объяснением.

РЕДАКТИРОВАТЬ : или это может быть ошибкой округления, о которой упоминает Википедия, если вы работаете с небольшим разделением. Но я бы сначала указал пальцем на разницу в прямом / вождении.

0 голосов
/ 19 марта 2009

Похоже, что вычисление, на которое вы ссылаетесь, использует сферическую систему координат. Формула почти правильная. Частью того, что может отбросить ваши расчеты, является радиус, который вы используете. 69.09 - это радиус сферы (в данном случае, земли). Как вы, возможно, знаете, Земля на самом деле не сфера, скорее эллипсоид. Я бы предложил попробовать следующую формулировку:

3963 * acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2)));

Для получения более точных результатов вам понадобятся расчеты Винсента или Хаверсайна.

РЕДАКТИРОВАТЬ: Чтобы уточнить, я не пытаюсь подразумевать, что большая часть ошибки, о которой вы сообщаете, связана с использованием вычисления сферических координат. Эта ошибка намного меньше, чем вы видите. Корректировка формулы, которую я представил, должна была стать более четкой версией формулы, поскольку 69.09 было значением радиуса Земли, скорректированным по системе градусов, которое менее интуитивно, чем простое использование радианов. Кроме того, стоит отметить, что для расчета очень малых расстояний использование приведенной выше формулы является очень точным (до расстояний около 1 м), если система, выполняющая вычисления, работает с достаточным количеством десятичных знаков. Использование поплавка в современных вычислениях дает вам эту точность.

0 голосов
/ 19 марта 2009

Я тоже ничего не знаю о геометрии, но Google предложил эту страницу . Возможно, вы найдете ее полезной

...