Нужна помощь в расчете географического расстояния - PullRequest
8 голосов
/ 14 января 2012

Я настраиваю небольшую программу, чтобы взять 2 географические координаты от пользователя и затем вычислить расстояние между ними (с учетом кривизны Земли). Поэтому я посмотрел википедию о том, что формула здесь .

Я в основном настроил свою функцию python, основываясь на этом, и вот что я придумал:

def geocalc(start_lat, start_long, end_lat, end_long):
    start_lat = math.radians(start_lat)
    start_long = math.radians(start_long)
    end_lat = math.radians(end_long)
    end_long = math.radians(end_long)

    d_lat = start_lat - end_lat
    d_long = start_long - end_long

    EARTH_R = 6372.8

    c = math.atan((math.sqrt( (math.cos(end_lat)*d_long)**2 +( (math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2)) / ((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long))) )

    return EARTH_R*c

Проблема в том, что результаты получаются действительно неточными. Я новичок в Python, поэтому некоторая помощь или совет будет принята с благодарностью!

Ответы [ 4 ]

11 голосов
/ 14 января 2012

У вас 4, 5 или 6 проблем:

(1) end_lat = math.radians(end_long) должно быть end_lat = math.radians(end_lat)

(2) вам не хватает некоторых вещей, о которых кто-то уже упоминал, скорее всего потому, что

(3) ваш код неразборчив (слишком длинная строка, лишние скобки, 17 бессмысленных примеров "математики")

(4) вы не заметили замечание в статье в Википедии об использовании atan2()

(5) Возможно, вы вводили координаты в широте и долготе

(6) delta(latitude) вычисляется без необходимости; оно не фигурирует в формуле

Собираем все вместе:

from math import radians, sqrt, sin, cos, atan2

def geocalc(lat1, lon1, lat2, lon2):
    lat1 = radians(lat1)
    lon1 = radians(lon1)
    lat2 = radians(lat2)
    lon2 = radians(lon2)

    dlon = lon1 - lon2

    EARTH_R = 6372.8

    y = sqrt(
        (cos(lat2) * sin(dlon)) ** 2
        + (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)) ** 2
        )
    x = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(dlon)
    c = atan2(y, x)
    return EARTH_R * c



>>> geocalc(36.12, -86.67, 33.94, -118.40)
2887.2599506071115
>>> geocalc(-6.508, 55.071, -8.886, 51.622)
463.09798886300376
>>> geocalc(55.071, -6.508, 51.622, -8.886)
414.7830891822618
4 голосов
/ 14 января 2012

Это работает (печать f возвращает 2887,26 км в соответствии с обработанным примером @ http://en.wikipedia.org/wiki/Great-circle_distance):

import math

def geocalc(start_lat, start_long, end_lat, end_long):

    start_lat = math.radians(start_lat)
    start_long = math.radians(start_long)
    end_lat = math.radians(end_lat)
    end_long = math.radians(end_long)

    d_lat = math.fabs(start_lat - end_lat)
    d_long = math.fabs(start_long - end_long)

    EARTH_R = 6372.8

    y = ((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long)))

    x = math.sqrt((math.cos(end_lat)*math.sin(d_long))**2 + ( (math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2)

    c = math.atan(x/y)

    return EARTH_R*c

f = geocalc(36.12, -86.67, 33.94, -118.40)
print f

Обратите внимание на эту строку в вашем представлении: end_lat = math.radians(end_long)

4 голосов
/ 14 января 2012

Вы можете использовать модуль геопсии, который имеет встроенную функцию для расчета расстояний, прокрутите вниз до «Расчет расстояний» по ссылке ниже: https://pypi.python.org/pypi/geopy

3 голосов
/ 14 января 2012

Я думаю, что вы пропустили math.sin (d_long) в начале, может быть, это так:

 c = math.atan((math.sqrt( (math.cos(end_lat)*math.sin(d_long))**2 +( (math.cos(start_lat)*math.sin(end_lat)) - (math.sin(start_lat)*math.cos(end_lat)*math.cos(d_long)))**2)) / ((math.sin(start_lat)*math.sin(end_lat)) + (math.cos(start_lat)*math.cos(end_lat)*math.cos(d_long))) )
...